Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library fasta.body_builder; | 5 library fasta.body_builder; |
| 6 | 6 |
| 7 import '../fasta_codes.dart' | 7 import '../fasta_codes.dart' |
| 8 show FastaMessage, codeExpectedButGot, codeExpectedFunctionBody; | 8 show FastaMessage, codeExpectedButGot, codeExpectedFunctionBody; |
| 9 | 9 |
| 10 import '../parser/parser.dart' show FormalParameterType, optional; | 10 import '../parser/parser.dart' show FormalParameterType, optional; |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 | 30 |
| 31 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy; | 31 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy; |
| 32 | 32 |
| 33 import 'package:kernel/core_types.dart' show CoreTypes; | 33 import 'package:kernel/core_types.dart' show CoreTypes; |
| 34 | 34 |
| 35 import 'frontend_accessors.dart' show buildIsNull, makeBinary, makeLet; | 35 import 'frontend_accessors.dart' show buildIsNull, makeBinary, makeLet; |
| 36 | 36 |
| 37 import '../parser/dart_vm_native.dart' show skipNativeClause; | 37 import '../parser/dart_vm_native.dart' show skipNativeClause; |
| 38 | 38 |
| 39 import '../scanner/token.dart' | 39 import '../scanner/token.dart' |
| 40 show BeginGroupToken, Token, isBinaryOperator, isMinusOperator; | 40 show |
| 41 BeginGroupToken, | |
| 42 Token, | |
| 43 isBinaryOperator, | |
| 44 isMinusOperator, | |
| 45 offsetForToken; | |
| 41 | 46 |
| 42 import '../errors.dart' show formatUnexpected, internalError; | 47 import '../errors.dart' show formatUnexpected, internalError; |
| 43 | 48 |
| 44 import '../source/scope_listener.dart' | 49 import '../source/scope_listener.dart' |
| 45 show JumpTargetKind, NullValue, ScopeListener; | 50 show JumpTargetKind, NullValue, ScopeListener; |
| 46 | 51 |
| 47 import '../scope.dart' show ProblemBuilder; | 52 import '../scope.dart' show ProblemBuilder; |
| 48 | 53 |
| 49 import '../source/outline_builder.dart' show asyncMarkerFromTokens; | 54 import '../source/outline_builder.dart' show asyncMarkerFromTokens; |
| 50 | 55 |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 229 | 234 |
| 230 List<Expression> popListForEffect(int n) { | 235 List<Expression> popListForEffect(int n) { |
| 231 List<Expression> list = | 236 List<Expression> list = |
| 232 new List<Expression>.filled(n, null, growable: true); | 237 new List<Expression>.filled(n, null, growable: true); |
| 233 for (int i = n - 1; i >= 0; i--) { | 238 for (int i = n - 1; i >= 0; i--) { |
| 234 list[i] = popForEffect(); | 239 list[i] = popForEffect(); |
| 235 } | 240 } |
| 236 return list; | 241 return list; |
| 237 } | 242 } |
| 238 | 243 |
| 239 Block popBlock(int count, int charOffset) { | 244 Block popBlock(int count, Token beginToken) { |
| 240 List<dynamic /*Statement | List<Statement>*/ > statements = | 245 List<dynamic /*Statement | List<Statement>*/ > statements = |
| 241 popList(count) ?? <Statement>[]; | 246 popList(count) ?? <Statement>[]; |
| 242 List<Statement> copy; | 247 List<Statement> copy; |
| 243 for (int i = 0; i < statements.length; i++) { | 248 for (int i = 0; i < statements.length; i++) { |
| 244 var statement = statements[i]; | 249 var statement = statements[i]; |
| 245 if (statement is List) { | 250 if (statement is List) { |
| 246 copy ??= new List<Statement>.from(statements.getRange(0, i)); | 251 copy ??= new List<Statement>.from(statements.getRange(0, i)); |
| 247 // TODO(sigmund): remove this assignment (issue #28651) | 252 // TODO(sigmund): remove this assignment (issue #28651) |
| 248 Iterable subStatements = statement; | 253 Iterable subStatements = statement; |
| 249 copy.addAll(subStatements); | 254 copy.addAll(subStatements); |
| 250 } else if (copy != null) { | 255 } else if (copy != null) { |
| 251 copy.add(statement); | 256 copy.add(statement); |
| 252 } | 257 } |
| 253 } | 258 } |
| 254 return astFactory.block(copy ?? statements, charOffset); | 259 return astFactory.block(copy ?? statements, beginToken); |
| 255 } | 260 } |
| 256 | 261 |
| 257 Statement popStatementIfNotNull(Object value) { | 262 Statement popStatementIfNotNull(Object value) { |
| 258 return value == null ? null : popStatement(); | 263 return value == null ? null : popStatement(); |
| 259 } | 264 } |
| 260 | 265 |
| 261 Statement popStatement() { | 266 Statement popStatement() { |
| 262 var statement = pop(); | 267 var statement = pop(); |
| 263 if (statement is List) { | 268 if (statement is List) { |
| 264 return new Block(new List<Statement>.from(statement)); | 269 return new Block(new List<Statement>.from(statement)); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 362 checkEmpty(-1); | 367 checkEmpty(-1); |
| 363 } | 368 } |
| 364 | 369 |
| 365 @override | 370 @override |
| 366 void endBlockFunctionBody(int count, Token beginToken, Token endToken) { | 371 void endBlockFunctionBody(int count, Token beginToken, Token endToken) { |
| 367 debugEvent("BlockFunctionBody"); | 372 debugEvent("BlockFunctionBody"); |
| 368 if (beginToken == null) { | 373 if (beginToken == null) { |
| 369 assert(count == 0); | 374 assert(count == 0); |
| 370 push(NullValue.Block); | 375 push(NullValue.Block); |
| 371 } else { | 376 } else { |
| 372 Block block = popBlock(count, beginToken.charOffset); | 377 Block block = popBlock(count, beginToken); |
| 373 exitLocalScope(); | 378 exitLocalScope(); |
| 374 push(block); | 379 push(block); |
| 375 } | 380 } |
| 376 } | 381 } |
| 377 | 382 |
| 378 @override | 383 @override |
| 379 void prepareInitializers() { | 384 void prepareInitializers() { |
| 380 scope = formalParameterScope; | 385 scope = formalParameterScope; |
| 381 assert(fieldInitializers.isEmpty); | 386 assert(fieldInitializers.isEmpty); |
| 382 final member = this.member; | 387 final member = this.member; |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 559 arguments.getRange(firstNamedArgumentIndex, arguments.length)); | 564 arguments.getRange(firstNamedArgumentIndex, arguments.length)); |
| 560 push(new Arguments(positional, named: named)); | 565 push(new Arguments(positional, named: named)); |
| 561 } else { | 566 } else { |
| 562 push(new Arguments(arguments)); | 567 push(new Arguments(arguments)); |
| 563 } | 568 } |
| 564 } | 569 } |
| 565 | 570 |
| 566 @override | 571 @override |
| 567 void handleParenthesizedExpression(BeginGroupToken token) { | 572 void handleParenthesizedExpression(BeginGroupToken token) { |
| 568 debugEvent("ParenthesizedExpression"); | 573 debugEvent("ParenthesizedExpression"); |
| 569 push(new ParenthesizedExpression( | 574 push(new ParenthesizedExpression(this, popForValue(), token.endGroup)); |
| 570 this, popForValue(), token.endGroup.charOffset)); | |
| 571 } | 575 } |
| 572 | 576 |
| 573 @override | 577 @override |
| 574 void endSend(Token beginToken, Token endToken) { | 578 void endSend(Token beginToken, Token endToken) { |
| 575 debugEvent("Send"); | 579 debugEvent("Send"); |
| 576 Arguments arguments = pop(); | 580 Arguments arguments = pop(); |
| 577 List<DartType> typeArguments = pop(); | 581 List<DartType> typeArguments = pop(); |
| 578 Object receiver = pop(); | 582 Object receiver = pop(); |
| 579 if (arguments != null && typeArguments != null) { | 583 if (arguments != null && typeArguments != null) { |
| 580 arguments.types.addAll(typeArguments); | 584 arguments.types.addAll(typeArguments); |
| 581 } else { | 585 } else { |
| 582 assert(typeArguments == null); | 586 assert(typeArguments == null); |
| 583 } | 587 } |
| 584 if (receiver is Identifier) { | 588 if (receiver is Identifier) { |
| 585 Name name = new Name(receiver.name, library.library); | 589 Name name = new Name(receiver.name, library.library); |
| 586 if (arguments == null) { | 590 if (arguments == null) { |
| 587 push(new IncompletePropertyAccessor(this, beginToken.charOffset, name)); | 591 push(new IncompletePropertyAccessor(this, beginToken, name)); |
| 588 } else { | 592 } else { |
| 589 push(new SendAccessor(this, beginToken.charOffset, name, arguments)); | 593 push(new SendAccessor(this, beginToken, name, arguments)); |
| 590 } | 594 } |
| 591 } else if (arguments == null) { | 595 } else if (arguments == null) { |
| 592 push(receiver); | 596 push(receiver); |
| 593 } else { | 597 } else { |
| 594 push(finishSend(receiver, arguments, beginToken.charOffset)); | 598 push(finishSend(receiver, arguments, beginToken.charOffset)); |
| 595 } | 599 } |
| 596 } | 600 } |
| 597 | 601 |
| 598 @override | 602 @override |
| 599 finishSend(Object receiver, Arguments arguments, int charOffset) { | 603 finishSend(Object receiver, Arguments arguments, int charOffset) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 615 toValue(receiver), callName, arguments, charOffset); | 619 toValue(receiver), callName, arguments, charOffset); |
| 616 } | 620 } |
| 617 } | 621 } |
| 618 | 622 |
| 619 @override | 623 @override |
| 620 void beginCascade(Token token) { | 624 void beginCascade(Token token) { |
| 621 debugEvent("beginCascade"); | 625 debugEvent("beginCascade"); |
| 622 Expression expression = popForValue(); | 626 Expression expression = popForValue(); |
| 623 if (expression is CascadeReceiver) { | 627 if (expression is CascadeReceiver) { |
| 624 push(expression); | 628 push(expression); |
| 625 push(new VariableAccessor( | 629 // TODO(paulberry): Previously we used expression.fileOffset; now we are |
| 626 this, expression.fileOffset, expression.variable)); | 630 // using token. Is that a problem? |
|
ahe
2017/04/25 17:39:59
I think so. Try running the service tests:
nice .
Paul Berry
2017/04/25 22:00:55
Thanks! I've verified that these tests pass and I
| |
| 631 push(new VariableAccessor(this, token, expression.variable)); | |
| 627 expression.extend(); | 632 expression.extend(); |
| 628 } else { | 633 } else { |
| 629 VariableDeclaration variable = | 634 VariableDeclaration variable = |
| 630 new VariableDeclaration.forValue(expression); | 635 new VariableDeclaration.forValue(expression); |
| 631 push(new CascadeReceiver(variable)); | 636 push(new CascadeReceiver(variable)); |
| 632 push(new VariableAccessor(this, expression.fileOffset, variable)); | 637 // TODO(paulberry): Previously we used expression.fileOffset; now we are |
| 638 // using token. Is that a problem? | |
| 639 push(new VariableAccessor(this, token, variable)); | |
| 633 } | 640 } |
| 634 } | 641 } |
| 635 | 642 |
| 636 @override | 643 @override |
| 637 void endCascade() { | 644 void endCascade() { |
| 638 debugEvent("endCascade"); | 645 debugEvent("endCascade"); |
| 639 Expression expression = popForEffect(); | 646 Expression expression = popForEffect(); |
| 640 CascadeReceiver cascadeReceiver = pop(); | 647 CascadeReceiver cascadeReceiver = pop(); |
| 641 cascadeReceiver.finalize(expression); | 648 cascadeReceiver.finalize(expression); |
| 642 push(cascadeReceiver); | 649 push(cascadeReceiver); |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 808 @override | 815 @override |
| 809 void handleIdentifier(Token token, IdentifierContext context) { | 816 void handleIdentifier(Token token, IdentifierContext context) { |
| 810 debugEvent("handleIdentifier"); | 817 debugEvent("handleIdentifier"); |
| 811 String name = token.lexeme; | 818 String name = token.lexeme; |
| 812 if (context.isScopeReference) { | 819 if (context.isScopeReference) { |
| 813 assert(!inInitializer || | 820 assert(!inInitializer || |
| 814 this.scope == enclosingScope || | 821 this.scope == enclosingScope || |
| 815 this.scope.parent == enclosingScope); | 822 this.scope.parent == enclosingScope); |
| 816 // This deals with this kind of initializer: `C(a) : a = a;` | 823 // This deals with this kind of initializer: `C(a) : a = a;` |
| 817 Scope scope = inInitializer ? enclosingScope : this.scope; | 824 Scope scope = inInitializer ? enclosingScope : this.scope; |
| 818 push(scopeLookup(scope, name, token.charOffset)); | 825 push(scopeLookup(scope, name, token)); |
| 819 return; | 826 return; |
| 820 } else if (context.inDeclaration) { | 827 } else if (context.inDeclaration) { |
| 821 if (context == IdentifierContext.topLevelVariableDeclaration || | 828 if (context == IdentifierContext.topLevelVariableDeclaration || |
| 822 context == IdentifierContext.fieldDeclaration) { | 829 context == IdentifierContext.fieldDeclaration) { |
| 823 constantExpressionRequired = member.isConst; | 830 constantExpressionRequired = member.isConst; |
| 824 } | 831 } |
| 825 } else if (constantExpressionRequired && | 832 } else if (constantExpressionRequired && |
| 826 !context.allowedInConstantExpression) { | 833 !context.allowedInConstantExpression) { |
| 827 addCompileTimeError( | 834 addCompileTimeError( |
| 828 token.charOffset, "Not a constant expression: $context"); | 835 token.charOffset, "Not a constant expression: $context"); |
| 829 } | 836 } |
| 830 push(new Identifier(name, token.charOffset)); | 837 push(new Identifier(token)); |
| 831 } | 838 } |
| 832 | 839 |
| 833 /// Look up [name] in [scope] using [charOffset] to report any | 840 /// Look up [name] in [scope] using [token] to report any |
| 834 /// problems. [isQualified] should be true if [name] is a qualified access | 841 /// problems. [isQualified] should be true if [name] is a qualified access |
|
ahe
2017/04/25 17:39:59
Perhaps this documentation of charOffset/token isn
Paul Berry
2017/04/25 22:00:55
Good point. Fixed.
| |
| 835 /// (which implies that it shouldn't be turned into a [ThisPropertyAccessor] | 842 /// (which implies that it shouldn't be turned into a [ThisPropertyAccessor] |
| 836 /// if the name doesn't resolve in the scope). | 843 /// if the name doesn't resolve in the scope). |
| 837 @override | 844 @override |
| 838 scopeLookup(Scope scope, String name, int charOffset, | 845 scopeLookup(Scope scope, String name, Token token, |
| 839 {bool isQualified: false, PrefixBuilder prefix}) { | 846 {bool isQualified: false, PrefixBuilder prefix}) { |
| 840 Builder builder = scope.lookup(name, charOffset, uri); | 847 Builder builder = scope.lookup(name, offsetForToken(token), uri); |
| 841 if (builder == null || (!isInstanceContext && builder.isInstanceMember)) { | 848 if (builder == null || (!isInstanceContext && builder.isInstanceMember)) { |
| 842 Name n = new Name(name, library.library); | 849 Name n = new Name(name, library.library); |
| 843 if (prefix != null && | 850 if (prefix != null && |
| 844 prefix.deferred && | 851 prefix.deferred && |
| 845 builder == null && | 852 builder == null && |
| 846 "loadLibrary" == name) { | 853 "loadLibrary" == name) { |
| 847 return buildCompileTimeError( | 854 return buildCompileTimeError( |
| 848 "Deferred loading isn't implemented yet.", charOffset); | 855 "Deferred loading isn't implemented yet.", offsetForToken(token)); |
| 849 } else if (!isQualified && isInstanceContext) { | 856 } else if (!isQualified && isInstanceContext) { |
| 850 assert(builder == null); | 857 assert(builder == null); |
| 851 if (constantExpressionRequired) { | 858 if (constantExpressionRequired) { |
| 852 return new UnresolvedAccessor(this, n, charOffset); | 859 return new UnresolvedAccessor(this, n, token); |
| 853 } | 860 } |
| 854 return new ThisPropertyAccessor(this, charOffset, n, null, null); | 861 return new ThisPropertyAccessor(this, token, n, null, null); |
| 855 } else if (isDartLibrary && | 862 } else if (isDartLibrary && |
| 856 name == "main" && | 863 name == "main" && |
| 857 library.uri.path == "_builtin" && | 864 library.uri.path == "_builtin" && |
| 858 member?.name == "_getMainClosure") { | 865 member?.name == "_getMainClosure") { |
| 859 // TODO(ahe): https://github.com/dart-lang/sdk/issues/28989 | 866 // TODO(ahe): https://github.com/dart-lang/sdk/issues/28989 |
| 860 return new NullLiteral()..fileOffset = charOffset; | 867 return new NullLiteral()..fileOffset = offsetForToken(token); |
| 861 } else { | 868 } else { |
| 862 return new UnresolvedAccessor(this, n, charOffset); | 869 return new UnresolvedAccessor(this, n, token); |
| 863 } | 870 } |
| 864 } else if (builder.isTypeDeclaration) { | 871 } else if (builder.isTypeDeclaration) { |
| 865 if (constantExpressionRequired && | 872 if (constantExpressionRequired && |
| 866 builder.isTypeVariable && | 873 builder.isTypeVariable && |
| 867 !member.isConstructor) { | 874 !member.isConstructor) { |
| 868 addCompileTimeError(charOffset, "Not a constant expression."); | 875 addCompileTimeError( |
| 876 offsetForToken(token), "Not a constant expression."); | |
| 869 } | 877 } |
| 870 return builder; | 878 return builder; |
| 871 } else if (builder.isLocal) { | 879 } else if (builder.isLocal) { |
| 872 if (constantExpressionRequired && | 880 if (constantExpressionRequired && |
| 873 !builder.isConst && | 881 !builder.isConst && |
| 874 !member.isConstructor) { | 882 !member.isConstructor) { |
| 875 addCompileTimeError(charOffset, "Not a constant expression."); | 883 addCompileTimeError( |
| 884 offsetForToken(token), "Not a constant expression."); | |
| 876 } | 885 } |
| 877 return new VariableAccessor(this, charOffset, builder.target); | 886 return new VariableAccessor(this, token, builder.target); |
| 878 } else if (builder.isInstanceMember) { | 887 } else if (builder.isInstanceMember) { |
| 879 if (constantExpressionRequired && | 888 if (constantExpressionRequired && |
| 880 !inInitializer && | 889 !inInitializer && |
| 881 // TODO(ahe): This is a hack because Fasta sets up the scope | 890 // TODO(ahe): This is a hack because Fasta sets up the scope |
| 882 // "this.field" parameters according to old semantics. Under the new | 891 // "this.field" parameters according to old semantics. Under the new |
| 883 // semantics, such parameters introduces a new parameter with that | 892 // semantics, such parameters introduces a new parameter with that |
| 884 // name that should be resolved here. | 893 // name that should be resolved here. |
| 885 !member.isConstructor) { | 894 !member.isConstructor) { |
| 886 addCompileTimeError(charOffset, "Not a constant expression."); | 895 addCompileTimeError( |
| 896 offsetForToken(token), "Not a constant expression."); | |
| 887 } | 897 } |
| 888 return new ThisPropertyAccessor( | 898 return new ThisPropertyAccessor( |
| 889 this, charOffset, new Name(name, library.library), null, null); | 899 this, token, new Name(name, library.library), null, null); |
| 890 } else if (builder.isRegularMethod) { | 900 } else if (builder.isRegularMethod) { |
| 891 assert(builder.isStatic || builder.isTopLevel); | 901 assert(builder.isStatic || builder.isTopLevel); |
| 892 return new StaticAccessor(this, charOffset, builder.target, null); | 902 return new StaticAccessor(this, token, builder.target, null); |
| 893 } else if (builder is PrefixBuilder) { | 903 } else if (builder is PrefixBuilder) { |
| 894 if (constantExpressionRequired && builder.deferred) { | 904 if (constantExpressionRequired && builder.deferred) { |
| 895 addCompileTimeError( | 905 addCompileTimeError( |
| 896 charOffset, | 906 offsetForToken(token), |
| 897 "'$name' can't be used in a constant expression because it's " | 907 "'$name' can't be used in a constant expression because it's " |
| 898 "marked as 'deferred' which means it isn't available until " | 908 "marked as 'deferred' which means it isn't available until " |
| 899 "loaded.\n" | 909 "loaded.\n" |
| 900 "You might try moving the constant to the deferred library, " | 910 "You might try moving the constant to the deferred library, " |
| 901 "or removing 'deferred' from the import."); | 911 "or removing 'deferred' from the import."); |
| 902 } | 912 } |
| 903 return builder; | 913 return builder; |
| 904 } else { | 914 } else { |
| 905 if (builder.hasProblem && builder is! AccessErrorBuilder) return builder; | 915 if (builder.hasProblem && builder is! AccessErrorBuilder) return builder; |
| 906 Builder setter; | 916 Builder setter; |
| 907 if (builder.isSetter) { | 917 if (builder.isSetter) { |
| 908 setter = builder; | 918 setter = builder; |
| 909 } else if (builder.isGetter) { | 919 } else if (builder.isGetter) { |
| 910 setter = scope.lookupSetter(name, charOffset, uri); | 920 setter = scope.lookupSetter(name, offsetForToken(token), uri); |
| 911 } else if (builder.isField && !builder.isFinal) { | 921 } else if (builder.isField && !builder.isFinal) { |
| 912 setter = builder; | 922 setter = builder; |
| 913 } | 923 } |
| 914 StaticAccessor accessor = | 924 StaticAccessor accessor = |
| 915 new StaticAccessor.fromBuilder(this, builder, charOffset, setter); | 925 new StaticAccessor.fromBuilder(this, builder, token, setter); |
| 916 if (constantExpressionRequired) { | 926 if (constantExpressionRequired) { |
| 917 Member readTarget = accessor.readTarget; | 927 Member readTarget = accessor.readTarget; |
| 918 if (!(readTarget is Field && readTarget.isConst || | 928 if (!(readTarget is Field && readTarget.isConst || |
| 919 // Static tear-offs are also compile time constants. | 929 // Static tear-offs are also compile time constants. |
| 920 readTarget is Procedure)) { | 930 readTarget is Procedure)) { |
| 921 addCompileTimeError(charOffset, "Not a constant expression."); | 931 addCompileTimeError( |
| 932 offsetForToken(token), "Not a constant expression."); | |
| 922 } | 933 } |
| 923 } | 934 } |
| 924 return accessor; | 935 return accessor; |
| 925 } | 936 } |
| 926 } | 937 } |
| 927 | 938 |
| 928 @override | 939 @override |
| 929 void handleQualified(Token period) { | 940 void handleQualified(Token period) { |
| 930 debugEvent("Qualified"); | 941 debugEvent("Qualified"); |
| 931 Identifier name = pop(); | 942 Identifier name = pop(); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1006 expressions.add(part); | 1017 expressions.add(part); |
| 1007 } | 1018 } |
| 1008 } | 1019 } |
| 1009 } | 1020 } |
| 1010 push(new StringConcatenation(expressions ?? parts)); | 1021 push(new StringConcatenation(expressions ?? parts)); |
| 1011 } | 1022 } |
| 1012 | 1023 |
| 1013 @override | 1024 @override |
| 1014 void handleLiteralInt(Token token) { | 1025 void handleLiteralInt(Token token) { |
| 1015 debugEvent("LiteralInt"); | 1026 debugEvent("LiteralInt"); |
| 1016 push(astFactory.intLiteral(int.parse(token.lexeme), token.charOffset)); | 1027 push(astFactory.intLiteral(int.parse(token.lexeme), token)); |
| 1017 } | 1028 } |
| 1018 | 1029 |
| 1019 @override | 1030 @override |
| 1020 void handleEmptyFunctionBody(Token semicolon) { | 1031 void handleEmptyFunctionBody(Token semicolon) { |
| 1021 debugEvent("ExpressionFunctionBody"); | 1032 debugEvent("ExpressionFunctionBody"); |
| 1022 endBlockFunctionBody(0, null, semicolon); | 1033 endBlockFunctionBody(0, null, semicolon); |
| 1023 } | 1034 } |
| 1024 | 1035 |
| 1025 @override | 1036 @override |
| 1026 void handleExpressionFunctionBody(Token arrowToken, Token endToken) { | 1037 void handleExpressionFunctionBody(Token arrowToken, Token endToken) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1046 Statement elsePart = popStatementIfNotNull(elseToken); | 1057 Statement elsePart = popStatementIfNotNull(elseToken); |
| 1047 Statement thenPart = popStatement(); | 1058 Statement thenPart = popStatement(); |
| 1048 Expression condition = popForValue(); | 1059 Expression condition = popForValue(); |
| 1049 push(new IfStatement(condition, thenPart, elsePart)); | 1060 push(new IfStatement(condition, thenPart, elsePart)); |
| 1050 } | 1061 } |
| 1051 | 1062 |
| 1052 @override | 1063 @override |
| 1053 void endVariableInitializer(Token assignmentOperator) { | 1064 void endVariableInitializer(Token assignmentOperator) { |
| 1054 debugEvent("VariableInitializer"); | 1065 debugEvent("VariableInitializer"); |
| 1055 assert(assignmentOperator.stringValue == "="); | 1066 assert(assignmentOperator.stringValue == "="); |
| 1056 pushNewLocalVariable(popForValue(), | 1067 pushNewLocalVariable(popForValue(), equalsToken: assignmentOperator); |
| 1057 equalsCharOffset: assignmentOperator.charOffset); | |
| 1058 } | 1068 } |
| 1059 | 1069 |
| 1060 @override | 1070 @override |
| 1061 void handleNoVariableInitializer(Token token) { | 1071 void handleNoVariableInitializer(Token token) { |
| 1062 debugEvent("NoVariableInitializer"); | 1072 debugEvent("NoVariableInitializer"); |
| 1063 pushNewLocalVariable(null); | 1073 pushNewLocalVariable(null); |
| 1064 } | 1074 } |
| 1065 | 1075 |
| 1066 void pushNewLocalVariable(Expression initializer, | 1076 void pushNewLocalVariable(Expression initializer, {Token equalsToken}) { |
| 1067 {int equalsCharOffset: TreeNode.noOffset}) { | |
| 1068 Identifier identifier = pop(); | 1077 Identifier identifier = pop(); |
| 1069 assert(currentLocalVariableModifiers != -1); | 1078 assert(currentLocalVariableModifiers != -1); |
| 1070 bool isConst = (currentLocalVariableModifiers & constMask) != 0; | 1079 bool isConst = (currentLocalVariableModifiers & constMask) != 0; |
| 1071 bool isFinal = (currentLocalVariableModifiers & finalMask) != 0; | 1080 bool isFinal = (currentLocalVariableModifiers & finalMask) != 0; |
| 1072 assert(isConst == constantExpressionRequired); | 1081 assert(isConst == constantExpressionRequired); |
| 1073 push(astFactory.variableDeclaration(identifier.name, identifier.fileOffset, | 1082 push(astFactory.variableDeclaration(identifier.name, identifier.token, |
| 1074 initializer: initializer, | 1083 initializer: initializer, |
| 1075 type: currentLocalVariableType, | 1084 type: currentLocalVariableType, |
| 1076 isFinal: isFinal, | 1085 isFinal: isFinal, |
| 1077 isConst: isConst, | 1086 isConst: isConst, |
| 1078 equalsCharOffset: equalsCharOffset)); | 1087 equalsToken: equalsToken)); |
| 1079 } | 1088 } |
| 1080 | 1089 |
| 1081 @override | 1090 @override |
| 1082 void endFieldInitializer(Token assignmentOperator, Token token) { | 1091 void endFieldInitializer(Token assignmentOperator, Token token) { |
| 1083 debugEvent("FieldInitializer"); | 1092 debugEvent("FieldInitializer"); |
| 1084 assert(assignmentOperator.stringValue == "="); | 1093 assert(assignmentOperator.stringValue == "="); |
| 1085 push(popForValue()); | 1094 push(popForValue()); |
| 1086 } | 1095 } |
| 1087 | 1096 |
| 1088 @override | 1097 @override |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1133 if (variables.length != 1) { | 1142 if (variables.length != 1) { |
| 1134 push(variables); | 1143 push(variables); |
| 1135 } else { | 1144 } else { |
| 1136 push(variables.single); | 1145 push(variables.single); |
| 1137 } | 1146 } |
| 1138 } | 1147 } |
| 1139 | 1148 |
| 1140 @override | 1149 @override |
| 1141 void endBlock(int count, Token beginToken, Token endToken) { | 1150 void endBlock(int count, Token beginToken, Token endToken) { |
| 1142 debugEvent("Block"); | 1151 debugEvent("Block"); |
| 1143 Block block = popBlock(count, beginToken.charOffset); | 1152 Block block = popBlock(count, beginToken); |
| 1144 exitLocalScope(); | 1153 exitLocalScope(); |
| 1145 push(block); | 1154 push(block); |
| 1146 } | 1155 } |
| 1147 | 1156 |
| 1148 @override | 1157 @override |
| 1149 void handleAssignmentExpression(Token token) { | 1158 void handleAssignmentExpression(Token token) { |
| 1150 debugEvent("AssignmentExpression"); | 1159 debugEvent("AssignmentExpression"); |
| 1151 Expression value = popForValue(); | 1160 Expression value = popForValue(); |
| 1152 var accessor = pop(); | 1161 var accessor = pop(); |
| 1153 if (accessor is TypeDeclarationBuilder) { | 1162 if (accessor is TypeDeclarationBuilder) { |
| 1154 push(wrapInvalid(new TypeLiteral( | 1163 push(wrapInvalid(new TypeLiteral( |
| 1155 accessor.buildTypesWithBuiltArguments(library, null)))); | 1164 accessor.buildTypesWithBuiltArguments(library, null)))); |
| 1156 } else if (accessor is! FastaAccessor) { | 1165 } else if (accessor is! FastaAccessor) { |
| 1157 push(buildCompileTimeError("Can't assign to this.", token.charOffset)); | 1166 push(buildCompileTimeError("Can't assign to this.", token.charOffset)); |
| 1158 } else { | 1167 } else { |
| 1159 push(new DelayedAssignment( | 1168 push(new DelayedAssignment( |
| 1160 this, token.charOffset, accessor, value, token.stringValue)); | 1169 this, token, accessor, value, token.stringValue)); |
| 1161 } | 1170 } |
| 1162 } | 1171 } |
| 1163 | 1172 |
| 1164 @override | 1173 @override |
| 1165 void enterLoop(int charOffset) { | 1174 void enterLoop(int charOffset) { |
| 1166 if (peek() is LabelTarget) { | 1175 if (peek() is LabelTarget) { |
| 1167 LabelTarget target = peek(); | 1176 LabelTarget target = peek(); |
| 1168 enterBreakTarget(charOffset, target.breakTarget); | 1177 enterBreakTarget(charOffset, target.breakTarget); |
| 1169 enterContinueTarget(charOffset, target.continueTarget); | 1178 enterContinueTarget(charOffset, target.continueTarget); |
| 1170 } else { | 1179 } else { |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1326 } else { | 1335 } else { |
| 1327 return internalError("Unhandled: ${name.runtimeType}"); | 1336 return internalError("Unhandled: ${name.runtimeType}"); |
| 1328 } | 1337 } |
| 1329 } | 1338 } |
| 1330 | 1339 |
| 1331 @override | 1340 @override |
| 1332 void endLiteralSymbol(Token hashToken, int identifierCount) { | 1341 void endLiteralSymbol(Token hashToken, int identifierCount) { |
| 1333 debugEvent("LiteralSymbol"); | 1342 debugEvent("LiteralSymbol"); |
| 1334 String value; | 1343 String value; |
| 1335 if (identifierCount == 1) { | 1344 if (identifierCount == 1) { |
| 1336 value = symbolPartToString(popForValue()); | 1345 value = symbolPartToString(pop()); |
|
ahe
2017/04/25 17:39:59
Why this change?
Paul Berry
2017/04/25 22:00:55
This is necessary in order to decouple Identifier
| |
| 1337 } else { | 1346 } else { |
| 1338 List parts = popList(identifierCount); | 1347 List parts = popList(identifierCount); |
| 1339 value = symbolPartToString(parts.first); | 1348 value = symbolPartToString(parts.first); |
| 1340 for (int i = 1; i < parts.length; i++) { | 1349 for (int i = 1; i < parts.length; i++) { |
| 1341 value += ".${symbolPartToString(parts[i])}"; | 1350 value += ".${symbolPartToString(parts[i])}"; |
| 1342 } | 1351 } |
| 1343 } | 1352 } |
| 1344 push(new SymbolLiteral(value)); | 1353 push(new SymbolLiteral(value)); |
| 1345 } | 1354 } |
| 1346 | 1355 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1391 if (suffix is Identifier) { | 1400 if (suffix is Identifier) { |
| 1392 suffix = suffix.name; | 1401 suffix = suffix.name; |
| 1393 } | 1402 } |
| 1394 Builder builder; | 1403 Builder builder; |
| 1395 if (prefix is Builder) { | 1404 if (prefix is Builder) { |
| 1396 builder = prefix; | 1405 builder = prefix; |
| 1397 } else { | 1406 } else { |
| 1398 builder = scope.lookup(prefix, beginToken.charOffset, uri); | 1407 builder = scope.lookup(prefix, beginToken.charOffset, uri); |
| 1399 } | 1408 } |
| 1400 if (builder is PrefixBuilder) { | 1409 if (builder is PrefixBuilder) { |
| 1401 name = scopeLookup(builder.exports, suffix, beginToken.charOffset, | 1410 name = scopeLookup(builder.exports, suffix, beginToken, |
| 1402 isQualified: true, prefix: builder); | 1411 isQualified: true, prefix: builder); |
| 1403 } else { | 1412 } else { |
| 1404 push(const DynamicType()); | 1413 push(const DynamicType()); |
| 1405 addCompileTimeError(beginToken.charOffset, | 1414 addCompileTimeError(beginToken.charOffset, |
| 1406 "Can't be used as a type: '${debugName(prefix, suffix)}'."); | 1415 "Can't be used as a type: '${debugName(prefix, suffix)}'."); |
| 1407 return; | 1416 return; |
| 1408 } | 1417 } |
| 1409 } | 1418 } |
| 1410 if (name is Identifier) { | 1419 if (name is Identifier) { |
| 1411 name = name.name; | 1420 name = name.name; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1527 } else if (thisKeyword == null) { | 1536 } else if (thisKeyword == null) { |
| 1528 variable = builder.build(library); | 1537 variable = builder.build(library); |
| 1529 variable.initializer = name.initializer; | 1538 variable.initializer = name.initializer; |
| 1530 } else if (builder.isField && builder.parent == classBuilder) { | 1539 } else if (builder.isField && builder.parent == classBuilder) { |
| 1531 FieldBuilder field = builder; | 1540 FieldBuilder field = builder; |
| 1532 if (type != null) { | 1541 if (type != null) { |
| 1533 nit("Ignoring type on 'this' parameter '${name.name}'.", | 1542 nit("Ignoring type on 'this' parameter '${name.name}'.", |
| 1534 thisKeyword.charOffset); | 1543 thisKeyword.charOffset); |
| 1535 } | 1544 } |
| 1536 type = field.target.type ?? const DynamicType(); | 1545 type = field.target.type ?? const DynamicType(); |
| 1537 variable = astFactory.variableDeclaration(name.name, name.fileOffset, | 1546 variable = astFactory.variableDeclaration(name.name, name.token, |
| 1538 type: type, | 1547 type: type, |
| 1539 initializer: name.initializer, | 1548 initializer: name.initializer, |
| 1540 isFinal: isFinal, | 1549 isFinal: isFinal, |
| 1541 isConst: isConst); | 1550 isConst: isConst); |
| 1542 } else { | 1551 } else { |
| 1543 addCompileTimeError( | 1552 addCompileTimeError(offsetForToken(name.token), |
| 1544 name.fileOffset, "'${name.name}' isn't a field in this class."); | 1553 "'${name.name}' isn't a field in this class."); |
| 1545 } | 1554 } |
| 1546 } | 1555 } |
| 1547 variable ??= astFactory.variableDeclaration(name.name, name.fileOffset, | 1556 variable ??= astFactory.variableDeclaration(name.name, name.token, |
| 1548 type: type ?? const DynamicType(), | 1557 type: type ?? const DynamicType(), |
| 1549 initializer: name.initializer, | 1558 initializer: name.initializer, |
| 1550 isFinal: isFinal, | 1559 isFinal: isFinal, |
| 1551 isConst: isConst); | 1560 isConst: isConst); |
| 1552 push(variable); | 1561 push(variable); |
| 1553 } | 1562 } |
| 1554 | 1563 |
| 1555 @override | 1564 @override |
| 1556 void endOptionalFormalParameters( | 1565 void endOptionalFormalParameters( |
| 1557 int count, Token beginToken, Token endToken) { | 1566 int count, Token beginToken, Token endToken) { |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1582 push(formals.toFunctionType(returnType)); | 1591 push(formals.toFunctionType(returnType)); |
| 1583 push(name); | 1592 push(name); |
| 1584 functionNestingLevel--; | 1593 functionNestingLevel--; |
| 1585 } | 1594 } |
| 1586 | 1595 |
| 1587 @override | 1596 @override |
| 1588 void handleValuedFormalParameter(Token equals, Token token) { | 1597 void handleValuedFormalParameter(Token equals, Token token) { |
| 1589 debugEvent("ValuedFormalParameter"); | 1598 debugEvent("ValuedFormalParameter"); |
| 1590 Expression initializer = popForValue(); | 1599 Expression initializer = popForValue(); |
| 1591 Identifier name = pop(); | 1600 Identifier name = pop(); |
| 1592 push(new InitializedIdentifier(name.name, initializer, name.fileOffset)); | 1601 push(new InitializedIdentifier(name.token, initializer)); |
| 1593 } | 1602 } |
| 1594 | 1603 |
| 1595 @override | 1604 @override |
| 1596 void handleFormalParameterWithoutValue(Token token) { | 1605 void handleFormalParameterWithoutValue(Token token) { |
| 1597 debugEvent("FormalParameterWithoutValue"); | 1606 debugEvent("FormalParameterWithoutValue"); |
| 1598 } | 1607 } |
| 1599 | 1608 |
| 1600 @override | 1609 @override |
| 1601 void endFormalParameters(int count, Token beginToken, Token endToken) { | 1610 void endFormalParameters(int count, Token beginToken, Token endToken) { |
| 1602 debugEvent("FormalParameters"); | 1611 debugEvent("FormalParameters"); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1684 push(NullValue.Expression); | 1693 push(NullValue.Expression); |
| 1685 } | 1694 } |
| 1686 | 1695 |
| 1687 @override | 1696 @override |
| 1688 void handleIndexedExpression( | 1697 void handleIndexedExpression( |
| 1689 Token openCurlyBracket, Token closeCurlyBracket) { | 1698 Token openCurlyBracket, Token closeCurlyBracket) { |
| 1690 debugEvent("IndexedExpression"); | 1699 debugEvent("IndexedExpression"); |
| 1691 Expression index = popForValue(); | 1700 Expression index = popForValue(); |
| 1692 var receiver = pop(); | 1701 var receiver = pop(); |
| 1693 if (receiver is ThisAccessor && receiver.isSuper) { | 1702 if (receiver is ThisAccessor && receiver.isSuper) { |
| 1694 push(new SuperIndexAccessor(this, receiver.offset, index, | 1703 push(new SuperIndexAccessor(this, receiver.token, index, |
| 1695 lookupSuperMember(indexGetName), lookupSuperMember(indexSetName))); | 1704 lookupSuperMember(indexGetName), lookupSuperMember(indexSetName))); |
| 1696 } else { | 1705 } else { |
| 1697 push(IndexAccessor.make(this, openCurlyBracket.charOffset, | 1706 push(IndexAccessor.make( |
| 1698 toValue(receiver), index, null, null)); | 1707 this, openCurlyBracket, toValue(receiver), index, null, null)); |
| 1699 } | 1708 } |
| 1700 } | 1709 } |
| 1701 | 1710 |
| 1702 @override | 1711 @override |
| 1703 void handleUnaryPrefixExpression(Token token) { | 1712 void handleUnaryPrefixExpression(Token token) { |
| 1704 debugEvent("UnaryPrefixExpression"); | 1713 debugEvent("UnaryPrefixExpression"); |
| 1705 var receiver = pop(); | 1714 var receiver = pop(); |
| 1706 if (optional("!", token)) { | 1715 if (optional("!", token)) { |
| 1707 push(new Not(toValue(receiver))); | 1716 push(new Not(toValue(receiver))); |
| 1708 } else { | 1717 } else { |
| 1709 String operator = token.stringValue; | 1718 String operator = token.stringValue; |
| 1710 if (optional("-", token)) { | 1719 if (optional("-", token)) { |
| 1711 operator = "unary-"; | 1720 operator = "unary-"; |
| 1712 } | 1721 } |
| 1713 if (receiver is ThisAccessor && receiver.isSuper) { | 1722 if (receiver is ThisAccessor && receiver.isSuper) { |
| 1714 push(toSuperMethodInvocation(buildMethodInvocation( | 1723 push(toSuperMethodInvocation(buildMethodInvocation( |
| 1715 new ThisExpression()..fileOffset = receiver.offset, | 1724 new ThisExpression()..fileOffset = offsetForToken(receiver.token), |
| 1716 new Name(operator), | 1725 new Name(operator), |
| 1717 new Arguments.empty(), | 1726 new Arguments.empty(), |
| 1718 token.charOffset))); | 1727 token.charOffset))); |
| 1719 } else { | 1728 } else { |
| 1720 push(buildMethodInvocation(toValue(receiver), new Name(operator), | 1729 push(buildMethodInvocation(toValue(receiver), new Name(operator), |
| 1721 new Arguments.empty(), token.charOffset)); | 1730 new Arguments.empty(), token.charOffset)); |
| 1722 } | 1731 } |
| 1723 } | 1732 } |
| 1724 } | 1733 } |
| 1725 | 1734 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1740 push(wrapInvalid(toValue(accessor))); | 1749 push(wrapInvalid(toValue(accessor))); |
| 1741 } | 1750 } |
| 1742 } | 1751 } |
| 1743 | 1752 |
| 1744 @override | 1753 @override |
| 1745 void handleUnaryPostfixAssignmentExpression(Token token) { | 1754 void handleUnaryPostfixAssignmentExpression(Token token) { |
| 1746 debugEvent("UnaryPostfixAssignmentExpression"); | 1755 debugEvent("UnaryPostfixAssignmentExpression"); |
| 1747 var accessor = pop(); | 1756 var accessor = pop(); |
| 1748 if (accessor is FastaAccessor) { | 1757 if (accessor is FastaAccessor) { |
| 1749 push(new DelayedPostfixIncrement( | 1758 push(new DelayedPostfixIncrement( |
| 1750 this, token.charOffset, accessor, incrementOperator(token), null)); | 1759 this, token, accessor, incrementOperator(token), null)); |
| 1751 } else { | 1760 } else { |
| 1752 push(wrapInvalid(toValue(accessor))); | 1761 push(wrapInvalid(toValue(accessor))); |
| 1753 } | 1762 } |
| 1754 } | 1763 } |
| 1755 | 1764 |
| 1756 @override | 1765 @override |
| 1757 void endConstructorReference( | 1766 void endConstructorReference( |
| 1758 Token start, Token periodBeforeName, Token endToken) { | 1767 Token start, Token periodBeforeName, Token endToken) { |
| 1759 debugEvent("ConstructorReference"); | 1768 debugEvent("ConstructorReference"); |
| 1760 // A constructor reference can contain up to three identifiers: | 1769 // A constructor reference can contain up to three identifiers: |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1777 // ClassBuilder, or a ThisPropertyAccessor. Otherwise, it's an error that | 1786 // ClassBuilder, or a ThisPropertyAccessor. Otherwise, it's an error that |
| 1778 // should be handled later. | 1787 // should be handled later. |
| 1779 Identifier suffix = popIfNotNull(periodBeforeName); | 1788 Identifier suffix = popIfNotNull(periodBeforeName); |
| 1780 Identifier identifier; | 1789 Identifier identifier; |
| 1781 List<DartType> typeArguments = pop(); | 1790 List<DartType> typeArguments = pop(); |
| 1782 dynamic type = pop(); | 1791 dynamic type = pop(); |
| 1783 if (type is List) { | 1792 if (type is List) { |
| 1784 var prefix = type[0]; | 1793 var prefix = type[0]; |
| 1785 identifier = type[1]; | 1794 identifier = type[1]; |
| 1786 if (prefix is PrefixBuilder) { | 1795 if (prefix is PrefixBuilder) { |
| 1787 type = scopeLookup(prefix.exports, identifier.name, start.charOffset, | 1796 type = scopeLookup(prefix.exports, identifier.name, start, |
| 1788 isQualified: true, prefix: prefix); | 1797 isQualified: true, prefix: prefix); |
| 1789 identifier = null; | 1798 identifier = null; |
| 1790 } else if (prefix is ClassBuilder) { | 1799 } else if (prefix is ClassBuilder) { |
| 1791 type = prefix; | 1800 type = prefix; |
| 1792 } else { | 1801 } else { |
| 1793 type = new Identifier(start.lexeme, start.charOffset); | 1802 type = new Identifier(start); |
| 1794 } | 1803 } |
| 1795 } | 1804 } |
| 1796 String name; | 1805 String name; |
| 1797 if (identifier != null && suffix != null) { | 1806 if (identifier != null && suffix != null) { |
| 1798 name = "${identifier.name}.${suffix.name}"; | 1807 name = "${identifier.name}.${suffix.name}"; |
| 1799 } else if (identifier != null) { | 1808 } else if (identifier != null) { |
| 1800 name = identifier.name; | 1809 name = identifier.name; |
| 1801 } else if (suffix != null) { | 1810 } else if (suffix != null) { |
| 1802 name = suffix.name; | 1811 name = suffix.name; |
| 1803 } else { | 1812 } else { |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1967 @override | 1976 @override |
| 1968 void endTypeArguments(int count, Token beginToken, Token endToken) { | 1977 void endTypeArguments(int count, Token beginToken, Token endToken) { |
| 1969 debugEvent("TypeArguments"); | 1978 debugEvent("TypeArguments"); |
| 1970 push(popList(count)); | 1979 push(popList(count)); |
| 1971 } | 1980 } |
| 1972 | 1981 |
| 1973 @override | 1982 @override |
| 1974 void handleThisExpression(Token token, IdentifierContext context) { | 1983 void handleThisExpression(Token token, IdentifierContext context) { |
| 1975 debugEvent("ThisExpression"); | 1984 debugEvent("ThisExpression"); |
| 1976 if (context.isScopeReference && isInstanceContext) { | 1985 if (context.isScopeReference && isInstanceContext) { |
| 1977 push(new ThisAccessor(this, token.charOffset, inInitializer)); | 1986 push(new ThisAccessor(this, token, inInitializer)); |
| 1978 } else { | 1987 } else { |
| 1979 push(new IncompleteError( | 1988 push(new IncompleteError( |
| 1980 this, token.charOffset, "Expected identifier, but got 'this'.")); | 1989 this, token, "Expected identifier, but got 'this'.")); |
| 1981 } | 1990 } |
| 1982 } | 1991 } |
| 1983 | 1992 |
| 1984 @override | 1993 @override |
| 1985 void handleSuperExpression(Token token, IdentifierContext context) { | 1994 void handleSuperExpression(Token token, IdentifierContext context) { |
| 1986 debugEvent("SuperExpression"); | 1995 debugEvent("SuperExpression"); |
| 1987 if (context.isScopeReference && isInstanceContext) { | 1996 if (context.isScopeReference && isInstanceContext) { |
| 1988 Member member = this.member.target; | 1997 Member member = this.member.target; |
| 1989 member.transformerFlags |= TransformerFlag.superCalls; | 1998 member.transformerFlags |= TransformerFlag.superCalls; |
| 1990 push(new ThisAccessor(this, token.charOffset, inInitializer, | 1999 push(new ThisAccessor(this, token, inInitializer, isSuper: true)); |
| 1991 isSuper: true)); | |
| 1992 } else { | 2000 } else { |
| 1993 push(new IncompleteError( | 2001 push(new IncompleteError( |
| 1994 this, token.charOffset, "Expected identifier, but got 'super'.")); | 2002 this, token, "Expected identifier, but got 'super'.")); |
| 1995 } | 2003 } |
| 1996 } | 2004 } |
| 1997 | 2005 |
| 1998 @override | 2006 @override |
| 1999 void handleNamedArgument(Token colon) { | 2007 void handleNamedArgument(Token colon) { |
| 2000 debugEvent("NamedArgument"); | 2008 debugEvent("NamedArgument"); |
| 2001 Expression value = popForValue(); | 2009 Expression value = popForValue(); |
| 2002 Identifier identifier = pop(); | 2010 Identifier identifier = pop(); |
| 2003 push(new NamedExpression(identifier.name, value)); | 2011 push(new NamedExpression(identifier.name, value)); |
| 2004 } | 2012 } |
| 2005 | 2013 |
| 2006 @override | 2014 @override |
| 2007 void endFunctionName(Token beginToken, Token token) { | 2015 void endFunctionName(Token beginToken, Token token) { |
| 2008 debugEvent("FunctionName"); | 2016 debugEvent("FunctionName"); |
| 2009 Identifier name = pop(); | 2017 Identifier name = pop(); |
| 2010 VariableDeclaration variable = astFactory | 2018 VariableDeclaration variable = |
| 2011 .variableDeclaration(name.name, name.fileOffset, isFinal: true); | 2019 astFactory.variableDeclaration(name.name, name.token, isFinal: true); |
| 2012 push(new FunctionDeclaration( | 2020 push(new FunctionDeclaration( |
| 2013 variable, new FunctionNode(new InvalidStatement())) | 2021 variable, new FunctionNode(new InvalidStatement())) |
| 2014 ..fileOffset = beginToken.charOffset); | 2022 ..fileOffset = beginToken.charOffset); |
| 2015 scope[variable.name] = new KernelVariableBuilder( | 2023 scope[variable.name] = new KernelVariableBuilder( |
| 2016 variable, member ?? classBuilder ?? library, uri); | 2024 variable, member ?? classBuilder ?? library, uri); |
| 2017 enterLocalScope(); | 2025 enterLocalScope(); |
| 2018 } | 2026 } |
| 2019 | 2027 |
| 2020 void enterFunction() { | 2028 void enterFunction() { |
| 2021 debugEvent("enterFunction"); | 2029 debugEvent("enterFunction"); |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2311 | 2319 |
| 2312 @override | 2320 @override |
| 2313 void handleSwitchCase( | 2321 void handleSwitchCase( |
| 2314 int labelCount, | 2322 int labelCount, |
| 2315 int expressionCount, | 2323 int expressionCount, |
| 2316 Token defaultKeyword, | 2324 Token defaultKeyword, |
| 2317 int statementCount, | 2325 int statementCount, |
| 2318 Token firstToken, | 2326 Token firstToken, |
| 2319 Token endToken) { | 2327 Token endToken) { |
| 2320 debugEvent("SwitchCase"); | 2328 debugEvent("SwitchCase"); |
| 2321 Block block = popBlock(statementCount, firstToken.charOffset); | 2329 Block block = popBlock(statementCount, firstToken); |
| 2322 exitLocalScope(); | 2330 exitLocalScope(); |
| 2323 List<Label> labels = pop(); | 2331 List<Label> labels = pop(); |
| 2324 List<Expression> expressions = pop(); | 2332 List<Expression> expressions = pop(); |
| 2325 List<int> expressionOffsets = <int>[]; | 2333 List<int> expressionOffsets = <int>[]; |
| 2326 for (Expression expression in expressions) { | 2334 for (Expression expression in expressions) { |
| 2327 expressionOffsets.add(expression.fileOffset); | 2335 expressionOffsets.add(expression.fileOffset); |
| 2328 } | 2336 } |
| 2329 push(new SwitchCase(expressions, expressionOffsets, block, | 2337 push(new SwitchCase(expressions, expressionOffsets, block, |
| 2330 isDefault: defaultKeyword != null) | 2338 isDefault: defaultKeyword != null) |
| 2331 ..fileOffset = firstToken.charOffset); | 2339 ..fileOffset = firstToken.charOffset); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2417 push(compileTimeErrorInLoopOrSwitch = buildCompileTimeErrorStatement( | 2425 push(compileTimeErrorInLoopOrSwitch = buildCompileTimeErrorStatement( |
| 2418 "Target of continue must be a label.", continueKeyword.charOffset)); | 2426 "Target of continue must be a label.", continueKeyword.charOffset)); |
| 2419 return; | 2427 return; |
| 2420 } | 2428 } |
| 2421 if (target == null) { | 2429 if (target == null) { |
| 2422 if (switchScope == null) { | 2430 if (switchScope == null) { |
| 2423 push(buildCompileTimeErrorStatement( | 2431 push(buildCompileTimeErrorStatement( |
| 2424 "Can't find label '$name'.", continueKeyword.next.charOffset)); | 2432 "Can't find label '$name'.", continueKeyword.next.charOffset)); |
| 2425 return; | 2433 return; |
| 2426 } | 2434 } |
| 2427 switchScope.forwardDeclareLabel( | 2435 switchScope.forwardDeclareLabel(identifier.name, |
| 2428 identifier.name, target = createGotoTarget(identifier.fileOffset)); | 2436 target = createGotoTarget(offsetForToken(identifier.token))); |
| 2429 } | 2437 } |
| 2430 if (target.isGotoTarget && | 2438 if (target.isGotoTarget && |
| 2431 target.functionNestingLevel == functionNestingLevel) { | 2439 target.functionNestingLevel == functionNestingLevel) { |
| 2432 ContinueSwitchStatement statement = new ContinueSwitchStatement(null); | 2440 ContinueSwitchStatement statement = new ContinueSwitchStatement(null); |
| 2433 target.addGoto(statement); | 2441 target.addGoto(statement); |
| 2434 push(statement); | 2442 push(statement); |
| 2435 return; | 2443 return; |
| 2436 } | 2444 } |
| 2437 } | 2445 } |
| 2438 if (target == null) { | 2446 if (target == null) { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2561 | 2569 |
| 2562 @override | 2570 @override |
| 2563 void handleOperator(Token token) { | 2571 void handleOperator(Token token) { |
| 2564 debugEvent("Operator"); | 2572 debugEvent("Operator"); |
| 2565 push(new Operator(token.stringValue)..fileOffset = token.charOffset); | 2573 push(new Operator(token.stringValue)..fileOffset = token.charOffset); |
| 2566 } | 2574 } |
| 2567 | 2575 |
| 2568 @override | 2576 @override |
| 2569 void handleSymbolVoid(Token token) { | 2577 void handleSymbolVoid(Token token) { |
| 2570 debugEvent("SymbolVoid"); | 2578 debugEvent("SymbolVoid"); |
| 2571 push(new Identifier(token.stringValue, token.charOffset)); | 2579 push(new Identifier(token)); |
| 2572 } | 2580 } |
| 2573 | 2581 |
| 2574 dynamic addCompileTimeError(int charOffset, String message, | 2582 dynamic addCompileTimeError(int charOffset, String message, |
| 2575 {bool silent: false}) { | 2583 {bool silent: false}) { |
| 2576 // TODO(ahe): If constantExpressionRequired is set, set it to false to | 2584 // TODO(ahe): If constantExpressionRequired is set, set it to false to |
| 2577 // avoid a long list of errors. | 2585 // avoid a long list of errors. |
| 2578 return library.addCompileTimeError(charOffset, message, fileUri: uri); | 2586 return library.addCompileTimeError(charOffset, message, fileUri: uri); |
| 2579 } | 2587 } |
| 2580 | 2588 |
| 2581 @override | 2589 @override |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2615 } | 2623 } |
| 2616 return expression; | 2624 return expression; |
| 2617 } | 2625 } |
| 2618 | 2626 |
| 2619 @override | 2627 @override |
| 2620 void debugEvent(String name) { | 2628 void debugEvent(String name) { |
| 2621 // printEvent(name); | 2629 // printEvent(name); |
| 2622 } | 2630 } |
| 2623 | 2631 |
| 2624 @override | 2632 @override |
| 2625 StaticGet makeStaticGet(Member readTarget, int offset) { | 2633 StaticGet makeStaticGet(Member readTarget, Token token) { |
| 2626 // TODO(paulberry): only record the dependencies mandated by the top level | 2634 // TODO(paulberry): only record the dependencies mandated by the top level |
| 2627 // type inference spec. | 2635 // type inference spec. |
| 2628 if (fieldDependencies != null && readTarget is KernelField) { | 2636 if (fieldDependencies != null && readTarget is KernelField) { |
| 2629 var fieldNode = _typeInferrer.getFieldNodeForReadTarget(readTarget); | 2637 var fieldNode = _typeInferrer.getFieldNodeForReadTarget(readTarget); |
| 2630 if (fieldNode != null) { | 2638 if (fieldNode != null) { |
| 2631 fieldDependencies.add(fieldNode); | 2639 fieldDependencies.add(fieldNode); |
| 2632 } | 2640 } |
| 2633 } | 2641 } |
| 2634 return astFactory.staticGet(readTarget, offset); | 2642 return astFactory.staticGet(readTarget, token); |
| 2635 } | 2643 } |
| 2636 } | 2644 } |
| 2637 | 2645 |
| 2638 // TODO(ahe): Shouldn't need to be an expression. | 2646 class Identifier { |
|
ahe
2017/04/25 17:39:59
Could remove the superclass in a separate CL?
Paul Berry
2017/04/25 22:00:55
Ok, I will do so before landing this CL.
| |
| 2639 class Identifier extends InvalidExpression { | 2647 final Token token; |
| 2640 final String name; | 2648 String get name => token.lexeme; |
| 2641 | 2649 |
| 2642 Identifier(this.name, int charOffset) { | 2650 Identifier(this.token); |
| 2643 fileOffset = charOffset; | |
| 2644 } | |
| 2645 | 2651 |
| 2646 Expression get initializer => null; | 2652 Expression get initializer => null; |
| 2647 | 2653 |
| 2648 String toString() => "identifier($name)"; | 2654 String toString() => "identifier($name)"; |
| 2649 } | 2655 } |
| 2650 | 2656 |
| 2651 // TODO(ahe): Shouldn't need to be an expression. | 2657 // TODO(ahe): Shouldn't need to be an expression. |
| 2652 class Operator extends InvalidExpression { | 2658 class Operator extends InvalidExpression { |
| 2653 final String name; | 2659 final String name; |
| 2654 | 2660 |
| 2655 Operator(this.name); | 2661 Operator(this.name); |
| 2656 | 2662 |
| 2657 String toString() => "operator($name)"; | 2663 String toString() => "operator($name)"; |
| 2658 } | 2664 } |
| 2659 | 2665 |
| 2660 class InitializedIdentifier extends Identifier { | 2666 class InitializedIdentifier extends Identifier { |
| 2661 final Expression initializer; | 2667 final Expression initializer; |
| 2662 | 2668 |
| 2663 InitializedIdentifier(String name, this.initializer, int charOffset) | 2669 InitializedIdentifier(Token token, this.initializer) : super(token); |
| 2664 : super(name, charOffset); | |
| 2665 | 2670 |
| 2666 String toString() => "initialized-identifier($name, $initializer)"; | 2671 String toString() => "initialized-identifier($name, $initializer)"; |
| 2667 } | 2672 } |
| 2668 | 2673 |
| 2669 // TODO(ahe): Shouldn't need to be an expression. | 2674 // TODO(ahe): Shouldn't need to be an expression. |
| 2670 class Label extends InvalidExpression { | 2675 class Label extends InvalidExpression { |
| 2671 String name; | 2676 String name; |
| 2672 | 2677 |
| 2673 Label(this.name); | 2678 Label(this.name); |
| 2674 | 2679 |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 2701 nextCascade.variable.initializer = expression; | 2706 nextCascade.variable.initializer = expression; |
| 2702 expression.parent = nextCascade.variable; | 2707 expression.parent = nextCascade.variable; |
| 2703 } | 2708 } |
| 2704 } | 2709 } |
| 2705 | 2710 |
| 2706 abstract class ContextAccessor extends FastaAccessor { | 2711 abstract class ContextAccessor extends FastaAccessor { |
| 2707 final BuilderHelper helper; | 2712 final BuilderHelper helper; |
| 2708 | 2713 |
| 2709 final FastaAccessor accessor; | 2714 final FastaAccessor accessor; |
| 2710 | 2715 |
| 2711 final int offset; | 2716 final Token token; |
| 2712 | 2717 |
| 2713 ContextAccessor(this.helper, this.offset, this.accessor); | 2718 ContextAccessor(this.helper, this.token, this.accessor); |
| 2714 | 2719 |
| 2715 @override | 2720 @override |
| 2716 Expression get builtBinary => internalError("Unsupported operation."); | 2721 Expression get builtBinary => internalError("Unsupported operation."); |
| 2717 | 2722 |
| 2718 @override | 2723 @override |
| 2719 void set builtBinary(Expression expression) { | 2724 void set builtBinary(Expression expression) { |
| 2720 internalError("Unsupported operation."); | 2725 internalError("Unsupported operation."); |
| 2721 } | 2726 } |
| 2722 | 2727 |
| 2723 @override | 2728 @override |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2765 {int offset: TreeNode.noOffset, | 2770 {int offset: TreeNode.noOffset, |
| 2766 bool voidContext: false, | 2771 bool voidContext: false, |
| 2767 Procedure interfaceTarget}) { | 2772 Procedure interfaceTarget}) { |
| 2768 return makeInvalidWrite(null); | 2773 return makeInvalidWrite(null); |
| 2769 } | 2774 } |
| 2770 | 2775 |
| 2771 makeInvalidRead() => internalError("not supported"); | 2776 makeInvalidRead() => internalError("not supported"); |
| 2772 | 2777 |
| 2773 Expression makeInvalidWrite(Expression value) { | 2778 Expression makeInvalidWrite(Expression value) { |
| 2774 return helper.buildCompileTimeError( | 2779 return helper.buildCompileTimeError( |
| 2775 "Can't be used as left-hand side of assignment.", offset); | 2780 "Can't be used as left-hand side of assignment.", |
| 2781 offsetForToken(token)); | |
| 2776 } | 2782 } |
| 2777 } | 2783 } |
| 2778 | 2784 |
| 2779 class DelayedAssignment extends ContextAccessor { | 2785 class DelayedAssignment extends ContextAccessor { |
| 2780 final Expression value; | 2786 final Expression value; |
| 2781 | 2787 |
| 2782 final String assignmentOperator; | 2788 final String assignmentOperator; |
| 2783 | 2789 |
| 2784 DelayedAssignment(BuilderHelper helper, int charOffset, | 2790 DelayedAssignment(BuilderHelper helper, Token token, FastaAccessor accessor, |
| 2785 FastaAccessor accessor, this.value, this.assignmentOperator) | 2791 this.value, this.assignmentOperator) |
| 2786 : super(helper, charOffset, accessor); | 2792 : super(helper, token, accessor); |
| 2787 | 2793 |
| 2788 Expression buildSimpleRead() { | 2794 Expression buildSimpleRead() { |
| 2789 return handleAssignment(false); | 2795 return handleAssignment(false); |
| 2790 } | 2796 } |
| 2791 | 2797 |
| 2792 Expression buildForEffect() { | 2798 Expression buildForEffect() { |
| 2793 return handleAssignment(true); | 2799 return handleAssignment(true); |
| 2794 } | 2800 } |
| 2795 | 2801 |
| 2796 Expression handleAssignment(bool voidContext) { | 2802 Expression handleAssignment(bool voidContext) { |
| 2797 if (identical("=", assignmentOperator)) { | 2803 if (identical("=", assignmentOperator)) { |
| 2798 return accessor.buildAssignment(value, voidContext: voidContext); | 2804 return accessor.buildAssignment(value, voidContext: voidContext); |
| 2799 } else if (identical("+=", assignmentOperator)) { | 2805 } else if (identical("+=", assignmentOperator)) { |
| 2800 return accessor.buildCompoundAssignment(plusName, value, | 2806 return accessor.buildCompoundAssignment(plusName, value, |
| 2801 offset: offset, voidContext: voidContext); | 2807 offset: offsetForToken(token), voidContext: voidContext); |
| 2802 } else if (identical("-=", assignmentOperator)) { | 2808 } else if (identical("-=", assignmentOperator)) { |
| 2803 return accessor.buildCompoundAssignment(minusName, value, | 2809 return accessor.buildCompoundAssignment(minusName, value, |
| 2804 offset: offset, voidContext: voidContext); | 2810 offset: offsetForToken(token), voidContext: voidContext); |
| 2805 } else if (identical("*=", assignmentOperator)) { | 2811 } else if (identical("*=", assignmentOperator)) { |
| 2806 return accessor.buildCompoundAssignment(multiplyName, value, | 2812 return accessor.buildCompoundAssignment(multiplyName, value, |
| 2807 offset: offset, voidContext: voidContext); | 2813 offset: offsetForToken(token), voidContext: voidContext); |
| 2808 } else if (identical("%=", assignmentOperator)) { | 2814 } else if (identical("%=", assignmentOperator)) { |
| 2809 return accessor.buildCompoundAssignment(percentName, value, | 2815 return accessor.buildCompoundAssignment(percentName, value, |
| 2810 offset: offset, voidContext: voidContext); | 2816 offset: offsetForToken(token), voidContext: voidContext); |
| 2811 } else if (identical("&=", assignmentOperator)) { | 2817 } else if (identical("&=", assignmentOperator)) { |
| 2812 return accessor.buildCompoundAssignment(ampersandName, value, | 2818 return accessor.buildCompoundAssignment(ampersandName, value, |
| 2813 offset: offset, voidContext: voidContext); | 2819 offset: offsetForToken(token), voidContext: voidContext); |
| 2814 } else if (identical("/=", assignmentOperator)) { | 2820 } else if (identical("/=", assignmentOperator)) { |
| 2815 return accessor.buildCompoundAssignment(divisionName, value, | 2821 return accessor.buildCompoundAssignment(divisionName, value, |
| 2816 offset: offset, voidContext: voidContext); | 2822 offset: offsetForToken(token), voidContext: voidContext); |
| 2817 } else if (identical("<<=", assignmentOperator)) { | 2823 } else if (identical("<<=", assignmentOperator)) { |
| 2818 return accessor.buildCompoundAssignment(leftShiftName, value, | 2824 return accessor.buildCompoundAssignment(leftShiftName, value, |
| 2819 offset: offset, voidContext: voidContext); | 2825 offset: offsetForToken(token), voidContext: voidContext); |
| 2820 } else if (identical(">>=", assignmentOperator)) { | 2826 } else if (identical(">>=", assignmentOperator)) { |
| 2821 return accessor.buildCompoundAssignment(rightShiftName, value, | 2827 return accessor.buildCompoundAssignment(rightShiftName, value, |
| 2822 offset: offset, voidContext: voidContext); | 2828 offset: offsetForToken(token), voidContext: voidContext); |
| 2823 } else if (identical("??=", assignmentOperator)) { | 2829 } else if (identical("??=", assignmentOperator)) { |
| 2824 return accessor.buildNullAwareAssignment(value, const DynamicType(), | 2830 return accessor.buildNullAwareAssignment(value, const DynamicType(), |
| 2825 voidContext: voidContext); | 2831 voidContext: voidContext); |
| 2826 } else if (identical("^=", assignmentOperator)) { | 2832 } else if (identical("^=", assignmentOperator)) { |
| 2827 return accessor.buildCompoundAssignment(caretName, value, | 2833 return accessor.buildCompoundAssignment(caretName, value, |
| 2828 offset: offset, voidContext: voidContext); | 2834 offset: offsetForToken(token), voidContext: voidContext); |
| 2829 } else if (identical("|=", assignmentOperator)) { | 2835 } else if (identical("|=", assignmentOperator)) { |
| 2830 return accessor.buildCompoundAssignment(barName, value, | 2836 return accessor.buildCompoundAssignment(barName, value, |
| 2831 offset: offset, voidContext: voidContext); | 2837 offset: offsetForToken(token), voidContext: voidContext); |
| 2832 } else if (identical("~/=", assignmentOperator)) { | 2838 } else if (identical("~/=", assignmentOperator)) { |
| 2833 return accessor.buildCompoundAssignment(mustacheName, value, | 2839 return accessor.buildCompoundAssignment(mustacheName, value, |
| 2834 offset: offset, voidContext: voidContext); | 2840 offset: offsetForToken(token), voidContext: voidContext); |
| 2835 } else { | 2841 } else { |
| 2836 return internalError("Unhandled: $assignmentOperator"); | 2842 return internalError("Unhandled: $assignmentOperator"); |
| 2837 } | 2843 } |
| 2838 } | 2844 } |
| 2839 | 2845 |
| 2840 Initializer buildFieldInitializer( | 2846 Initializer buildFieldInitializer( |
| 2841 Map<String, FieldInitializer> initializers) { | 2847 Map<String, FieldInitializer> initializers) { |
| 2842 if (!identical("=", assignmentOperator) || | 2848 if (!identical("=", assignmentOperator) || |
| 2843 !accessor.isThisPropertyAccessor) { | 2849 !accessor.isThisPropertyAccessor) { |
| 2844 return accessor.buildFieldInitializer(initializers); | 2850 return accessor.buildFieldInitializer(initializers); |
| 2845 } | 2851 } |
| 2846 String name = accessor.plainNameForRead; | 2852 String name = accessor.plainNameForRead; |
| 2847 FieldInitializer initializer = initializers[name]; | 2853 FieldInitializer initializer = initializers[name]; |
| 2848 if (initializer != null && initializer.value == null) { | 2854 if (initializer != null && initializer.value == null) { |
| 2849 initializers.remove(name); | 2855 initializers.remove(name); |
| 2850 initializer.value = value..parent = initializer; | 2856 initializer.value = value..parent = initializer; |
| 2851 return initializer; | 2857 return initializer; |
| 2852 } | 2858 } |
| 2853 return accessor.buildFieldInitializer(initializers); | 2859 return accessor.buildFieldInitializer(initializers); |
| 2854 } | 2860 } |
| 2855 } | 2861 } |
| 2856 | 2862 |
| 2857 class DelayedPostfixIncrement extends ContextAccessor { | 2863 class DelayedPostfixIncrement extends ContextAccessor { |
| 2858 final Name binaryOperator; | 2864 final Name binaryOperator; |
| 2859 | 2865 |
| 2860 final Procedure interfaceTarget; | 2866 final Procedure interfaceTarget; |
| 2861 | 2867 |
| 2862 DelayedPostfixIncrement(BuilderHelper helper, int offset, | 2868 DelayedPostfixIncrement(BuilderHelper helper, Token token, |
| 2863 FastaAccessor accessor, this.binaryOperator, this.interfaceTarget) | 2869 FastaAccessor accessor, this.binaryOperator, this.interfaceTarget) |
| 2864 : super(helper, offset, accessor); | 2870 : super(helper, token, accessor); |
| 2865 | 2871 |
| 2866 Expression buildSimpleRead() { | 2872 Expression buildSimpleRead() { |
| 2867 return accessor.buildPostfixIncrement(binaryOperator, | 2873 return accessor.buildPostfixIncrement(binaryOperator, |
| 2868 offset: offset, voidContext: false, interfaceTarget: interfaceTarget); | 2874 offset: offsetForToken(token), |
| 2875 voidContext: false, | |
| 2876 interfaceTarget: interfaceTarget); | |
| 2869 } | 2877 } |
| 2870 | 2878 |
| 2871 Expression buildForEffect() { | 2879 Expression buildForEffect() { |
| 2872 return accessor.buildPostfixIncrement(binaryOperator, | 2880 return accessor.buildPostfixIncrement(binaryOperator, |
| 2873 offset: offset, voidContext: true, interfaceTarget: interfaceTarget); | 2881 offset: offsetForToken(token), |
| 2882 voidContext: true, | |
| 2883 interfaceTarget: interfaceTarget); | |
| 2874 } | 2884 } |
| 2875 } | 2885 } |
| 2876 | 2886 |
| 2877 class JumpTarget extends Builder { | 2887 class JumpTarget extends Builder { |
| 2878 final List<Statement> users = <Statement>[]; | 2888 final List<Statement> users = <Statement>[]; |
| 2879 | 2889 |
| 2880 final JumpTargetKind kind; | 2890 final JumpTargetKind kind; |
| 2881 | 2891 |
| 2882 final int functionNestingLevel; | 2892 final int functionNestingLevel; |
| 2883 | 2893 |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3094 } else if (node is PrefixBuilder) { | 3104 } else if (node is PrefixBuilder) { |
| 3095 return node.name; | 3105 return node.name; |
| 3096 } else if (node is ThisAccessor) { | 3106 } else if (node is ThisAccessor) { |
| 3097 return node.isSuper ? "super" : "this"; | 3107 return node.isSuper ? "super" : "this"; |
| 3098 } else if (node is FastaAccessor) { | 3108 } else if (node is FastaAccessor) { |
| 3099 return node.plainNameForRead; | 3109 return node.plainNameForRead; |
| 3100 } else { | 3110 } else { |
| 3101 return internalError("Unhandled: ${node.runtimeType}"); | 3111 return internalError("Unhandled: ${node.runtimeType}"); |
| 3102 } | 3112 } |
| 3103 } | 3113 } |
| OLD | NEW |