Chromium Code Reviews| Index: pkg/front_end/lib/src/fasta/kernel/body_builder.dart |
| diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart |
| index 34fd49fe5cac6f483360547f31bb67e1092e835b..7dfa85ba183acc5c8098256359b4fd4eb3d4d983 100644 |
| --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart |
| +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart |
| @@ -37,7 +37,12 @@ import 'frontend_accessors.dart' show buildIsNull, makeBinary, makeLet; |
| import '../parser/dart_vm_native.dart' show skipNativeClause; |
| import '../scanner/token.dart' |
| - show BeginGroupToken, Token, isBinaryOperator, isMinusOperator; |
| + show |
| + BeginGroupToken, |
| + Token, |
| + isBinaryOperator, |
| + isMinusOperator, |
| + offsetForToken; |
| import '../errors.dart' show formatUnexpected, internalError; |
| @@ -236,7 +241,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| return list; |
| } |
| - Block popBlock(int count, int charOffset) { |
| + Block popBlock(int count, Token beginToken) { |
| List<dynamic /*Statement | List<Statement>*/ > statements = |
| popList(count) ?? <Statement>[]; |
| List<Statement> copy; |
| @@ -251,7 +256,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| copy.add(statement); |
| } |
| } |
| - return astFactory.block(copy ?? statements, charOffset); |
| + return astFactory.block(copy ?? statements, beginToken); |
| } |
| Statement popStatementIfNotNull(Object value) { |
| @@ -369,7 +374,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| assert(count == 0); |
| push(NullValue.Block); |
| } else { |
| - Block block = popBlock(count, beginToken.charOffset); |
| + Block block = popBlock(count, beginToken); |
| exitLocalScope(); |
| push(block); |
| } |
| @@ -566,8 +571,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| @override |
| void handleParenthesizedExpression(BeginGroupToken token) { |
| debugEvent("ParenthesizedExpression"); |
| - push(new ParenthesizedExpression( |
| - this, popForValue(), token.endGroup.charOffset)); |
| + push(new ParenthesizedExpression(this, popForValue(), token.endGroup)); |
| } |
| @override |
| @@ -584,9 +588,9 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| if (receiver is Identifier) { |
| Name name = new Name(receiver.name, library.library); |
| if (arguments == null) { |
| - push(new IncompletePropertyAccessor(this, beginToken.charOffset, name)); |
| + push(new IncompletePropertyAccessor(this, beginToken, name)); |
| } else { |
| - push(new SendAccessor(this, beginToken.charOffset, name, arguments)); |
| + push(new SendAccessor(this, beginToken, name, arguments)); |
| } |
| } else if (arguments == null) { |
| push(receiver); |
| @@ -622,14 +626,17 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| Expression expression = popForValue(); |
| if (expression is CascadeReceiver) { |
| push(expression); |
| - push(new VariableAccessor( |
| - this, expression.fileOffset, expression.variable)); |
| + // TODO(paulberry): Previously we used expression.fileOffset; now we are |
| + // 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
|
| + push(new VariableAccessor(this, token, expression.variable)); |
| expression.extend(); |
| } else { |
| VariableDeclaration variable = |
| new VariableDeclaration.forValue(expression); |
| push(new CascadeReceiver(variable)); |
| - push(new VariableAccessor(this, expression.fileOffset, variable)); |
| + // TODO(paulberry): Previously we used expression.fileOffset; now we are |
| + // using token. Is that a problem? |
| + push(new VariableAccessor(this, token, variable)); |
| } |
| } |
| @@ -815,7 +822,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| this.scope.parent == enclosingScope); |
| // This deals with this kind of initializer: `C(a) : a = a;` |
| Scope scope = inInitializer ? enclosingScope : this.scope; |
| - push(scopeLookup(scope, name, token.charOffset)); |
| + push(scopeLookup(scope, name, token)); |
| return; |
| } else if (context.inDeclaration) { |
| if (context == IdentifierContext.topLevelVariableDeclaration || |
| @@ -827,17 +834,17 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| addCompileTimeError( |
| token.charOffset, "Not a constant expression: $context"); |
| } |
| - push(new Identifier(name, token.charOffset)); |
| + push(new Identifier(token)); |
| } |
| - /// Look up [name] in [scope] using [charOffset] to report any |
| + /// Look up [name] in [scope] using [token] to report any |
| /// 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.
|
| /// (which implies that it shouldn't be turned into a [ThisPropertyAccessor] |
| /// if the name doesn't resolve in the scope). |
| @override |
| - scopeLookup(Scope scope, String name, int charOffset, |
| + scopeLookup(Scope scope, String name, Token token, |
| {bool isQualified: false, PrefixBuilder prefix}) { |
| - Builder builder = scope.lookup(name, charOffset, uri); |
| + Builder builder = scope.lookup(name, offsetForToken(token), uri); |
| if (builder == null || (!isInstanceContext && builder.isInstanceMember)) { |
| Name n = new Name(name, library.library); |
| if (prefix != null && |
| @@ -845,36 +852,38 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| builder == null && |
| "loadLibrary" == name) { |
| return buildCompileTimeError( |
| - "Deferred loading isn't implemented yet.", charOffset); |
| + "Deferred loading isn't implemented yet.", offsetForToken(token)); |
| } else if (!isQualified && isInstanceContext) { |
| assert(builder == null); |
| if (constantExpressionRequired) { |
| - return new UnresolvedAccessor(this, n, charOffset); |
| + return new UnresolvedAccessor(this, n, token); |
| } |
| - return new ThisPropertyAccessor(this, charOffset, n, null, null); |
| + return new ThisPropertyAccessor(this, token, n, null, null); |
| } else if (isDartLibrary && |
| name == "main" && |
| library.uri.path == "_builtin" && |
| member?.name == "_getMainClosure") { |
| // TODO(ahe): https://github.com/dart-lang/sdk/issues/28989 |
| - return new NullLiteral()..fileOffset = charOffset; |
| + return new NullLiteral()..fileOffset = offsetForToken(token); |
| } else { |
| - return new UnresolvedAccessor(this, n, charOffset); |
| + return new UnresolvedAccessor(this, n, token); |
| } |
| } else if (builder.isTypeDeclaration) { |
| if (constantExpressionRequired && |
| builder.isTypeVariable && |
| !member.isConstructor) { |
| - addCompileTimeError(charOffset, "Not a constant expression."); |
| + addCompileTimeError( |
| + offsetForToken(token), "Not a constant expression."); |
| } |
| return builder; |
| } else if (builder.isLocal) { |
| if (constantExpressionRequired && |
| !builder.isConst && |
| !member.isConstructor) { |
| - addCompileTimeError(charOffset, "Not a constant expression."); |
| + addCompileTimeError( |
| + offsetForToken(token), "Not a constant expression."); |
| } |
| - return new VariableAccessor(this, charOffset, builder.target); |
| + return new VariableAccessor(this, token, builder.target); |
| } else if (builder.isInstanceMember) { |
| if (constantExpressionRequired && |
| !inInitializer && |
| @@ -883,17 +892,18 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| // semantics, such parameters introduces a new parameter with that |
| // name that should be resolved here. |
| !member.isConstructor) { |
| - addCompileTimeError(charOffset, "Not a constant expression."); |
| + addCompileTimeError( |
| + offsetForToken(token), "Not a constant expression."); |
| } |
| return new ThisPropertyAccessor( |
| - this, charOffset, new Name(name, library.library), null, null); |
| + this, token, new Name(name, library.library), null, null); |
| } else if (builder.isRegularMethod) { |
| assert(builder.isStatic || builder.isTopLevel); |
| - return new StaticAccessor(this, charOffset, builder.target, null); |
| + return new StaticAccessor(this, token, builder.target, null); |
| } else if (builder is PrefixBuilder) { |
| if (constantExpressionRequired && builder.deferred) { |
| addCompileTimeError( |
| - charOffset, |
| + offsetForToken(token), |
| "'$name' can't be used in a constant expression because it's " |
| "marked as 'deferred' which means it isn't available until " |
| "loaded.\n" |
| @@ -907,18 +917,19 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| if (builder.isSetter) { |
| setter = builder; |
| } else if (builder.isGetter) { |
| - setter = scope.lookupSetter(name, charOffset, uri); |
| + setter = scope.lookupSetter(name, offsetForToken(token), uri); |
| } else if (builder.isField && !builder.isFinal) { |
| setter = builder; |
| } |
| StaticAccessor accessor = |
| - new StaticAccessor.fromBuilder(this, builder, charOffset, setter); |
| + new StaticAccessor.fromBuilder(this, builder, token, setter); |
| if (constantExpressionRequired) { |
| Member readTarget = accessor.readTarget; |
| if (!(readTarget is Field && readTarget.isConst || |
| // Static tear-offs are also compile time constants. |
| readTarget is Procedure)) { |
| - addCompileTimeError(charOffset, "Not a constant expression."); |
| + addCompileTimeError( |
| + offsetForToken(token), "Not a constant expression."); |
| } |
| } |
| return accessor; |
| @@ -1013,7 +1024,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| @override |
| void handleLiteralInt(Token token) { |
| debugEvent("LiteralInt"); |
| - push(astFactory.intLiteral(int.parse(token.lexeme), token.charOffset)); |
| + push(astFactory.intLiteral(int.parse(token.lexeme), token)); |
| } |
| @override |
| @@ -1053,8 +1064,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| void endVariableInitializer(Token assignmentOperator) { |
| debugEvent("VariableInitializer"); |
| assert(assignmentOperator.stringValue == "="); |
| - pushNewLocalVariable(popForValue(), |
| - equalsCharOffset: assignmentOperator.charOffset); |
| + pushNewLocalVariable(popForValue(), equalsToken: assignmentOperator); |
| } |
| @override |
| @@ -1063,19 +1073,18 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| pushNewLocalVariable(null); |
| } |
| - void pushNewLocalVariable(Expression initializer, |
| - {int equalsCharOffset: TreeNode.noOffset}) { |
| + void pushNewLocalVariable(Expression initializer, {Token equalsToken}) { |
| Identifier identifier = pop(); |
| assert(currentLocalVariableModifiers != -1); |
| bool isConst = (currentLocalVariableModifiers & constMask) != 0; |
| bool isFinal = (currentLocalVariableModifiers & finalMask) != 0; |
| assert(isConst == constantExpressionRequired); |
| - push(astFactory.variableDeclaration(identifier.name, identifier.fileOffset, |
| + push(astFactory.variableDeclaration(identifier.name, identifier.token, |
| initializer: initializer, |
| type: currentLocalVariableType, |
| isFinal: isFinal, |
| isConst: isConst, |
| - equalsCharOffset: equalsCharOffset)); |
| + equalsToken: equalsToken)); |
| } |
| @override |
| @@ -1140,7 +1149,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| @override |
| void endBlock(int count, Token beginToken, Token endToken) { |
| debugEvent("Block"); |
| - Block block = popBlock(count, beginToken.charOffset); |
| + Block block = popBlock(count, beginToken); |
| exitLocalScope(); |
| push(block); |
| } |
| @@ -1157,7 +1166,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| push(buildCompileTimeError("Can't assign to this.", token.charOffset)); |
| } else { |
| push(new DelayedAssignment( |
| - this, token.charOffset, accessor, value, token.stringValue)); |
| + this, token, accessor, value, token.stringValue)); |
| } |
| } |
| @@ -1333,7 +1342,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| debugEvent("LiteralSymbol"); |
| String value; |
| if (identifierCount == 1) { |
| - value = symbolPartToString(popForValue()); |
| + 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
|
| } else { |
| List parts = popList(identifierCount); |
| value = symbolPartToString(parts.first); |
| @@ -1398,7 +1407,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| builder = scope.lookup(prefix, beginToken.charOffset, uri); |
| } |
| if (builder is PrefixBuilder) { |
| - name = scopeLookup(builder.exports, suffix, beginToken.charOffset, |
| + name = scopeLookup(builder.exports, suffix, beginToken, |
| isQualified: true, prefix: builder); |
| } else { |
| push(const DynamicType()); |
| @@ -1534,17 +1543,17 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| thisKeyword.charOffset); |
| } |
| type = field.target.type ?? const DynamicType(); |
| - variable = astFactory.variableDeclaration(name.name, name.fileOffset, |
| + variable = astFactory.variableDeclaration(name.name, name.token, |
| type: type, |
| initializer: name.initializer, |
| isFinal: isFinal, |
| isConst: isConst); |
| } else { |
| - addCompileTimeError( |
| - name.fileOffset, "'${name.name}' isn't a field in this class."); |
| + addCompileTimeError(offsetForToken(name.token), |
| + "'${name.name}' isn't a field in this class."); |
| } |
| } |
| - variable ??= astFactory.variableDeclaration(name.name, name.fileOffset, |
| + variable ??= astFactory.variableDeclaration(name.name, name.token, |
| type: type ?? const DynamicType(), |
| initializer: name.initializer, |
| isFinal: isFinal, |
| @@ -1589,7 +1598,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| debugEvent("ValuedFormalParameter"); |
| Expression initializer = popForValue(); |
| Identifier name = pop(); |
| - push(new InitializedIdentifier(name.name, initializer, name.fileOffset)); |
| + push(new InitializedIdentifier(name.token, initializer)); |
| } |
| @override |
| @@ -1691,11 +1700,11 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| Expression index = popForValue(); |
| var receiver = pop(); |
| if (receiver is ThisAccessor && receiver.isSuper) { |
| - push(new SuperIndexAccessor(this, receiver.offset, index, |
| + push(new SuperIndexAccessor(this, receiver.token, index, |
| lookupSuperMember(indexGetName), lookupSuperMember(indexSetName))); |
| } else { |
| - push(IndexAccessor.make(this, openCurlyBracket.charOffset, |
| - toValue(receiver), index, null, null)); |
| + push(IndexAccessor.make( |
| + this, openCurlyBracket, toValue(receiver), index, null, null)); |
| } |
| } |
| @@ -1712,7 +1721,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| } |
| if (receiver is ThisAccessor && receiver.isSuper) { |
| push(toSuperMethodInvocation(buildMethodInvocation( |
| - new ThisExpression()..fileOffset = receiver.offset, |
| + new ThisExpression()..fileOffset = offsetForToken(receiver.token), |
| new Name(operator), |
| new Arguments.empty(), |
| token.charOffset))); |
| @@ -1747,7 +1756,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| var accessor = pop(); |
| if (accessor is FastaAccessor) { |
| push(new DelayedPostfixIncrement( |
| - this, token.charOffset, accessor, incrementOperator(token), null)); |
| + this, token, accessor, incrementOperator(token), null)); |
| } else { |
| push(wrapInvalid(toValue(accessor))); |
| } |
| @@ -1784,13 +1793,13 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| var prefix = type[0]; |
| identifier = type[1]; |
| if (prefix is PrefixBuilder) { |
| - type = scopeLookup(prefix.exports, identifier.name, start.charOffset, |
| + type = scopeLookup(prefix.exports, identifier.name, start, |
| isQualified: true, prefix: prefix); |
| identifier = null; |
| } else if (prefix is ClassBuilder) { |
| type = prefix; |
| } else { |
| - type = new Identifier(start.lexeme, start.charOffset); |
| + type = new Identifier(start); |
| } |
| } |
| String name; |
| @@ -1974,10 +1983,10 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| void handleThisExpression(Token token, IdentifierContext context) { |
| debugEvent("ThisExpression"); |
| if (context.isScopeReference && isInstanceContext) { |
| - push(new ThisAccessor(this, token.charOffset, inInitializer)); |
| + push(new ThisAccessor(this, token, inInitializer)); |
| } else { |
| push(new IncompleteError( |
| - this, token.charOffset, "Expected identifier, but got 'this'.")); |
| + this, token, "Expected identifier, but got 'this'.")); |
| } |
| } |
| @@ -1987,11 +1996,10 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| if (context.isScopeReference && isInstanceContext) { |
| Member member = this.member.target; |
| member.transformerFlags |= TransformerFlag.superCalls; |
| - push(new ThisAccessor(this, token.charOffset, inInitializer, |
| - isSuper: true)); |
| + push(new ThisAccessor(this, token, inInitializer, isSuper: true)); |
| } else { |
| push(new IncompleteError( |
| - this, token.charOffset, "Expected identifier, but got 'super'.")); |
| + this, token, "Expected identifier, but got 'super'.")); |
| } |
| } |
| @@ -2007,8 +2015,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| void endFunctionName(Token beginToken, Token token) { |
| debugEvent("FunctionName"); |
| Identifier name = pop(); |
| - VariableDeclaration variable = astFactory |
| - .variableDeclaration(name.name, name.fileOffset, isFinal: true); |
| + VariableDeclaration variable = |
| + astFactory.variableDeclaration(name.name, name.token, isFinal: true); |
| push(new FunctionDeclaration( |
| variable, new FunctionNode(new InvalidStatement())) |
| ..fileOffset = beginToken.charOffset); |
| @@ -2318,7 +2326,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| Token firstToken, |
| Token endToken) { |
| debugEvent("SwitchCase"); |
| - Block block = popBlock(statementCount, firstToken.charOffset); |
| + Block block = popBlock(statementCount, firstToken); |
| exitLocalScope(); |
| List<Label> labels = pop(); |
| List<Expression> expressions = pop(); |
| @@ -2424,8 +2432,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| "Can't find label '$name'.", continueKeyword.next.charOffset)); |
| return; |
| } |
| - switchScope.forwardDeclareLabel( |
| - identifier.name, target = createGotoTarget(identifier.fileOffset)); |
| + switchScope.forwardDeclareLabel(identifier.name, |
| + target = createGotoTarget(offsetForToken(identifier.token))); |
| } |
| if (target.isGotoTarget && |
| target.functionNestingLevel == functionNestingLevel) { |
| @@ -2568,7 +2576,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| @override |
| void handleSymbolVoid(Token token) { |
| debugEvent("SymbolVoid"); |
| - push(new Identifier(token.stringValue, token.charOffset)); |
| + push(new Identifier(token)); |
| } |
| dynamic addCompileTimeError(int charOffset, String message, |
| @@ -2622,7 +2630,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| } |
| @override |
| - StaticGet makeStaticGet(Member readTarget, int offset) { |
| + StaticGet makeStaticGet(Member readTarget, Token token) { |
| // TODO(paulberry): only record the dependencies mandated by the top level |
| // type inference spec. |
| if (fieldDependencies != null && readTarget is KernelField) { |
| @@ -2631,17 +2639,15 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| fieldDependencies.add(fieldNode); |
| } |
| } |
| - return astFactory.staticGet(readTarget, offset); |
| + return astFactory.staticGet(readTarget, token); |
| } |
| } |
| -// TODO(ahe): Shouldn't need to be an expression. |
| -class Identifier extends InvalidExpression { |
| - final String name; |
| +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.
|
| + final Token token; |
| + String get name => token.lexeme; |
| - Identifier(this.name, int charOffset) { |
| - fileOffset = charOffset; |
| - } |
| + Identifier(this.token); |
| Expression get initializer => null; |
| @@ -2660,8 +2666,7 @@ class Operator extends InvalidExpression { |
| class InitializedIdentifier extends Identifier { |
| final Expression initializer; |
| - InitializedIdentifier(String name, this.initializer, int charOffset) |
| - : super(name, charOffset); |
| + InitializedIdentifier(Token token, this.initializer) : super(token); |
| String toString() => "initialized-identifier($name, $initializer)"; |
| } |
| @@ -2708,9 +2713,9 @@ abstract class ContextAccessor extends FastaAccessor { |
| final FastaAccessor accessor; |
| - final int offset; |
| + final Token token; |
| - ContextAccessor(this.helper, this.offset, this.accessor); |
| + ContextAccessor(this.helper, this.token, this.accessor); |
| @override |
| Expression get builtBinary => internalError("Unsupported operation."); |
| @@ -2772,7 +2777,8 @@ abstract class ContextAccessor extends FastaAccessor { |
| Expression makeInvalidWrite(Expression value) { |
| return helper.buildCompileTimeError( |
| - "Can't be used as left-hand side of assignment.", offset); |
| + "Can't be used as left-hand side of assignment.", |
| + offsetForToken(token)); |
| } |
| } |
| @@ -2781,9 +2787,9 @@ class DelayedAssignment extends ContextAccessor { |
| final String assignmentOperator; |
| - DelayedAssignment(BuilderHelper helper, int charOffset, |
| - FastaAccessor accessor, this.value, this.assignmentOperator) |
| - : super(helper, charOffset, accessor); |
| + DelayedAssignment(BuilderHelper helper, Token token, FastaAccessor accessor, |
| + this.value, this.assignmentOperator) |
| + : super(helper, token, accessor); |
| Expression buildSimpleRead() { |
| return handleAssignment(false); |
| @@ -2798,40 +2804,40 @@ class DelayedAssignment extends ContextAccessor { |
| return accessor.buildAssignment(value, voidContext: voidContext); |
| } else if (identical("+=", assignmentOperator)) { |
| return accessor.buildCompoundAssignment(plusName, value, |
| - offset: offset, voidContext: voidContext); |
| + offset: offsetForToken(token), voidContext: voidContext); |
| } else if (identical("-=", assignmentOperator)) { |
| return accessor.buildCompoundAssignment(minusName, value, |
| - offset: offset, voidContext: voidContext); |
| + offset: offsetForToken(token), voidContext: voidContext); |
| } else if (identical("*=", assignmentOperator)) { |
| return accessor.buildCompoundAssignment(multiplyName, value, |
| - offset: offset, voidContext: voidContext); |
| + offset: offsetForToken(token), voidContext: voidContext); |
| } else if (identical("%=", assignmentOperator)) { |
| return accessor.buildCompoundAssignment(percentName, value, |
| - offset: offset, voidContext: voidContext); |
| + offset: offsetForToken(token), voidContext: voidContext); |
| } else if (identical("&=", assignmentOperator)) { |
| return accessor.buildCompoundAssignment(ampersandName, value, |
| - offset: offset, voidContext: voidContext); |
| + offset: offsetForToken(token), voidContext: voidContext); |
| } else if (identical("/=", assignmentOperator)) { |
| return accessor.buildCompoundAssignment(divisionName, value, |
| - offset: offset, voidContext: voidContext); |
| + offset: offsetForToken(token), voidContext: voidContext); |
| } else if (identical("<<=", assignmentOperator)) { |
| return accessor.buildCompoundAssignment(leftShiftName, value, |
| - offset: offset, voidContext: voidContext); |
| + offset: offsetForToken(token), voidContext: voidContext); |
| } else if (identical(">>=", assignmentOperator)) { |
| return accessor.buildCompoundAssignment(rightShiftName, value, |
| - offset: offset, voidContext: voidContext); |
| + offset: offsetForToken(token), voidContext: voidContext); |
| } else if (identical("??=", assignmentOperator)) { |
| return accessor.buildNullAwareAssignment(value, const DynamicType(), |
| voidContext: voidContext); |
| } else if (identical("^=", assignmentOperator)) { |
| return accessor.buildCompoundAssignment(caretName, value, |
| - offset: offset, voidContext: voidContext); |
| + offset: offsetForToken(token), voidContext: voidContext); |
| } else if (identical("|=", assignmentOperator)) { |
| return accessor.buildCompoundAssignment(barName, value, |
| - offset: offset, voidContext: voidContext); |
| + offset: offsetForToken(token), voidContext: voidContext); |
| } else if (identical("~/=", assignmentOperator)) { |
| return accessor.buildCompoundAssignment(mustacheName, value, |
| - offset: offset, voidContext: voidContext); |
| + offset: offsetForToken(token), voidContext: voidContext); |
| } else { |
| return internalError("Unhandled: $assignmentOperator"); |
| } |
| @@ -2859,18 +2865,22 @@ class DelayedPostfixIncrement extends ContextAccessor { |
| final Procedure interfaceTarget; |
| - DelayedPostfixIncrement(BuilderHelper helper, int offset, |
| + DelayedPostfixIncrement(BuilderHelper helper, Token token, |
| FastaAccessor accessor, this.binaryOperator, this.interfaceTarget) |
| - : super(helper, offset, accessor); |
| + : super(helper, token, accessor); |
| Expression buildSimpleRead() { |
| return accessor.buildPostfixIncrement(binaryOperator, |
| - offset: offset, voidContext: false, interfaceTarget: interfaceTarget); |
| + offset: offsetForToken(token), |
| + voidContext: false, |
| + interfaceTarget: interfaceTarget); |
| } |
| Expression buildForEffect() { |
| return accessor.buildPostfixIncrement(binaryOperator, |
| - offset: offset, voidContext: true, interfaceTarget: interfaceTarget); |
| + offset: offsetForToken(token), |
| + voidContext: true, |
| + interfaceTarget: interfaceTarget); |
| } |
| } |