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 '../parser/parser.dart' show FormalParameterType, optional; | 7 import '../parser/parser.dart' show FormalParameterType, optional; |
8 | 8 |
9 import '../parser/error_kind.dart' show ErrorKind; | 9 import '../parser/error_kind.dart' show ErrorKind; |
10 | 10 |
11 import '../parser/identifier_context.dart' show IdentifierContext; | 11 import '../parser/identifier_context.dart' show IdentifierContext; |
12 | 12 |
| 13 import 'package:front_end/src/fasta/builder/ast_factory.dart'; |
| 14 import 'package:front_end/src/fasta/kernel/kernel_ast_factory.dart'; |
| 15 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart'; |
| 16 import 'package:front_end/src/fasta/type_inference/local_type_inferrer.dart'; |
| 17 import '../builder/shadow_ast.dart'; |
13 import 'package:kernel/ast.dart'; | 18 import 'package:kernel/ast.dart'; |
14 | 19 |
15 import 'package:kernel/clone.dart' show CloneVisitor; | 20 import 'package:kernel/clone.dart' show CloneVisitor; |
16 | 21 |
17 import 'package:kernel/transformations/flags.dart' show TransformerFlag; | 22 import 'package:kernel/transformations/flags.dart' show TransformerFlag; |
18 | 23 |
19 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy; | 24 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy; |
20 | 25 |
21 import 'package:kernel/core_types.dart' show CoreTypes; | 26 import 'package:kernel/core_types.dart' show CoreTypes; |
22 | 27 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 CloneVisitor cloner; | 100 CloneVisitor cloner; |
96 | 101 |
97 bool constantExpressionRequired = false; | 102 bool constantExpressionRequired = false; |
98 | 103 |
99 DartType currentLocalVariableType; | 104 DartType currentLocalVariableType; |
100 | 105 |
101 // Using non-null value to initialize this field based on performance advice | 106 // Using non-null value to initialize this field based on performance advice |
102 // from VM engineers. TODO(ahe): Does this still apply? | 107 // from VM engineers. TODO(ahe): Does this still apply? |
103 int currentLocalVariableModifiers = -1; | 108 int currentLocalVariableModifiers = -1; |
104 | 109 |
| 110 final AstFactory _ast = new KernelAstFactory(); |
| 111 |
| 112 final LocalTypeInferrer _typeInferrer; |
| 113 |
105 BodyBuilder( | 114 BodyBuilder( |
106 KernelLibraryBuilder library, | 115 KernelLibraryBuilder library, |
107 this.member, | 116 this.member, |
108 Scope scope, | 117 Scope scope, |
109 this.formalParameterScope, | 118 this.formalParameterScope, |
110 this.hierarchy, | 119 this.hierarchy, |
111 this.coreTypes, | 120 CoreTypes coreTypes, |
112 this.classBuilder, | 121 this.classBuilder, |
113 this.isInstanceMember, | 122 this.isInstanceMember, |
114 this.uri) | 123 this.uri) |
115 : enclosingScope = scope, | 124 : coreTypes = coreTypes, |
| 125 enclosingScope = scope, |
116 library = library, | 126 library = library, |
117 isDartLibrary = library.uri.scheme == "dart", | 127 isDartLibrary = library.uri.scheme == "dart", |
| 128 // TODO(paulberry): put this behind a flag. |
| 129 _typeInferrer = new LocalTypeInferrer(coreTypes), |
118 super(scope); | 130 super(scope); |
119 | 131 |
120 bool get hasParserError => recoverableErrors.isNotEmpty; | 132 bool get hasParserError => recoverableErrors.isNotEmpty; |
121 | 133 |
122 bool get inConstructor { | 134 bool get inConstructor { |
123 return functionNestingLevel == 0 && member is KernelConstructorBuilder; | 135 return functionNestingLevel == 0 && member is KernelConstructorBuilder; |
124 } | 136 } |
125 | 137 |
126 bool get isInstanceContext { | 138 bool get isInstanceContext { |
127 return isInstanceMember || member is KernelConstructorBuilder; | 139 return isInstanceMember || member is KernelConstructorBuilder; |
128 } | 140 } |
129 | 141 |
130 @override | 142 @override |
131 void push(Object node) { | 143 void push(Object node) { |
132 inInitializer = false; | 144 inInitializer = false; |
133 super.push(node); | 145 super.push(node); |
134 } | 146 } |
135 | 147 |
136 Expression popForValue() => toValue(pop()); | 148 ShadowExpression popForValue() => toValue(pop()); |
137 | 149 |
138 Expression popForEffect() => toEffect(pop()); | 150 ShadowExpression popForEffect() => toEffect(pop()); |
139 | 151 |
140 Expression popForValueIfNotNull(Object value) { | 152 ShadowExpression popForValueIfNotNull(Object value) { |
141 return value == null ? null : popForValue(); | 153 return value == null ? null : popForValue(); |
142 } | 154 } |
143 | 155 |
144 @override | 156 @override |
145 Expression toValue(Object node) { | 157 ShadowExpression toValue(Object node) { |
146 if (node is UnresolvedIdentifier) { | 158 if (node is UnresolvedIdentifier) { |
147 if (isDartLibrary && | 159 if (isDartLibrary && |
148 node.name.name == "main" && | 160 node.name.name == "main" && |
149 library.uri.path == "_builtin" && | 161 library.uri.path == "_builtin" && |
150 member?.name == "_getMainClosure") { | 162 member?.name == "_getMainClosure") { |
151 // TODO(ahe): https://github.com/dart-lang/sdk/issues/28989 | 163 // TODO(ahe): https://github.com/dart-lang/sdk/issues/28989 |
152 return new NullLiteral()..fileOffset = node.fileOffset; | 164 return _ast.nullLiteral(node.fileOffset); |
153 } | 165 } |
154 return throwNoSuchMethodError( | 166 return throwNoSuchMethodError( |
155 node.name.name, new Arguments.empty(), node.fileOffset, | 167 node.name.name, new Arguments.empty(), node.fileOffset, |
156 isGetter: true); | 168 isGetter: true); |
157 } else if (node is BuilderAccessor) { | 169 } else if (node is BuilderAccessor) { |
158 return node.buildSimpleRead(); | 170 return node.buildSimpleRead(); |
159 } else if (node is TypeVariableBuilder) { | 171 } else if (node is TypeVariableBuilder) { |
160 TypeParameterType type = node.buildTypesWithBuiltArguments(library, null); | 172 TypeParameterType type = node.buildTypesWithBuiltArguments(library, null); |
161 if (!isInstanceContext && type.parameter.parent is Class) { | 173 if (!isInstanceContext && type.parameter.parent is Class) { |
162 return buildCompileTimeError( | 174 return buildCompileTimeError( |
163 "Type variables can only be used in instance methods."); | 175 "Type variables can only be used in instance methods."); |
164 } else { | 176 } else { |
165 if (constantExpressionRequired) { | 177 if (constantExpressionRequired) { |
166 addCompileTimeError(-1, | 178 addCompileTimeError(-1, |
167 "Type variable can't be used as a constant expression $type."); | 179 "Type variable can't be used as a constant expression $type."); |
168 } | 180 } |
169 return new TypeLiteral(type); | 181 return new TypeLiteral(type) as ShadowExpression; |
170 } | 182 } |
171 } else if (node is TypeDeclarationBuilder) { | 183 } else if (node is TypeDeclarationBuilder) { |
172 return new TypeLiteral(node.buildTypesWithBuiltArguments(library, null)); | 184 return new TypeLiteral(node.buildTypesWithBuiltArguments(library, null)) |
| 185 as ShadowExpression; |
173 } else if (node is KernelTypeBuilder) { | 186 } else if (node is KernelTypeBuilder) { |
174 return new TypeLiteral(node.build(library)); | 187 return new TypeLiteral(node.build(library)) as ShadowExpression; |
175 } else if (node is Expression) { | 188 } else if (node is ShadowExpression) { |
176 return node; | 189 return node; |
177 } else if (node is PrefixBuilder) { | 190 } else if (node is PrefixBuilder) { |
178 return buildCompileTimeError("A library can't be used as an expression."); | 191 return buildCompileTimeError("A library can't be used as an expression."); |
179 } else if (node is ProblemBuilder) { | 192 } else if (node is ProblemBuilder) { |
180 return buildProblemExpression(node, -1); | 193 return buildProblemExpression(node, -1); |
181 } else { | 194 } else { |
182 return internalError("Unhandled: ${node.runtimeType}"); | 195 return internalError("Unhandled: ${node.runtimeType}"); |
183 } | 196 } |
184 } | 197 } |
185 | 198 |
186 Expression toEffect(Object node) { | 199 ShadowExpression toEffect(Object node) { |
187 if (node is BuilderAccessor) return node.buildForEffect(); | 200 if (node is BuilderAccessor) return node.buildForEffect(); |
188 return toValue(node); | 201 return toValue(node); |
189 } | 202 } |
190 | 203 |
191 List<Expression> popListForValue(int n) { | 204 List<ShadowExpression> popListForValue(int n) { |
192 List<Expression> list = | 205 List<ShadowExpression> list = _ast.expressionList(n); |
193 new List<Expression>.filled(n, null, growable: true); | |
194 for (int i = n - 1; i >= 0; i--) { | 206 for (int i = n - 1; i >= 0; i--) { |
195 list[i] = popForValue(); | 207 list[i] = popForValue(); |
196 } | 208 } |
197 return list; | 209 return list; |
198 } | 210 } |
199 | 211 |
200 List<Expression> popListForEffect(int n) { | 212 List<ShadowExpression> popListForEffect(int n) { |
201 List<Expression> list = | 213 List<ShadowExpression> list = _ast.expressionList(n); |
202 new List<Expression>.filled(n, null, growable: true); | |
203 for (int i = n - 1; i >= 0; i--) { | 214 for (int i = n - 1; i >= 0; i--) { |
204 list[i] = popForEffect(); | 215 list[i] = popForEffect(); |
205 } | 216 } |
206 return list; | 217 return list; |
207 } | 218 } |
208 | 219 |
209 Block popBlock(int count, int charOffset) { | 220 ShadowBlock popBlock(int count, int charOffset) { |
210 List<dynamic /*Statement | List<Statement>*/ > statements = | 221 List<dynamic /*Statement | List<Statement>*/ > statements = |
211 popList(count) ?? <Statement>[]; | 222 popList(count) ?? <Statement>[]; |
212 List<Statement> copy; | 223 List<Statement> copy; |
213 for (int i = 0; i < statements.length; i++) { | 224 for (int i = 0; i < statements.length; i++) { |
214 var statement = statements[i]; | 225 var statement = statements[i]; |
215 if (statement is List) { | 226 if (statement is List) { |
216 copy ??= new List<Statement>.from(statements.getRange(0, i)); | 227 copy ??= new List<Statement>.from(statements.getRange(0, i)); |
217 // TODO(sigmund): remove this assignment (issue #28651) | 228 // TODO(sigmund): remove this assignment (issue #28651) |
218 Iterable subStatements = statement; | 229 Iterable subStatements = statement; |
219 copy.addAll(subStatements); | 230 copy.addAll(subStatements); |
220 } else if (copy != null) { | 231 } else if (copy != null) { |
221 copy.add(statement); | 232 copy.add(statement); |
222 } | 233 } |
223 } | 234 } |
224 return new Block(copy ?? statements)..fileOffset = charOffset; | 235 return _ast.block(copy ?? statements, charOffset); |
225 } | 236 } |
226 | 237 |
227 Statement popStatementIfNotNull(Object value) { | 238 Statement popStatementIfNotNull(Object value) { |
228 return value == null ? null : popStatement(); | 239 return value == null ? null : popStatement(); |
229 } | 240 } |
230 | 241 |
231 Statement popStatement() { | 242 Statement popStatement() { |
232 var statement = pop(); | 243 var statement = pop(); |
233 if (statement is List) { | 244 if (statement is List) { |
234 return new Block(new List<Statement>.from(statement)); | 245 return new Block(new List<Statement>.from(statement)); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 checkEmpty(-1); | 341 checkEmpty(-1); |
331 } | 342 } |
332 | 343 |
333 @override | 344 @override |
334 void endBlockFunctionBody(int count, Token beginToken, Token endToken) { | 345 void endBlockFunctionBody(int count, Token beginToken, Token endToken) { |
335 debugEvent("BlockFunctionBody"); | 346 debugEvent("BlockFunctionBody"); |
336 if (beginToken == null) { | 347 if (beginToken == null) { |
337 assert(count == 0); | 348 assert(count == 0); |
338 push(NullValue.Block); | 349 push(NullValue.Block); |
339 } else { | 350 } else { |
340 Block block = popBlock(count, beginToken.charOffset); | 351 ShadowBlock block = popBlock(count, beginToken.charOffset); |
341 exitLocalScope(); | 352 exitLocalScope(); |
342 push(block); | 353 push(block); |
343 } | 354 } |
344 } | 355 } |
345 | 356 |
346 @override | 357 @override |
347 void prepareInitializers() { | 358 void prepareInitializers() { |
348 scope = formalParameterScope; | 359 scope = formalParameterScope; |
349 assert(fieldInitializers.isEmpty); | 360 assert(fieldInitializers.isEmpty); |
350 final member = this.member; | 361 final member = this.member; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 void handleNoInitializers() { | 422 void handleNoInitializers() { |
412 debugEvent("NoInitializers"); | 423 debugEvent("NoInitializers"); |
413 } | 424 } |
414 | 425 |
415 @override | 426 @override |
416 void endInitializers(int count, Token beginToken, Token endToken) { | 427 void endInitializers(int count, Token beginToken, Token endToken) { |
417 debugEvent("Initializers"); | 428 debugEvent("Initializers"); |
418 } | 429 } |
419 | 430 |
420 @override | 431 @override |
421 void finishFunction( | 432 void finishFunction(FormalParameters formals, AsyncMarker asyncModifier, |
422 FormalParameters formals, AsyncMarker asyncModifier, Statement body) { | 433 ShadowStatement body) { |
423 debugEvent("finishFunction"); | 434 debugEvent("finishFunction"); |
424 KernelFunctionBuilder builder = member; | 435 KernelFunctionBuilder builder = member; |
425 if (builder is KernelConstructorBuilder) { | 436 if (builder is KernelConstructorBuilder) { |
426 if (asyncModifier != AsyncMarker.Sync) { | 437 if (asyncModifier != AsyncMarker.Sync) { |
427 // TODO(ahe): Change this to a null check. | 438 // TODO(ahe): Change this to a null check. |
428 addCompileTimeError(body?.fileOffset, | 439 addCompileTimeError((body as Statement)?.fileOffset, |
429 "Can't be marked as ${asyncModifier}: ${builder.name}"); | 440 "Can't be marked as ${asyncModifier}: ${builder.name}"); |
430 } | 441 } |
431 } else if (builder is KernelProcedureBuilder) { | 442 } else if (builder is KernelProcedureBuilder) { |
432 builder.asyncModifier = asyncModifier; | 443 builder.asyncModifier = asyncModifier; |
433 } else { | 444 } else { |
434 internalError("Unhandled: ${builder.runtimeType}"); | 445 internalError("Unhandled: ${builder.runtimeType}"); |
435 } | 446 } |
436 builder.body = body; | 447 _typeInferrer.inferBody(body); |
| 448 builder.body = body as Statement; |
437 if (formals?.optional != null) { | 449 if (formals?.optional != null) { |
438 Iterator<FormalParameterBuilder> formalBuilders = | 450 Iterator<FormalParameterBuilder> formalBuilders = |
439 builder.formals.skip(formals.required.length).iterator; | 451 builder.formals.skip(formals.required.length).iterator; |
440 for (VariableDeclaration parameter in formals.optional.formals) { | 452 for (VariableDeclaration parameter in formals.optional.formals) { |
441 bool hasMore = formalBuilders.moveNext(); | 453 bool hasMore = formalBuilders.moveNext(); |
442 assert(hasMore); | 454 assert(hasMore); |
443 VariableDeclaration realParameter = formalBuilders.current.target; | 455 VariableDeclaration realParameter = formalBuilders.current.target; |
444 Expression initializer = parameter.initializer ?? new NullLiteral(); | 456 Expression initializer = parameter.initializer ?? new NullLiteral(); |
445 realParameter.initializer = initializer..parent = realParameter; | 457 realParameter.initializer = initializer..parent = realParameter; |
446 } | 458 } |
447 } | 459 } |
448 } | 460 } |
449 | 461 |
450 @override | 462 @override |
451 void endExpressionStatement(Token token) { | 463 void endExpressionStatement(Token token) { |
452 debugEvent("ExpressionStatement"); | 464 debugEvent("ExpressionStatement"); |
453 push(new ExpressionStatement(popForEffect())); | 465 push(new ExpressionStatement(popForEffect() as Expression)); |
454 } | 466 } |
455 | 467 |
456 @override | 468 @override |
457 void endArguments(int count, Token beginToken, Token endToken) { | 469 void endArguments(int count, Token beginToken, Token endToken) { |
458 debugEvent("Arguments"); | 470 debugEvent("Arguments"); |
459 List arguments = popList(count) ?? <Expression>[]; | 471 List arguments = popList(count) ?? <Expression>[]; |
460 int firstNamedArgumentIndex = arguments.length; | 472 int firstNamedArgumentIndex = arguments.length; |
461 for (int i = 0; i < arguments.length; i++) { | 473 for (int i = 0; i < arguments.length; i++) { |
462 var node = arguments[i]; | 474 var node = arguments[i]; |
463 if (node is NamedExpression) { | 475 if (node is NamedExpression) { |
464 firstNamedArgumentIndex = | 476 firstNamedArgumentIndex = |
465 i < firstNamedArgumentIndex ? i : firstNamedArgumentIndex; | 477 i < firstNamedArgumentIndex ? i : firstNamedArgumentIndex; |
466 } else { | 478 } else { |
467 arguments[i] = toValue(node); | 479 arguments[i] = toValue(node); |
468 if (i > firstNamedArgumentIndex) { | 480 if (i > firstNamedArgumentIndex) { |
469 arguments[i] = new NamedExpression( | 481 arguments[i] = new NamedExpression( |
470 "#$i", | 482 "#$i", |
471 buildCompileTimeError( | 483 buildCompileTimeError( |
472 "Expected named argument.", arguments[i].fileOffset)); | 484 "Expected named argument.", arguments[i].fileOffset) |
| 485 as Expression); |
473 } | 486 } |
474 } | 487 } |
475 } | 488 } |
476 if (firstNamedArgumentIndex < arguments.length) { | 489 if (firstNamedArgumentIndex < arguments.length) { |
477 List<Expression> positional = new List<Expression>.from( | 490 List<Expression> positional = new List<Expression>.from( |
478 arguments.getRange(0, firstNamedArgumentIndex)); | 491 arguments.getRange(0, firstNamedArgumentIndex)); |
479 List<NamedExpression> named = new List<NamedExpression>.from( | 492 List<NamedExpression> named = new List<NamedExpression>.from( |
480 arguments.getRange(firstNamedArgumentIndex, arguments.length)); | 493 arguments.getRange(firstNamedArgumentIndex, arguments.length)); |
481 push(new Arguments(positional, named: named)); | 494 push(new Arguments(positional, named: named)); |
482 } else { | 495 } else { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 if (receiver is BuilderAccessor) { | 539 if (receiver is BuilderAccessor) { |
527 if (constantExpressionRequired && !isIdentical(receiver)) { | 540 if (constantExpressionRequired && !isIdentical(receiver)) { |
528 addCompileTimeError(charOffset, "Not a constant expression."); | 541 addCompileTimeError(charOffset, "Not a constant expression."); |
529 } | 542 } |
530 return receiver.doInvocation(charOffset, arguments); | 543 return receiver.doInvocation(charOffset, arguments); |
531 } else if (receiver is UnresolvedIdentifier) { | 544 } else if (receiver is UnresolvedIdentifier) { |
532 return throwNoSuchMethodError( | 545 return throwNoSuchMethodError( |
533 receiver.name.name, arguments, receiver.fileOffset); | 546 receiver.name.name, arguments, receiver.fileOffset); |
534 } else { | 547 } else { |
535 return buildMethodInvocation( | 548 return buildMethodInvocation( |
536 toValue(receiver), callName, arguments, charOffset); | 549 toValue(receiver) as Expression, callName, arguments, charOffset); |
537 } | 550 } |
538 } | 551 } |
539 | 552 |
540 @override | 553 @override |
541 void beginCascade(Token token) { | 554 void beginCascade(Token token) { |
542 debugEvent("beginCascade"); | 555 debugEvent("beginCascade"); |
543 Expression expression = popForValue(); | 556 Expression expression = popForValue() as Expression; |
544 if (expression is CascadeReceiver) { | 557 if (expression is CascadeReceiver) { |
545 push(expression); | 558 push(expression); |
546 push(new VariableAccessor( | 559 push(new VariableAccessor( |
547 this, expression.fileOffset, expression.variable)); | 560 this, expression.fileOffset, expression.variable)); |
548 expression.extend(); | 561 expression.extend(); |
549 } else { | 562 } else { |
550 VariableDeclaration variable = | 563 VariableDeclaration variable = |
551 new VariableDeclaration.forValue(expression); | 564 new VariableDeclaration.forValue(expression); |
552 push(new CascadeReceiver(variable)); | 565 push(new CascadeReceiver(variable)); |
553 push(new VariableAccessor(this, expression.fileOffset, variable)); | 566 push(new VariableAccessor(this, expression.fileOffset, variable)); |
554 } | 567 } |
555 } | 568 } |
556 | 569 |
557 @override | 570 @override |
558 void endCascade() { | 571 void endCascade() { |
559 debugEvent("endCascade"); | 572 debugEvent("endCascade"); |
560 Expression expression = popForEffect(); | 573 Expression expression = popForEffect() as Expression; |
561 CascadeReceiver cascadeReceiver = pop(); | 574 CascadeReceiver cascadeReceiver = pop(); |
562 cascadeReceiver.finalize(expression); | 575 cascadeReceiver.finalize(expression); |
563 push(cascadeReceiver); | 576 push(cascadeReceiver); |
564 } | 577 } |
565 | 578 |
566 @override | 579 @override |
567 void handleBinaryExpression(Token token) { | 580 void handleBinaryExpression(Token token) { |
568 debugEvent("BinaryExpression"); | 581 debugEvent("BinaryExpression"); |
569 if (optional(".", token) || optional("..", token)) { | 582 if (optional(".", token) || optional("..", token)) { |
570 return doDotOrCascadeExpression(token); | 583 return doDotOrCascadeExpression(token); |
571 } | 584 } |
572 if (optional("&&", token) || optional("||", token)) { | 585 if (optional("&&", token) || optional("||", token)) { |
573 return doLogicalExpression(token); | 586 return doLogicalExpression(token); |
574 } | 587 } |
575 if (optional("??", token)) return doIfNull(token); | 588 if (optional("??", token)) return doIfNull(token); |
576 if (optional("?.", token)) return doIfNotNull(token); | 589 if (optional("?.", token)) return doIfNotNull(token); |
577 Expression argument = popForValue(); | 590 Expression argument = popForValue() as Expression; |
578 var receiver = pop(); | 591 var receiver = pop(); |
579 bool isSuper = false; | 592 bool isSuper = false; |
580 if (receiver is ThisAccessor && receiver.isSuper) { | 593 if (receiver is ThisAccessor && receiver.isSuper) { |
581 isSuper = true; | 594 isSuper = true; |
582 receiver = new ThisExpression(); | 595 receiver = new ThisExpression(); |
583 } | 596 } |
584 push(buildBinaryOperator(toValue(receiver), token, argument, isSuper)); | 597 push(buildBinaryOperator( |
| 598 toValue(receiver) as Expression, token, argument, isSuper)); |
585 } | 599 } |
586 | 600 |
587 Expression buildBinaryOperator( | 601 Expression buildBinaryOperator( |
588 Expression a, Token token, Expression b, bool isSuper) { | 602 Expression a, Token token, Expression b, bool isSuper) { |
589 bool negate = false; | 603 bool negate = false; |
590 String operator = token.stringValue; | 604 String operator = token.stringValue; |
591 if (identical("!=", operator)) { | 605 if (identical("!=", operator)) { |
592 operator = "=="; | 606 operator = "=="; |
593 negate = true; | 607 negate = true; |
594 } | 608 } |
595 if (!isBinaryOperator(operator) && !isMinusOperator(operator)) { | 609 if (!isBinaryOperator(operator) && !isMinusOperator(operator)) { |
596 return buildCompileTimeError( | 610 return buildCompileTimeError( |
597 "Not an operator: '$operator'.", token.charOffset); | 611 "Not an operator: '$operator'.", token.charOffset) as Expression; |
598 } else { | 612 } else { |
599 Expression result = | 613 Expression result = |
600 makeBinary(a, new Name(operator), null, b, token.charOffset); | 614 makeBinary(a, new Name(operator), null, b, token.charOffset); |
601 if (isSuper) { | 615 if (isSuper) { |
602 result = toSuperMethodInvocation(result); | 616 result = toSuperMethodInvocation(result); |
603 } | 617 } |
604 return negate ? new Not(result) : result; | 618 return negate ? new Not(result) : result; |
605 } | 619 } |
606 } | 620 } |
607 | 621 |
608 void doLogicalExpression(Token token) { | 622 void doLogicalExpression(Token token) { |
609 Expression argument = popForValue(); | 623 Expression argument = popForValue() as Expression; |
610 Expression receiver = popForValue(); | 624 Expression receiver = popForValue() as Expression; |
611 push(new LogicalExpression(receiver, token.stringValue, argument)); | 625 push(new LogicalExpression(receiver, token.stringValue, argument)); |
612 } | 626 } |
613 | 627 |
614 /// Handle `a ?? b`. | 628 /// Handle `a ?? b`. |
615 void doIfNull(Token token) { | 629 void doIfNull(Token token) { |
616 Expression b = popForValue(); | 630 Expression b = popForValue() as Expression; |
617 Expression a = popForValue(); | 631 Expression a = popForValue() as Expression; |
618 VariableDeclaration variable = new VariableDeclaration.forValue(a); | 632 VariableDeclaration variable = new VariableDeclaration.forValue(a); |
619 push(makeLet( | 633 push(makeLet( |
620 variable, | 634 variable, |
621 new ConditionalExpression(buildIsNull(new VariableGet(variable)), b, | 635 new ConditionalExpression(buildIsNull(new VariableGet(variable)), b, |
622 new VariableGet(variable), const DynamicType()))); | 636 new VariableGet(variable), const DynamicType()))); |
623 } | 637 } |
624 | 638 |
625 /// Handle `a?.b(...)`. | 639 /// Handle `a?.b(...)`. |
626 void doIfNotNull(Token token) { | 640 void doIfNotNull(Token token) { |
627 IncompleteSend send = pop(); | 641 IncompleteSend send = pop(); |
(...skipping 19 matching lines...) Expand all Loading... |
647 new ThisExpression(), target, node.arguments); | 661 new ThisExpression(), target, node.arguments); |
648 result = new SuperMethodInvocation(node.name, node.arguments, null); | 662 result = new SuperMethodInvocation(node.name, node.arguments, null); |
649 return result; | 663 return result; |
650 } else { | 664 } else { |
651 isNoSuchMethod = true; | 665 isNoSuchMethod = true; |
652 } | 666 } |
653 } | 667 } |
654 } | 668 } |
655 if (isNoSuchMethod) { | 669 if (isNoSuchMethod) { |
656 return throwNoSuchMethodError( | 670 return throwNoSuchMethodError( |
657 node.name.name, node.arguments, node.fileOffset, | 671 node.name.name, node.arguments, node.fileOffset, isSuper: true) |
658 isSuper: true); | 672 as Expression; |
659 } | 673 } |
660 // TODO(ahe): Use [DirectPropertyGet] when possible. | 674 // TODO(ahe): Use [DirectPropertyGet] when possible. |
661 Expression receiver = new DirectPropertyGet(new ThisExpression(), target); | 675 Expression receiver = new DirectPropertyGet(new ThisExpression(), target); |
662 receiver = new SuperPropertyGet(node.name, target); | 676 receiver = new SuperPropertyGet(node.name, target); |
663 return buildMethodInvocation( | 677 return buildMethodInvocation( |
664 receiver, callName, node.arguments, node.fileOffset); | 678 receiver, callName, node.arguments, node.fileOffset); |
665 } | 679 } |
666 | 680 |
667 bool areArgumentsCompatible(FunctionNode function, Arguments arguments) { | 681 bool areArgumentsCompatible(FunctionNode function, Arguments arguments) { |
668 // TODO(ahe): Implement this. | 682 // TODO(ahe): Implement this. |
669 return true; | 683 return true; |
670 } | 684 } |
671 | 685 |
672 @override | 686 @override |
673 Expression throwNoSuchMethodError( | 687 ShadowExpression throwNoSuchMethodError( |
674 String name, Arguments arguments, int charOffset, | 688 String name, Arguments arguments, int charOffset, |
675 {bool isSuper: false, isGetter: false, isSetter: false}) { | 689 {bool isSuper: false, isGetter: false, isSetter: false}) { |
676 String errorName = isSuper ? "super.$name" : name; | 690 String errorName = isSuper ? "super.$name" : name; |
677 if (isGetter) { | 691 if (isGetter) { |
678 warning("Getter not found: '$errorName'.", charOffset); | 692 warning("Getter not found: '$errorName'.", charOffset); |
679 } else if (isSetter) { | 693 } else if (isSetter) { |
680 warning("Setter not found: '$errorName'.", charOffset); | 694 warning("Setter not found: '$errorName'.", charOffset); |
681 } else { | 695 } else { |
682 warning("Method not found: '$errorName'.", charOffset); | 696 warning("Method not found: '$errorName'.", charOffset); |
683 } | 697 } |
684 Constructor constructor = | 698 Constructor constructor = |
685 coreTypes.getClass("dart:core", "NoSuchMethodError").constructors.first; | 699 coreTypes.getClass("dart:core", "NoSuchMethodError").constructors.first; |
686 return new Throw(new ConstructorInvocation( | 700 return new Throw(new ConstructorInvocation( |
687 constructor, | 701 constructor, |
688 new Arguments(<Expression>[ | 702 new Arguments(<Expression>[ |
689 new NullLiteral(), | 703 new NullLiteral(), |
690 new SymbolLiteral(name), | 704 new SymbolLiteral(name), |
691 new ListLiteral(arguments.positional), | 705 new ListLiteral(arguments.positional), |
692 new MapLiteral(arguments.named.map((arg) { | 706 new MapLiteral(arguments.named.map((arg) { |
693 return new MapEntry(new SymbolLiteral(arg.name), arg.value); | 707 return new MapEntry(new SymbolLiteral(arg.name), arg.value); |
694 }).toList()), | 708 }).toList()), |
695 new NullLiteral() | 709 new NullLiteral() |
696 ]))); | 710 ]))) as ShadowExpression; |
697 } | 711 } |
698 | 712 |
699 @override | 713 @override |
700 Member lookupSuperMember(Name name, {bool isSetter: false}) { | 714 Member lookupSuperMember(Name name, {bool isSetter: false}) { |
701 Class superclass = classBuilder.cls.superclass; | 715 Class superclass = classBuilder.cls.superclass; |
702 return superclass == null | 716 return superclass == null |
703 ? null | 717 ? null |
704 : hierarchy.getDispatchTarget(superclass, name, setter: isSetter); | 718 : hierarchy.getDispatchTarget(superclass, name, setter: isSetter); |
705 } | 719 } |
706 | 720 |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
853 expressions.add( | 867 expressions.add( |
854 new StringLiteral(unescapeFirstStringPart(first.lexeme, quote))); | 868 new StringLiteral(unescapeFirstStringPart(first.lexeme, quote))); |
855 } | 869 } |
856 for (int i = 1; i < parts.length - 1; i++) { | 870 for (int i = 1; i < parts.length - 1; i++) { |
857 var part = parts[i]; | 871 var part = parts[i]; |
858 if (part is Token) { | 872 if (part is Token) { |
859 if (part.lexeme.length != 0) { | 873 if (part.lexeme.length != 0) { |
860 expressions.add(new StringLiteral(unescape(part.lexeme, quote))); | 874 expressions.add(new StringLiteral(unescape(part.lexeme, quote))); |
861 } | 875 } |
862 } else { | 876 } else { |
863 expressions.add(toValue(part)); | 877 expressions.add(toValue(part) as Expression); |
864 } | 878 } |
865 } | 879 } |
866 // Contains more than just \' or \". | 880 // Contains more than just \' or \". |
867 if (last.lexeme.length > 1) { | 881 if (last.lexeme.length > 1) { |
868 expressions | 882 expressions |
869 .add(new StringLiteral(unescapeLastStringPart(last.lexeme, quote))); | 883 .add(new StringLiteral(unescapeLastStringPart(last.lexeme, quote))); |
870 } | 884 } |
871 push(new StringConcatenation(expressions) | 885 push(new StringConcatenation(expressions) |
872 ..fileOffset = endToken.charOffset); | 886 ..fileOffset = endToken.charOffset); |
873 } | 887 } |
874 } | 888 } |
875 | 889 |
876 @override | 890 @override |
877 void handleScript(Token token) { | 891 void handleScript(Token token) { |
878 debugEvent("Script"); | 892 debugEvent("Script"); |
879 } | 893 } |
880 | 894 |
881 @override | 895 @override |
882 void handleStringJuxtaposition(int literalCount) { | 896 void handleStringJuxtaposition(int literalCount) { |
883 debugEvent("StringJuxtaposition"); | 897 debugEvent("StringJuxtaposition"); |
884 List<Expression> parts = popListForValue(literalCount); | 898 List<Expression> parts = popListForValue(literalCount) as List<Expression>; |
885 List<Expression> expressions; | 899 List<Expression> expressions; |
886 // Flatten string juxtapositions of string interpolation. | 900 // Flatten string juxtapositions of string interpolation. |
887 for (int i = 0; i < parts.length; i++) { | 901 for (int i = 0; i < parts.length; i++) { |
888 Expression part = parts[i]; | 902 Expression part = parts[i]; |
889 if (part is StringConcatenation) { | 903 if (part is StringConcatenation) { |
890 if (expressions == null) { | 904 if (expressions == null) { |
891 expressions = parts.sublist(0, i); | 905 expressions = parts.sublist(0, i); |
892 } | 906 } |
893 expressions.addAll(part.expressions); | 907 expressions.addAll(part.expressions); |
894 } else { | 908 } else { |
895 if (expressions != null) { | 909 if (expressions != null) { |
896 expressions.add(part); | 910 expressions.add(part); |
897 } | 911 } |
898 } | 912 } |
899 } | 913 } |
900 push(new StringConcatenation(expressions ?? parts)); | 914 push(new StringConcatenation(expressions ?? parts)); |
901 } | 915 } |
902 | 916 |
903 @override | 917 @override |
904 void handleLiteralInt(Token token) { | 918 void handleLiteralInt(Token token) { |
905 debugEvent("LiteralInt"); | 919 debugEvent("LiteralInt"); |
906 push( | 920 push(_ast.intLiteral(int.parse(token.lexeme), token.charOffset)); |
907 new IntLiteral(int.parse(token.lexeme))..fileOffset = token.charOffset); | |
908 } | 921 } |
909 | 922 |
910 @override | 923 @override |
911 void handleEmptyFunctionBody(Token semicolon) { | 924 void handleEmptyFunctionBody(Token semicolon) { |
912 debugEvent("ExpressionFunctionBody"); | 925 debugEvent("ExpressionFunctionBody"); |
913 endBlockFunctionBody(0, null, semicolon); | 926 endBlockFunctionBody(0, null, semicolon); |
914 } | 927 } |
915 | 928 |
916 @override | 929 @override |
917 void handleExpressionFunctionBody(Token arrowToken, Token endToken) { | 930 void handleExpressionFunctionBody(Token arrowToken, Token endToken) { |
918 debugEvent("ExpressionFunctionBody"); | 931 debugEvent("ExpressionFunctionBody"); |
919 endReturnStatement(true, arrowToken.next, endToken); | 932 endReturnStatement(true, arrowToken.next, endToken); |
920 } | 933 } |
921 | 934 |
922 @override | 935 @override |
923 void endReturnStatement( | 936 void endReturnStatement( |
924 bool hasExpression, Token beginToken, Token endToken) { | 937 bool hasExpression, Token beginToken, Token endToken) { |
925 debugEvent("ReturnStatement"); | 938 debugEvent("ReturnStatement"); |
926 Expression expression = hasExpression ? popForValue() : null; | 939 ShadowExpression expression = hasExpression ? popForValue() : null; |
927 if (expression != null && inConstructor) { | 940 if (expression != null && inConstructor) { |
928 push(buildCompileTimeErrorStatement( | 941 push(buildCompileTimeErrorStatement( |
929 "Can't return from a constructor.", beginToken.charOffset)); | 942 "Can't return from a constructor.", beginToken.charOffset)); |
930 } else { | 943 } else { |
931 push(new ReturnStatement(expression)..fileOffset = beginToken.charOffset); | 944 push(_ast.returnStatement(expression, beginToken.charOffset)); |
932 } | 945 } |
933 } | 946 } |
934 | 947 |
935 @override | 948 @override |
936 void endIfStatement(Token ifToken, Token elseToken) { | 949 void endIfStatement(Token ifToken, Token elseToken) { |
937 Statement elsePart = popStatementIfNotNull(elseToken); | 950 Statement elsePart = popStatementIfNotNull(elseToken); |
938 Statement thenPart = popStatement(); | 951 Statement thenPart = popStatement(); |
939 Expression condition = popForValue(); | 952 Expression condition = popForValue() as Expression; |
940 push(new IfStatement(condition, thenPart, elsePart)); | 953 push(new IfStatement(condition, thenPart, elsePart)); |
941 } | 954 } |
942 | 955 |
943 @override | 956 @override |
944 void endVariableInitializer(Token assignmentOperator) { | 957 void endVariableInitializer(Token assignmentOperator) { |
945 debugEvent("VariableInitializer"); | 958 debugEvent("VariableInitializer"); |
946 assert(assignmentOperator.stringValue == "="); | 959 assert(assignmentOperator.stringValue == "="); |
947 pushNewLocalVariable(popForValue(), | 960 pushNewLocalVariable(popForValue(), |
948 equalsCharOffset: assignmentOperator.charOffset); | 961 equalsCharOffset: assignmentOperator.charOffset); |
949 } | 962 } |
950 | 963 |
951 @override | 964 @override |
952 void handleNoVariableInitializer(Token token) { | 965 void handleNoVariableInitializer(Token token) { |
953 debugEvent("NoVariableInitializer"); | 966 debugEvent("NoVariableInitializer"); |
954 pushNewLocalVariable(null); | 967 pushNewLocalVariable(null); |
955 } | 968 } |
956 | 969 |
957 void pushNewLocalVariable(Expression initializer, | 970 void pushNewLocalVariable(ShadowExpression initializer, |
958 {int equalsCharOffset: TreeNode.noOffset}) { | 971 {int equalsCharOffset: TreeNode.noOffset}) { |
959 Identifier identifier = pop(); | 972 Identifier identifier = pop(); |
960 assert(currentLocalVariableModifiers != -1); | 973 assert(currentLocalVariableModifiers != -1); |
961 bool isConst = (currentLocalVariableModifiers & constMask) != 0; | 974 bool isConst = (currentLocalVariableModifiers & constMask) != 0; |
962 bool isFinal = (currentLocalVariableModifiers & finalMask) != 0; | 975 bool isFinal = (currentLocalVariableModifiers & finalMask) != 0; |
963 assert(isConst == constantExpressionRequired); | 976 assert(isConst == constantExpressionRequired); |
964 push(new VariableDeclaration(identifier.name, | 977 var variable = _ast.variableDeclaration(identifier.name, |
965 initializer: initializer, | 978 initializer: initializer, |
966 type: currentLocalVariableType ?? const DynamicType(), | 979 type: currentLocalVariableType, |
967 isFinal: isFinal, | 980 isFinal: isFinal, |
968 isConst: isConst)..fileEqualsOffset = equalsCharOffset); | 981 isConst: isConst, |
| 982 charOffset: equalsCharOffset); |
| 983 _typeInferrer.finishVariableDeclaration( |
| 984 currentLocalVariableType, initializer, variable); |
| 985 push(variable); |
969 } | 986 } |
970 | 987 |
971 @override | 988 @override |
972 void endFieldInitializer(Token assignmentOperator) { | 989 void endFieldInitializer(Token assignmentOperator) { |
973 debugEvent("FieldInitializer"); | 990 debugEvent("FieldInitializer"); |
974 assert(assignmentOperator.stringValue == "="); | 991 assert(assignmentOperator.stringValue == "="); |
975 push(popForValue()); | 992 push(popForValue()); |
976 } | 993 } |
977 | 994 |
978 @override | 995 @override |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1015 if (variables.length != 1) { | 1032 if (variables.length != 1) { |
1016 push(variables); | 1033 push(variables); |
1017 } else { | 1034 } else { |
1018 push(variables.single); | 1035 push(variables.single); |
1019 } | 1036 } |
1020 } | 1037 } |
1021 | 1038 |
1022 @override | 1039 @override |
1023 void endBlock(int count, Token beginToken, Token endToken) { | 1040 void endBlock(int count, Token beginToken, Token endToken) { |
1024 debugEvent("Block"); | 1041 debugEvent("Block"); |
1025 Block block = popBlock(count, beginToken.charOffset); | 1042 ShadowBlock block = popBlock(count, beginToken.charOffset); |
1026 exitLocalScope(); | 1043 exitLocalScope(); |
1027 push(block); | 1044 push(block); |
1028 } | 1045 } |
1029 | 1046 |
1030 @override | 1047 @override |
1031 void handleAssignmentExpression(Token token) { | 1048 void handleAssignmentExpression(Token token) { |
1032 debugEvent("AssignmentExpression"); | 1049 debugEvent("AssignmentExpression"); |
1033 Expression value = popForValue(); | 1050 Expression value = popForValue() as Expression; |
1034 var accessor = pop(); | 1051 var accessor = pop(); |
1035 if (accessor is TypeDeclarationBuilder) { | 1052 if (accessor is TypeDeclarationBuilder) { |
1036 push(wrapInvalid(new TypeLiteral( | 1053 push(wrapInvalid(new TypeLiteral( |
1037 accessor.buildTypesWithBuiltArguments(library, null)))); | 1054 accessor.buildTypesWithBuiltArguments(library, null)))); |
1038 } else if (accessor is! BuilderAccessor) { | 1055 } else if (accessor is! BuilderAccessor) { |
1039 push(buildCompileTimeError("Can't assign to this.", token.charOffset)); | 1056 push(buildCompileTimeError("Can't assign to this.", token.charOffset)); |
1040 } else { | 1057 } else { |
1041 push(new DelayedAssignment( | 1058 push(new DelayedAssignment( |
1042 this, token.charOffset, accessor, value, token.stringValue)); | 1059 this, token.charOffset, accessor, value, token.stringValue)); |
1043 } | 1060 } |
(...skipping 18 matching lines...) Expand all Loading... |
1062 } else { | 1079 } else { |
1063 push(statement); | 1080 push(statement); |
1064 } | 1081 } |
1065 } | 1082 } |
1066 | 1083 |
1067 @override | 1084 @override |
1068 void endForStatement(Token forKeyword, Token leftSeparator, | 1085 void endForStatement(Token forKeyword, Token leftSeparator, |
1069 int updateExpressionCount, Token endToken) { | 1086 int updateExpressionCount, Token endToken) { |
1070 debugEvent("ForStatement"); | 1087 debugEvent("ForStatement"); |
1071 Statement body = popStatement(); | 1088 Statement body = popStatement(); |
1072 List<Expression> updates = popListForEffect(updateExpressionCount); | 1089 List<Expression> updates = |
| 1090 popListForEffect(updateExpressionCount) as List<Expression>; |
1073 Statement conditionStatement = popStatement(); | 1091 Statement conditionStatement = popStatement(); |
1074 Expression condition = null; | 1092 Expression condition = null; |
1075 if (conditionStatement is ExpressionStatement) { | 1093 if (conditionStatement is ExpressionStatement) { |
1076 condition = conditionStatement.expression; | 1094 condition = conditionStatement.expression; |
1077 } else { | 1095 } else { |
1078 assert(conditionStatement is EmptyStatement); | 1096 assert(conditionStatement is EmptyStatement); |
1079 } | 1097 } |
1080 List<VariableDeclaration> variables = <VariableDeclaration>[]; | 1098 List<VariableDeclaration> variables = <VariableDeclaration>[]; |
1081 dynamic variableOrExpression = pop(); | 1099 dynamic variableOrExpression = pop(); |
1082 Statement begin; | 1100 Statement begin; |
(...skipping 27 matching lines...) Expand all Loading... |
1110 if (breakTarget.hasUsers) { | 1128 if (breakTarget.hasUsers) { |
1111 result = new LabeledStatement(result); | 1129 result = new LabeledStatement(result); |
1112 breakTarget.resolveBreaks(result); | 1130 breakTarget.resolveBreaks(result); |
1113 } | 1131 } |
1114 exitLoopOrSwitch(result); | 1132 exitLoopOrSwitch(result); |
1115 } | 1133 } |
1116 | 1134 |
1117 @override | 1135 @override |
1118 void endAwaitExpression(Token beginToken, Token endToken) { | 1136 void endAwaitExpression(Token beginToken, Token endToken) { |
1119 debugEvent("AwaitExpression"); | 1137 debugEvent("AwaitExpression"); |
1120 push( | 1138 push(new AwaitExpression(popForValue() as Expression) |
1121 new AwaitExpression(popForValue())..fileOffset = beginToken.charOffset); | 1139 ..fileOffset = beginToken.charOffset); |
1122 } | 1140 } |
1123 | 1141 |
1124 @override | 1142 @override |
1125 void handleAsyncModifier(Token asyncToken, Token starToken) { | 1143 void handleAsyncModifier(Token asyncToken, Token starToken) { |
1126 debugEvent("AsyncModifier"); | 1144 debugEvent("AsyncModifier"); |
1127 push(asyncMarkerFromTokens(asyncToken, starToken)); | 1145 push(asyncMarkerFromTokens(asyncToken, starToken)); |
1128 } | 1146 } |
1129 | 1147 |
1130 @override | 1148 @override |
1131 void handleLiteralList( | 1149 void handleLiteralList( |
1132 int count, Token beginToken, Token constKeyword, Token endToken) { | 1150 int count, Token beginToken, Token constKeyword, Token endToken) { |
1133 debugEvent("LiteralList"); | 1151 debugEvent("LiteralList"); |
1134 List<Expression> expressions = popListForValue(count); | 1152 List<ShadowExpression> expressions = popListForValue(count); |
1135 List<DartType> typeArguments = pop(); | 1153 List<DartType> typeArguments = pop(); |
1136 DartType typeArgument = const DynamicType(); | 1154 DartType typeArgument; |
1137 if (typeArguments != null) { | 1155 if (typeArguments != null) { |
1138 typeArgument = typeArguments.first; | 1156 typeArgument = typeArguments.first; |
1139 if (typeArguments.length > 1) { | 1157 if (typeArguments.length > 1) { |
1140 typeArgument = const DynamicType(); | 1158 typeArgument = null; |
1141 warning( | 1159 warning( |
1142 "Too many type arguments on List literal.", beginToken.charOffset); | 1160 "Too many type arguments on List literal.", beginToken.charOffset); |
1143 } | 1161 } |
1144 } | 1162 } |
1145 push(new ListLiteral(expressions, | 1163 push(_ast.listLiteral(expressions, typeArgument, constKeyword != null, |
1146 typeArgument: typeArgument, isConst: constKeyword != null) | 1164 constKeyword?.charOffset ?? beginToken.charOffset)); |
1147 ..fileOffset = constKeyword?.charOffset ?? beginToken.charOffset); | |
1148 } | 1165 } |
1149 | 1166 |
1150 @override | 1167 @override |
1151 void handleLiteralBool(Token token) { | 1168 void handleLiteralBool(Token token) { |
1152 debugEvent("LiteralBool"); | 1169 debugEvent("LiteralBool"); |
1153 bool value = optional("true", token); | 1170 bool value = optional("true", token); |
1154 assert(value || optional("false", token)); | 1171 assert(value || optional("false", token)); |
1155 push(new BoolLiteral(value)..fileOffset = token.charOffset); | 1172 push(new BoolLiteral(value)..fileOffset = token.charOffset); |
1156 } | 1173 } |
1157 | 1174 |
1158 @override | 1175 @override |
1159 void handleLiteralDouble(Token token) { | 1176 void handleLiteralDouble(Token token) { |
1160 debugEvent("LiteralDouble"); | 1177 debugEvent("LiteralDouble"); |
1161 push(new DoubleLiteral(double.parse(token.lexeme)) | 1178 push(new DoubleLiteral(double.parse(token.lexeme)) |
1162 ..fileOffset = token.charOffset); | 1179 ..fileOffset = token.charOffset); |
1163 } | 1180 } |
1164 | 1181 |
1165 @override | 1182 @override |
1166 void handleLiteralNull(Token token) { | 1183 void handleLiteralNull(Token token) { |
1167 debugEvent("LiteralNull"); | 1184 debugEvent("LiteralNull"); |
1168 push(new NullLiteral()..fileOffset = token.charOffset); | 1185 push(_ast.nullLiteral(token.charOffset)); |
1169 } | 1186 } |
1170 | 1187 |
1171 @override | 1188 @override |
1172 void handleLiteralMap( | 1189 void handleLiteralMap( |
1173 int count, Token beginToken, Token constKeyword, Token endToken) { | 1190 int count, Token beginToken, Token constKeyword, Token endToken) { |
1174 debugEvent("LiteralMap"); | 1191 debugEvent("LiteralMap"); |
1175 List<MapEntry> entries = popList(count) ?? <MapEntry>[]; | 1192 List<MapEntry> entries = popList(count) ?? <MapEntry>[]; |
1176 List<DartType> typeArguments = pop(); | 1193 List<DartType> typeArguments = pop(); |
1177 DartType keyType = const DynamicType(); | 1194 DartType keyType = const DynamicType(); |
1178 DartType valueType = const DynamicType(); | 1195 DartType valueType = const DynamicType(); |
1179 if (typeArguments != null) { | 1196 if (typeArguments != null) { |
1180 if (typeArguments.length != 2) { | 1197 if (typeArguments.length != 2) { |
1181 keyType = const DynamicType(); | 1198 keyType = const DynamicType(); |
1182 valueType = const DynamicType(); | 1199 valueType = const DynamicType(); |
1183 warning( | 1200 warning( |
1184 "Map literal requires two type arguments.", beginToken.charOffset); | 1201 "Map literal requires two type arguments.", beginToken.charOffset); |
1185 } else { | 1202 } else { |
1186 keyType = typeArguments[0]; | 1203 keyType = typeArguments[0]; |
1187 valueType = typeArguments[1]; | 1204 valueType = typeArguments[1]; |
1188 } | 1205 } |
1189 } | 1206 } |
1190 push(new MapLiteral(entries, | 1207 push(new MapLiteral(entries, |
1191 keyType: keyType, valueType: valueType, isConst: constKeyword != null) | 1208 keyType: keyType, valueType: valueType, isConst: constKeyword != null) |
1192 ..fileOffset = constKeyword?.charOffset ?? beginToken.charOffset); | 1209 ..fileOffset = constKeyword?.charOffset ?? beginToken.charOffset); |
1193 } | 1210 } |
1194 | 1211 |
1195 @override | 1212 @override |
1196 void endLiteralMapEntry(Token colon, Token endToken) { | 1213 void endLiteralMapEntry(Token colon, Token endToken) { |
1197 debugEvent("LiteralMapEntry"); | 1214 debugEvent("LiteralMapEntry"); |
1198 Expression value = popForValue(); | 1215 Expression value = popForValue() as Expression; |
1199 Expression key = popForValue(); | 1216 Expression key = popForValue() as Expression; |
1200 push(new MapEntry(key, value)); | 1217 push(new MapEntry(key, value)); |
1201 } | 1218 } |
1202 | 1219 |
1203 String symbolPartToString(name) { | 1220 String symbolPartToString(name) { |
1204 if (name is Identifier) { | 1221 if (name is Identifier) { |
1205 return name.name; | 1222 return name.name; |
1206 } else if (name is Operator) { | 1223 } else if (name is Operator) { |
1207 return name.name; | 1224 return name.name; |
1208 } else { | 1225 } else { |
1209 return internalError("Unhandled: ${name.runtimeType}"); | 1226 return internalError("Unhandled: ${name.runtimeType}"); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1329 @override | 1346 @override |
1330 void handleVoidKeyword(Token token) { | 1347 void handleVoidKeyword(Token token) { |
1331 debugEvent("VoidKeyword"); | 1348 debugEvent("VoidKeyword"); |
1332 push(const VoidType()); | 1349 push(const VoidType()); |
1333 } | 1350 } |
1334 | 1351 |
1335 @override | 1352 @override |
1336 void handleAsOperator(Token operator, Token endToken) { | 1353 void handleAsOperator(Token operator, Token endToken) { |
1337 debugEvent("AsOperator"); | 1354 debugEvent("AsOperator"); |
1338 DartType type = pop(); | 1355 DartType type = pop(); |
1339 Expression expression = popForValue(); | 1356 Expression expression = popForValue() as Expression; |
1340 push(new AsExpression(expression, type)..fileOffset = operator.charOffset); | 1357 push(new AsExpression(expression, type)..fileOffset = operator.charOffset); |
1341 } | 1358 } |
1342 | 1359 |
1343 @override | 1360 @override |
1344 void handleIsOperator(Token operator, Token not, Token endToken) { | 1361 void handleIsOperator(Token operator, Token not, Token endToken) { |
1345 debugEvent("IsOperator"); | 1362 debugEvent("IsOperator"); |
1346 DartType type = pop(); | 1363 DartType type = pop(); |
1347 Expression expression = popForValue(); | 1364 Expression expression = popForValue() as Expression; |
1348 expression = new IsExpression(expression, type) | 1365 expression = new IsExpression(expression, type) |
1349 ..fileOffset = operator.charOffset; | 1366 ..fileOffset = operator.charOffset; |
1350 if (not != null) { | 1367 if (not != null) { |
1351 expression = new Not(expression); | 1368 expression = new Not(expression); |
1352 } | 1369 } |
1353 push(expression); | 1370 push(expression); |
1354 } | 1371 } |
1355 | 1372 |
1356 @override | 1373 @override |
1357 void handleConditionalExpression(Token question, Token colon) { | 1374 void handleConditionalExpression(Token question, Token colon) { |
1358 debugEvent("ConditionalExpression"); | 1375 debugEvent("ConditionalExpression"); |
1359 Expression elseExpression = popForValue(); | 1376 Expression elseExpression = popForValue() as Expression; |
1360 Expression thenExpression = popForValue(); | 1377 Expression thenExpression = popForValue() as Expression; |
1361 Expression condition = popForValue(); | 1378 Expression condition = popForValue() as Expression; |
1362 push(new ConditionalExpression( | 1379 push(new ConditionalExpression( |
1363 condition, thenExpression, elseExpression, const DynamicType())); | 1380 condition, thenExpression, elseExpression, const DynamicType())); |
1364 } | 1381 } |
1365 | 1382 |
1366 @override | 1383 @override |
1367 void endThrowExpression(Token throwToken, Token endToken) { | 1384 void endThrowExpression(Token throwToken, Token endToken) { |
1368 debugEvent("ThrowExpression"); | 1385 debugEvent("ThrowExpression"); |
1369 Expression expression = popForValue(); | 1386 Expression expression = popForValue() as Expression; |
1370 push(new Throw(expression)..fileOffset = throwToken.charOffset); | 1387 push(new Throw(expression)..fileOffset = throwToken.charOffset); |
1371 } | 1388 } |
1372 | 1389 |
1373 @override | 1390 @override |
1374 void endFormalParameter(Token covariantKeyword, Token thisKeyword, | 1391 void endFormalParameter(Token covariantKeyword, Token thisKeyword, |
1375 Token nameToken, FormalParameterType kind) { | 1392 Token nameToken, FormalParameterType kind) { |
1376 debugEvent("FormalParameter"); | 1393 debugEvent("FormalParameter"); |
1377 // TODO(ahe): Need beginToken here. | 1394 // TODO(ahe): Need beginToken here. |
1378 int charOffset = thisKeyword?.charOffset; | 1395 int charOffset = thisKeyword?.charOffset; |
1379 if (thisKeyword != null) { | 1396 if (thisKeyword != null) { |
1380 if (!inConstructor) { | 1397 if (!inConstructor) { |
1381 addCompileTimeError(thisKeyword.charOffset, | 1398 addCompileTimeError(thisKeyword.charOffset, |
1382 "'this' parameters can only be used on constructors."); | 1399 "'this' parameters can only be used on constructors."); |
1383 thisKeyword = null; | 1400 thisKeyword = null; |
1384 } | 1401 } |
1385 } | 1402 } |
1386 Identifier name = pop(); | 1403 Identifier name = pop(); |
1387 DartType type = pop(); | 1404 DartType type = pop(); |
1388 pop(); // Modifiers. | 1405 pop(); // Modifiers. |
1389 ignore(Unhandled.Metadata); | 1406 ignore(Unhandled.Metadata); |
1390 VariableDeclaration variable; | 1407 ShadowVariableDeclaration variable; |
1391 if (!inCatchClause && functionNestingLevel == 0) { | 1408 if (!inCatchClause && functionNestingLevel == 0) { |
1392 dynamic builder = formalParameterScope.lookup(name.name, charOffset, uri); | 1409 dynamic builder = formalParameterScope.lookup(name.name, charOffset, uri); |
1393 if (builder == null) { | 1410 if (builder == null) { |
1394 if (thisKeyword == null) { | 1411 if (thisKeyword == null) { |
1395 internalError("Internal error: formal missing for '${name.name}'"); | 1412 internalError("Internal error: formal missing for '${name.name}'"); |
1396 } else { | 1413 } else { |
1397 addCompileTimeError(thisKeyword.charOffset, | 1414 addCompileTimeError(thisKeyword.charOffset, |
1398 "'${name.name}' isn't a field in this class."); | 1415 "'${name.name}' isn't a field in this class."); |
1399 thisKeyword = null; | 1416 thisKeyword = null; |
1400 } | 1417 } |
1401 } else if (thisKeyword == null) { | 1418 } else if (thisKeyword == null) { |
1402 variable = builder.build(library); | 1419 variable = builder.build(library); |
1403 variable.initializer = name.initializer; | 1420 (variable as VariableDeclaration).initializer = name.initializer; |
1404 } else if (builder.isField && builder.parent == classBuilder) { | 1421 } else if (builder.isField && builder.parent == classBuilder) { |
1405 FieldBuilder field = builder; | 1422 FieldBuilder field = builder; |
1406 if (type != null) { | 1423 if (type != null) { |
1407 nit("Ignoring type on 'this' parameter '${name.name}'.", | 1424 nit("Ignoring type on 'this' parameter '${name.name}'.", |
1408 thisKeyword.charOffset); | 1425 thisKeyword.charOffset); |
1409 } | 1426 } |
1410 type = field.target.type ?? const DynamicType(); | 1427 type = field.target.type ?? const DynamicType(); |
1411 variable = new VariableDeclaration(name.name, | 1428 variable = _ast.variableDeclaration(name.name, |
1412 type: type, initializer: name.initializer); | 1429 type: type, |
| 1430 initializer: name.initializer as ShadowExpression, |
| 1431 charOffset: name.fileOffset); |
1413 } else { | 1432 } else { |
1414 addCompileTimeError( | 1433 addCompileTimeError( |
1415 name.fileOffset, "'${name.name}' isn't a field in this class."); | 1434 name.fileOffset, "'${name.name}' isn't a field in this class."); |
1416 } | 1435 } |
1417 } | 1436 } |
1418 variable ??= new VariableDeclaration(name.name, | 1437 variable ??= _ast.variableDeclaration(name.name, |
1419 type: type ?? const DynamicType(), | 1438 type: type, |
1420 initializer: name.initializer)..fileOffset = name.fileOffset; | 1439 initializer: name.initializer as ShadowExpression, |
| 1440 charOffset: name.fileOffset); |
1421 push(variable); | 1441 push(variable); |
1422 } | 1442 } |
1423 | 1443 |
1424 @override | 1444 @override |
1425 void endOptionalFormalParameters( | 1445 void endOptionalFormalParameters( |
1426 int count, Token beginToken, Token endToken) { | 1446 int count, Token beginToken, Token endToken) { |
1427 debugEvent("OptionalFormalParameters"); | 1447 debugEvent("OptionalFormalParameters"); |
1428 FormalParameterType kind = optional("{", beginToken) | 1448 FormalParameterType kind = optional("{", beginToken) |
1429 ? FormalParameterType.NAMED | 1449 ? FormalParameterType.NAMED |
1430 : FormalParameterType.POSITIONAL; | 1450 : FormalParameterType.POSITIONAL; |
(...skipping 18 matching lines...) Expand all Loading... |
1449 Identifier name = pop(); | 1469 Identifier name = pop(); |
1450 DartType returnType = pop(); | 1470 DartType returnType = pop(); |
1451 push(formals.toFunctionType(returnType)); | 1471 push(formals.toFunctionType(returnType)); |
1452 push(name); | 1472 push(name); |
1453 functionNestingLevel--; | 1473 functionNestingLevel--; |
1454 } | 1474 } |
1455 | 1475 |
1456 @override | 1476 @override |
1457 void handleValuedFormalParameter(Token equals, Token token) { | 1477 void handleValuedFormalParameter(Token equals, Token token) { |
1458 debugEvent("ValuedFormalParameter"); | 1478 debugEvent("ValuedFormalParameter"); |
1459 Expression initializer = popForValue(); | 1479 Expression initializer = popForValue() as Expression; |
1460 Identifier name = pop(); | 1480 Identifier name = pop(); |
1461 push(new InitializedIdentifier(name.name, initializer)); | 1481 push(new InitializedIdentifier(name.name, initializer)); |
1462 } | 1482 } |
1463 | 1483 |
1464 @override | 1484 @override |
1465 void handleFormalParameterWithoutValue(Token token) { | 1485 void handleFormalParameterWithoutValue(Token token) { |
1466 debugEvent("FormalParameterWithoutValue"); | 1486 debugEvent("FormalParameterWithoutValue"); |
1467 } | 1487 } |
1468 | 1488 |
1469 @override | 1489 @override |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1547 @override | 1567 @override |
1548 void handleNoExpression(Token token) { | 1568 void handleNoExpression(Token token) { |
1549 debugEvent("NoExpression"); | 1569 debugEvent("NoExpression"); |
1550 push(NullValue.Expression); | 1570 push(NullValue.Expression); |
1551 } | 1571 } |
1552 | 1572 |
1553 @override | 1573 @override |
1554 void handleIndexedExpression( | 1574 void handleIndexedExpression( |
1555 Token openCurlyBracket, Token closeCurlyBracket) { | 1575 Token openCurlyBracket, Token closeCurlyBracket) { |
1556 debugEvent("IndexedExpression"); | 1576 debugEvent("IndexedExpression"); |
1557 Expression index = popForValue(); | 1577 Expression index = popForValue() as Expression; |
1558 var receiver = pop(); | 1578 var receiver = pop(); |
1559 if (receiver is ThisAccessor && receiver.isSuper) { | 1579 if (receiver is ThisAccessor && receiver.isSuper) { |
1560 push(new SuperIndexAccessor(this, receiver.charOffset, index, | 1580 push(new SuperIndexAccessor(this, receiver.charOffset, index, |
1561 lookupSuperMember(indexGetName), lookupSuperMember(indexSetName))); | 1581 lookupSuperMember(indexGetName), lookupSuperMember(indexSetName))); |
1562 } else { | 1582 } else { |
1563 push(IndexAccessor.make(this, openCurlyBracket.charOffset, | 1583 push(IndexAccessor.make(this, openCurlyBracket.charOffset, |
1564 toValue(receiver), index, null, null)); | 1584 toValue(receiver) as Expression, index, null, null)); |
1565 } | 1585 } |
1566 } | 1586 } |
1567 | 1587 |
1568 @override | 1588 @override |
1569 void handleUnaryPrefixExpression(Token token) { | 1589 void handleUnaryPrefixExpression(Token token) { |
1570 debugEvent("UnaryPrefixExpression"); | 1590 debugEvent("UnaryPrefixExpression"); |
1571 var receiver = pop(); | 1591 var receiver = pop(); |
1572 if (optional("!", token)) { | 1592 if (optional("!", token)) { |
1573 push(new Not(toValue(receiver))); | 1593 push(new Not(toValue(receiver) as Expression)); |
1574 } else { | 1594 } else { |
1575 String operator = token.stringValue; | 1595 String operator = token.stringValue; |
1576 if (optional("-", token)) { | 1596 if (optional("-", token)) { |
1577 operator = "unary-"; | 1597 operator = "unary-"; |
1578 } | 1598 } |
1579 if (receiver is ThisAccessor && receiver.isSuper) { | 1599 if (receiver is ThisAccessor && receiver.isSuper) { |
1580 push(toSuperMethodInvocation(buildMethodInvocation( | 1600 push(toSuperMethodInvocation(buildMethodInvocation( |
1581 new ThisExpression()..fileOffset = receiver.charOffset, | 1601 new ThisExpression()..fileOffset = receiver.charOffset, |
1582 new Name(operator), | 1602 new Name(operator), |
1583 new Arguments.empty(), | 1603 new Arguments.empty(), |
1584 token.charOffset))); | 1604 token.charOffset))); |
1585 } else { | 1605 } else { |
1586 push(buildMethodInvocation(toValue(receiver), new Name(operator), | 1606 push(buildMethodInvocation(toValue(receiver) as Expression, |
1587 new Arguments.empty(), token.charOffset)); | 1607 new Name(operator), new Arguments.empty(), token.charOffset)); |
1588 } | 1608 } |
1589 } | 1609 } |
1590 } | 1610 } |
1591 | 1611 |
1592 Name incrementOperator(Token token) { | 1612 Name incrementOperator(Token token) { |
1593 if (optional("++", token)) return plusName; | 1613 if (optional("++", token)) return plusName; |
1594 if (optional("--", token)) return minusName; | 1614 if (optional("--", token)) return minusName; |
1595 return internalError("Unknown increment operator: ${token.lexeme}"); | 1615 return internalError("Unknown increment operator: ${token.lexeme}"); |
1596 } | 1616 } |
1597 | 1617 |
1598 @override | 1618 @override |
1599 void handleUnaryPrefixAssignmentExpression(Token token) { | 1619 void handleUnaryPrefixAssignmentExpression(Token token) { |
1600 debugEvent("UnaryPrefixAssignmentExpression"); | 1620 debugEvent("UnaryPrefixAssignmentExpression"); |
1601 var accessor = pop(); | 1621 var accessor = pop(); |
1602 if (accessor is BuilderAccessor) { | 1622 if (accessor is BuilderAccessor) { |
1603 push(accessor.buildPrefixIncrement( | 1623 push(accessor.buildPrefixIncrement( |
1604 incrementOperator(token), token.charOffset)); | 1624 incrementOperator(token), token.charOffset)); |
1605 } else { | 1625 } else { |
1606 push(wrapInvalid(toValue(accessor))); | 1626 push(wrapInvalid(toValue(accessor) as Expression)); |
1607 } | 1627 } |
1608 } | 1628 } |
1609 | 1629 |
1610 @override | 1630 @override |
1611 void handleUnaryPostfixAssignmentExpression(Token token) { | 1631 void handleUnaryPostfixAssignmentExpression(Token token) { |
1612 debugEvent("UnaryPostfixAssignmentExpression"); | 1632 debugEvent("UnaryPostfixAssignmentExpression"); |
1613 var accessor = pop(); | 1633 var accessor = pop(); |
1614 if (accessor is BuilderAccessor) { | 1634 if (accessor is BuilderAccessor) { |
1615 push(new DelayedPostfixIncrement( | 1635 push(new DelayedPostfixIncrement( |
1616 this, token.charOffset, accessor, incrementOperator(token), null)); | 1636 this, token.charOffset, accessor, incrementOperator(token), null)); |
1617 } else { | 1637 } else { |
1618 push(wrapInvalid(toValue(accessor))); | 1638 push(wrapInvalid(toValue(accessor) as Expression)); |
1619 } | 1639 } |
1620 } | 1640 } |
1621 | 1641 |
1622 @override | 1642 @override |
1623 void endConstructorReference( | 1643 void endConstructorReference( |
1624 Token start, Token periodBeforeName, Token endToken) { | 1644 Token start, Token periodBeforeName, Token endToken) { |
1625 debugEvent("ConstructorReference"); | 1645 debugEvent("ConstructorReference"); |
1626 // A constructor reference can contain up to three identifiers: | 1646 // A constructor reference can contain up to three identifiers: |
1627 // | 1647 // |
1628 // a) type <type-arguments>? | 1648 // a) type <type-arguments>? |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1676 } | 1696 } |
1677 | 1697 |
1678 @override | 1698 @override |
1679 Expression buildStaticInvocation(Member target, Arguments arguments, | 1699 Expression buildStaticInvocation(Member target, Arguments arguments, |
1680 {bool isConst: false, int charOffset: -1}) { | 1700 {bool isConst: false, int charOffset: -1}) { |
1681 List<TypeParameter> typeParameters = target.function.typeParameters; | 1701 List<TypeParameter> typeParameters = target.function.typeParameters; |
1682 if (target is Constructor) { | 1702 if (target is Constructor) { |
1683 typeParameters = target.enclosingClass.typeParameters; | 1703 typeParameters = target.enclosingClass.typeParameters; |
1684 } | 1704 } |
1685 if (!checkArguments(target.function, arguments, typeParameters)) { | 1705 if (!checkArguments(target.function, arguments, typeParameters)) { |
1686 return throwNoSuchMethodError(target.name.name, arguments, charOffset); | 1706 return throwNoSuchMethodError(target.name.name, arguments, charOffset) |
| 1707 as Expression; |
1687 } | 1708 } |
1688 if (target is Constructor) { | 1709 if (target is Constructor) { |
1689 return new ConstructorInvocation(target, arguments) | 1710 return new ConstructorInvocation(target, arguments) |
1690 ..isConst = isConst | 1711 ..isConst = isConst |
1691 ..fileOffset = charOffset; | 1712 ..fileOffset = charOffset; |
1692 } else { | 1713 } else { |
1693 return new StaticInvocation(target, arguments) | 1714 return new StaticInvocation(target, arguments) |
1694 ..isConst = isConst | 1715 ..isConst = isConst |
1695 ..fileOffset = charOffset; | 1716 ..fileOffset = charOffset; |
1696 } | 1717 } |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1837 isSuper: true)); | 1858 isSuper: true)); |
1838 } else { | 1859 } else { |
1839 push(new IncompleteError( | 1860 push(new IncompleteError( |
1840 this, token.charOffset, "Expected identifier, but got 'super'.")); | 1861 this, token.charOffset, "Expected identifier, but got 'super'.")); |
1841 } | 1862 } |
1842 } | 1863 } |
1843 | 1864 |
1844 @override | 1865 @override |
1845 void handleNamedArgument(Token colon) { | 1866 void handleNamedArgument(Token colon) { |
1846 debugEvent("NamedArgument"); | 1867 debugEvent("NamedArgument"); |
1847 Expression value = popForValue(); | 1868 Expression value = popForValue() as Expression; |
1848 Identifier identifier = pop(); | 1869 Identifier identifier = pop(); |
1849 push(new NamedExpression(identifier.name, value)); | 1870 push(new NamedExpression(identifier.name, value)); |
1850 } | 1871 } |
1851 | 1872 |
1852 @override | 1873 @override |
1853 void endFunctionName(Token beginToken, Token token) { | 1874 void endFunctionName(Token beginToken, Token token) { |
1854 debugEvent("FunctionName"); | 1875 debugEvent("FunctionName"); |
1855 Identifier name = pop(); | 1876 Identifier name = pop(); |
1856 VariableDeclaration variable = | 1877 VariableDeclaration variable = |
1857 new VariableDeclaration(name.name, isFinal: true); | 1878 new VariableDeclaration(name.name, isFinal: true); |
1858 push(new FunctionDeclaration( | 1879 push(new FunctionDeclaration( |
1859 variable, new FunctionNode(new InvalidStatement())) | 1880 variable, new FunctionNode(new InvalidStatement())) |
1860 ..fileOffset = beginToken.charOffset); | 1881 ..fileOffset = beginToken.charOffset); |
1861 scope[variable.name] = new KernelVariableBuilder( | 1882 scope[variable.name] = new KernelVariableBuilder( |
1862 variable, member ?? classBuilder ?? library, uri); | 1883 variable, member ?? classBuilder ?? library, uri); |
1863 enterLocalScope(); | 1884 enterLocalScope(); |
1864 } | 1885 } |
1865 | 1886 |
1866 void enterFunction() { | 1887 void enterFunction(bool isNamed) { |
1867 debugEvent("enterFunction"); | 1888 debugEvent("enterFunction"); |
1868 functionNestingLevel++; | 1889 functionNestingLevel++; |
1869 push(switchScope ?? NullValue.SwitchScope); | 1890 push(switchScope ?? NullValue.SwitchScope); |
1870 switchScope = null; | 1891 switchScope = null; |
1871 } | 1892 } |
1872 | 1893 |
1873 void exitFunction() { | 1894 void exitFunction() { |
1874 debugEvent("exitFunction"); | 1895 debugEvent("exitFunction"); |
1875 functionNestingLevel--; | 1896 functionNestingLevel--; |
1876 switchScope = pop(); | 1897 switchScope = pop(); |
1877 } | 1898 } |
1878 | 1899 |
1879 @override | 1900 @override |
1880 void beginFunction(Token token) { | 1901 void beginFunction(Token token) { |
1881 debugEvent("beginFunction"); | 1902 debugEvent("beginFunction"); |
1882 enterFunction(); | 1903 enterFunction(true); |
1883 } | 1904 } |
1884 | 1905 |
1885 @override | 1906 @override |
1886 void beginUnnamedFunction(Token token) { | 1907 void beginUnnamedFunction(Token token) { |
1887 debugEvent("beginUnnamedFunction"); | 1908 debugEvent("beginUnnamedFunction"); |
1888 enterFunction(); | 1909 enterFunction(false); |
1889 } | 1910 } |
1890 | 1911 |
1891 @override | 1912 @override |
1892 void endFunction(Token getOrSet, Token endToken) { | 1913 void endFunction(Token getOrSet, Token endToken) { |
1893 debugEvent("Function"); | 1914 debugEvent("Function"); |
1894 Statement body = popStatement(); | 1915 Statement body = popStatement(); |
1895 AsyncMarker asyncModifier = pop(); | 1916 AsyncMarker asyncModifier = pop(); |
1896 if (functionNestingLevel != 0) { | 1917 if (functionNestingLevel != 0) { |
1897 exitLocalScope(); | 1918 exitLocalScope(); |
1898 } | 1919 } |
(...skipping 25 matching lines...) Expand all Loading... |
1924 Statement body = popStatement(); | 1945 Statement body = popStatement(); |
1925 AsyncMarker asyncModifier = pop(); | 1946 AsyncMarker asyncModifier = pop(); |
1926 exitLocalScope(); | 1947 exitLocalScope(); |
1927 FormalParameters formals = pop(); | 1948 FormalParameters formals = pop(); |
1928 exitFunction(); | 1949 exitFunction(); |
1929 List<TypeParameter> typeParameters = pop(); | 1950 List<TypeParameter> typeParameters = pop(); |
1930 FunctionNode function = formals.addToFunction(new FunctionNode(body, | 1951 FunctionNode function = formals.addToFunction(new FunctionNode(body, |
1931 typeParameters: typeParameters, asyncMarker: asyncModifier) | 1952 typeParameters: typeParameters, asyncMarker: asyncModifier) |
1932 ..fileOffset = beginToken.charOffset | 1953 ..fileOffset = beginToken.charOffset |
1933 ..fileEndOffset = token.charOffset); | 1954 ..fileEndOffset = token.charOffset); |
1934 push(new FunctionExpression(function)..fileOffset = beginToken.charOffset); | 1955 push(new KernelFunctionExpression(function) |
| 1956 ..fileOffset = beginToken.charOffset); |
1935 } | 1957 } |
1936 | 1958 |
1937 @override | 1959 @override |
1938 void endDoWhileStatement( | 1960 void endDoWhileStatement( |
1939 Token doKeyword, Token whileKeyword, Token endToken) { | 1961 Token doKeyword, Token whileKeyword, Token endToken) { |
1940 debugEvent("DoWhileStatement"); | 1962 debugEvent("DoWhileStatement"); |
1941 Expression condition = popForValue(); | 1963 Expression condition = popForValue() as Expression; |
1942 Statement body = popStatement(); | 1964 Statement body = popStatement(); |
1943 JumpTarget continueTarget = exitContinueTarget(); | 1965 JumpTarget continueTarget = exitContinueTarget(); |
1944 JumpTarget breakTarget = exitBreakTarget(); | 1966 JumpTarget breakTarget = exitBreakTarget(); |
1945 if (continueTarget.hasUsers) { | 1967 if (continueTarget.hasUsers) { |
1946 body = new LabeledStatement(body); | 1968 body = new LabeledStatement(body); |
1947 continueTarget.resolveContinues(body); | 1969 continueTarget.resolveContinues(body); |
1948 } | 1970 } |
1949 Statement result = new DoStatement(body, condition); | 1971 Statement result = new DoStatement(body, condition); |
1950 if (breakTarget.hasUsers) { | 1972 if (breakTarget.hasUsers) { |
1951 result = new LabeledStatement(result); | 1973 result = new LabeledStatement(result); |
1952 breakTarget.resolveBreaks(result); | 1974 breakTarget.resolveBreaks(result); |
1953 } | 1975 } |
1954 exitLoopOrSwitch(result); | 1976 exitLoopOrSwitch(result); |
1955 } | 1977 } |
1956 | 1978 |
1957 @override | 1979 @override |
1958 void beginForInExpression(Token token) { | 1980 void beginForInExpression(Token token) { |
1959 enterLocalScope(scope.parent); | 1981 enterLocalScope(scope.parent); |
1960 } | 1982 } |
1961 | 1983 |
1962 @override | 1984 @override |
1963 void endForInExpression(Token token) { | 1985 void endForInExpression(Token token) { |
1964 debugEvent("ForInExpression"); | 1986 debugEvent("ForInExpression"); |
1965 Expression expression = popForValue(); | 1987 Expression expression = popForValue() as Expression; |
1966 exitLocalScope(); | 1988 exitLocalScope(); |
1967 push(expression ?? NullValue.Expression); | 1989 push(expression ?? NullValue.Expression); |
1968 } | 1990 } |
1969 | 1991 |
1970 @override | 1992 @override |
1971 void endForIn(Token awaitToken, Token forToken, Token leftParenthesis, | 1993 void endForIn(Token awaitToken, Token forToken, Token leftParenthesis, |
1972 Token inKeyword, Token rightParenthesis, Token endToken) { | 1994 Token inKeyword, Token rightParenthesis, Token endToken) { |
1973 debugEvent("ForIn"); | 1995 debugEvent("ForIn"); |
1974 Statement body = popStatement(); | 1996 Statement body = popStatement(); |
1975 Expression expression = popForValue(); | 1997 Expression expression = popForValue() as Expression; |
1976 var lvalue = pop(); | 1998 var lvalue = pop(); |
1977 exitLocalScope(); | 1999 exitLocalScope(); |
1978 JumpTarget continueTarget = exitContinueTarget(); | 2000 JumpTarget continueTarget = exitContinueTarget(); |
1979 JumpTarget breakTarget = exitBreakTarget(); | 2001 JumpTarget breakTarget = exitBreakTarget(); |
1980 if (continueTarget.hasUsers) { | 2002 if (continueTarget.hasUsers) { |
1981 body = new LabeledStatement(body); | 2003 body = new LabeledStatement(body); |
1982 continueTarget.resolveContinues(body); | 2004 continueTarget.resolveContinues(body); |
1983 } | 2005 } |
1984 VariableDeclaration variable; | 2006 VariableDeclaration variable; |
1985 if (lvalue is VariableDeclaration) { | 2007 if (lvalue is VariableDeclaration) { |
1986 variable = lvalue; | 2008 variable = lvalue; |
1987 } else if (lvalue is BuilderAccessor) { | 2009 } else if (lvalue is BuilderAccessor) { |
1988 /// We are in this case, where `lvalue` isn't a [VariableDeclaration]: | 2010 /// We are in this case, where `lvalue` isn't a [VariableDeclaration]: |
1989 /// | 2011 /// |
1990 /// for (lvalue in expression) body | 2012 /// for (lvalue in expression) body |
1991 /// | 2013 /// |
1992 /// This is normalized to: | 2014 /// This is normalized to: |
1993 /// | 2015 /// |
1994 /// for (final #t in expression) { | 2016 /// for (final #t in expression) { |
1995 /// lvalue = #t; | 2017 /// lvalue = #t; |
1996 /// body; | 2018 /// body; |
1997 /// } | 2019 /// } |
1998 variable = new VariableDeclaration.forValue(null); | 2020 variable = new VariableDeclaration.forValue(null); |
1999 body = combineStatements( | 2021 body = combineStatements( |
2000 new ExpressionStatement(lvalue | 2022 new ExpressionStatement(lvalue |
2001 .buildAssignment(new VariableGet(variable), voidContext: true)), | 2023 .buildAssignment(new VariableGet(variable), voidContext: true)), |
2002 body); | 2024 body); |
2003 } else { | 2025 } else { |
2004 variable = new VariableDeclaration.forValue(buildCompileTimeError( | 2026 variable = new VariableDeclaration.forValue(buildCompileTimeError( |
2005 "Expected lvalue, but got ${lvalue}", forToken.next.next.charOffset)); | 2027 "Expected lvalue, but got ${lvalue}", |
| 2028 forToken.next.next.charOffset) as Expression); |
2006 } | 2029 } |
2007 Statement result = new ForInStatement(variable, expression, body, | 2030 Statement result = new ForInStatement(variable, expression, body, |
2008 isAsync: awaitToken != null)..fileOffset = body.fileOffset; | 2031 isAsync: awaitToken != null)..fileOffset = body.fileOffset; |
2009 if (breakTarget.hasUsers) { | 2032 if (breakTarget.hasUsers) { |
2010 result = new LabeledStatement(result); | 2033 result = new LabeledStatement(result); |
2011 breakTarget.resolveBreaks(result); | 2034 breakTarget.resolveBreaks(result); |
2012 } | 2035 } |
2013 exitLoopOrSwitch(result); | 2036 exitLoopOrSwitch(result); |
2014 } | 2037 } |
2015 | 2038 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2064 @override | 2087 @override |
2065 void handleFinallyBlock(Token finallyKeyword) { | 2088 void handleFinallyBlock(Token finallyKeyword) { |
2066 debugEvent("FinallyBlock"); | 2089 debugEvent("FinallyBlock"); |
2067 // Do nothing, handled by [endTryStatement]. | 2090 // Do nothing, handled by [endTryStatement]. |
2068 } | 2091 } |
2069 | 2092 |
2070 @override | 2093 @override |
2071 void endWhileStatement(Token whileKeyword, Token endToken) { | 2094 void endWhileStatement(Token whileKeyword, Token endToken) { |
2072 debugEvent("WhileStatement"); | 2095 debugEvent("WhileStatement"); |
2073 Statement body = popStatement(); | 2096 Statement body = popStatement(); |
2074 Expression condition = popForValue(); | 2097 Expression condition = popForValue() as Expression; |
2075 JumpTarget continueTarget = exitContinueTarget(); | 2098 JumpTarget continueTarget = exitContinueTarget(); |
2076 JumpTarget breakTarget = exitBreakTarget(); | 2099 JumpTarget breakTarget = exitBreakTarget(); |
2077 if (continueTarget.hasUsers) { | 2100 if (continueTarget.hasUsers) { |
2078 body = new LabeledStatement(body); | 2101 body = new LabeledStatement(body); |
2079 continueTarget.resolveContinues(body); | 2102 continueTarget.resolveContinues(body); |
2080 } | 2103 } |
2081 Statement result = new WhileStatement(condition, body); | 2104 Statement result = new WhileStatement(condition, body); |
2082 if (breakTarget.hasUsers) { | 2105 if (breakTarget.hasUsers) { |
2083 result = new LabeledStatement(result); | 2106 result = new LabeledStatement(result); |
2084 breakTarget.resolveBreaks(result); | 2107 breakTarget.resolveBreaks(result); |
2085 } | 2108 } |
2086 exitLoopOrSwitch(result); | 2109 exitLoopOrSwitch(result); |
2087 } | 2110 } |
2088 | 2111 |
2089 @override | 2112 @override |
2090 void handleEmptyStatement(Token token) { | 2113 void handleEmptyStatement(Token token) { |
2091 debugEvent("EmptyStatement"); | 2114 debugEvent("EmptyStatement"); |
2092 push(new EmptyStatement()); | 2115 push(new EmptyStatement()); |
2093 } | 2116 } |
2094 | 2117 |
2095 @override | 2118 @override |
2096 void handleAssertStatement(Token assertKeyword, Token leftParenthesis, | 2119 void handleAssertStatement(Token assertKeyword, Token leftParenthesis, |
2097 Token commaToken, Token rightParenthesis, Token semicolonToken) { | 2120 Token commaToken, Token rightParenthesis, Token semicolonToken) { |
2098 debugEvent("AssertStatement"); | 2121 debugEvent("AssertStatement"); |
2099 Expression message = popForValueIfNotNull(commaToken); | 2122 Expression message = popForValueIfNotNull(commaToken) as Expression; |
2100 Expression condition = popForValue(); | 2123 Expression condition = popForValue() as Expression; |
2101 push(new AssertStatement(condition, message)); | 2124 push(new AssertStatement(condition, message)); |
2102 } | 2125 } |
2103 | 2126 |
2104 @override | 2127 @override |
2105 void endYieldStatement(Token yieldToken, Token starToken, Token endToken) { | 2128 void endYieldStatement(Token yieldToken, Token starToken, Token endToken) { |
2106 debugEvent("YieldStatement"); | 2129 debugEvent("YieldStatement"); |
2107 push(new YieldStatement(popForValue(), isYieldStar: starToken != null) | 2130 push(new YieldStatement(popForValue() as Expression, |
2108 ..fileOffset = yieldToken.charOffset); | 2131 isYieldStar: starToken != null)..fileOffset = yieldToken.charOffset); |
2109 } | 2132 } |
2110 | 2133 |
2111 @override | 2134 @override |
2112 void beginSwitchBlock(Token token) { | 2135 void beginSwitchBlock(Token token) { |
2113 debugEvent("beginSwitchBlock"); | 2136 debugEvent("beginSwitchBlock"); |
2114 enterLocalScope(); | 2137 enterLocalScope(); |
2115 enterSwitchScope(); | 2138 enterSwitchScope(); |
2116 enterBreakTarget(token.charOffset); | 2139 enterBreakTarget(token.charOffset); |
2117 } | 2140 } |
2118 | 2141 |
2119 @override | 2142 @override |
2120 void beginSwitchCase(int labelCount, int expressionCount, Token firstToken) { | 2143 void beginSwitchCase(int labelCount, int expressionCount, Token firstToken) { |
2121 debugEvent("beginSwitchCase"); | 2144 debugEvent("beginSwitchCase"); |
2122 List labelsAndExpressions = popList(labelCount + expressionCount); | 2145 List labelsAndExpressions = popList(labelCount + expressionCount); |
2123 List<Label> labels = <Label>[]; | 2146 List<Label> labels = <Label>[]; |
2124 List<Expression> expressions = <Expression>[]; | 2147 List<Expression> expressions = <Expression>[]; |
2125 if (labelsAndExpressions != null) { | 2148 if (labelsAndExpressions != null) { |
2126 for (var labelOrExpression in labelsAndExpressions) { | 2149 for (var labelOrExpression in labelsAndExpressions) { |
2127 if (labelOrExpression is Label) { | 2150 if (labelOrExpression is Label) { |
2128 labels.add(labelOrExpression); | 2151 labels.add(labelOrExpression); |
2129 } else { | 2152 } else { |
2130 expressions.add(toValue(labelOrExpression)); | 2153 expressions.add(toValue(labelOrExpression) as Expression); |
2131 } | 2154 } |
2132 } | 2155 } |
2133 } | 2156 } |
2134 assert(scope == switchScope); | 2157 assert(scope == switchScope); |
2135 for (Label label in labels) { | 2158 for (Label label in labels) { |
2136 if (scope.hasLocalLabel(label.name)) { | 2159 if (scope.hasLocalLabel(label.name)) { |
2137 // TODO(ahe): Should validate this is a goto target and not duplicated. | 2160 // TODO(ahe): Should validate this is a goto target and not duplicated. |
2138 scope.claimLabel(label.name); | 2161 scope.claimLabel(label.name); |
2139 } else { | 2162 } else { |
2140 scope.declareLabel(label.name, createGotoTarget(firstToken.charOffset)); | 2163 scope.declareLabel(label.name, createGotoTarget(firstToken.charOffset)); |
2141 } | 2164 } |
2142 } | 2165 } |
2143 push(expressions); | 2166 push(expressions); |
2144 push(labels); | 2167 push(labels); |
2145 enterLocalScope(); | 2168 enterLocalScope(); |
2146 } | 2169 } |
2147 | 2170 |
2148 @override | 2171 @override |
2149 void handleSwitchCase( | 2172 void handleSwitchCase( |
2150 int labelCount, | 2173 int labelCount, |
2151 int expressionCount, | 2174 int expressionCount, |
2152 Token defaultKeyword, | 2175 Token defaultKeyword, |
2153 int statementCount, | 2176 int statementCount, |
2154 Token firstToken, | 2177 Token firstToken, |
2155 Token endToken) { | 2178 Token endToken) { |
2156 debugEvent("SwitchCase"); | 2179 debugEvent("SwitchCase"); |
2157 Block block = popBlock(statementCount, firstToken.charOffset); | 2180 Block block = popBlock(statementCount, firstToken.charOffset) as Block; |
2158 exitLocalScope(); | 2181 exitLocalScope(); |
2159 List<Label> labels = pop(); | 2182 List<Label> labels = pop(); |
2160 List<Expression> expressions = pop(); | 2183 List<Expression> expressions = pop(); |
2161 List<int> expressionOffsets = <int>[]; | 2184 List<int> expressionOffsets = <int>[]; |
2162 for (Expression expression in expressions) { | 2185 for (Expression expression in expressions) { |
2163 expressionOffsets.add(expression.fileOffset); | 2186 expressionOffsets.add(expression.fileOffset); |
2164 } | 2187 } |
2165 push(new SwitchCase(expressions, expressionOffsets, block, | 2188 push(new SwitchCase(expressions, expressionOffsets, block, |
2166 isDefault: defaultKeyword != null)..fileOffset = firstToken.charOffset); | 2189 isDefault: defaultKeyword != null)..fileOffset = firstToken.charOffset); |
2167 push(labels); | 2190 push(labels); |
(...skipping 17 matching lines...) Expand all Loading... |
2185 JumpTarget target = switchScope.lookupLabel(label.name); | 2208 JumpTarget target = switchScope.lookupLabel(label.name); |
2186 if (target != null) { | 2209 if (target != null) { |
2187 target.resolveGotos(current); | 2210 target.resolveGotos(current); |
2188 } | 2211 } |
2189 } | 2212 } |
2190 // TODO(ahe): Validate that there's only one default and it's last. | 2213 // TODO(ahe): Validate that there's only one default and it's last. |
2191 } | 2214 } |
2192 JumpTarget target = exitBreakTarget(); | 2215 JumpTarget target = exitBreakTarget(); |
2193 exitSwitchScope(); | 2216 exitSwitchScope(); |
2194 exitLocalScope(); | 2217 exitLocalScope(); |
2195 Expression expression = popForValue(); | 2218 Expression expression = popForValue() as Expression; |
2196 Statement result = new SwitchStatement(expression, cases); | 2219 Statement result = new SwitchStatement(expression, cases); |
2197 if (target.hasUsers) { | 2220 if (target.hasUsers) { |
2198 result = new LabeledStatement(result); | 2221 result = new LabeledStatement(result); |
2199 target.resolveBreaks(result); | 2222 target.resolveBreaks(result); |
2200 } | 2223 } |
2201 exitLoopOrSwitch(result); | 2224 exitLoopOrSwitch(result); |
2202 } | 2225 } |
2203 | 2226 |
2204 @override | 2227 @override |
2205 void handleCaseMatch(Token caseKeyword, Token colon) { | 2228 void handleCaseMatch(Token caseKeyword, Token colon) { |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2338 if (trailing.contains(token.stringValue) && trailing.contains(expected)) { | 2361 if (trailing.contains(token.stringValue) && trailing.contains(expected)) { |
2339 arguments.putIfAbsent("actual", () => token.lexeme); | 2362 arguments.putIfAbsent("actual", () => token.lexeme); |
2340 handleRecoverableError(token, ErrorKind.ExpectedButGot, arguments); | 2363 handleRecoverableError(token, ErrorKind.ExpectedButGot, arguments); |
2341 return newSyntheticToken(token); | 2364 return newSyntheticToken(token); |
2342 } | 2365 } |
2343 } | 2366 } |
2344 return super.handleUnrecoverableError(token, kind, arguments); | 2367 return super.handleUnrecoverableError(token, kind, arguments); |
2345 } | 2368 } |
2346 | 2369 |
2347 @override | 2370 @override |
2348 Expression buildCompileTimeError(error, [int charOffset = -1]) { | 2371 ShadowExpression buildCompileTimeError(error, [int charOffset = -1]) { |
2349 addCompileTimeError(charOffset, error); | 2372 addCompileTimeError(charOffset, error); |
2350 String message = formatUnexpected(uri, charOffset, error); | 2373 String message = formatUnexpected(uri, charOffset, error); |
2351 Builder constructor = library.loader.getCompileTimeError(); | 2374 Builder constructor = library.loader.getCompileTimeError(); |
2352 return new Throw(buildStaticInvocation(constructor.target, | 2375 return new Throw(buildStaticInvocation(constructor.target, |
2353 new Arguments(<Expression>[new StringLiteral(message)]), | 2376 new Arguments(<Expression>[new StringLiteral(message)]), |
2354 isConst: false)); // TODO(ahe): Make this const. | 2377 isConst: false) as Expression) |
| 2378 as ShadowExpression; // TODO(ahe): Make this const. |
2355 } | 2379 } |
2356 | 2380 |
2357 Statement buildCompileTimeErrorStatement(error, [int charOffset = -1]) { | 2381 Statement buildCompileTimeErrorStatement(error, [int charOffset = -1]) { |
2358 return new ExpressionStatement(buildCompileTimeError(error, charOffset)); | 2382 return new ExpressionStatement( |
| 2383 buildCompileTimeError(error, charOffset) as Expression); |
2359 } | 2384 } |
2360 | 2385 |
2361 @override | 2386 @override |
2362 Initializer buildCompileTimeErrorIntializer(error, [int charOffset = -1]) { | 2387 Initializer buildCompileTimeErrorIntializer(error, [int charOffset = -1]) { |
2363 return new LocalInitializer(new VariableDeclaration.forValue( | 2388 return new LocalInitializer(new VariableDeclaration.forValue( |
2364 buildCompileTimeError(error, charOffset))); | 2389 buildCompileTimeError(error, charOffset) as Expression)); |
2365 } | 2390 } |
2366 | 2391 |
2367 @override | 2392 @override |
2368 Expression buildProblemExpression(ProblemBuilder builder, int charOffset) { | 2393 ShadowExpression buildProblemExpression( |
| 2394 ProblemBuilder builder, int charOffset) { |
2369 return buildCompileTimeError(builder.message, charOffset); | 2395 return buildCompileTimeError(builder.message, charOffset); |
2370 } | 2396 } |
2371 | 2397 |
2372 @override | 2398 @override |
2373 void handleOperator(Token token) { | 2399 void handleOperator(Token token) { |
2374 debugEvent("Operator"); | 2400 debugEvent("Operator"); |
2375 push(new Operator(token.stringValue)..fileOffset = token.charOffset); | 2401 push(new Operator(token.stringValue)..fileOffset = token.charOffset); |
2376 } | 2402 } |
2377 | 2403 |
2378 @override | 2404 @override |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2493 final BuilderAccessor accessor; | 2519 final BuilderAccessor accessor; |
2494 | 2520 |
2495 ContextAccessor(this.helper, this.charOffset, this.accessor); | 2521 ContextAccessor(this.helper, this.charOffset, this.accessor); |
2496 | 2522 |
2497 String get plainNameForRead => internalError("Unsupported operation."); | 2523 String get plainNameForRead => internalError("Unsupported operation."); |
2498 | 2524 |
2499 Expression doInvocation(int charOffset, Arguments arguments) { | 2525 Expression doInvocation(int charOffset, Arguments arguments) { |
2500 return internalError("Unhandled: ${runtimeType}", uri, charOffset); | 2526 return internalError("Unhandled: ${runtimeType}", uri, charOffset); |
2501 } | 2527 } |
2502 | 2528 |
2503 Expression buildSimpleRead(); | 2529 ShadowExpression buildSimpleRead(); |
2504 | 2530 |
2505 Expression buildForEffect(); | 2531 ShadowExpression buildForEffect(); |
2506 | 2532 |
2507 Expression buildAssignment(Expression value, {bool voidContext: false}) { | 2533 Expression buildAssignment(Expression value, {bool voidContext: false}) { |
2508 return makeInvalidWrite(value); | 2534 return makeInvalidWrite(value); |
2509 } | 2535 } |
2510 | 2536 |
2511 Expression buildNullAwareAssignment(Expression value, DartType type, | 2537 Expression buildNullAwareAssignment(Expression value, DartType type, |
2512 {bool voidContext: false}) { | 2538 {bool voidContext: false}) { |
2513 return makeInvalidWrite(value); | 2539 return makeInvalidWrite(value); |
2514 } | 2540 } |
2515 | 2541 |
(...skipping 10 matching lines...) Expand all Loading... |
2526 | 2552 |
2527 Expression buildPostfixIncrement(Name binaryOperator, int charOffset, | 2553 Expression buildPostfixIncrement(Name binaryOperator, int charOffset, |
2528 {bool voidContext: false, Procedure interfaceTarget}) { | 2554 {bool voidContext: false, Procedure interfaceTarget}) { |
2529 return makeInvalidWrite(null); | 2555 return makeInvalidWrite(null); |
2530 } | 2556 } |
2531 | 2557 |
2532 makeInvalidRead() => internalError("not supported"); | 2558 makeInvalidRead() => internalError("not supported"); |
2533 | 2559 |
2534 Expression makeInvalidWrite(Expression value) { | 2560 Expression makeInvalidWrite(Expression value) { |
2535 return helper.buildCompileTimeError( | 2561 return helper.buildCompileTimeError( |
2536 "Can't be used as left-hand side of assignment.", charOffset); | 2562 "Can't be used as left-hand side of assignment.", charOffset) |
| 2563 as Expression; |
2537 } | 2564 } |
2538 } | 2565 } |
2539 | 2566 |
2540 class DelayedAssignment extends ContextAccessor { | 2567 class DelayedAssignment extends ContextAccessor { |
2541 final Expression value; | 2568 final Expression value; |
2542 | 2569 |
2543 final String assignmentOperator; | 2570 final String assignmentOperator; |
2544 | 2571 |
2545 DelayedAssignment(BuilderHelper helper, int charOffset, | 2572 DelayedAssignment(BuilderHelper helper, int charOffset, |
2546 BuilderAccessor accessor, this.value, this.assignmentOperator) | 2573 BuilderAccessor accessor, this.value, this.assignmentOperator) |
2547 : super(helper, charOffset, accessor); | 2574 : super(helper, charOffset, accessor); |
2548 | 2575 |
2549 Expression buildSimpleRead() { | 2576 ShadowExpression buildSimpleRead() { |
2550 return handleAssignment(false); | 2577 return handleAssignment(false) as ShadowExpression; |
2551 } | 2578 } |
2552 | 2579 |
2553 Expression buildForEffect() { | 2580 ShadowExpression buildForEffect() { |
2554 return handleAssignment(true); | 2581 return handleAssignment(true) as ShadowExpression; |
2555 } | 2582 } |
2556 | 2583 |
2557 Expression handleAssignment(bool voidContext) { | 2584 Expression handleAssignment(bool voidContext) { |
2558 if (identical("=", assignmentOperator)) { | 2585 if (identical("=", assignmentOperator)) { |
2559 return accessor.buildAssignment(value, voidContext: voidContext); | 2586 return accessor.buildAssignment(value, voidContext: voidContext); |
2560 } else if (identical("+=", assignmentOperator)) { | 2587 } else if (identical("+=", assignmentOperator)) { |
2561 return accessor.buildCompoundAssignment(plusName, value, charOffset, | 2588 return accessor.buildCompoundAssignment(plusName, value, charOffset, |
2562 voidContext: voidContext); | 2589 voidContext: voidContext); |
2563 } else if (identical("-=", assignmentOperator)) { | 2590 } else if (identical("-=", assignmentOperator)) { |
2564 return accessor.buildCompoundAssignment(minusName, value, charOffset, | 2591 return accessor.buildCompoundAssignment(minusName, value, charOffset, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2617 | 2644 |
2618 class DelayedPostfixIncrement extends ContextAccessor { | 2645 class DelayedPostfixIncrement extends ContextAccessor { |
2619 final Name binaryOperator; | 2646 final Name binaryOperator; |
2620 | 2647 |
2621 final Procedure interfaceTarget; | 2648 final Procedure interfaceTarget; |
2622 | 2649 |
2623 DelayedPostfixIncrement(BuilderHelper helper, int charOffset, | 2650 DelayedPostfixIncrement(BuilderHelper helper, int charOffset, |
2624 BuilderAccessor accessor, this.binaryOperator, this.interfaceTarget) | 2651 BuilderAccessor accessor, this.binaryOperator, this.interfaceTarget) |
2625 : super(helper, charOffset, accessor); | 2652 : super(helper, charOffset, accessor); |
2626 | 2653 |
2627 Expression buildSimpleRead() { | 2654 ShadowExpression buildSimpleRead() { |
2628 return accessor.buildPostfixIncrement(binaryOperator, charOffset, | 2655 return accessor.buildPostfixIncrement(binaryOperator, charOffset, |
2629 voidContext: false, interfaceTarget: interfaceTarget); | 2656 voidContext: false, |
| 2657 interfaceTarget: interfaceTarget) as ShadowExpression; |
2630 } | 2658 } |
2631 | 2659 |
2632 Expression buildForEffect() { | 2660 ShadowExpression buildForEffect() { |
2633 return accessor.buildPostfixIncrement(binaryOperator, charOffset, | 2661 return accessor.buildPostfixIncrement(binaryOperator, charOffset, |
2634 voidContext: true, interfaceTarget: interfaceTarget); | 2662 voidContext: true, |
| 2663 interfaceTarget: interfaceTarget) as ShadowExpression; |
2635 } | 2664 } |
2636 } | 2665 } |
2637 | 2666 |
2638 class JumpTarget extends Builder { | 2667 class JumpTarget extends Builder { |
2639 final List<Statement> users = <Statement>[]; | 2668 final List<Statement> users = <Statement>[]; |
2640 | 2669 |
2641 final JumpTargetKind kind; | 2670 final JumpTargetKind kind; |
2642 | 2671 |
2643 final int functionNestingLevel; | 2672 final int functionNestingLevel; |
2644 | 2673 |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2857 } else if (node is PrefixBuilder) { | 2886 } else if (node is PrefixBuilder) { |
2858 return node.name; | 2887 return node.name; |
2859 } else if (node is ThisAccessor) { | 2888 } else if (node is ThisAccessor) { |
2860 return node.isSuper ? "super" : "this"; | 2889 return node.isSuper ? "super" : "this"; |
2861 } else if (node is BuilderAccessor) { | 2890 } else if (node is BuilderAccessor) { |
2862 return node.plainNameForRead; | 2891 return node.plainNameForRead; |
2863 } else { | 2892 } else { |
2864 return internalError("Unhandled: ${node.runtimeType}"); | 2893 return internalError("Unhandled: ${node.runtimeType}"); |
2865 } | 2894 } |
2866 } | 2895 } |
OLD | NEW |