| Index: pkg/compiler/lib/src/constants/expressions.dart
|
| diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
|
| index 5aeb27b8665ee030ea7e311c7dc652288e461581..291babc6687d42ac808a22ef28115b80c986b922 100644
|
| --- a/pkg/compiler/lib/src/constants/expressions.dart
|
| +++ b/pkg/compiler/lib/src/constants/expressions.dart
|
| @@ -4,7 +4,8 @@
|
|
|
| library dart2js.constants.expressions;
|
|
|
| -import '../dart2jslib.dart' show assertDebugMode;
|
| +import '../constants/constant_system.dart';
|
| +import '../dart2jslib.dart' show assertDebugMode, Compiler;
|
| import '../dart_types.dart';
|
| import '../elements/elements.dart' show
|
| ConstructorElement,
|
| @@ -13,6 +14,7 @@ import '../elements/elements.dart' show
|
| FunctionElement,
|
| VariableElement;
|
| import '../resolution/operators.dart';
|
| +import '../tree/tree.dart' show DartString;
|
| import '../universe/universe.dart' show CallStructure;
|
| import 'values.dart';
|
|
|
| @@ -43,6 +45,15 @@ enum ConstantExpressionKind {
|
| NAMED_REFERENCE,
|
| }
|
|
|
| +/// Environment used for evaluating constant expressions.
|
| +abstract class Environment {
|
| + // TODO(johnniwinther): Replace this with [CoreTypes] and maybe [Backend].
|
| + Compiler get compiler;
|
| +
|
| + /// Read environments string passed in using the '-Dname=value' option.
|
| + String readFromEnvironment(String name);
|
| +}
|
| +
|
| /// The normalized arguments passed to a const constructor computed from the
|
| /// actual [arguments] and the [defaultValues] of the called construrctor.
|
| class Arguments {
|
| @@ -198,7 +209,7 @@ class RedirectingFactoryConstantConstructor implements ConstantConstructor {
|
| RedirectingFactoryConstantConstructor(this.constructorInvocation);
|
|
|
| ConstantConstructorKind get kind {
|
| - return ConstantConstructorKind.REDIRECTING_GENERATIVE;
|
| + return ConstantConstructorKind.REDIRECTING_FACTORY;
|
| }
|
|
|
| InterfaceType computeInstanceType(InterfaceType newType) {
|
| @@ -250,6 +261,11 @@ abstract class ConstantExpression {
|
| /// Substitute free variables using arguments.
|
| ConstantExpression apply(Arguments arguments) => this;
|
|
|
| + /// Compute the [ConstantValue] for this expression using the [environment]
|
| + /// and the [constantSystem].
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem);
|
| +
|
| String getText() {
|
| ConstExpPrinter printer = new ConstExpPrinter();
|
| accept(printer);
|
| @@ -293,6 +309,13 @@ class ErroneousConstantExpression extends ConstantExpression {
|
| }
|
|
|
| @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + // TODO(johnniwinther): Use non-constant values for errors.
|
| + return value;
|
| + }
|
| +
|
| + @override
|
| int _computeHashCode() => 13;
|
|
|
| @override
|
| @@ -323,6 +346,12 @@ class BoolConstantExpression extends PrimitiveConstantExpression {
|
| }
|
|
|
| @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + return constantSystem.createBool(primitiveValue);
|
| + }
|
| +
|
| + @override
|
| int _computeHashCode() => 13 * primitiveValue.hashCode;
|
|
|
| @override
|
| @@ -345,6 +374,12 @@ class IntConstantExpression extends PrimitiveConstantExpression {
|
| }
|
|
|
| @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + return constantSystem.createInt(primitiveValue);
|
| + }
|
| +
|
| + @override
|
| int _computeHashCode() => 17 * primitiveValue.hashCode;
|
|
|
| @override
|
| @@ -367,6 +402,12 @@ class DoubleConstantExpression extends PrimitiveConstantExpression {
|
| }
|
|
|
| @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + return constantSystem.createDouble(primitiveValue);
|
| + }
|
| +
|
| + @override
|
| int _computeHashCode() => 19 * primitiveValue.hashCode;
|
|
|
| @override
|
| @@ -389,6 +430,12 @@ class StringConstantExpression extends PrimitiveConstantExpression {
|
| }
|
|
|
| @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + return constantSystem.createString(new DartString.literal(primitiveValue));
|
| + }
|
| +
|
| + @override
|
| int _computeHashCode() => 23 * primitiveValue.hashCode;
|
|
|
| @override
|
| @@ -407,6 +454,12 @@ class NullConstantExpression extends PrimitiveConstantExpression {
|
| return visitor.visitNull(this, context);
|
| }
|
|
|
| + @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + return constantSystem.createNull();
|
| + }
|
| +
|
| get primitiveValue => null;
|
|
|
| @override
|
| @@ -431,11 +484,18 @@ class ListConstantExpression extends ConstantExpression {
|
| }
|
|
|
| @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + return constantSystem.createList(type,
|
| + values.map((v) => v.evaluate(environment, constantSystem)).toList());
|
| + }
|
| +
|
| ConstantExpression apply(Arguments arguments) {
|
| return new ListConstantExpression(null, type,
|
| values.map((v) => v.apply(arguments)).toList());
|
| }
|
|
|
| + @override
|
| int _computeHashCode() {
|
| int hashCode = 13 * type.hashCode + 17 * values.length;
|
| for (ConstantExpression value in values) {
|
| @@ -471,12 +531,21 @@ class MapConstantExpression extends ConstantExpression {
|
| }
|
|
|
| @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + return constantSystem.createMap(environment.compiler,
|
| + type,
|
| + keys.map((k) => k.evaluate(environment, constantSystem)).toList(),
|
| + values.map((v) => v.evaluate(environment, constantSystem)).toList());
|
| + }
|
| +
|
| ConstantExpression apply(Arguments arguments) {
|
| return new MapConstantExpression(null, type,
|
| keys.map((k) => k.apply(arguments)).toList(),
|
| values.map((v) => v.apply(arguments)).toList());
|
| }
|
|
|
| + @override
|
| int _computeHashCode() {
|
| int hashCode = 13 * type.hashCode + 17 * values.length;
|
| for (ConstantExpression value in values) {
|
| @@ -536,6 +605,19 @@ class ConstructedConstantExpression extends ConstantExpression {
|
| this.arguments.map((a) => a.apply(arguments)).toList());
|
| }
|
|
|
| + @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + Map<FieldElement, ConstantValue> fieldValues =
|
| + <FieldElement, ConstantValue>{};
|
| + computeInstanceFields().forEach(
|
| + (FieldElement field, ConstantExpression constant) {
|
| + fieldValues[field] = constant.evaluate(environment, constantSystem);
|
| + });
|
| + return new ConstructedConstantValue(computeInstanceType(), fieldValues);
|
| + }
|
| +
|
| + @override
|
| int _computeHashCode() {
|
| int hashCode =
|
| 13 * type.hashCode +
|
| @@ -578,6 +660,34 @@ class ConcatenateConstantExpression extends ConstantExpression {
|
| }
|
|
|
| @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + DartString accumulator;
|
| + for (ConstantExpression expression in expressions) {
|
| + ConstantValue value = expression.evaluate(environment, constantSystem);
|
| + DartString valueString;
|
| + if (value.isNum || value.isBool) {
|
| + PrimitiveConstantValue primitive = value;
|
| + valueString =
|
| + new DartString.literal(primitive.primitiveValue.toString());
|
| + } else if (value.isString) {
|
| + PrimitiveConstantValue primitive = value;
|
| + valueString = primitive.primitiveValue;
|
| + } else {
|
| + // TODO(johnniwinther): Specialize message to indicated that the problem
|
| + // is not constness but the types of the const expressions.
|
| + return new NonConstantValue();
|
| + }
|
| + if (accumulator == null) {
|
| + accumulator = valueString;
|
| + } else {
|
| + accumulator = new DartString.concat(accumulator, valueString);
|
| + }
|
| + }
|
| + return constantSystem.createString(accumulator);
|
| + }
|
| +
|
| + @override
|
| int _computeHashCode() {
|
| int hashCode = 17 * expressions.length;
|
| for (ConstantExpression value in expressions) {
|
| @@ -616,6 +726,13 @@ class SymbolConstantExpression extends ConstantExpression {
|
| bool _equals(SymbolConstantExpression other) {
|
| return name == other.name;
|
| }
|
| +
|
| + @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + // TODO(johnniwinther): Implement this.
|
| + throw new UnsupportedError('SymbolConstantExpression.evaluate');
|
| + }
|
| }
|
|
|
| /// Type literal.
|
| @@ -635,6 +752,12 @@ class TypeConstantExpression extends ConstantExpression {
|
| }
|
|
|
| @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + return constantSystem.createType(environment.compiler, type);
|
| + }
|
| +
|
| + @override
|
| int _computeHashCode() => 13 * type.hashCode;
|
|
|
| @override
|
| @@ -657,6 +780,12 @@ class VariableConstantExpression extends ConstantExpression {
|
| }
|
|
|
| @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + return element.constant.evaluate(environment, constantSystem);
|
| + }
|
| +
|
| + @override
|
| int _computeHashCode() => 13 * element.hashCode;
|
|
|
| @override
|
| @@ -679,6 +808,12 @@ class FunctionConstantExpression extends ConstantExpression {
|
| }
|
|
|
| @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + return new FunctionConstantValue(element);
|
| + }
|
| +
|
| + @override
|
| int _computeHashCode() => 13 * element.hashCode;
|
|
|
| @override
|
| @@ -704,6 +839,14 @@ class BinaryConstantExpression extends ConstantExpression {
|
| return visitor.visitBinary(this, context);
|
| }
|
|
|
| + @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + return constantSystem.lookupBinary(operator).fold(
|
| + left.evaluate(environment, constantSystem),
|
| + right.evaluate(environment, constantSystem));
|
| + }
|
| +
|
| ConstantExpression apply(Arguments arguments) {
|
| return new BinaryConstantExpression(
|
| value,
|
| @@ -765,6 +908,14 @@ class IdenticalConstantExpression extends ConstantExpression {
|
| return visitor.visitIdentical(this, context);
|
| }
|
|
|
| + @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + return constantSystem.identity.fold(
|
| + left.evaluate(environment, constantSystem),
|
| + right.evaluate(environment, constantSystem));
|
| + }
|
| +
|
| ConstantExpression apply(Arguments arguments) {
|
| return new IdenticalConstantExpression(
|
| value,
|
| @@ -803,6 +954,13 @@ class UnaryConstantExpression extends ConstantExpression {
|
| return visitor.visitUnary(this, context);
|
| }
|
|
|
| + @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + return constantSystem.lookupUnary(operator).fold(
|
| + expression.evaluate(environment, constantSystem));
|
| + }
|
| +
|
| ConstantExpression apply(Arguments arguments) {
|
| return new UnaryConstantExpression(
|
| value,
|
| @@ -872,6 +1030,24 @@ class ConditionalConstantExpression extends ConstantExpression {
|
| trueExp == other.trueExp &&
|
| falseExp == other.falseExp;
|
| }
|
| +
|
| + @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + ConstantValue conditionValue =
|
| + condition.evaluate(environment, constantSystem);
|
| + ConstantValue trueValue =
|
| + trueExp.evaluate(environment, constantSystem);
|
| + ConstantValue falseValue =
|
| + falseExp.evaluate(environment, constantSystem);
|
| + if (conditionValue.isTrue) {
|
| + return trueValue;
|
| + } else if (conditionValue.isFalse) {
|
| + return falseValue;
|
| + } else {
|
| + return new NonConstantValue();
|
| + }
|
| + }
|
| }
|
|
|
| /// A reference to a position parameter.
|
| @@ -901,6 +1077,12 @@ class PositionalArgumentReference extends ConstantExpression {
|
|
|
| @override
|
| bool _equals(PositionalArgumentReference other) => index == other.index;
|
| +
|
| + @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + throw new UnsupportedError('PositionalArgumentReference.evaluate');
|
| + }
|
| }
|
|
|
| /// A reference to a named parameter.
|
| @@ -930,6 +1112,12 @@ class NamedArgumentReference extends ConstantExpression {
|
|
|
| @override
|
| bool _equals(NamedArgumentReference other) => name == other.name;
|
| +
|
| + @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + throw new UnsupportedError('NamedArgumentReference.evaluate');
|
| + }
|
| }
|
|
|
| abstract class FromEnvironmentConstantExpression extends ConstantExpression {
|
| @@ -970,6 +1158,19 @@ class BoolFromEnvironmentConstantExpression
|
| return visitor.visitBoolFromEnvironment(this, context);
|
| }
|
|
|
| + @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + String text = environment.readFromEnvironment(name);
|
| + if (text == 'true') {
|
| + return constantSystem.createBool(true);
|
| + } else if (text == 'false') {
|
| + return constantSystem.createBool(false);
|
| + } else {
|
| + return defaultValue.evaluate(environment, constantSystem);
|
| + }
|
| + }
|
| +
|
| ConstantExpression apply(Arguments arguments) {
|
| return new BoolFromEnvironmentConstantExpression(
|
| null, name, defaultValue.apply(arguments));
|
| @@ -994,6 +1195,21 @@ class IntFromEnvironmentConstantExpression
|
| return visitor.visitIntFromEnvironment(this, context);
|
| }
|
|
|
| + @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + int value;
|
| + String text = environment.readFromEnvironment(name);
|
| + if (text != null) {
|
| + value = int.parse(text, onError: (_) => null);
|
| + }
|
| + if (value == null) {
|
| + return defaultValue.evaluate(environment, constantSystem);
|
| + } else {
|
| + return constantSystem.createInt(value);
|
| + }
|
| + }
|
| +
|
| ConstantExpression apply(Arguments arguments) {
|
| return new IntFromEnvironmentConstantExpression(
|
| null, name, defaultValue.apply(arguments));
|
| @@ -1018,6 +1234,16 @@ class StringFromEnvironmentConstantExpression
|
| return visitor.visitStringFromEnvironment(this, context);
|
| }
|
|
|
| + @override
|
| + ConstantValue evaluate(Environment environment,
|
| + ConstantSystem constantSystem) {
|
| + String text = environment.readFromEnvironment(name);
|
| + if (text == null) {
|
| + return defaultValue.evaluate(environment, constantSystem);
|
| + } else {
|
| + return constantSystem.createString(new DartString.literal(text));
|
| + }
|
| + }
|
|
|
| ConstantExpression apply(Arguments arguments) {
|
| return new StringFromEnvironmentConstantExpression(
|
|
|