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 f5876d8d495fc08127bbaec7def20f9fc9333615..a1c37688a01b33dd4361e689ec7eab00fda1fd89 100644 |
--- a/pkg/compiler/lib/src/compile_time_constants.dart |
+++ b/pkg/compiler/lib/src/compile_time_constants.dart |
@@ -22,6 +22,16 @@ import 'universe/universe.dart' show CallStructure; |
/// A [ConstantEnvironment] provides access for constants compiled for variable |
/// initializers. |
abstract class ConstantEnvironment { |
+ /// The [ConstantSystem] used by this environment. |
+ ConstantSystem get constantSystem; |
+ |
+ /// Returns the constant value computed for [expression]. |
+ // TODO(johnniwinther): Support directly evaluation of [expression]. |
+ ConstantValue getConstantValue(ConstantExpression expression); |
+ |
+ /// Returns the constant value for the initializer of [element]. |
+ ConstantValue getConstantValueForVariable(VariableElement element); |
+ |
/// Returns the constant for the initializer of [element]. |
ConstantExpression getConstantForVariable(VariableElement element); |
} |
@@ -73,13 +83,18 @@ abstract class ConstantCompiler extends ConstantEnvironment { |
/// A [BackendConstantEnvironment] provides access to constants needed for |
/// backend implementation. |
abstract class BackendConstantEnvironment extends ConstantEnvironment { |
+ /// Returns the compile-time constant value associated with [node]. |
+ /// |
+ /// Depending on implementation, the constant might be stored in [elements]. |
+ ConstantValue getConstantValueForNode(Node node, TreeElements elements); |
+ |
/// Returns the compile-time constant associated with [node]. |
/// |
/// Depending on implementation, the constant might be stored in [elements]. |
ConstantExpression getConstantForNode(Node node, TreeElements elements); |
/// Returns the compile-time constant value of [metadata]. |
- ConstantExpression getConstantForMetadata(MetadataAnnotation metadata); |
+ ConstantValue getConstantValueForMetadata(MetadataAnnotation metadata); |
} |
/// Interface for the task that compiles the constant environments for the |
@@ -87,6 +102,13 @@ abstract class BackendConstantEnvironment extends ConstantEnvironment { |
abstract class ConstantCompilerTask extends CompilerTask |
implements ConstantCompiler { |
ConstantCompilerTask(Compiler compiler) : super(compiler); |
+ |
+ /// Copy all cached constant values from [task]. |
+ /// |
+ /// This is a hack to support reuse cached compilers in memory_compiler. |
+ // TODO(johnniwinther): Remove this when values are computed from the |
+ // expressions. |
+ void copyConstantValues(ConstantCompilerTask task); |
} |
/** |
@@ -117,8 +139,17 @@ abstract class ConstantCompilerBase implements ConstantCompiler { |
/** The set of variable elements that are in the process of being computed. */ |
final Set<VariableElement> pendingVariables = new Set<VariableElement>(); |
+ final Map<ConstantExpression, ConstantValue> constantValueMap = |
+ <ConstantExpression, ConstantValue>{}; |
+ |
ConstantCompilerBase(this.compiler, this.constantSystem); |
+ @override |
+ ConstantValue getConstantValueForVariable(VariableElement element) { |
+ return getConstantValue(initialVariableValues[element.declaration]); |
+ } |
+ |
+ @override |
ConstantExpression getConstantForVariable(VariableElement element) { |
return initialVariableValues[element.declaration]; |
} |
@@ -159,35 +190,39 @@ abstract class ConstantCompilerBase implements ConstantCompiler { |
if (isConst) { |
compiler.reportError( |
node, MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS); |
- return new ErroneousConstantExpression(); |
+ ConstantExpression expression = new ErroneousConstantExpression(); |
+ constantValueMap[expression] = constantSystem.createNull(); |
+ return expression; |
} |
return null; |
} |
pendingVariables.add(element); |
Expression initializer = element.initializer; |
- ConstantExpression value; |
+ ConstantExpression expression; |
if (initializer == null) { |
// No initial value. |
- value = new NullConstantExpression(new NullConstantValue()); |
+ expression = new NullConstantExpression(); |
+ constantValueMap[expression] = constantSystem.createNull(); |
} else { |
- value = compileNodeWithDefinitions( |
+ expression = compileNodeWithDefinitions( |
initializer, definitions, isConst: isConst); |
if (compiler.enableTypeAssertions && |
- value != null && |
+ expression != null && |
element.isField) { |
DartType elementType = element.type; |
- if (elementType.isMalformed && !value.value.isNull) { |
+ ConstantValue value = getConstantValue(expression); |
+ if (elementType.isMalformed && !value.isNull) { |
if (isConst) { |
ErroneousElement element = elementType.element; |
compiler.reportError( |
node, element.messageKind, element.messageArguments); |
} else { |
// We need to throw an exception at runtime. |
- value = null; |
+ expression = null; |
} |
} else { |
- DartType constantType = value.value.getType(compiler.coreTypes); |
+ DartType constantType = value.getType(compiler.coreTypes); |
if (!constantSystem.isSubtype(compiler.types, |
constantType, elementType)) { |
if (isConst) { |
@@ -197,20 +232,20 @@ abstract class ConstantCompilerBase implements ConstantCompiler { |
} else { |
// If the field cannot be lazily initialized, we will throw |
// the exception at runtime. |
- value = null; |
+ expression = null; |
} |
} |
} |
} |
} |
- if (value != null) { |
- initialVariableValues[element.declaration] = value; |
+ if (expression != null) { |
+ initialVariableValues[element.declaration] = expression; |
} else { |
assert(invariant(element, !isConst, |
message: "Variable $element does not compile to a constant.")); |
} |
pendingVariables.remove(element); |
- return value; |
+ return expression; |
} |
ConstantExpression compileNodeWithDefinitions(Node node, |
@@ -220,7 +255,15 @@ abstract class ConstantCompilerBase implements ConstantCompiler { |
CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator( |
this, definitions, compiler, isConst: isConst); |
AstConstant constant = evaluator.evaluate(node); |
- return constant != null ? constant.expression : null; |
+ if (constant != null) { |
+ constantValueMap[constant.expression] = constant.value; |
+ return constant.expression; |
+ } |
+ return null; |
+ } |
+ |
+ ConstantValue getConstantValue(ConstantExpression expression) { |
+ return constantValueMap[expression]; |
} |
ConstantExpression compileNode(Node node, TreeElements elements, |
@@ -255,10 +298,6 @@ class DartConstantCompiler extends ConstantCompilerBase { |
return definitions.getConstant(node); |
} |
- ConstantExpression getConstantForMetadata(MetadataAnnotation metadata) { |
- return metadata.constant; |
- } |
- |
ConstantExpression compileNodeWithDefinitions(Node node, |
TreeElements definitions, |
{bool isConst: true}) { |
@@ -312,23 +351,26 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
AstConstant visitLiteralBool(LiteralBool node) { |
return new AstConstant( |
- context, node, new BoolConstantExpression( |
- node.value, |
- constantSystem.createBool(node.value))); |
+ context, |
+ node, |
+ new BoolConstantExpression(node.value), |
+ constantSystem.createBool(node.value)); |
} |
AstConstant visitLiteralDouble(LiteralDouble node) { |
return new AstConstant( |
- context, node, new DoubleConstantExpression( |
- node.value, |
- constantSystem.createDouble(node.value))); |
+ context, |
+ node, |
+ new DoubleConstantExpression(node.value), |
+ constantSystem.createDouble(node.value)); |
} |
AstConstant visitLiteralInt(LiteralInt node) { |
return new AstConstant( |
- context, node, new IntConstantExpression( |
- node.value, |
- constantSystem.createInt(node.value))); |
+ context, |
+ node, |
+ new IntConstantExpression(node.value), |
+ constantSystem.createInt(node.value)); |
} |
AstConstant visitLiteralList(LiteralList node) { |
@@ -349,10 +391,10 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
} |
DartType type = elements.getType(node); |
return new AstConstant( |
- context, node, new ListConstantExpression( |
- constantSystem.createList(type, argumentValues), |
- type, |
- argumentExpressions)); |
+ context, |
+ node, |
+ new ListConstantExpression(type, argumentExpressions), |
+ constantSystem.createList(type, argumentValues)); |
} |
AstConstant visitLiteralMap(LiteralMap node) { |
@@ -360,9 +402,9 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
return signalNotCompileTimeConstant(node); |
} |
List<ConstantExpression> keyExpressions = <ConstantExpression>[]; |
+ List<ConstantExpression> valueExpressions = <ConstantExpression>[]; |
List<ConstantValue> keyValues = <ConstantValue>[]; |
- Map<ConstantValue, ConstantExpression> map = |
- new Map<ConstantValue, ConstantExpression>(); |
+ Map<ConstantValue, ConstantValue> map = <ConstantValue, ConstantValue>{}; |
for (Link<Node> link = node.entries.nodes; |
!link.isEmpty; |
link = link.tail) { |
@@ -371,40 +413,45 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
if (key == null) { |
return null; |
} |
+ AstConstant value = evaluateConstant(entry.value); |
+ if (value == null) { |
+ return null; |
+ } |
if (!map.containsKey(key.value)) { |
- keyExpressions.add(key.expression); |
keyValues.add(key.value); |
} else { |
compiler.reportWarning(entry.key, MessageKind.EQUAL_MAP_ENTRY_KEY); |
} |
- AstConstant value = evaluateConstant(entry.value); |
- if (value == null) { |
- return null; |
- } |
- map[key.value] = value.expression; |
+ keyExpressions.add(key.expression); |
+ valueExpressions.add(value.expression); |
+ map[key.value] = value.value; |
} |
- List<ConstantExpression> valueExpressions = map.values.toList(); |
InterfaceType type = elements.getType(node); |
return new AstConstant( |
- context, node, new MapConstantExpression( |
- constantSystem.createMap(compiler, type, keyValues, |
- valueExpressions.map((e) => e.value).toList()), |
+ context, |
+ node, |
+ new MapConstantExpression( |
type, |
keyExpressions, |
- valueExpressions)); |
+ valueExpressions), |
+ constantSystem.createMap( |
+ compiler, type, keyValues, map.values.toList())); |
} |
AstConstant visitLiteralNull(LiteralNull node) { |
return new AstConstant( |
- context, node, new NullConstantExpression( |
- constantSystem.createNull())); |
+ context, |
+ node, |
+ new NullConstantExpression(), |
+ constantSystem.createNull()); |
} |
AstConstant visitLiteralString(LiteralString node) { |
return new AstConstant( |
- context, node, new StringConstantExpression( |
- node.dartString.slowToString(), |
- constantSystem.createString(node.dartString))); |
+ context, |
+ node, |
+ new StringConstantExpression(node.dartString.slowToString()), |
+ constantSystem.createString(node.dartString)); |
} |
AstConstant visitStringJuxtaposition(StringJuxtaposition node) { |
@@ -414,11 +461,12 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
StringConstantValue leftValue = left.value; |
StringConstantValue rightValue = right.value; |
return new AstConstant( |
- context, node, new ConcatenateConstantExpression( |
- constantSystem.createString( |
- new DartString.concat( |
- leftValue.primitiveValue, rightValue.primitiveValue)), |
- [left.expression, right.expression])); |
+ context, |
+ node, |
+ new ConcatenateConstantExpression([left.expression, right.expression]), |
+ constantSystem.createString( |
+ new DartString.concat( |
+ leftValue.primitiveValue, rightValue.primitiveValue))); |
} |
AstConstant visitStringInterpolation(StringInterpolation node) { |
@@ -459,30 +507,31 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
new DartString.concat(accumulator, partStringValue.primitiveValue); |
}; |
return new AstConstant( |
- context, node, new ConcatenateConstantExpression( |
- constantSystem.createString(accumulator), |
- subexpressions)); |
+ context, |
+ node, |
+ new ConcatenateConstantExpression(subexpressions), |
+ constantSystem.createString(accumulator)); |
} |
AstConstant visitLiteralSymbol(LiteralSymbol node) { |
InterfaceType type = compiler.symbolClass.rawType; |
String text = node.slowNameString; |
List<AstConstant> arguments = |
- <AstConstant>[new AstConstant(context, node, |
- new StringConstantExpression( |
- text, |
- constantSystem.createString(new LiteralDartString(text))))]; |
+ <AstConstant>[new AstConstant( |
+ context, |
+ node, |
+ new StringConstantExpression(text), |
+ constantSystem.createString(new LiteralDartString(text)))]; |
ConstructorElement constructor = compiler.symbolConstructor; |
AstConstant constant = createConstructorInvocation( |
node, type, constructor, CallStructure.ONE_ARG, |
normalizedArguments: arguments); |
return new AstConstant( |
- context, node, new SymbolConstantExpression(constant.value, text)); |
+ context, node, new SymbolConstantExpression(text), constant.value); |
} |
- ConstantExpression makeTypeConstant(DartType elementType) { |
- return new TypeConstantExpression( |
- constantSystem.createType(compiler, elementType), elementType); |
+ ConstantValue makeTypeConstant(DartType elementType) { |
+ return constantSystem.createType(compiler, elementType); |
} |
/// Returns true if the prefix of the send resolves to a deferred import |
@@ -498,7 +547,8 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
if (Elements.isClass(element) || Elements.isTypedef(element)) { |
TypeDeclarationElement typeDeclarationElement = element; |
DartType type = typeDeclarationElement.rawType; |
- return new AstConstant(element, node, makeTypeConstant(type)); |
+ return new AstConstant(element, node, |
+ new TypeConstantExpression(type), makeTypeConstant(type)); |
} |
return signalNotCompileTimeConstant(node); |
} |
@@ -507,13 +557,15 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
AstConstant visitSend(Send send) { |
Element element = elements[send]; |
if (send.isPropertyAccess) { |
- ConstantExpression result; |
- |
+ AstConstant result; |
if (Elements.isStaticOrTopLevelFunction(element)) { |
FunctionElementX function = element; |
function.computeType(compiler); |
- result = new FunctionConstantExpression( |
- new FunctionConstantValue(function), function); |
+ result = new AstConstant( |
+ context, |
+ send, |
+ new FunctionConstantExpression(function), |
+ new FunctionConstantValue(function)); |
} else if (Elements.isStaticOrTopLevelField(element)) { |
ConstantExpression elementExpression; |
if (element.isConst) { |
@@ -522,12 +574,20 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
elementExpression = handler.compileVariable(element); |
} |
if (elementExpression != null) { |
- result = |
- new VariableConstantExpression(elementExpression.value, element); |
+ result = new AstConstant( |
+ context, |
+ send, |
+ new VariableConstantExpression(element), |
+ handler.getConstantValue(elementExpression)); |
} |
} else if (Elements.isClass(element) || Elements.isTypedef(element)) { |
assert(elements.isTypeLiteral(send)); |
- result = makeTypeConstant(elements.getTypeLiteralType(send)); |
+ DartType elementType = elements.getTypeLiteralType(send); |
+ result = new AstConstant( |
+ context, |
+ send, |
+ new TypeConstantExpression(elementType), |
+ makeTypeConstant(elementType)); |
} else if (send.receiver != null) { |
if (send.selector.asIdentifier().source == "length") { |
AstConstant left = evaluate(send.receiver); |
@@ -535,8 +595,11 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
StringConstantValue stringConstantValue = left.value; |
DartString string = stringConstantValue.primitiveValue; |
IntConstantValue length = constantSystem.createInt(string.length); |
- result = |
- new StringLengthConstantExpression(length, left.expression); |
+ result = new AstConstant( |
+ context, |
+ send, |
+ new StringLengthConstantExpression(left.expression), |
+ length); |
} |
} |
// Fall through to error handling. |
@@ -546,8 +609,11 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
ConstantExpression variableExpression = |
handler.compileConstant(element); |
if (variableExpression != null) { |
- result = new VariableConstantExpression(variableExpression.value, |
- element); |
+ result = new AstConstant( |
+ context, |
+ send, |
+ new VariableConstantExpression(element), |
+ handler.getConstantValue(variableExpression)); |
} |
} |
if (result == null) { |
@@ -559,14 +625,17 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
} |
PrefixElement prefix = compiler.deferredLoadTask |
.deferredPrefixElement(send, elements); |
- result = new DeferredConstantExpression( |
- new DeferredConstantValue(result.value, prefix), |
- result, |
- prefix); |
+ result = new AstConstant( |
+ context, |
+ send, |
+ new DeferredConstantExpression( |
+ result.expression, |
+ prefix), |
+ new DeferredConstantValue(result.value, prefix)); |
compiler.deferredLoadTask |
.registerConstantDeferredUse(result.value, prefix); |
} |
- return new AstConstant(context, send, result); |
+ return result; |
} else if (send.isCall) { |
if (element == compiler.identicalFunction |
&& send.argumentCount() == 2) { |
@@ -579,8 +648,11 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
constantSystem.identity.fold(left.value, right.value); |
if (result != null) { |
return new AstConstant( |
- context, send, new IdenticalConstantExpression(result, |
- left.expression, right.expression)); |
+ context, |
+ send, |
+ new IdenticalConstantExpression( |
+ left.expression, right.expression), |
+ result); |
} |
} |
return signalNotCompileTimeConstant(send); |
@@ -601,8 +673,11 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
return signalNotCompileTimeConstant(send); |
} |
return new AstConstant( |
- context, send, new UnaryConstantExpression(folded, |
- operator, receiverConstant.expression)); |
+ context, |
+ send, |
+ new UnaryConstantExpression( |
+ operator, receiverConstant.expression), |
+ folded); |
} else if (send.isOperator && !send.isPostfix) { |
assert(send.argumentCount() == 1); |
AstConstant left = evaluate(send.receiver); |
@@ -645,8 +720,11 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
return signalNotCompileTimeConstant(send); |
} |
return new AstConstant( |
- context, send, new BinaryConstantExpression(folded, |
- left.expression, operator, right.expression)); |
+ context, |
+ send, |
+ new BinaryConstantExpression( |
+ left.expression, operator, right.expression), |
+ folded); |
} |
return signalNotCompileTimeConstant(send); |
} |
@@ -672,13 +750,15 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
} |
BoolConstantValue boolCondition = condition.value; |
return new AstConstant( |
- context, node, new ConditionalConstantExpression( |
- boolCondition.primitiveValue |
- ? thenExpression.value |
- : elseExpression.value, |
+ context, |
+ node, |
+ new ConditionalConstantExpression( |
condition.expression, |
thenExpression.expression, |
- elseExpression.expression)); |
+ elseExpression.expression), |
+ boolCondition.primitiveValue |
+ ? thenExpression.value |
+ : elseExpression.value); |
} |
AstConstant visitSendSet(SendSet node) { |
@@ -702,7 +782,8 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
AstConstant compileDefaultValue(VariableElement element) { |
ConstantExpression constant = handler.compileConstant(element); |
- return new AstConstant.fromDefaultValue(element, constant); |
+ return new AstConstant.fromDefaultValue( |
+ element, constant, handler.getConstantValue(constant)); |
} |
target.computeSignature(compiler); |
@@ -774,14 +855,17 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
ConstructorElement implementation = target.implementation; |
if (implementation.isErroneous) { |
+ // TODO(johnniwinther): This should probably be an [ErroneousAstConstant]. |
return new AstConstant( |
- context, node, new ConstructedConstantExpression( |
- new ConstructedConstantValue( |
- constructedType, const <FieldElement, ConstantValue>{}), |
+ context, |
+ node, |
+ new ConstructedConstantExpression( |
type, |
constructor, |
callStructure, |
- const <ConstantExpression>[])); |
+ const <ConstantExpression>[]), |
+ new ConstructedConstantValue( |
+ constructedType, const <FieldElement, ConstantValue>{})); |
} |
List<AstConstant> concreteArguments; |
@@ -888,15 +972,15 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
} |
if (constructor == compiler.intEnvironment) { |
expression = new IntFromEnvironmentConstantExpression( |
- value, name, defaultValue); |
+ name, defaultValue); |
} else if (constructor == compiler.boolEnvironment) { |
expression = new BoolFromEnvironmentConstantExpression( |
- value, name, defaultValue); |
+ name, defaultValue); |
} else if (constructor == compiler.stringEnvironment) { |
expression = new StringFromEnvironmentConstantExpression( |
- value, name, defaultValue); |
+ name, defaultValue); |
} |
- return new AstConstant(context, node, expression); |
+ return new AstConstant(context, node, expression, value); |
} |
if (value == null) { |
@@ -939,8 +1023,7 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
assert(invariant(node, compiler.compilationFailed, |
message: "makeConstructedConstant can only be called with the " |
"effective target: $constructor")); |
- return new AstConstant( |
- context, node, new ErroneousConstantExpression()); |
+ return new ErroneousAstConstant(context, node); |
} |
assert(invariant(node, callStructure.signatureApplies(constructor) || |
compiler.compilationFailed, |
@@ -958,12 +1041,14 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
fieldValues[field] = astConstant.value; |
}); |
return new AstConstant( |
- context, node, new ConstructedConstantExpression( |
- new ConstructedConstantValue(constructedType, fieldValues), |
+ context, |
+ node, |
+ new ConstructedConstantExpression( |
type, |
constructor, |
callStructure, |
- concreteArguments.map((e) => e.expression).toList())); |
+ concreteArguments.map((e) => e.expression).toList()), |
+ new ConstructedConstantValue(constructedType, fieldValues)); |
} |
AstConstant visitParenthesizedExpression(ParenthesizedExpression node) { |
@@ -982,7 +1067,10 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
error(node, message); |
return new AstConstant( |
- null, node, new ErroneousConstantExpression()); |
+ context, |
+ node, |
+ new ErroneousConstantExpression(), |
+ new NullConstantValue()); |
} |
// Else we don't need to do anything. The final handler is only |
// optimistically trying to compile constants. So it is normal that we |
@@ -1188,8 +1276,11 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator { |
AstConstant fieldValue = fieldValues[field]; |
if (fieldValue == null) { |
// Use the default value. |
+ ConstantExpression fieldExpression = handler.compileConstant(field); |
fieldValue = new AstConstant.fromDefaultValue( |
- field, handler.compileConstant(field)); |
+ field, |
+ fieldExpression, |
+ handler.getConstantValue(fieldExpression)); |
} |
fieldConstants[field] = fieldValue; |
}, |
@@ -1211,27 +1302,30 @@ class AstConstant { |
final Element element; |
final Node node; |
final ConstantExpression expression; |
+ final ConstantValue value; |
- AstConstant(this.element, this.node, this.expression); |
+ AstConstant(this.element, this.node, this.expression, this.value); |
factory AstConstant.fromDefaultValue( |
VariableElement element, |
- ConstantExpression constant) { |
+ ConstantExpression constant, |
+ ConstantValue value) { |
return new AstConstant( |
element, |
element.initializer != null ? element.initializer : element.node, |
- constant); |
+ constant, |
+ value); |
} |
- ConstantValue get value => expression.value; |
- |
String toString() => expression.toString(); |
} |
/// A synthetic constant used to recover from errors. |
class ErroneousAstConstant extends AstConstant { |
ErroneousAstConstant(Element element, Node node) |
- : super(element, node, new ErroneousConstantExpression()); |
+ : super(element, node, |
+ // TODO(johnniwinther): Return a [NonConstantValue] instead. |
+ new ErroneousConstantExpression(), new NullConstantValue()); |
} |
// TODO(johnniwinther): Avoid the need for this hack. |