| 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 |