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 221e89fc7008066ac1eb74f6db65938c97a0b50a..30cd354438c3cde8ac8db4b352feccaf3a8ee61a 100644 |
| --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart |
| +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart |
| @@ -280,7 +280,9 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| Uri get uri => library.fileUri ?? library.uri; |
| @override |
| - JumpTarget createJumpTarget(JumpTargetKind kind) => new JumpTarget(kind); |
| + JumpTarget createJumpTarget(JumpTargetKind kind, int charOffset) { |
| + return new JumpTarget(kind, member, charOffset); |
| + } |
| @override |
| void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) { |
| @@ -706,9 +708,10 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| isFirstIdentifier = true; |
| } |
| - Builder computeSetter(Builder builder, Scope scope, String name) { |
| + Builder computeSetter( |
| + Builder builder, Scope scope, String name, int charOffset) { |
| if (builder.isSetter) return builder; |
| - if (builder.isGetter) return scope.lookupSetter(name); |
| + if (builder.isGetter) return scope.lookupSetter(name, charOffset, uri); |
| return builder.isField ? (builder.isFinal ? null : builder) : null; |
| } |
| @@ -721,7 +724,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; |
| - Builder builder = scope.lookup(name); |
| + Builder builder = scope.lookup(name, token.charOffset, uri); |
| push(builderToFirstExpression(builder, name, token.charOffset)); |
| } else { |
| push(new Identifier(name)..fileOffset = token.charOffset); |
| @@ -733,7 +736,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| {bool isPrefix: false}) { |
| if (builder == null || (!isInstanceContext && builder.isInstanceMember)) { |
| if (!isPrefix && identical(name, "dynamic") && builder == null) { |
| - return new KernelNamedTypeBuilder(name, null); |
| + return new KernelNamedTypeBuilder(name, null, charOffset, uri); |
| } |
| Name n = new Name(name, library.library); |
| if (!isPrefix && isInstanceContext) { |
| @@ -768,7 +771,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| } |
| Member getter = builder.target.hasGetter ? builder.target : null; |
| Member setter = builder.target.hasSetter ? builder.target : null; |
| - setter ??= computeSetter(builder, scope, name)?.target; |
| + setter ??= computeSetter(builder, scope, name, charOffset)?.target; |
| return |
| new StaticAccessor(this, charOffset, getter, setter); |
| } |
| @@ -907,7 +910,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| internalError("unhandled identifier: ${node.runtimeType}"); |
| } |
| push(variable); |
| - scope[variable.name] = new KernelVariableBuilder(variable); |
| + scope[variable.name] = |
| + new KernelVariableBuilder(variable, member ?? classBuilder); |
|
Johnni Winther
2017/02/13 08:42:03
Should it be `member ?? classBuilder ?? library` ?
ahe
2017/02/13 10:44:23
I've added a TODO. It should be the current part,
|
| } |
| @override |
| @@ -959,14 +963,14 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| } |
| @override |
| - void enterLoop() { |
| + void enterLoop(int charOffset) { |
| if (peek() is LabelTarget) { |
| LabelTarget target = peek(); |
| - enterBreakTarget(target.breakTarget); |
| - enterContinueTarget(target.continueTarget); |
| + enterBreakTarget(charOffset, target.breakTarget); |
| + enterContinueTarget(charOffset, target.continueTarget); |
| } else{ |
| - enterBreakTarget(); |
| - enterContinueTarget(); |
| + enterBreakTarget(charOffset); |
| + enterContinueTarget(charOffset); |
| } |
| } |
| @@ -1140,10 +1144,10 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| push(new SymbolLiteral(value)); |
| } |
| - DartType toKernelType(String name, List<DartType> arguments) { |
| + DartType toKernelType(String name, List<DartType> arguments, int charOffset) { |
| if (identical(name, "void")) return const VoidType(); |
| if (identical(name, "dynamic")) return const DynamicType(); |
| - Builder builder = scope.lookup(name); |
| + Builder builder = scope.lookup(name, charOffset, uri); |
| if (builder is TypeDeclarationBuilder) { |
| return builder.buildTypesWithBuiltArguments(arguments); |
| } |
| @@ -1178,7 +1182,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| if (prefix is Builder) { |
| builder = prefix; |
| } else { |
| - builder = scope.lookup(prefix); |
| + builder = scope.lookup(prefix, beginToken.charOffset, uri); |
| } |
| if (builder is PrefixBuilder) { |
| name = builder.exports[suffix]; |
| @@ -1204,7 +1208,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| } else if (name is TypeBuilder) { |
| push(name.build()); |
| } else { |
| - push(toKernelType(name, arguments)); |
| + push(toKernelType(name, arguments, beginToken.charOffset)); |
| } |
| if (peek() is TypeParameterType) { |
| TypeParameterType type = peek(); |
| @@ -1263,6 +1267,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| @override |
| void endFormalParameter(Token thisKeyword) { |
| debugEvent("FormalParameter"); |
| + // TODO(ahe): Need beginToken here. |
| + int charOffset = thisKeyword?.charOffset; |
| if (thisKeyword != null) { |
| if (!inConstructor) { |
| return inputError("'this' parameters can only be used on constructors.", |
| @@ -1275,7 +1281,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| ignore(Unhandled.Metadata); |
| VariableDeclaration variable; |
| if (!inCatchClause && functionNestingLevel == 0) { |
| - var builder = formalParameterScope.lookup(name.name); |
| + var builder = formalParameterScope.lookup(name.name, charOffset, uri); |
| if (builder == null) { |
| return inputError("'${name.name}' isn't a field in this class.", |
| name.fileOffset); |
| @@ -1353,7 +1359,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| popList(count) ?? <VariableDeclaration>[], optional); |
| push(formals); |
| if (inCatchClause || functionNestingLevel != 0) { |
| - enterLocalScope(formals.computeFormalParameterScope(scope)); |
| + enterLocalScope(formals.computeFormalParameterScope( |
| + scope, member ?? classBuilder ?? library)); |
| } |
| } |
| @@ -1718,7 +1725,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| name.name, isFinal: true); |
| push(new FunctionDeclaration(variable, |
| new FunctionNode(new InvalidStatement()))); |
| - scope[variable.name] = new KernelVariableBuilder(variable); |
| + scope[variable.name] = |
| + new KernelVariableBuilder(variable, member ?? classBuilder); |
|
Johnni Winther
2017/02/13 08:42:03
Ditto.
ahe
2017/02/13 10:44:23
Done.
|
| enterLocalScope(); |
| } |
| @@ -1868,7 +1876,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| debugEvent("beginLabeledStatement"); |
| List<Label> labels = popList(labelCount); |
| enterLocalScope(); |
| - LabelTarget target = new LabelTarget(); |
| + LabelTarget target = new LabelTarget(member, token.charOffset); |
| for (Label label in labels) { |
| scope[label.name] = target; |
| } |
| @@ -1953,7 +1961,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| debugEvent("beginSwitchBlock"); |
| enterLocalScope(); |
| enterSwitchScope(); |
| - enterBreakTarget(); |
| + enterBreakTarget(token.charOffset); |
| } |
| @override |
| @@ -1975,7 +1983,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| for (Label label in labels) { |
| Builder existing = scope.local[label.name]; |
| if (existing == null) { |
| - scope[label.name] = createGotoTarget(); |
| + scope[label.name] = createGotoTarget(firstToken.charOffset); |
| } else { |
| // TODO(ahe): Should validate this is a goto target and not duplicated. |
| } |
| @@ -2017,7 +2025,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| List<Label> labels = pop(); |
| SwitchCase current = cases[i] = pop(); |
| for (Label label in labels) { |
| - JumpTarget target = switchScope.lookup(label.name); |
| + JumpTarget target = |
| + switchScope.lookup(label.name, label.fileOffset, uri); |
| if (target != null) { |
| target.resolveGotos(current); |
| } |
| @@ -2051,7 +2060,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| if (hasTarget) { |
| Identifier identifier = pop(); |
| name = identifier.name; |
| - target = scope.lookup(identifier.name); |
| + target = scope.lookup( |
| + identifier.name, breakKeyword.next.charOffset, uri); |
| } |
| if (target == null && name == null) { |
| push(compileTimeErrorInLoopOrSwitch = |
| @@ -2078,7 +2088,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| if (hasTarget) { |
| Identifier identifier = pop(); |
| name = identifier.name; |
| - target = scope.lookup(identifier.name); |
| + target = scope.lookup( |
| + identifier.name, continueKeyword.next.charOffset, uri); |
| if (target != null && target is! JumpTarget) { |
| push(compileTimeErrorInLoopOrSwitch = |
| buildCompileTimeErrorStatement( |
| @@ -2092,7 +2103,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| continueKeyword.next.charOffset)); |
| return; |
| } |
| - switchScope[identifier.name] = target = createGotoTarget(); |
| + switchScope[identifier.name] = target = |
| + createGotoTarget(identifier.fileOffset); |
| } |
| if (target.isGotoTarget) { |
| ContinueSwitchStatement statement = new ContinueSwitchStatement(null); |
| @@ -2485,7 +2497,8 @@ class JumpTarget extends Builder { |
| final JumpTargetKind kind; |
| - JumpTarget(this.kind); |
| + JumpTarget(this.kind, MemberBuilder member, int charOffset) |
| + : super(member, charOffset, member.fileUri); |
| bool get isBreakTarget => kind == JumpTargetKind.Break; |
| @@ -2536,11 +2549,15 @@ class JumpTarget extends Builder { |
| } |
| class LabelTarget extends Builder implements JumpTarget { |
| - final JumpTarget breakTarget = new JumpTarget(JumpTargetKind.Break); |
| + final JumpTarget breakTarget; |
| - final JumpTarget continueTarget = new JumpTarget(JumpTargetKind.Continue); |
| + final JumpTarget continueTarget; |
| - LabelTarget(); |
| + LabelTarget(MemberBuilder member, int charOffset) |
| + : breakTarget = new JumpTarget(JumpTargetKind.Break, member, charOffset), |
| + continueTarget = |
| + new JumpTarget(JumpTargetKind.Continue, member, charOffset), |
| + super(member, charOffset, member.fileUri); |
| bool get hasUsers => breakTarget.hasUsers || continueTarget.hasUsers; |
| @@ -2634,15 +2651,15 @@ class FormalParameters { |
| requiredParameterCount: requiredParameterCount); |
| } |
| - Scope computeFormalParameterScope(Scope parent) { |
| + Scope computeFormalParameterScope(Scope parent, Builder builder) { |
| if (required.length == 0 && optional == null) return parent; |
| Map<String, Builder> local = <String, Builder>{}; |
| for (VariableDeclaration parameter in required) { |
| - local[parameter.name] = new KernelVariableBuilder(parameter); |
| + local[parameter.name] = new KernelVariableBuilder(parameter, builder); |
| } |
| if (optional != null) { |
| for (VariableDeclaration parameter in optional.formals) { |
| - local[parameter.name] = new KernelVariableBuilder(parameter); |
| + local[parameter.name] = new KernelVariableBuilder(parameter, builder); |
| } |
| } |
| return new Scope(local, parent, isModifiable: false); |