| 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; |
| 11 | 11 |
| 12 import '../parser/identifier_context.dart' show IdentifierContext; | 12 import '../parser/identifier_context.dart' show IdentifierContext; |
| 13 | 13 |
| 14 import 'package:front_end/src/fasta/builder/ast_factory.dart' show AstFactory; | 14 import 'package:front_end/src/fasta/builder/ast_factory.dart' show AstFactory; |
| 15 | 15 |
| 16 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart' | 16 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart' |
| 17 show KernelField, KernelVariableDeclaration; | 17 show KernelField; |
| 18 | 18 |
| 19 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart' | 19 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart' |
| 20 show FieldNode; | 20 show FieldNode; |
| 21 | 21 |
| 22 import 'package:front_end/src/fasta/type_inference/type_inferrer.dart' | 22 import 'package:front_end/src/fasta/type_inference/type_inferrer.dart' |
| 23 show TypeInferrer; | 23 show TypeInferrer; |
| 24 | 24 |
| 25 import 'package:front_end/src/fasta/type_inference/type_promotion.dart' |
| 26 show TypePromoter; |
| 27 |
| 25 import 'package:kernel/ast.dart'; | 28 import 'package:kernel/ast.dart'; |
| 26 | 29 |
| 27 import 'package:kernel/clone.dart' show CloneVisitor; | 30 import 'package:kernel/clone.dart' show CloneVisitor; |
| 28 | 31 |
| 29 import 'package:kernel/transformations/flags.dart' show TransformerFlag; | 32 import 'package:kernel/transformations/flags.dart' show TransformerFlag; |
| 30 | 33 |
| 31 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy; | 34 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy; |
| 32 | 35 |
| 33 import 'package:kernel/core_types.dart' show CoreTypes; | 36 import 'package:kernel/core_types.dart' show CoreTypes; |
| 34 | 37 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 final Map<String, FieldInitializer> fieldInitializers = | 86 final Map<String, FieldInitializer> fieldInitializers = |
| 84 <String, FieldInitializer>{}; | 87 <String, FieldInitializer>{}; |
| 85 | 88 |
| 86 final Scope enclosingScope; | 89 final Scope enclosingScope; |
| 87 | 90 |
| 88 final bool isDartLibrary; | 91 final bool isDartLibrary; |
| 89 | 92 |
| 90 @override | 93 @override |
| 91 final Uri uri; | 94 final Uri uri; |
| 92 | 95 |
| 93 final TypeInferrer<Statement, Expression, KernelVariableDeclaration, | 96 final TypeInferrer<Statement, Expression, VariableDeclaration, KernelField> |
| 94 KernelField> _typeInferrer; | 97 _typeInferrer; |
| 95 | 98 |
| 99 @override |
| 96 final AstFactory astFactory; | 100 final AstFactory astFactory; |
| 97 | 101 |
| 102 @override |
| 103 final TypePromoter<Expression, VariableDeclaration> typePromoter; |
| 104 |
| 98 /// If not `null`, dependencies on fields are accumulated into this list. | 105 /// If not `null`, dependencies on fields are accumulated into this list. |
| 99 /// | 106 /// |
| 100 /// If `null`, no dependency information is recorded. | 107 /// If `null`, no dependency information is recorded. |
| 101 final List<FieldNode<KernelField>> fieldDependencies; | 108 final List<FieldNode<KernelField>> fieldDependencies; |
| 102 | 109 |
| 103 /// Only used when [member] is a constructor. It tracks if an implicit super | 110 /// Only used when [member] is a constructor. It tracks if an implicit super |
| 104 /// initializer is needed. | 111 /// initializer is needed. |
| 105 /// | 112 /// |
| 106 /// An implicit super initializer isn't needed | 113 /// An implicit super initializer isn't needed |
| 107 /// | 114 /// |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 this.isInstanceMember, | 156 this.isInstanceMember, |
| 150 this.uri, | 157 this.uri, |
| 151 this._typeInferrer, | 158 this._typeInferrer, |
| 152 this.astFactory, | 159 this.astFactory, |
| 153 {this.fieldDependencies}) | 160 {this.fieldDependencies}) |
| 154 : enclosingScope = scope, | 161 : enclosingScope = scope, |
| 155 library = library, | 162 library = library, |
| 156 isDartLibrary = library.uri.scheme == "dart", | 163 isDartLibrary = library.uri.scheme == "dart", |
| 157 needsImplicitSuperInitializer = | 164 needsImplicitSuperInitializer = |
| 158 coreTypes.objectClass != classBuilder?.cls, | 165 coreTypes.objectClass != classBuilder?.cls, |
| 166 typePromoter = _typeInferrer.typePromoter, |
| 159 super(scope); | 167 super(scope); |
| 160 | 168 |
| 161 bool get hasParserError => recoverableErrors.isNotEmpty; | 169 bool get hasParserError => recoverableErrors.isNotEmpty; |
| 162 | 170 |
| 163 bool get inConstructor { | 171 bool get inConstructor { |
| 164 return functionNestingLevel == 0 && member is KernelConstructorBuilder; | 172 return functionNestingLevel == 0 && member is KernelConstructorBuilder; |
| 165 } | 173 } |
| 166 | 174 |
| 167 bool get isInstanceContext { | 175 bool get isInstanceContext { |
| 168 return isInstanceMember || member is KernelConstructorBuilder; | 176 return isInstanceMember || member is KernelConstructorBuilder; |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 | 456 |
| 449 @override | 457 @override |
| 450 void endInitializers(int count, Token beginToken, Token endToken) { | 458 void endInitializers(int count, Token beginToken, Token endToken) { |
| 451 debugEvent("Initializers"); | 459 debugEvent("Initializers"); |
| 452 } | 460 } |
| 453 | 461 |
| 454 @override | 462 @override |
| 455 void finishFunction( | 463 void finishFunction( |
| 456 FormalParameters formals, AsyncMarker asyncModifier, Statement body) { | 464 FormalParameters formals, AsyncMarker asyncModifier, Statement body) { |
| 457 debugEvent("finishFunction"); | 465 debugEvent("finishFunction"); |
| 466 typePromoter.finished(); |
| 458 _typeInferrer.inferStatement(body); | 467 _typeInferrer.inferStatement(body); |
| 459 KernelFunctionBuilder builder = member; | 468 KernelFunctionBuilder builder = member; |
| 460 builder.body = body; | 469 builder.body = body; |
| 461 if (formals?.optional != null) { | 470 if (formals?.optional != null) { |
| 462 Iterator<FormalParameterBuilder> formalBuilders = | 471 Iterator<FormalParameterBuilder> formalBuilders = |
| 463 builder.formals.skip(formals.required.length).iterator; | 472 builder.formals.skip(formals.required.length).iterator; |
| 464 for (VariableDeclaration parameter in formals.optional.formals) { | 473 for (VariableDeclaration parameter in formals.optional.formals) { |
| 465 bool hasMore = formalBuilders.moveNext(); | 474 bool hasMore = formalBuilders.moveNext(); |
| 466 assert(hasMore); | 475 assert(hasMore); |
| 467 VariableDeclaration realParameter = formalBuilders.current.target; | 476 VariableDeclaration realParameter = formalBuilders.current.target; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 /// >and no body is provided, then c implicitly has an empty body {}. | 531 /// >and no body is provided, then c implicitly has an empty body {}. |
| 523 /// We use an empty statement instead. | 532 /// We use an empty statement instead. |
| 524 constructor.function.body = new EmptyStatement(); | 533 constructor.function.body = new EmptyStatement(); |
| 525 constructor.function.body.parent = constructor.function; | 534 constructor.function.body.parent = constructor.function; |
| 526 } | 535 } |
| 527 } | 536 } |
| 528 | 537 |
| 529 @override | 538 @override |
| 530 void endExpressionStatement(Token token) { | 539 void endExpressionStatement(Token token) { |
| 531 debugEvent("ExpressionStatement"); | 540 debugEvent("ExpressionStatement"); |
| 532 push(new ExpressionStatement(popForEffect())); | 541 push(astFactory.expressionStatement(popForEffect())); |
| 533 } | 542 } |
| 534 | 543 |
| 535 @override | 544 @override |
| 536 void endArguments(int count, Token beginToken, Token endToken) { | 545 void endArguments(int count, Token beginToken, Token endToken) { |
| 537 debugEvent("Arguments"); | 546 debugEvent("Arguments"); |
| 538 List arguments = popList(count) ?? <Expression>[]; | 547 List arguments = popList(count) ?? <Expression>[]; |
| 539 int firstNamedArgumentIndex = arguments.length; | 548 int firstNamedArgumentIndex = arguments.length; |
| 540 for (int i = 0; i < arguments.length; i++) { | 549 for (int i = 0; i < arguments.length; i++) { |
| 541 var node = arguments[i]; | 550 var node = arguments[i]; |
| 542 if (node is NamedExpression) { | 551 if (node is NamedExpression) { |
| (...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1035 Expression expression = hasExpression ? popForValue() : null; | 1044 Expression expression = hasExpression ? popForValue() : null; |
| 1036 if (expression != null && inConstructor) { | 1045 if (expression != null && inConstructor) { |
| 1037 push(buildCompileTimeErrorStatement( | 1046 push(buildCompileTimeErrorStatement( |
| 1038 "Can't return from a constructor.", beginToken.charOffset)); | 1047 "Can't return from a constructor.", beginToken.charOffset)); |
| 1039 } else { | 1048 } else { |
| 1040 push(new ReturnStatement(expression)..fileOffset = beginToken.charOffset); | 1049 push(new ReturnStatement(expression)..fileOffset = beginToken.charOffset); |
| 1041 } | 1050 } |
| 1042 } | 1051 } |
| 1043 | 1052 |
| 1044 @override | 1053 @override |
| 1054 void beginThenStatement(Token token) { |
| 1055 Expression condition = popForValue(); |
| 1056 typePromoter.enterThen(condition); |
| 1057 push(condition); |
| 1058 super.beginThenStatement(token); |
| 1059 } |
| 1060 |
| 1061 @override |
| 1062 void endThenStatement(Token token) { |
| 1063 typePromoter.enterElse(); |
| 1064 super.endThenStatement(token); |
| 1065 } |
| 1066 |
| 1067 @override |
| 1045 void endIfStatement(Token ifToken, Token elseToken) { | 1068 void endIfStatement(Token ifToken, Token elseToken) { |
| 1046 Statement elsePart = popStatementIfNotNull(elseToken); | 1069 Statement elsePart = popStatementIfNotNull(elseToken); |
| 1047 Statement thenPart = popStatement(); | 1070 Statement thenPart = popStatement(); |
| 1048 Expression condition = popForValue(); | 1071 Expression condition = popForValue(); |
| 1049 push(new IfStatement(condition, thenPart, elsePart)); | 1072 typePromoter.exitConditional(); |
| 1073 push(astFactory.ifStatement(condition, thenPart, elsePart)); |
| 1050 } | 1074 } |
| 1051 | 1075 |
| 1052 @override | 1076 @override |
| 1053 void endVariableInitializer(Token assignmentOperator) { | 1077 void endVariableInitializer(Token assignmentOperator) { |
| 1054 debugEvent("VariableInitializer"); | 1078 debugEvent("VariableInitializer"); |
| 1055 assert(assignmentOperator.stringValue == "="); | 1079 assert(assignmentOperator.stringValue == "="); |
| 1056 pushNewLocalVariable(popForValue(), | 1080 pushNewLocalVariable(popForValue(), |
| 1057 equalsCharOffset: assignmentOperator.charOffset); | 1081 equalsCharOffset: assignmentOperator.charOffset); |
| 1058 } | 1082 } |
| 1059 | 1083 |
| 1060 @override | 1084 @override |
| 1061 void handleNoVariableInitializer(Token token) { | 1085 void handleNoVariableInitializer(Token token) { |
| 1062 debugEvent("NoVariableInitializer"); | 1086 debugEvent("NoVariableInitializer"); |
| 1063 pushNewLocalVariable(null); | 1087 pushNewLocalVariable(null); |
| 1064 } | 1088 } |
| 1065 | 1089 |
| 1066 void pushNewLocalVariable(Expression initializer, | 1090 void pushNewLocalVariable(Expression initializer, |
| 1067 {int equalsCharOffset: TreeNode.noOffset}) { | 1091 {int equalsCharOffset: TreeNode.noOffset}) { |
| 1068 Identifier identifier = pop(); | 1092 Identifier identifier = pop(); |
| 1069 assert(currentLocalVariableModifiers != -1); | 1093 assert(currentLocalVariableModifiers != -1); |
| 1070 bool isConst = (currentLocalVariableModifiers & constMask) != 0; | 1094 bool isConst = (currentLocalVariableModifiers & constMask) != 0; |
| 1071 bool isFinal = (currentLocalVariableModifiers & finalMask) != 0; | 1095 bool isFinal = (currentLocalVariableModifiers & finalMask) != 0; |
| 1072 assert(isConst == constantExpressionRequired); | 1096 assert(isConst == constantExpressionRequired); |
| 1073 push(astFactory.variableDeclaration(identifier.name, identifier.fileOffset, | 1097 push(astFactory.variableDeclaration( |
| 1098 identifier.name, identifier.fileOffset, functionNestingLevel, |
| 1074 initializer: initializer, | 1099 initializer: initializer, |
| 1075 type: currentLocalVariableType, | 1100 type: currentLocalVariableType, |
| 1076 isFinal: isFinal, | 1101 isFinal: isFinal, |
| 1077 isConst: isConst, | 1102 isConst: isConst, |
| 1078 equalsCharOffset: equalsCharOffset)); | 1103 equalsCharOffset: equalsCharOffset)); |
| 1079 } | 1104 } |
| 1080 | 1105 |
| 1081 @override | 1106 @override |
| 1082 void endFieldInitializer(Token assignmentOperator, Token token) { | 1107 void endFieldInitializer(Token assignmentOperator, Token token) { |
| 1083 debugEvent("FieldInitializer"); | 1108 debugEvent("FieldInitializer"); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1203 } | 1228 } |
| 1204 if (variableOrExpression is VariableDeclaration) { | 1229 if (variableOrExpression is VariableDeclaration) { |
| 1205 variables.add(variableOrExpression); | 1230 variables.add(variableOrExpression); |
| 1206 } else if (variableOrExpression is List) { | 1231 } else if (variableOrExpression is List) { |
| 1207 // TODO(sigmund): remove this assignment (see issue #28651) | 1232 // TODO(sigmund): remove this assignment (see issue #28651) |
| 1208 Iterable vars = variableOrExpression; | 1233 Iterable vars = variableOrExpression; |
| 1209 variables.addAll(vars); | 1234 variables.addAll(vars); |
| 1210 } else if (variableOrExpression == null) { | 1235 } else if (variableOrExpression == null) { |
| 1211 // Do nothing. | 1236 // Do nothing. |
| 1212 } else if (variableOrExpression is Expression) { | 1237 } else if (variableOrExpression is Expression) { |
| 1213 begin = new ExpressionStatement(variableOrExpression); | 1238 begin = astFactory.expressionStatement(variableOrExpression); |
| 1214 } else { | 1239 } else { |
| 1215 return internalError("Unhandled: ${variableOrExpression.runtimeType}"); | 1240 return internalError("Unhandled: ${variableOrExpression.runtimeType}"); |
| 1216 } | 1241 } |
| 1217 exitLocalScope(); | 1242 exitLocalScope(); |
| 1218 JumpTarget continueTarget = exitContinueTarget(); | 1243 JumpTarget continueTarget = exitContinueTarget(); |
| 1219 JumpTarget breakTarget = exitBreakTarget(); | 1244 JumpTarget breakTarget = exitBreakTarget(); |
| 1220 if (continueTarget.hasUsers) { | 1245 if (continueTarget.hasUsers) { |
| 1221 body = new LabeledStatement(body); | 1246 body = new LabeledStatement(body); |
| 1222 continueTarget.resolveContinues(body); | 1247 continueTarget.resolveContinues(body); |
| 1223 } | 1248 } |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1453 debugEvent("AsOperator"); | 1478 debugEvent("AsOperator"); |
| 1454 DartType type = pop(); | 1479 DartType type = pop(); |
| 1455 Expression expression = popForValue(); | 1480 Expression expression = popForValue(); |
| 1456 push(new AsExpression(expression, type)..fileOffset = operator.charOffset); | 1481 push(new AsExpression(expression, type)..fileOffset = operator.charOffset); |
| 1457 } | 1482 } |
| 1458 | 1483 |
| 1459 @override | 1484 @override |
| 1460 void handleIsOperator(Token operator, Token not, Token endToken) { | 1485 void handleIsOperator(Token operator, Token not, Token endToken) { |
| 1461 debugEvent("IsOperator"); | 1486 debugEvent("IsOperator"); |
| 1462 DartType type = pop(); | 1487 DartType type = pop(); |
| 1463 Expression expression = popForValue(); | 1488 Expression operand = popForValue(); |
| 1464 expression = new IsExpression(expression, type) | 1489 bool isInverted = not != null; |
| 1465 ..fileOffset = operator.charOffset; | 1490 Expression isExpression = |
| 1466 if (not != null) { | 1491 astFactory.isExpression(operand, type, operator.charOffset, isInverted); |
| 1467 expression = new Not(expression); | 1492 if (operand is VariableGet) { |
| 1493 typePromoter.handleIsCheck(isExpression, isInverted, operand.variable, |
| 1494 type, functionNestingLevel); |
| 1468 } | 1495 } |
| 1469 push(expression); | 1496 push(isExpression); |
| 1470 } | 1497 } |
| 1471 | 1498 |
| 1472 @override | 1499 @override |
| 1473 void handleConditionalExpression(Token question, Token colon) { | 1500 void handleConditionalExpression(Token question, Token colon) { |
| 1474 debugEvent("ConditionalExpression"); | 1501 debugEvent("ConditionalExpression"); |
| 1475 Expression elseExpression = popForValue(); | 1502 Expression elseExpression = popForValue(); |
| 1476 Expression thenExpression = popForValue(); | 1503 Expression thenExpression = popForValue(); |
| 1477 Expression condition = popForValue(); | 1504 Expression condition = popForValue(); |
| 1478 push(new ConditionalExpression( | 1505 push(new ConditionalExpression( |
| 1479 condition, thenExpression, elseExpression, const DynamicType())); | 1506 condition, thenExpression, elseExpression, const DynamicType())); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1527 } else if (thisKeyword == null) { | 1554 } else if (thisKeyword == null) { |
| 1528 variable = builder.build(library); | 1555 variable = builder.build(library); |
| 1529 variable.initializer = name.initializer; | 1556 variable.initializer = name.initializer; |
| 1530 } else if (builder.isField && builder.parent == classBuilder) { | 1557 } else if (builder.isField && builder.parent == classBuilder) { |
| 1531 FieldBuilder field = builder; | 1558 FieldBuilder field = builder; |
| 1532 if (type != null) { | 1559 if (type != null) { |
| 1533 nit("Ignoring type on 'this' parameter '${name.name}'.", | 1560 nit("Ignoring type on 'this' parameter '${name.name}'.", |
| 1534 thisKeyword.charOffset); | 1561 thisKeyword.charOffset); |
| 1535 } | 1562 } |
| 1536 type = field.target.type ?? const DynamicType(); | 1563 type = field.target.type ?? const DynamicType(); |
| 1537 variable = astFactory.variableDeclaration(name.name, name.fileOffset, | 1564 variable = astFactory.variableDeclaration( |
| 1565 name.name, name.fileOffset, functionNestingLevel, |
| 1538 type: type, | 1566 type: type, |
| 1539 initializer: name.initializer, | 1567 initializer: name.initializer, |
| 1540 isFinal: isFinal, | 1568 isFinal: isFinal, |
| 1541 isConst: isConst); | 1569 isConst: isConst); |
| 1542 } else { | 1570 } else { |
| 1543 addCompileTimeError( | 1571 addCompileTimeError( |
| 1544 name.fileOffset, "'${name.name}' isn't a field in this class."); | 1572 name.fileOffset, "'${name.name}' isn't a field in this class."); |
| 1545 } | 1573 } |
| 1546 } | 1574 } |
| 1547 variable ??= astFactory.variableDeclaration(name.name, name.fileOffset, | 1575 variable ??= astFactory.variableDeclaration( |
| 1576 name.name, name.fileOffset, functionNestingLevel, |
| 1548 type: type ?? const DynamicType(), | 1577 type: type ?? const DynamicType(), |
| 1549 initializer: name.initializer, | 1578 initializer: name.initializer, |
| 1550 isFinal: isFinal, | 1579 isFinal: isFinal, |
| 1551 isConst: isConst); | 1580 isConst: isConst); |
| 1552 push(variable); | 1581 push(variable); |
| 1553 } | 1582 } |
| 1554 | 1583 |
| 1555 @override | 1584 @override |
| 1556 void endOptionalFormalParameters( | 1585 void endOptionalFormalParameters( |
| 1557 int count, Token beginToken, Token endToken) { | 1586 int count, Token beginToken, Token endToken) { |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2000 debugEvent("NamedArgument"); | 2029 debugEvent("NamedArgument"); |
| 2001 Expression value = popForValue(); | 2030 Expression value = popForValue(); |
| 2002 Identifier identifier = pop(); | 2031 Identifier identifier = pop(); |
| 2003 push(new NamedExpression(identifier.name, value)); | 2032 push(new NamedExpression(identifier.name, value)); |
| 2004 } | 2033 } |
| 2005 | 2034 |
| 2006 @override | 2035 @override |
| 2007 void endFunctionName(Token beginToken, Token token) { | 2036 void endFunctionName(Token beginToken, Token token) { |
| 2008 debugEvent("FunctionName"); | 2037 debugEvent("FunctionName"); |
| 2009 Identifier name = pop(); | 2038 Identifier name = pop(); |
| 2010 VariableDeclaration variable = astFactory | 2039 VariableDeclaration variable = astFactory.variableDeclaration( |
| 2011 .variableDeclaration(name.name, name.fileOffset, isFinal: true); | 2040 name.name, name.fileOffset, functionNestingLevel, |
| 2041 isFinal: true); |
| 2012 push(new FunctionDeclaration( | 2042 push(new FunctionDeclaration( |
| 2013 variable, new FunctionNode(new InvalidStatement())) | 2043 variable, new FunctionNode(new InvalidStatement())) |
| 2014 ..fileOffset = beginToken.charOffset); | 2044 ..fileOffset = beginToken.charOffset); |
| 2015 scope[variable.name] = new KernelVariableBuilder( | 2045 scope[variable.name] = new KernelVariableBuilder( |
| 2016 variable, member ?? classBuilder ?? library, uri); | 2046 variable, member ?? classBuilder ?? library, uri); |
| 2017 enterLocalScope(); | 2047 enterLocalScope(); |
| 2018 } | 2048 } |
| 2019 | 2049 |
| 2020 void enterFunction() { | 2050 void enterFunction() { |
| 2021 debugEvent("enterFunction"); | 2051 debugEvent("enterFunction"); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2081 Statement body = popStatement(); | 2111 Statement body = popStatement(); |
| 2082 AsyncMarker asyncModifier = pop(); | 2112 AsyncMarker asyncModifier = pop(); |
| 2083 exitLocalScope(); | 2113 exitLocalScope(); |
| 2084 FormalParameters formals = pop(); | 2114 FormalParameters formals = pop(); |
| 2085 exitFunction(); | 2115 exitFunction(); |
| 2086 List<TypeParameter> typeParameters = pop(); | 2116 List<TypeParameter> typeParameters = pop(); |
| 2087 FunctionNode function = formals.addToFunction(new FunctionNode(body, | 2117 FunctionNode function = formals.addToFunction(new FunctionNode(body, |
| 2088 typeParameters: typeParameters, asyncMarker: asyncModifier) | 2118 typeParameters: typeParameters, asyncMarker: asyncModifier) |
| 2089 ..fileOffset = beginToken.charOffset | 2119 ..fileOffset = beginToken.charOffset |
| 2090 ..fileEndOffset = token.charOffset); | 2120 ..fileEndOffset = token.charOffset); |
| 2091 push(new FunctionExpression(function)..fileOffset = beginToken.charOffset); | 2121 push(astFactory.functionExpression(function, beginToken.charOffset)); |
| 2092 } | 2122 } |
| 2093 | 2123 |
| 2094 @override | 2124 @override |
| 2095 void endDoWhileStatement( | 2125 void endDoWhileStatement( |
| 2096 Token doKeyword, Token whileKeyword, Token endToken) { | 2126 Token doKeyword, Token whileKeyword, Token endToken) { |
| 2097 debugEvent("DoWhileStatement"); | 2127 debugEvent("DoWhileStatement"); |
| 2098 Expression condition = popForValue(); | 2128 Expression condition = popForValue(); |
| 2099 Statement body = popStatement(); | 2129 Statement body = popStatement(); |
| 2100 JumpTarget continueTarget = exitContinueTarget(); | 2130 JumpTarget continueTarget = exitContinueTarget(); |
| 2101 JumpTarget breakTarget = exitBreakTarget(); | 2131 JumpTarget breakTarget = exitBreakTarget(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2147 /// for (lvalue in expression) body | 2177 /// for (lvalue in expression) body |
| 2148 /// | 2178 /// |
| 2149 /// This is normalized to: | 2179 /// This is normalized to: |
| 2150 /// | 2180 /// |
| 2151 /// for (final #t in expression) { | 2181 /// for (final #t in expression) { |
| 2152 /// lvalue = #t; | 2182 /// lvalue = #t; |
| 2153 /// body; | 2183 /// body; |
| 2154 /// } | 2184 /// } |
| 2155 variable = new VariableDeclaration.forValue(null); | 2185 variable = new VariableDeclaration.forValue(null); |
| 2156 body = combineStatements( | 2186 body = combineStatements( |
| 2157 new ExpressionStatement(lvalue | 2187 astFactory.expressionStatement(lvalue |
| 2158 .buildAssignment(new VariableGet(variable), voidContext: true)), | 2188 .buildAssignment(new VariableGet(variable), voidContext: true)), |
| 2159 body); | 2189 body); |
| 2160 } else { | 2190 } else { |
| 2161 variable = new VariableDeclaration.forValue(buildCompileTimeError( | 2191 variable = new VariableDeclaration.forValue(buildCompileTimeError( |
| 2162 "Expected lvalue, but got ${lvalue}", forToken.next.next.charOffset)); | 2192 "Expected lvalue, but got ${lvalue}", forToken.next.next.charOffset)); |
| 2163 } | 2193 } |
| 2164 Statement result = new ForInStatement(variable, expression, body, | 2194 Statement result = new ForInStatement(variable, expression, body, |
| 2165 isAsync: awaitToken != null) | 2195 isAsync: awaitToken != null) |
| 2166 ..fileOffset = body.fileOffset; | 2196 ..fileOffset = body.fileOffset; |
| 2167 if (breakTarget.hasUsers) { | 2197 if (breakTarget.hasUsers) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2209 } | 2239 } |
| 2210 target.continueTarget.resolveContinues(statement); | 2240 target.continueTarget.resolveContinues(statement); |
| 2211 } | 2241 } |
| 2212 push(statement); | 2242 push(statement); |
| 2213 } | 2243 } |
| 2214 | 2244 |
| 2215 @override | 2245 @override |
| 2216 void endRethrowStatement(Token throwToken, Token endToken) { | 2246 void endRethrowStatement(Token throwToken, Token endToken) { |
| 2217 debugEvent("RethrowStatement"); | 2247 debugEvent("RethrowStatement"); |
| 2218 if (inCatchBlock) { | 2248 if (inCatchBlock) { |
| 2219 push(new ExpressionStatement( | 2249 push(astFactory.expressionStatement( |
| 2220 new Rethrow()..fileOffset = throwToken.charOffset)); | 2250 new Rethrow()..fileOffset = throwToken.charOffset)); |
| 2221 } else { | 2251 } else { |
| 2222 push(buildCompileTimeErrorStatement( | 2252 push(buildCompileTimeErrorStatement( |
| 2223 "'rethrow' can only be used in catch clauses.", | 2253 "'rethrow' can only be used in catch clauses.", |
| 2224 throwToken.charOffset)); | 2254 throwToken.charOffset)); |
| 2225 } | 2255 } |
| 2226 } | 2256 } |
| 2227 | 2257 |
| 2228 @override | 2258 @override |
| 2229 void handleFinallyBlock(Token finallyKeyword) { | 2259 void handleFinallyBlock(Token finallyKeyword) { |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2518 Expression buildAbstractClassInstantiationError(String className, | 2548 Expression buildAbstractClassInstantiationError(String className, |
| 2519 [int charOffset = -1]) { | 2549 [int charOffset = -1]) { |
| 2520 warning("The class '$className' is abstract and can't be instantiated.", | 2550 warning("The class '$className' is abstract and can't be instantiated.", |
| 2521 charOffset); | 2551 charOffset); |
| 2522 Builder constructor = library.loader.getAbstractClassInstantiationError(); | 2552 Builder constructor = library.loader.getAbstractClassInstantiationError(); |
| 2523 return new Throw(buildStaticInvocation(constructor.target, | 2553 return new Throw(buildStaticInvocation(constructor.target, |
| 2524 new Arguments(<Expression>[new StringLiteral(className)]))); | 2554 new Arguments(<Expression>[new StringLiteral(className)]))); |
| 2525 } | 2555 } |
| 2526 | 2556 |
| 2527 Statement buildCompileTimeErrorStatement(error, [int charOffset = -1]) { | 2557 Statement buildCompileTimeErrorStatement(error, [int charOffset = -1]) { |
| 2528 return new ExpressionStatement(buildCompileTimeError(error, charOffset)); | 2558 return astFactory |
| 2559 .expressionStatement(buildCompileTimeError(error, charOffset)); |
| 2529 } | 2560 } |
| 2530 | 2561 |
| 2531 @override | 2562 @override |
| 2532 Initializer buildInvalidIntializer(Expression expression, | 2563 Initializer buildInvalidIntializer(Expression expression, |
| 2533 [int charOffset = -1]) { | 2564 [int charOffset = -1]) { |
| 2534 needsImplicitSuperInitializer = false; | 2565 needsImplicitSuperInitializer = false; |
| 2535 return new LocalInitializer(new VariableDeclaration.forValue(expression)) | 2566 return new LocalInitializer(new VariableDeclaration.forValue(expression)) |
| 2536 ..fileOffset = charOffset; | 2567 ..fileOffset = charOffset; |
| 2537 } | 2568 } |
| 2538 | 2569 |
| (...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3094 } else if (node is PrefixBuilder) { | 3125 } else if (node is PrefixBuilder) { |
| 3095 return node.name; | 3126 return node.name; |
| 3096 } else if (node is ThisAccessor) { | 3127 } else if (node is ThisAccessor) { |
| 3097 return node.isSuper ? "super" : "this"; | 3128 return node.isSuper ? "super" : "this"; |
| 3098 } else if (node is FastaAccessor) { | 3129 } else if (node is FastaAccessor) { |
| 3099 return node.plainNameForRead; | 3130 return node.plainNameForRead; |
| 3100 } else { | 3131 } else { |
| 3101 return internalError("Unhandled: ${node.runtimeType}"); | 3132 return internalError("Unhandled: ${node.runtimeType}"); |
| 3102 } | 3133 } |
| 3103 } | 3134 } |
| OLD | NEW |