| 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 335248de2593beb6b35bb85a4a86ad7b7f4e6644..83fe991f6f7b7a54dcc4874fbc0cfbce3bee0767 100644
|
| --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
|
| +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
|
| @@ -188,6 +188,10 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| return buildCompileTimeError(
|
| "Type variables can only be used in instance methods.");
|
| } else {
|
| + if (constantExpressionRequired) {
|
| + addCompileTimeError(-1,
|
| + "Type variable can't be used as a constant expression $type.");
|
| + }
|
| return new TypeLiteral(type);
|
| }
|
| } else if (node is TypeDeclarationBuilder) {
|
| @@ -540,6 +544,9 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| @override
|
| finishSend(Object receiver, Arguments arguments, int charOffset) {
|
| if (receiver is BuilderAccessor) {
|
| + if (constantExpressionRequired) {
|
| + addCompileTimeError(charOffset, "Not a constant expression.");
|
| + }
|
| return receiver.doInvocation(charOffset, arguments);
|
| } else if (receiver is UnresolvedIdentifier) {
|
| return throwNoSuchMethodError(
|
| @@ -747,6 +754,19 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| Builder builder = scope.lookup(name, token.charOffset, uri);
|
| push(builderToFirstExpression(builder, name, token.charOffset));
|
| } else {
|
| + if (constantExpressionRequired) {
|
| + if (context != IdentifierContext.namedArgumentReference &&
|
| + context != IdentifierContext.constructorReferenceContinuation &&
|
| + context != IdentifierContext.expressionContinuation &&
|
| + context != IdentifierContext.typeReferenceContinuation &&
|
| + context != IdentifierContext.localVariableDeclaration &&
|
| + context !=
|
| + IdentifierContext
|
| + .constructorReferenceContinuationAfterTypeArguments) {
|
| + addCompileTimeError(
|
| + token.charOffset, "Not a constant expression: $context");
|
| + }
|
| + }
|
| push(new Identifier(name)..fileOffset = token.charOffset);
|
| }
|
| }
|
| @@ -758,15 +778,30 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| Name n = new Name(name, library.library);
|
| if (!isPrefix && isInstanceContext) {
|
| assert(builder == null);
|
| + if (constantExpressionRequired) {
|
| + addCompileTimeError(charOffset, "Not a constant expression.");
|
| + }
|
| return new ThisPropertyAccessor(this, charOffset, n, null, null);
|
| } else {
|
| + if (constantExpressionRequired) {
|
| + addCompileTimeError(charOffset, "Not a constant expression.");
|
| + }
|
| return new UnresolvedIdentifier(n)..fileOffset = charOffset;
|
| }
|
| } else if (builder.isTypeDeclaration) {
|
| + if (constantExpressionRequired && builder.isTypeVariable) {
|
| + addCompileTimeError(charOffset, "Not a constant expression.");
|
| + }
|
| return builder;
|
| } else if (builder.isLocal) {
|
| + if (constantExpressionRequired && !builder.isConst) {
|
| + addCompileTimeError(charOffset, "Not a constant expression.");
|
| + }
|
| return new VariableAccessor(this, charOffset, builder.target);
|
| } else if (builder.isInstanceMember) {
|
| + if (constantExpressionRequired) {
|
| + addCompileTimeError(charOffset, "Not a constant expression.");
|
| + }
|
| return new ThisPropertyAccessor(
|
| this, charOffset, new Name(name, library.library), null, null);
|
| } else if (builder.isRegularMethod) {
|
| @@ -775,6 +810,9 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| } else if (builder is PrefixBuilder) {
|
| return builder;
|
| } else if (builder is MixedAccessor) {
|
| + if (constantExpressionRequired && !builder.getter.target.isConst) {
|
| + addCompileTimeError(charOffset, "Not a constant expression.");
|
| + }
|
| return new StaticAccessor(
|
| this, charOffset, builder.getter.target, builder.setter.target);
|
| } else {
|
| @@ -787,7 +825,15 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| } else if (builder.isField && !builder.isFinal) {
|
| setter = builder;
|
| }
|
| - return new StaticAccessor.fromBuilder(this, builder, charOffset, setter);
|
| + StaticAccessor accessor =
|
| + new StaticAccessor.fromBuilder(this, builder, charOffset, setter);
|
| + if (constantExpressionRequired) {
|
| + Member readTarget = accessor.readTarget;
|
| + if (!(readTarget is Field && readTarget.isConst)) {
|
| + addCompileTimeError(charOffset, "Not a constant expression.");
|
| + }
|
| + }
|
| + return accessor;
|
| }
|
| }
|
|
|
| @@ -1215,6 +1261,9 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|
|
| DartType kernelTypeFromBuilder(
|
| Builder builder, List<DartType> arguments, int charOffset) {
|
| + if (constantExpressionRequired && builder is TypeVariableBuilder) {
|
| + addCompileTimeError(charOffset, "Not a constant expression.");
|
| + }
|
| if (builder is TypeDeclarationBuilder) {
|
| return builder.buildTypesWithBuiltArguments(library, arguments);
|
| } else if (builder.hasProblem) {
|
| @@ -1272,6 +1321,10 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| warning("'${name.name}' isn't a type.", beginToken.charOffset);
|
| push(const DynamicType());
|
| } else if (name is TypeVariableBuilder) {
|
| + if (constantExpressionRequired) {
|
| + addCompileTimeError(
|
| + beginToken.charOffset, "Not a constant expression.");
|
| + }
|
| push(name.buildTypesWithBuiltArguments(library, arguments));
|
| } else if (name is TypeDeclarationBuilder) {
|
| push(name.buildTypesWithBuiltArguments(library, arguments));
|
| @@ -2348,6 +2401,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|
|
| dynamic addCompileTimeError(int charOffset, String message,
|
| {bool silent: false}) {
|
| + // TODO(ahe): If constantExpressionRequired is set, set it to false to
|
| + // avoid a long list of errors.
|
| return library.addCompileTimeError(charOffset, message, fileUri: uri);
|
| }
|
|
|
| @@ -2361,6 +2416,15 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| }
|
|
|
| @override
|
| + void warning(String message, [int charOffset = -1]) {
|
| + if (constantExpressionRequired) {
|
| + addCompileTimeError(charOffset, message);
|
| + } else {
|
| + super.warning(message, charOffset);
|
| + }
|
| + }
|
| +
|
| + @override
|
| void debugEvent(String name) {
|
| // printEvent(name);
|
| }
|
|
|