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 e868b64fd5bf7a2150c2afb1d0f3fca63ef8fac5..abe11c953615c736fe3df550b779a6715c4ae2e1 100644 |
| --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart |
| +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart |
| @@ -306,6 +306,16 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| } |
| void declareVariable(VariableDeclaration variable) { |
| + // ignore: UNUSED_LOCAL_VARIABLE |
| + Statement discardedStatement; |
| + String name = variable.name; |
| + int offset = variable.fileOffset; |
| + if (scope.local[name] != null) { |
| + discardedStatement = pop(); |
| + push(buildCompileTimeErrorStatement( |
| + "'$name' already declared in this scope.", offset)); |
| + return; |
|
Paul Berry
2017/05/24 20:46:15
This may cause problems with the integration into
ahe
2017/05/24 21:06:38
Good point. We should probably add a compile-time
ahe
2017/05/29 07:18:00
Done.
|
| + } |
| InputError error = scope.declare( |
| variable.name, |
| new KernelVariableBuilder( |
| @@ -313,10 +323,10 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| variable.fileOffset, |
| uri); |
| if (error != null) { |
| - addCompileTimeError( |
| - variable.fileOffset, |
| - "Can't declare '${variable.name}' because it was already used in " |
| - "this scope."); |
| + discardedStatement = pop(); |
|
Paul Berry
2017/05/24 20:46:15
Is this code reachable? It looks like scope.decla
ahe
2017/05/24 21:06:38
The code isn't reachable at the moment because sco
Paul Berry
2017/05/24 22:10:39
Ah, ok. Thanks for the clarification.
I have con
Paul Berry
2017/05/24 22:12:59
If you want to defer this to a future CL, that's o
ahe
2017/05/25 10:38:31
This is one of the things that I have implemented
Paul Berry
2017/05/25 11:47:17
Ah, ok. That wasn't obvious to me. Thank you.
I
ahe
2017/05/25 13:16:15
I will add comments.
ahe
2017/05/29 07:18:00
Done.
|
| + push(buildCompileTimeErrorStatement( |
| + "Can't declare '$name' because it was already used in this scope.", |
| + offset)); |
| library.addCompileTimeError(error.charOffset, error.error, |
| fileUri: error.uri); |
| } |
| @@ -1678,7 +1688,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| if ((inCatchClause || functionNestingLevel != 0) && |
| kind != MemberKind.GeneralizedFunctionType) { |
| enterLocalScope(formals.computeFormalParameterScope( |
| - scope, member ?? classBuilder ?? library)); |
| + scope, member ?? classBuilder ?? library, this)); |
| } |
| } |
| @@ -2131,13 +2141,20 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| debugEvent("FunctionDeclaration"); |
| FunctionNode function = pop(); |
| exitLocalScope(); |
| - FunctionDeclaration declaration = pop(); |
| - function.returnType = pop() ?? const DynamicType(); |
| - declaration.variable.type = function.functionType; |
| + var declaration = pop(); |
| + var returnType = pop() ?? const DynamicType(); |
| pop(); // Modifiers. |
| exitFunction(); |
| - declaration.function = function; |
| - function.parent = declaration; |
| + if (declaration is FunctionDeclaration) { |
| + function.returnType = returnType; |
| + declaration.variable.type = function.functionType; |
| + declaration.function = function; |
| + function.parent = declaration; |
| + } else { |
| + // If [declaration] isn't a [FunctionDeclaration], it must be because |
| + // there was a compile-time error. |
|
Paul Berry
2017/05/24 20:46:15
Maybe add a similar todo here, e.g.: "TODO(paulber
ahe
2017/05/29 07:18:00
Done.
|
| + assert(library.compileTimeErrors.isNotEmpty); |
| + } |
| push(declaration); |
| } |
| @@ -2642,6 +2659,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| push(new Identifier(token)); |
| } |
| + @override |
| dynamic addCompileTimeError(int charOffset, String message, |
| {bool silent: false}) { |
| // TODO(ahe): If constantExpressionRequired is set, set it to false to |
| @@ -3125,15 +3143,23 @@ class FormalParameters { |
| requiredParameterCount: requiredParameterCount); |
| } |
| - Scope computeFormalParameterScope(Scope parent, Builder builder) { |
| + Scope computeFormalParameterScope( |
| + Scope parent, Builder builder, BuilderHelper helper) { |
| if (required.length == 0 && optional == null) return parent; |
| Map<String, Builder> local = <String, Builder>{}; |
| + |
| for (VariableDeclaration parameter in required) { |
| + if (local[parameter.name] != null) { |
| + helper.addCompileTimeError(parameter.fileOffset, "Duplicated name."); |
| + } |
| local[parameter.name] = |
| new KernelVariableBuilder(parameter, builder, builder.fileUri); |
| } |
| if (optional != null) { |
| for (VariableDeclaration parameter in optional.formals) { |
| + if (local[parameter.name] != null) { |
| + helper.addCompileTimeError(parameter.fileOffset, "Duplicated name."); |
| + } |
| local[parameter.name] = |
| new KernelVariableBuilder(parameter, builder, builder.fileUri); |
| } |