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 564a8a3138c4aad1f287b68d48ff728fefdc55c4..b83b7a0644a36e96004f4b445d524b00a987eda8 100644 |
--- a/pkg/compiler/lib/src/compile_time_constants.dart |
+++ b/pkg/compiler/lib/src/compile_time_constants.dart |
@@ -13,13 +13,17 @@ import 'compiler.dart' show |
Compiler; |
import 'constant_system_dart.dart'; |
import 'constants/constant_system.dart'; |
+import 'constants/constructors.dart'; |
import 'constants/evaluation.dart'; |
import 'constants/expressions.dart'; |
import 'constants/values.dart'; |
+import 'core_types.dart'; |
import 'dart_types.dart'; |
import 'elements/elements.dart'; |
import 'elements/modelx.dart' show |
FunctionElementX; |
+import 'enqueue.dart' show |
+ WorldImpact; |
import 'resolution/tree_elements.dart' show |
TreeElements; |
import 'resolution/operators.dart'; |
@@ -91,7 +95,7 @@ abstract class ConstantCompiler extends ConstantEnvironment { |
/// Evaluates [constant] and caches the result. |
// TODO(johnniwinther): Remove when all constants are evaluated. |
- void evaluate(ConstantExpression constant); |
+ void evaluate(Spannable spannable, ConstantExpression constant); |
} |
/// A [BackendConstantEnvironment] provides access to constants needed for |
@@ -175,10 +179,10 @@ abstract class ConstantCompilerBase implements ConstantCompiler { |
} |
@override |
- void evaluate(ConstantExpression constant) { |
+ void evaluate(Spannable spannable, ConstantExpression constant) { |
constantValueMap.putIfAbsent(constant, () { |
return constant.evaluate( |
- new _CompilerEnvironment(compiler), |
+ new CompilerEnvironment(compiler, spannable), |
constantSystem); |
}); |
} |
@@ -290,6 +294,14 @@ abstract class ConstantCompilerBase implements ConstantCompiler { |
ConstantExpression compileNodeWithDefinitions( |
Node node, TreeElements definitions, {bool isConst: true}) { |
assert(node != null); |
+ ConstantExpression constantExpression = definitions.getConstant(node); |
+ if (constantExpression != null) { |
+ constantValueMap.putIfAbsent(constantExpression, () { |
+ return constantExpression.evaluate( |
+ new CompilerEnvironment(compiler, node), constantSystem); |
+ }); |
+ return constantExpression; |
+ } |
CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator( |
this, definitions, compiler, isConst: isConst); |
AstConstant constant = evaluator.evaluate(node); |
@@ -298,6 +310,16 @@ abstract class ConstantCompilerBase implements ConstantCompiler { |
return constant.expression; |
} |
return null; |
+ /* |
+ if (constantExpression == null) { |
+ compiler.internalError(node, "No constant computed for $node."); |
+ } |
+ constantValueMap.putIfAbsent( |
+ constantExpression, () { |
+ return constantExpression.evaluate( |
+ new CompilerEnvironment(compiler, node), constantSystem); |
+ }); |
+ return constantExpression;*/ |
} |
ConstantValue getConstantValue(ConstantExpression expression) { |
@@ -325,6 +347,74 @@ abstract class ConstantCompilerBase implements ConstantCompiler { |
} |
} |
+class CompilerEnvironment implements Environment { |
+ final Compiler compiler; |
+ final Spannable spannable; |
+ final Set<VariableElement> evaluatingVariables = new Set<VariableElement>(); |
+ final Set<ConstructorElement> evaluatingConstructors = |
+ new Set<ConstructorElement>(); |
+ |
+ CompilerEnvironment(this.compiler, this.spannable); |
+ |
+ @override |
+ CoreTypes get coreTypes => compiler.coreTypes; |
+ |
+ @override |
+ String readFromEnvironment(String name) => compiler.fromEnvironment(name); |
+ |
+ @override |
+ void reportWarning(ConstantExpression expression, |
+ MessageKind kind, |
+ Map arguments) { |
+ compiler.reporter.reportWarningMessage(spannable, kind, arguments); |
+ } |
+ |
+ @override |
+ void reportError(ConstantExpression expression, |
+ MessageKind kind, |
+ Map arguments) { |
+ compiler.reporter.reportErrorMessage(spannable, kind, arguments); |
+ } |
+ |
+ @override |
+ ConstantValue evaluateConstructor( |
+ ConstructorElement constructor, |
+ ConstantValue evaluate()) { |
+ if (evaluatingConstructors.contains(constructor)) { |
+ return new NonConstantValue(); |
+ } |
+ ConstructorElement parentConstructor = constructor; |
+ while (parentConstructor != null) { |
+ _analyzeElementEagerly(compiler, parentConstructor); |
+ ConstantConstructor constantConstructor = |
+ parentConstructor.constantConstructor; |
+ assert(invariant(parentConstructor, constantConstructor != null, |
+ message: "No constant constructor on ${parentConstructor}.")); |
+ parentConstructor = constantConstructor.parentConstructor; |
+ } |
+ evaluatingConstructors.add(constructor); |
+ ConstantValue value = evaluate(); |
+ evaluatingConstructors.remove(constructor); |
+ return value; |
+ } |
+ |
+ @override |
+ ConstantValue evaluateVariable( |
+ VariableElement variable, |
+ ConstantValue evaluate()) { |
+ if (evaluatingVariables.contains(variable)) { |
+ return new NonConstantValue(); |
+ } |
+ if (!variable.isLocal) { |
+ _analyzeElementEagerly(compiler, variable); |
+ } |
+ evaluatingVariables.add(variable); |
+ ConstantValue value = evaluate(); |
+ evaluatingVariables.remove(variable); |
+ return value; |
+ } |
+} |
+ |
/// [ConstantCompiler] that uses the Dart semantics for the compile-time |
/// constant evaluation. |
class DartConstantCompiler extends ConstantCompilerBase { |
@@ -874,7 +964,8 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
ConstructorElement constructor, CallStructure callStructure, |
List<AstConstant> normalizedArguments, |
List<AstConstant> concreteArguments) { |
- var firstArgument = normalizedArguments[0].value; |
+ |
+ ConstantValue firstArgument = normalizedArguments[0].value; |
ConstantValue defaultValue = normalizedArguments[1].value; |
if (firstArgument.isNull) { |
@@ -884,7 +975,7 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
} |
if (!firstArgument.isString) { |
- DartType type = defaultValue.getType(compiler.coreTypes); |
+ DartType type = firstArgument.getType(compiler.coreTypes); |
reporter.reportErrorMessage( |
normalizedArguments[0].node, |
MessageKind.NOT_ASSIGNABLE, |
@@ -926,7 +1017,8 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> { |
return null; |
} |
- String name = firstArgument.primitiveValue.slowToString(); |
+ PrimitiveConstantValue nameArgument = firstArgument; |
+ String name = nameArgument.primitiveValue.slowToString(); |
String value = compiler.fromEnvironment(name); |
AstConstant createEvaluatedConstant(ConstantValue value) { |
@@ -1263,14 +1355,3 @@ TreeElements _analyzeElementEagerly(Compiler compiler, AstElement element) { |
compiler.resolution.analyzeElement(element.declaration); |
return element.resolvedAst.elements; |
} |
- |
-class _CompilerEnvironment implements Environment { |
- final Compiler compiler; |
- |
- _CompilerEnvironment(this.compiler); |
- |
- @override |
- String readFromEnvironment(String name) { |
- return compiler.fromEnvironment(name); |
- } |
-} |