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 |