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 d27c9446e019b3ee3ae3cbd7f3c6eac46308bf6c..8afec2ee626ba9b20be7266195d54e6293e688f2 100644 |
| --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart |
| +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart |
| @@ -410,6 +410,11 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| ProcedureBuilder member = this.member; |
| scope = member.computeFormalParameterInitializerScope(scope); |
| if (member is KernelConstructorBuilder) { |
| + if (member.isConst && |
| + (classBuilder.cls.superclass?.isMixinApplication ?? false)) { |
| + addCompileTimeError(member.charOffset, |
| + "Can't extend a mixin application and be 'const'."); |
| + } |
| if (member.formals != null) { |
| for (KernelFormalParameterBuilder formal in member.formals) { |
| if (formal.hasThis) { |
| @@ -1214,7 +1219,22 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| @override |
| void handleNoVariableInitializer(Token token) { |
| debugEvent("NoVariableInitializer"); |
| - pushNewLocalVariable(null); |
| + bool isConst = (currentLocalVariableModifiers & constMask) != 0; |
| + bool isFinal = (currentLocalVariableModifiers & finalMask) != 0; |
| + Expression initializer; |
| + if (!optional("in", token)) { |
| + // A for-in loop-variable can't have an initializer. So let's remain |
| + // silent if the next token is `in`. Since a for-in loop can only have |
| + // one variable it must be followed by `in`. |
| + if (isConst) { |
| + initializer = buildCompileTimeError( |
| + "A 'const' variable must be initialized.", token.charOffset); |
| + } else if (isFinal) { |
| + initializer = buildCompileTimeError( |
| + "A 'final' variable must be initialized.", token.charOffset); |
| + } |
| + } |
| + pushNewLocalVariable(initializer); |
| } |
| void pushNewLocalVariable(Expression initializer, {Token equalsToken}) { |
| @@ -1981,6 +2001,9 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| target.name.name, arguments, charOffset); |
| } |
| if (target is Constructor) { |
| + if (isConst && !target.isConst) { |
| + return buildCompileTimeError("Not a const constructor.", charOffset); |
| + } |
| return new KernelConstructorInvocation(target, initialTarget, arguments, |
| isConst: isConst) |
| ..fileOffset = charOffset; |
| @@ -1990,6 +2013,10 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| isConst: isConst) |
| ..fileOffset = charOffset; |
| } else { |
| + Procedure factory = target; |
|
Johnni Winther
2017/06/12 07:46:16
Shouldn't this be in the if branch above?
ahe
2017/06/12 08:13:22
Yes, good catch!
This is a merge problem. Paul ad
|
| + if (isConst && !factory.isConst) { |
| + return buildCompileTimeError("Not a const factory.", charOffset); |
| + } |
| return new KernelStaticInvocation(target, arguments, isConst: isConst) |
| ..fileOffset = charOffset; |
| } |
| @@ -2341,6 +2368,10 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| if (lvalue is VariableDeclaration) { |
| declaresVariable = true; |
| variable = lvalue; |
| + if (variable.isConst) { |
| + addCompileTimeError( |
| + variable.fileOffset, "A for-in loop-variable can't be 'const'."); |
| + } |
| } else if (lvalue is FastaAccessor) { |
| /// We are in this case, where `lvalue` isn't a [VariableDeclaration]: |
| /// |
| @@ -2888,6 +2919,11 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper { |
| Initializer buildSuperInitializer( |
| Constructor constructor, Arguments arguments, |
| [int charOffset = -1]) { |
| + if (member.isConst && !constructor.isConst) { |
| + return buildInvalidInitializer( |
| + buildCompileTimeError("Super constructor isn't const.", charOffset), |
| + charOffset); |
| + } |
| needsImplicitSuperInitializer = false; |
| return new SuperInitializer(constructor, arguments) |
| ..fileOffset = charOffset; |