| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library fasta.body_builder; | 5 library fasta.body_builder; |
| 6 | 6 |
| 7 import '../fasta_codes.dart' | 7 import '../fasta_codes.dart' |
| 8 show FastaMessage, codeExpectedButGot, codeExpectedFunctionBody; | 8 show FastaMessage, codeExpectedButGot, codeExpectedFunctionBody; |
| 9 | 9 |
| 10 import '../parser/parser.dart' show FormalParameterType, optional; | 10 import '../parser/parser.dart' show FormalParameterType, optional; |
| (...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 } | 657 } |
| 658 if (optional("&&", token) || optional("||", token)) { | 658 if (optional("&&", token) || optional("||", token)) { |
| 659 return doLogicalExpression(token); | 659 return doLogicalExpression(token); |
| 660 } | 660 } |
| 661 if (optional("??", token)) return doIfNull(token); | 661 if (optional("??", token)) return doIfNull(token); |
| 662 if (optional("?.", token)) return doIfNotNull(token); | 662 if (optional("?.", token)) return doIfNotNull(token); |
| 663 Expression argument = popForValue(); | 663 Expression argument = popForValue(); |
| 664 var receiver = pop(); | 664 var receiver = pop(); |
| 665 bool isSuper = false; | 665 bool isSuper = false; |
| 666 if (receiver is ThisAccessor && receiver.isSuper) { | 666 if (receiver is ThisAccessor && receiver.isSuper) { |
| 667 ThisAccessor thisAccessorReceiver = receiver; |
| 667 isSuper = true; | 668 isSuper = true; |
| 668 receiver = new ThisExpression(); | 669 receiver = astFactory.thisExpression(thisAccessorReceiver.token); |
| 669 } | 670 } |
| 670 push(buildBinaryOperator(toValue(receiver), token, argument, isSuper)); | 671 push(buildBinaryOperator(toValue(receiver), token, argument, isSuper)); |
| 671 } | 672 } |
| 672 | 673 |
| 673 Expression buildBinaryOperator( | 674 Expression buildBinaryOperator( |
| 674 Expression a, Token token, Expression b, bool isSuper) { | 675 Expression a, Token token, Expression b, bool isSuper) { |
| 675 bool negate = false; | 676 bool negate = false; |
| 676 String operator = token.stringValue; | 677 String operator = token.stringValue; |
| 677 if (identical("!=", operator)) { | 678 if (identical("!=", operator)) { |
| 678 operator = "=="; | 679 operator = "=="; |
| 679 negate = true; | 680 negate = true; |
| 680 } | 681 } |
| 681 if (!isBinaryOperator(operator) && !isMinusOperator(operator)) { | 682 if (!isBinaryOperator(operator) && !isMinusOperator(operator)) { |
| 682 return buildCompileTimeError( | 683 return buildCompileTimeError( |
| 683 "Not an operator: '$operator'.", token.charOffset); | 684 "Not an operator: '$operator'.", token.charOffset); |
| 684 } else { | 685 } else { |
| 685 Expression result = | 686 Expression result = |
| 686 makeBinary(a, new Name(operator), null, b, offset: token.charOffset); | 687 makeBinary(a, new Name(operator), null, b, offset: token.charOffset); |
| 687 if (isSuper) { | 688 if (isSuper) { |
| 688 result = toSuperMethodInvocation(result); | 689 result = toSuperMethodInvocation(result); |
| 689 } | 690 } |
| 690 return negate ? new Not(result) : result; | 691 return negate ? astFactory.not(null, result) : result; |
| 691 } | 692 } |
| 692 } | 693 } |
| 693 | 694 |
| 694 void doLogicalExpression(Token token) { | 695 void doLogicalExpression(Token token) { |
| 695 Expression argument = popForValue(); | 696 Expression argument = popForValue(); |
| 696 Expression receiver = popForValue(); | 697 Expression receiver = popForValue(); |
| 697 push(new LogicalExpression(receiver, token.stringValue, argument)); | 698 push(astFactory.logicalExpression(receiver, token.stringValue, argument)); |
| 698 } | 699 } |
| 699 | 700 |
| 700 /// Handle `a ?? b`. | 701 /// Handle `a ?? b`. |
| 701 void doIfNull(Token token) { | 702 void doIfNull(Token token) { |
| 702 Expression b = popForValue(); | 703 Expression b = popForValue(); |
| 703 Expression a = popForValue(); | 704 Expression a = popForValue(); |
| 704 VariableDeclaration variable = new VariableDeclaration.forValue(a); | 705 VariableDeclaration variable = new VariableDeclaration.forValue(a); |
| 705 push(makeLet( | 706 push(makeLet( |
| 706 variable, | 707 variable, |
| 707 new ConditionalExpression(buildIsNull(new VariableGet(variable)), b, | 708 new ConditionalExpression(buildIsNull(new VariableGet(variable)), b, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 722 } | 723 } |
| 723 | 724 |
| 724 @override | 725 @override |
| 725 Expression toSuperMethodInvocation(MethodInvocation node) { | 726 Expression toSuperMethodInvocation(MethodInvocation node) { |
| 726 Member target = lookupSuperMember(node.name); | 727 Member target = lookupSuperMember(node.name); |
| 727 bool isNoSuchMethod = target == null; | 728 bool isNoSuchMethod = target == null; |
| 728 if (target is Procedure) { | 729 if (target is Procedure) { |
| 729 if (!target.isAccessor) { | 730 if (!target.isAccessor) { |
| 730 if (areArgumentsCompatible(target.function, node.arguments)) { | 731 if (areArgumentsCompatible(target.function, node.arguments)) { |
| 731 // TODO(ahe): Use [DirectMethodInvocation] when possible. | 732 // TODO(ahe): Use [DirectMethodInvocation] when possible. |
| 732 Expression result = new DirectMethodInvocation( | 733 Expression result = astFactory.directMethodInvocation( |
| 733 new ThisExpression(), target, node.arguments); | 734 new ThisExpression(), target, node.arguments); |
| 734 result = new SuperMethodInvocation(node.name, node.arguments, null); | 735 result = astFactory.superMethodInvocation( |
| 736 null, node.name, node.arguments, null); |
| 735 return result; | 737 return result; |
| 736 } else { | 738 } else { |
| 737 isNoSuchMethod = true; | 739 isNoSuchMethod = true; |
| 738 } | 740 } |
| 739 } | 741 } |
| 740 } | 742 } |
| 741 if (isNoSuchMethod) { | 743 if (isNoSuchMethod) { |
| 742 return throwNoSuchMethodError( | 744 return throwNoSuchMethodError( |
| 743 node.name.name, node.arguments, node.fileOffset, | 745 node.name.name, node.arguments, node.fileOffset, |
| 744 isSuper: true); | 746 isSuper: true); |
| 745 } | 747 } |
| 746 // TODO(ahe): Use [DirectPropertyGet] when possible. | 748 // TODO(ahe): Use [DirectPropertyGet] when possible. |
| 747 Expression receiver = new DirectPropertyGet(new ThisExpression(), target); | 749 Expression receiver = |
| 748 receiver = new SuperPropertyGet(node.name, target); | 750 astFactory.directPropertyGet(new ThisExpression(), target); |
| 751 receiver = astFactory.superPropertyGet(node.name, target); |
| 749 return buildMethodInvocation( | 752 return buildMethodInvocation( |
| 750 receiver, callName, node.arguments, node.fileOffset); | 753 receiver, callName, node.arguments, node.fileOffset); |
| 751 } | 754 } |
| 752 | 755 |
| 753 bool areArgumentsCompatible(FunctionNode function, Arguments arguments) { | 756 bool areArgumentsCompatible(FunctionNode function, Arguments arguments) { |
| 754 // TODO(ahe): Implement this. | 757 // TODO(ahe): Implement this. |
| 755 return true; | 758 return true; |
| 756 } | 759 } |
| 757 | 760 |
| 758 @override | 761 @override |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1170 exitLocalScope(); | 1173 exitLocalScope(); |
| 1171 push(block); | 1174 push(block); |
| 1172 } | 1175 } |
| 1173 | 1176 |
| 1174 @override | 1177 @override |
| 1175 void handleAssignmentExpression(Token token) { | 1178 void handleAssignmentExpression(Token token) { |
| 1176 debugEvent("AssignmentExpression"); | 1179 debugEvent("AssignmentExpression"); |
| 1177 Expression value = popForValue(); | 1180 Expression value = popForValue(); |
| 1178 var accessor = pop(); | 1181 var accessor = pop(); |
| 1179 if (accessor is TypeDeclarationBuilder) { | 1182 if (accessor is TypeDeclarationBuilder) { |
| 1180 push(wrapInvalid(new TypeLiteral( | 1183 push(wrapInvalid(astFactory |
| 1181 accessor.buildTypesWithBuiltArguments(library, null)))); | 1184 .typeLiteral(accessor.buildTypesWithBuiltArguments(library, null)))); |
| 1182 } else if (accessor is! FastaAccessor) { | 1185 } else if (accessor is! FastaAccessor) { |
| 1183 push(buildCompileTimeError("Can't assign to this.", token.charOffset)); | 1186 push(buildCompileTimeError("Can't assign to this.", token.charOffset)); |
| 1184 } else { | 1187 } else { |
| 1185 push(new DelayedAssignment( | 1188 push(new DelayedAssignment( |
| 1186 this, token, accessor, value, token.stringValue)); | 1189 this, token, accessor, value, token.stringValue)); |
| 1187 } | 1190 } |
| 1188 } | 1191 } |
| 1189 | 1192 |
| 1190 @override | 1193 @override |
| 1191 void enterLoop(int charOffset) { | 1194 void enterLoop(int charOffset) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1252 result = new Block(<Statement>[begin, result]); | 1255 result = new Block(<Statement>[begin, result]); |
| 1253 } | 1256 } |
| 1254 if (breakTarget.hasUsers) { | 1257 if (breakTarget.hasUsers) { |
| 1255 result = new LabeledStatement(result); | 1258 result = new LabeledStatement(result); |
| 1256 breakTarget.resolveBreaks(result); | 1259 breakTarget.resolveBreaks(result); |
| 1257 } | 1260 } |
| 1258 exitLoopOrSwitch(result); | 1261 exitLoopOrSwitch(result); |
| 1259 } | 1262 } |
| 1260 | 1263 |
| 1261 @override | 1264 @override |
| 1262 void endAwaitExpression(Token beginToken, Token endToken) { | 1265 void endAwaitExpression(Token keyword, Token endToken) { |
| 1263 debugEvent("AwaitExpression"); | 1266 debugEvent("AwaitExpression"); |
| 1264 push( | 1267 push(astFactory.awaitExpression(keyword, popForValue())); |
| 1265 new AwaitExpression(popForValue())..fileOffset = beginToken.charOffset); | |
| 1266 } | 1268 } |
| 1267 | 1269 |
| 1268 @override | 1270 @override |
| 1269 void handleAsyncModifier(Token asyncToken, Token starToken) { | 1271 void handleAsyncModifier(Token asyncToken, Token starToken) { |
| 1270 debugEvent("AsyncModifier"); | 1272 debugEvent("AsyncModifier"); |
| 1271 push(asyncMarkerFromTokens(asyncToken, starToken)); | 1273 push(asyncMarkerFromTokens(asyncToken, starToken)); |
| 1272 } | 1274 } |
| 1273 | 1275 |
| 1274 @override | 1276 @override |
| 1275 void handleLiteralList( | 1277 void handleLiteralList( |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1323 if (typeArguments.length != 2) { | 1325 if (typeArguments.length != 2) { |
| 1324 keyType = const DynamicType(); | 1326 keyType = const DynamicType(); |
| 1325 valueType = const DynamicType(); | 1327 valueType = const DynamicType(); |
| 1326 warningNotError( | 1328 warningNotError( |
| 1327 "Map literal requires two type arguments.", beginToken.charOffset); | 1329 "Map literal requires two type arguments.", beginToken.charOffset); |
| 1328 } else { | 1330 } else { |
| 1329 keyType = typeArguments[0]; | 1331 keyType = typeArguments[0]; |
| 1330 valueType = typeArguments[1]; | 1332 valueType = typeArguments[1]; |
| 1331 } | 1333 } |
| 1332 } | 1334 } |
| 1333 push(new MapLiteral(entries, | 1335 push(astFactory.mapLiteral(beginToken, constKeyword, entries, |
| 1334 keyType: keyType, valueType: valueType, isConst: constKeyword != null) | 1336 keyType: keyType, valueType: valueType)); |
| 1335 ..fileOffset = constKeyword?.charOffset ?? beginToken.charOffset); | |
| 1336 } | 1337 } |
| 1337 | 1338 |
| 1338 @override | 1339 @override |
| 1339 void endLiteralMapEntry(Token colon, Token endToken) { | 1340 void endLiteralMapEntry(Token colon, Token endToken) { |
| 1340 debugEvent("LiteralMapEntry"); | 1341 debugEvent("LiteralMapEntry"); |
| 1341 Expression value = popForValue(); | 1342 Expression value = popForValue(); |
| 1342 Expression key = popForValue(); | 1343 Expression key = popForValue(); |
| 1343 push(new MapEntry(key, value)); | 1344 push(new MapEntry(key, value)); |
| 1344 } | 1345 } |
| 1345 | 1346 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1359 String value; | 1360 String value; |
| 1360 if (identifierCount == 1) { | 1361 if (identifierCount == 1) { |
| 1361 value = symbolPartToString(pop()); | 1362 value = symbolPartToString(pop()); |
| 1362 } else { | 1363 } else { |
| 1363 List parts = popList(identifierCount); | 1364 List parts = popList(identifierCount); |
| 1364 value = symbolPartToString(parts.first); | 1365 value = symbolPartToString(parts.first); |
| 1365 for (int i = 1; i < parts.length; i++) { | 1366 for (int i = 1; i < parts.length; i++) { |
| 1366 value += ".${symbolPartToString(parts[i])}"; | 1367 value += ".${symbolPartToString(parts[i])}"; |
| 1367 } | 1368 } |
| 1368 } | 1369 } |
| 1369 push(new SymbolLiteral(value)); | 1370 push(astFactory.symbolLiteral(hashToken, value)); |
| 1370 } | 1371 } |
| 1371 | 1372 |
| 1372 DartType kernelTypeFromString( | 1373 DartType kernelTypeFromString( |
| 1373 String name, List<DartType> arguments, int charOffset) { | 1374 String name, List<DartType> arguments, int charOffset) { |
| 1374 Builder builder = scope.lookup(name, charOffset, uri); | 1375 Builder builder = scope.lookup(name, charOffset, uri); |
| 1375 if (builder == null) { | 1376 if (builder == null) { |
| 1376 warning("Type not found: '$name'.", charOffset); | 1377 warning("Type not found: '$name'.", charOffset); |
| 1377 return const DynamicType(); | 1378 return const DynamicType(); |
| 1378 } else { | 1379 } else { |
| 1379 return kernelTypeFromBuilder(builder, arguments, charOffset); | 1380 return kernelTypeFromBuilder(builder, arguments, charOffset); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1471 void handleVoidKeyword(Token token) { | 1472 void handleVoidKeyword(Token token) { |
| 1472 debugEvent("VoidKeyword"); | 1473 debugEvent("VoidKeyword"); |
| 1473 push(const VoidType()); | 1474 push(const VoidType()); |
| 1474 } | 1475 } |
| 1475 | 1476 |
| 1476 @override | 1477 @override |
| 1477 void handleAsOperator(Token operator, Token endToken) { | 1478 void handleAsOperator(Token operator, Token endToken) { |
| 1478 debugEvent("AsOperator"); | 1479 debugEvent("AsOperator"); |
| 1479 DartType type = pop(); | 1480 DartType type = pop(); |
| 1480 Expression expression = popForValue(); | 1481 Expression expression = popForValue(); |
| 1481 push(new AsExpression(expression, type)..fileOffset = operator.charOffset); | 1482 push(astFactory.asExpression(expression, operator, type)); |
| 1482 } | 1483 } |
| 1483 | 1484 |
| 1484 @override | 1485 @override |
| 1485 void handleIsOperator(Token operator, Token not, Token endToken) { | 1486 void handleIsOperator(Token operator, Token not, Token endToken) { |
| 1486 debugEvent("IsOperator"); | 1487 debugEvent("IsOperator"); |
| 1487 DartType type = pop(); | 1488 DartType type = pop(); |
| 1488 Expression operand = popForValue(); | 1489 Expression operand = popForValue(); |
| 1489 bool isInverted = not != null; | 1490 bool isInverted = not != null; |
| 1490 Expression isExpression = | 1491 Expression isExpression = |
| 1491 astFactory.isExpression(operand, type, operator, isInverted); | 1492 astFactory.isExpression(operand, type, operator, isInverted); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1507 } | 1508 } |
| 1508 | 1509 |
| 1509 @override | 1510 @override |
| 1510 void endThrowExpression(Token throwToken, Token endToken) { | 1511 void endThrowExpression(Token throwToken, Token endToken) { |
| 1511 debugEvent("ThrowExpression"); | 1512 debugEvent("ThrowExpression"); |
| 1512 Expression expression = popForValue(); | 1513 Expression expression = popForValue(); |
| 1513 if (constantExpressionRequired) { | 1514 if (constantExpressionRequired) { |
| 1514 push(buildCompileTimeError( | 1515 push(buildCompileTimeError( |
| 1515 "Not a constant expression.", throwToken.charOffset)); | 1516 "Not a constant expression.", throwToken.charOffset)); |
| 1516 } else { | 1517 } else { |
| 1517 push(new Throw(expression)..fileOffset = throwToken.charOffset); | 1518 push(astFactory.throwExpression(throwToken, expression)); |
| 1518 } | 1519 } |
| 1519 } | 1520 } |
| 1520 | 1521 |
| 1521 @override | 1522 @override |
| 1522 void endFormalParameter(Token covariantKeyword, Token thisKeyword, | 1523 void endFormalParameter(Token covariantKeyword, Token thisKeyword, |
| 1523 Token nameToken, FormalParameterType kind) { | 1524 Token nameToken, FormalParameterType kind) { |
| 1524 debugEvent("FormalParameter"); | 1525 debugEvent("FormalParameter"); |
| 1525 // TODO(ahe): Need beginToken here. | 1526 // TODO(ahe): Need beginToken here. |
| 1526 int charOffset = thisKeyword?.charOffset; | 1527 int charOffset = thisKeyword?.charOffset; |
| 1527 if (thisKeyword != null) { | 1528 if (thisKeyword != null) { |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1726 push(IndexAccessor.make( | 1727 push(IndexAccessor.make( |
| 1727 this, openCurlyBracket, toValue(receiver), index, null, null)); | 1728 this, openCurlyBracket, toValue(receiver), index, null, null)); |
| 1728 } | 1729 } |
| 1729 } | 1730 } |
| 1730 | 1731 |
| 1731 @override | 1732 @override |
| 1732 void handleUnaryPrefixExpression(Token token) { | 1733 void handleUnaryPrefixExpression(Token token) { |
| 1733 debugEvent("UnaryPrefixExpression"); | 1734 debugEvent("UnaryPrefixExpression"); |
| 1734 var receiver = pop(); | 1735 var receiver = pop(); |
| 1735 if (optional("!", token)) { | 1736 if (optional("!", token)) { |
| 1736 push(new Not(toValue(receiver))); | 1737 push(astFactory.not(token, toValue(receiver))); |
| 1737 } else { | 1738 } else { |
| 1738 String operator = token.stringValue; | 1739 String operator = token.stringValue; |
| 1739 if (optional("-", token)) { | 1740 if (optional("-", token)) { |
| 1740 operator = "unary-"; | 1741 operator = "unary-"; |
| 1741 } | 1742 } |
| 1742 if (receiver is ThisAccessor && receiver.isSuper) { | 1743 if (receiver is ThisAccessor && receiver.isSuper) { |
| 1743 push(toSuperMethodInvocation(buildMethodInvocation( | 1744 push(toSuperMethodInvocation(buildMethodInvocation( |
| 1744 new ThisExpression()..fileOffset = offsetForToken(receiver.token), | 1745 astFactory.thisExpression(receiver.token), |
| 1745 new Name(operator), | 1746 new Name(operator), |
| 1746 new Arguments.empty(), | 1747 new Arguments.empty(), |
| 1747 token.charOffset))); | 1748 token.charOffset))); |
| 1748 } else { | 1749 } else { |
| 1749 push(buildMethodInvocation(toValue(receiver), new Name(operator), | 1750 push(buildMethodInvocation(toValue(receiver), new Name(operator), |
| 1750 new Arguments.empty(), token.charOffset)); | 1751 new Arguments.empty(), token.charOffset)); |
| 1751 } | 1752 } |
| 1752 } | 1753 } |
| 1753 } | 1754 } |
| 1754 | 1755 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1842 {bool isConst: false, int charOffset: -1}) { | 1843 {bool isConst: false, int charOffset: -1}) { |
| 1843 List<TypeParameter> typeParameters = target.function.typeParameters; | 1844 List<TypeParameter> typeParameters = target.function.typeParameters; |
| 1844 if (target is Constructor) { | 1845 if (target is Constructor) { |
| 1845 assert(!target.enclosingClass.isAbstract); | 1846 assert(!target.enclosingClass.isAbstract); |
| 1846 typeParameters = target.enclosingClass.typeParameters; | 1847 typeParameters = target.enclosingClass.typeParameters; |
| 1847 } | 1848 } |
| 1848 if (!checkArguments(target.function, arguments, typeParameters)) { | 1849 if (!checkArguments(target.function, arguments, typeParameters)) { |
| 1849 return throwNoSuchMethodError(target.name.name, arguments, charOffset); | 1850 return throwNoSuchMethodError(target.name.name, arguments, charOffset); |
| 1850 } | 1851 } |
| 1851 if (target is Constructor) { | 1852 if (target is Constructor) { |
| 1852 return new ConstructorInvocation(target, arguments) | 1853 return astFactory.constructorInvocation(target, arguments, |
| 1853 ..isConst = isConst | 1854 isConst: isConst) |
| 1854 ..fileOffset = charOffset; | 1855 ..fileOffset = charOffset; |
| 1855 } else { | 1856 } else { |
| 1856 return new StaticInvocation(target, arguments) | 1857 return astFactory.staticInvocation(target, arguments, isConst: isConst) |
| 1857 ..isConst = isConst | |
| 1858 ..fileOffset = charOffset; | 1858 ..fileOffset = charOffset; |
| 1859 } | 1859 } |
| 1860 } | 1860 } |
| 1861 | 1861 |
| 1862 @override | 1862 @override |
| 1863 bool checkArguments(FunctionNode function, Arguments arguments, | 1863 bool checkArguments(FunctionNode function, Arguments arguments, |
| 1864 List<TypeParameter> typeParameters) { | 1864 List<TypeParameter> typeParameters) { |
| 1865 if (arguments.positional.length < function.requiredParameterCount || | 1865 if (arguments.positional.length < function.requiredParameterCount || |
| 1866 arguments.positional.length > function.positionalParameters.length) { | 1866 arguments.positional.length > function.positionalParameters.length) { |
| 1867 return false; | 1867 return false; |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2235 if (target.continueTarget.hasUsers) { | 2235 if (target.continueTarget.hasUsers) { |
| 2236 if (statement is! LabeledStatement) { | 2236 if (statement is! LabeledStatement) { |
| 2237 statement = new LabeledStatement(statement); | 2237 statement = new LabeledStatement(statement); |
| 2238 } | 2238 } |
| 2239 target.continueTarget.resolveContinues(statement); | 2239 target.continueTarget.resolveContinues(statement); |
| 2240 } | 2240 } |
| 2241 push(statement); | 2241 push(statement); |
| 2242 } | 2242 } |
| 2243 | 2243 |
| 2244 @override | 2244 @override |
| 2245 void endRethrowStatement(Token throwToken, Token endToken) { | 2245 void endRethrowStatement(Token rethrowToken, Token endToken) { |
| 2246 debugEvent("RethrowStatement"); | 2246 debugEvent("RethrowStatement"); |
| 2247 if (inCatchBlock) { | 2247 if (inCatchBlock) { |
| 2248 push(astFactory.expressionStatement( | 2248 push(astFactory |
| 2249 new Rethrow()..fileOffset = throwToken.charOffset)); | 2249 .expressionStatement(astFactory.rethrowExpression(rethrowToken))); |
| 2250 } else { | 2250 } else { |
| 2251 push(buildCompileTimeErrorStatement( | 2251 push(buildCompileTimeErrorStatement( |
| 2252 "'rethrow' can only be used in catch clauses.", | 2252 "'rethrow' can only be used in catch clauses.", |
| 2253 throwToken.charOffset)); | 2253 rethrowToken.charOffset)); |
| 2254 } | 2254 } |
| 2255 } | 2255 } |
| 2256 | 2256 |
| 2257 @override | 2257 @override |
| 2258 void handleFinallyBlock(Token finallyKeyword) { | 2258 void handleFinallyBlock(Token finallyKeyword) { |
| 2259 debugEvent("FinallyBlock"); | 2259 debugEvent("FinallyBlock"); |
| 2260 // Do nothing, handled by [endTryStatement]. | 2260 // Do nothing, handled by [endTryStatement]. |
| 2261 } | 2261 } |
| 2262 | 2262 |
| 2263 @override | 2263 @override |
| (...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3126 } else if (node is PrefixBuilder) { | 3126 } else if (node is PrefixBuilder) { |
| 3127 return node.name; | 3127 return node.name; |
| 3128 } else if (node is ThisAccessor) { | 3128 } else if (node is ThisAccessor) { |
| 3129 return node.isSuper ? "super" : "this"; | 3129 return node.isSuper ? "super" : "this"; |
| 3130 } else if (node is FastaAccessor) { | 3130 } else if (node is FastaAccessor) { |
| 3131 return node.plainNameForRead; | 3131 return node.plainNameForRead; |
| 3132 } else { | 3132 } else { |
| 3133 return internalError("Unhandled: ${node.runtimeType}"); | 3133 return internalError("Unhandled: ${node.runtimeType}"); |
| 3134 } | 3134 } |
| 3135 } | 3135 } |
| OLD | NEW |