Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(590)

Side by Side Diff: pkg/front_end/lib/src/fasta/kernel/body_builder.dart

Issue 2768533002: Fasta type inference prototype #2
Patch Set: Rework atop 415c868589d02e98eb839f48150f4203d5cecdb0 Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/builder/shadow_ast.dart ('k') | pkg/front_end/lib/src/fasta/kernel/builder_accessors.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698