| 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);
|
| - }
|
| -}
|
|
|