Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(771)

Unified Diff: pkg/compiler/lib/src/compile_time_constants.dart

Issue 1148343004: Remove ConstantExpression.value (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Update comments. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/compiler/lib/src/compiler.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.
« no previous file with comments | « no previous file | pkg/compiler/lib/src/compiler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698