| Index: pkg/compiler/lib/src/compile_time_constants.dart
|
| diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart
|
| index 71962e88957bcc163fdc0d7df455753022b6ab8c..1c066ed2c0485add0ec9bd279654610dc58306a5 100644
|
| --- a/pkg/compiler/lib/src/compile_time_constants.dart
|
| +++ b/pkg/compiler/lib/src/compile_time_constants.dart
|
| @@ -414,7 +414,10 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
|
| AstConstant evaluate(Node node) {
|
| // TODO(johnniwinther): should there be a visitErrorNode?
|
| if (node is ErrorNode) return new ErroneousAstConstant(context, node);
|
| - return node.accept(this);
|
| + AstConstant result = node.accept(this);
|
| + assert(invariant(node, !isEvaluatingConstant || result != null,
|
| + message: "No AstConstant computed for the node."));
|
| + return result;
|
| }
|
|
|
| AstConstant evaluateConstant(Node node) {
|
| @@ -422,7 +425,8 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
|
| isEvaluatingConstant = true;
|
| AstConstant result = node.accept(this);
|
| isEvaluatingConstant = oldIsEvaluatingConstant;
|
| - assert(result != null);
|
| + assert(invariant(node, result != null,
|
| + message: "No AstConstant computed for the node."));
|
| return result;
|
| }
|
|
|
| @@ -461,8 +465,8 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
|
| !link.isEmpty;
|
| link = link.tail) {
|
| AstConstant argument = evaluateConstant(link.head);
|
| - if (argument == null) {
|
| - return null;
|
| + if (argument == null || argument.isError) {
|
| + return argument;
|
| }
|
| argumentExpressions.add(argument.expression);
|
| argumentValues.add(argument.value);
|
| @@ -488,12 +492,12 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
|
| link = link.tail) {
|
| LiteralMapEntry entry = link.head;
|
| AstConstant key = evaluateConstant(entry.key);
|
| - if (key == null) {
|
| - return null;
|
| + if (key == null || key.isError) {
|
| + return key;
|
| }
|
| AstConstant value = evaluateConstant(entry.value);
|
| - if (value == null) {
|
| - return null;
|
| + if (value == null || value.isError) {
|
| + return value;
|
| }
|
| if (!map.containsKey(key.value)) {
|
| keyValues.add(key.value);
|
| @@ -530,7 +534,12 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
|
| AstConstant visitStringJuxtaposition(StringJuxtaposition node) {
|
| AstConstant left = evaluate(node.first);
|
| AstConstant right = evaluate(node.second);
|
| - if (left == null || right == null) return null;
|
| + if (left == null || left.isError) {
|
| + return left;
|
| + }
|
| + if (right == null || right.isError) {
|
| + return right;
|
| + }
|
| StringConstantValue leftValue = left.value;
|
| StringConstantValue rightValue = right.value;
|
| return new AstConstant(
|
| @@ -544,16 +553,16 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
|
| AstConstant visitStringInterpolation(StringInterpolation node) {
|
| List<ConstantExpression> subexpressions = <ConstantExpression>[];
|
| AstConstant initialString = evaluate(node.string);
|
| - if (initialString == null) {
|
| - return null;
|
| + if (initialString == null || initialString.isError) {
|
| + return initialString;
|
| }
|
| subexpressions.add(initialString.expression);
|
| StringConstantValue initialStringValue = initialString.value;
|
| DartString accumulator = initialStringValue.primitiveValue;
|
| for (StringInterpolationPart part in node.parts) {
|
| AstConstant subexpression = evaluate(part.expression);
|
| - if (subexpression == null) {
|
| - return null;
|
| + if (subexpression == null || subexpression.isError) {
|
| + return subexpression;
|
| }
|
| subexpressions.add(subexpression.expression);
|
| ConstantValue expression = subexpression.value;
|
| @@ -578,7 +587,6 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
|
| accumulator =
|
| new DartString.concat(accumulator, partStringValue.primitiveValue);
|
| }
|
| - ;
|
| return new AstConstant(
|
| context,
|
| node,
|
| @@ -725,8 +733,8 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
|
| } else if (send.isPrefix) {
|
| assert(send.isOperator);
|
| AstConstant receiverConstant = evaluate(send.receiver);
|
| - if (receiverConstant == null) {
|
| - return null;
|
| + if (receiverConstant == null || receiverConstant.isError) {
|
| + return receiverConstant;
|
| }
|
| Operator node = send.selector;
|
| UnaryOperator operator = UnaryOperator.parse(node.source);
|
| @@ -747,8 +755,11 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
|
| assert(send.argumentCount() == 1);
|
| AstConstant left = evaluate(send.receiver);
|
| AstConstant right = evaluate(send.argumentsNode.nodes.head);
|
| - if (left == null || right == null) {
|
| - return null;
|
| + if (left == null || left.isError) {
|
| + return left;
|
| + }
|
| + if (right == null || right.isError) {
|
| + return right;
|
| }
|
| ConstantValue leftValue = left.value;
|
| ConstantValue rightValue = right.value;
|
| @@ -796,8 +807,8 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
|
|
|
| AstConstant visitConditional(Conditional node) {
|
| AstConstant condition = evaluate(node.condition);
|
| - if (condition == null) {
|
| - return null;
|
| + if (condition == null || condition.isError) {
|
| + return condition;
|
| } else if (!condition.value.isBool) {
|
| DartType conditionType = condition.value.getType(coreTypes);
|
| if (isEvaluatingConstant) {
|
| @@ -809,8 +820,11 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
|
| }
|
| AstConstant thenExpression = evaluate(node.thenExpression);
|
| AstConstant elseExpression = evaluate(node.elseExpression);
|
| - if (thenExpression == null || elseExpression == null) {
|
| - return null;
|
| + if (thenExpression == null || thenExpression.isError) {
|
| + return thenExpression;
|
| + }
|
| + if (elseExpression == null || elseExpression.isError) {
|
| + return elseExpression;
|
| }
|
| BoolConstantValue boolCondition = condition.value;
|
| return new AstConstant(
|
| @@ -978,48 +992,43 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
|
| ConstantValue defaultValue = normalizedArguments[1].value;
|
|
|
| if (firstArgument.isNull) {
|
| - reporter.reportErrorMessage(
|
| + return reportNotCompileTimeConstant(
|
| normalizedArguments[0].node, MessageKind.NULL_NOT_ALLOWED);
|
| - return null;
|
| }
|
|
|
| if (!firstArgument.isString) {
|
| DartType type = defaultValue.getType(coreTypes);
|
| - reporter.reportErrorMessage(
|
| + return reportNotCompileTimeConstant(
|
| normalizedArguments[0].node,
|
| MessageKind.NOT_ASSIGNABLE,
|
| {'fromType': type, 'toType': coreTypes.stringType});
|
| - return null;
|
| }
|
|
|
| if (constructor.isIntFromEnvironmentConstructor &&
|
| !(defaultValue.isNull || defaultValue.isInt)) {
|
| DartType type = defaultValue.getType(coreTypes);
|
| - reporter.reportErrorMessage(
|
| + return reportNotCompileTimeConstant(
|
| normalizedArguments[1].node,
|
| MessageKind.NOT_ASSIGNABLE,
|
| {'fromType': type, 'toType': coreTypes.intType});
|
| - return null;
|
| }
|
|
|
| if (constructor.isBoolFromEnvironmentConstructor &&
|
| !(defaultValue.isNull || defaultValue.isBool)) {
|
| DartType type = defaultValue.getType(coreTypes);
|
| - reporter.reportErrorMessage(
|
| + return reportNotCompileTimeConstant(
|
| normalizedArguments[1].node,
|
| MessageKind.NOT_ASSIGNABLE,
|
| {'fromType': type, 'toType': coreTypes.boolType});
|
| - return null;
|
| }
|
|
|
| if (constructor.isStringFromEnvironmentConstructor &&
|
| !(defaultValue.isNull || defaultValue.isString)) {
|
| DartType type = defaultValue.getType(coreTypes);
|
| - reporter.reportErrorMessage(
|
| + return reportNotCompileTimeConstant(
|
| normalizedArguments[1].node,
|
| MessageKind.NOT_ASSIGNABLE,
|
| {'fromType': type, 'toType': coreTypes.stringType});
|
| - return null;
|
| }
|
|
|
| String name = firstArgument.primitiveValue.slowToString();
|
| @@ -1103,6 +1112,11 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
|
| fieldConstants.forEach((FieldElement field, AstConstant astConstant) {
|
| fieldValues[field] = astConstant.value;
|
| });
|
| + for (AstConstant fieldValue in fieldConstants.values) {
|
| + if (fieldValue.isError) {
|
| + return fieldValue;
|
| + }
|
| + }
|
| return new AstConstant(
|
| context,
|
| node,
|
| @@ -1115,13 +1129,18 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
|
| return node.expression.accept(this);
|
| }
|
|
|
| + AstConstant reportNotCompileTimeConstant(Node node, MessageKind message,
|
| + [Map arguments = const {}]) {
|
| + reporter.reportErrorMessage(node, message, arguments);
|
| + return new AstConstant(context, node, new ErroneousConstantExpression(),
|
| + new NullConstantValue());
|
| + }
|
| +
|
| AstConstant signalNotCompileTimeConstant(Node node,
|
| - {MessageKind message: MessageKind.NOT_A_COMPILE_TIME_CONSTANT}) {
|
| + {MessageKind message: MessageKind.NOT_A_COMPILE_TIME_CONSTANT,
|
| + Map arguments: const {}}) {
|
| if (isEvaluatingConstant) {
|
| - reporter.reportErrorMessage(node, message);
|
| -
|
| - return new AstConstant(context, node, new ErroneousConstantExpression(),
|
| - new NullConstantValue());
|
| + return reportNotCompileTimeConstant(node, message, arguments);
|
| }
|
| // Else we don't need to do anything. The final handler is only
|
| // optimistically trying to compile constants. So it is normal that we
|
| @@ -1372,6 +1391,8 @@ class AstConstant {
|
| value);
|
| }
|
|
|
| + bool get isError => expression.kind == ConstantExpressionKind.ERRONEOUS;
|
| +
|
| String toString() => expression.toString();
|
| }
|
|
|
|
|