| 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 23d65f295ea6b880d9ae3699a9cfe3cb64e68d56..17f333ac785d6f95de149677e97d265053ccd50e 100644
|
| --- a/pkg/compiler/lib/src/constants/expressions.dart
|
| +++ b/pkg/compiler/lib/src/constants/expressions.dart
|
| @@ -5,6 +5,7 @@
|
| library dart2js.constants.expressions;
|
|
|
| import '../constants/constant_system.dart';
|
| +import '../core_types.dart';
|
| import '../dart2jslib.dart' show assertDebugMode, Compiler;
|
| import '../dart_types.dart';
|
| import '../elements/elements.dart' show
|
| @@ -275,6 +276,10 @@ abstract class ConstantExpression {
|
| ConstantValue evaluate(Environment environment,
|
| ConstantSystem constantSystem);
|
|
|
| + /// Returns the type of this constant expression, if it is independent of the
|
| + /// environment values.
|
| + DartType getKnownType(CoreTypes coreTypes) => null;
|
| +
|
| String getText() {
|
| ConstExpPrinter printer = new ConstExpPrinter();
|
| accept(printer);
|
| @@ -360,6 +365,9 @@ class BoolConstantExpression extends PrimitiveConstantExpression {
|
| bool _equals(BoolConstantExpression other) {
|
| return primitiveValue == other.primitiveValue;
|
| }
|
| +
|
| + @override
|
| + DartType getKnownType(CoreTypes coreTypes) => coreTypes.boolType;
|
| }
|
|
|
| /// Integer literal constant.
|
| @@ -387,6 +395,9 @@ class IntConstantExpression extends PrimitiveConstantExpression {
|
| bool _equals(IntConstantExpression other) {
|
| return primitiveValue == other.primitiveValue;
|
| }
|
| +
|
| + @override
|
| + DartType getKnownType(CoreTypes coreTypes) => coreTypes.intType;
|
| }
|
|
|
| /// Double literal constant.
|
| @@ -414,6 +425,9 @@ class DoubleConstantExpression extends PrimitiveConstantExpression {
|
| bool _equals(DoubleConstantExpression other) {
|
| return primitiveValue == other.primitiveValue;
|
| }
|
| +
|
| + @override
|
| + DartType getKnownType(CoreTypes coreTypes) => coreTypes.doubleType;
|
| }
|
|
|
| /// String literal constant.
|
| @@ -441,6 +455,9 @@ class StringConstantExpression extends PrimitiveConstantExpression {
|
| bool _equals(StringConstantExpression other) {
|
| return primitiveValue == other.primitiveValue;
|
| }
|
| +
|
| + @override
|
| + DartType getKnownType(CoreTypes coreTypes) => coreTypes.stringType;
|
| }
|
|
|
| /// Null literal constant.
|
| @@ -466,6 +483,9 @@ class NullConstantExpression extends PrimitiveConstantExpression {
|
|
|
| @override
|
| bool _equals(NullConstantExpression other) => true;
|
| +
|
| + @override
|
| + DartType getKnownType(CoreTypes coreTypes) => coreTypes.nullType;
|
| }
|
|
|
| /// Literal list constant.
|
| @@ -511,6 +531,9 @@ class ListConstantExpression extends ConstantExpression {
|
| }
|
| return true;
|
| }
|
| +
|
| + @override
|
| + DartType getKnownType(CoreTypes coreTypes) => type;
|
| }
|
|
|
| /// Literal map constant.
|
| @@ -562,6 +585,9 @@ class MapConstantExpression extends ConstantExpression {
|
| }
|
| return true;
|
| }
|
| +
|
| + @override
|
| + DartType getKnownType(CoreTypes coreTypes) => type;
|
| }
|
|
|
| /// Invocation of a const constructor.
|
| @@ -699,6 +725,9 @@ class ConcatenateConstantExpression extends ConstantExpression {
|
| }
|
| return true;
|
| }
|
| +
|
| + @override
|
| + DartType getKnownType(CoreTypes coreTypes) => coreTypes.stringType;
|
| }
|
|
|
| /// Symbol literal.
|
| @@ -727,6 +756,9 @@ class SymbolConstantExpression extends ConstantExpression {
|
| // TODO(johnniwinther): Implement this.
|
| throw new UnsupportedError('SymbolConstantExpression.evaluate');
|
| }
|
| +
|
| + @override
|
| + DartType getKnownType(CoreTypes coreTypes) => coreTypes.symbolType;
|
| }
|
|
|
| /// Type literal.
|
| @@ -757,6 +789,9 @@ class TypeConstantExpression extends ConstantExpression {
|
| bool _equals(TypeConstantExpression other) {
|
| return type == other.type;
|
| }
|
| +
|
| + @override
|
| + DartType getKnownType(CoreTypes coreTypes) => coreTypes.typeType;
|
| }
|
|
|
| /// Reference to a constant local, top-level, or static variable.
|
| @@ -811,6 +846,9 @@ class FunctionConstantExpression extends ConstantExpression {
|
| bool _equals(FunctionConstantExpression other) {
|
| return element == other.element;
|
| }
|
| +
|
| + @override
|
| + DartType getKnownType(CoreTypes coreTypes) => coreTypes.functionType;
|
| }
|
|
|
| /// A constant binary expression like `a * b`.
|
| @@ -844,6 +882,58 @@ class BinaryConstantExpression extends ConstantExpression {
|
| right.apply(arguments));
|
| }
|
|
|
| + DartType getKnownType(CoreTypes coreTypes) {
|
| + DartType knownLeftType = left.getKnownType(coreTypes);
|
| + DartType knownRightType = right.getKnownType(coreTypes);
|
| + switch (operator.kind) {
|
| + case BinaryOperatorKind.EQ:
|
| + case BinaryOperatorKind.NOT_EQ:
|
| + case BinaryOperatorKind.LOGICAL_AND:
|
| + case BinaryOperatorKind.LOGICAL_OR:
|
| + case BinaryOperatorKind.GT:
|
| + case BinaryOperatorKind.LT:
|
| + case BinaryOperatorKind.GTEQ:
|
| + case BinaryOperatorKind.LTEQ:
|
| + return coreTypes.boolType;
|
| + case BinaryOperatorKind.ADD:
|
| + if (knownLeftType == coreTypes.stringType) {
|
| + assert(knownRightType == coreTypes.stringType);
|
| + return coreTypes.stringType;
|
| + } else if (knownLeftType == coreTypes.intType &&
|
| + knownRightType == coreTypes.intType) {
|
| + return coreTypes.intType;
|
| + }
|
| + assert(knownLeftType == coreTypes.doubleType ||
|
| + knownRightType == coreTypes.doubleType);
|
| + return coreTypes.doubleType;
|
| + case BinaryOperatorKind.SUB:
|
| + case BinaryOperatorKind.MUL:
|
| + case BinaryOperatorKind.MOD:
|
| + if (knownLeftType == coreTypes.intType &&
|
| + knownRightType == coreTypes.intType) {
|
| + return coreTypes.intType;
|
| + }
|
| + assert(knownLeftType == coreTypes.doubleType ||
|
| + knownRightType == coreTypes.doubleType);
|
| + return coreTypes.doubleType;
|
| + case BinaryOperatorKind.DIV:
|
| + return coreTypes.doubleType;
|
| + case BinaryOperatorKind.IDIV:
|
| + return coreTypes.intType;
|
| + case BinaryOperatorKind.AND:
|
| + case BinaryOperatorKind.OR:
|
| + case BinaryOperatorKind.XOR:
|
| + case BinaryOperatorKind.SHR:
|
| + case BinaryOperatorKind.SHL:
|
| + return coreTypes.intType;
|
| + case BinaryOperatorKind.IF_NULL:
|
| + case BinaryOperatorKind.INDEX:
|
| + throw new UnsupportedError(
|
| + 'Unexpected constant binary operator: $operator');
|
| + }
|
| + }
|
| +
|
| +
|
| int get precedence => PRECEDENCE_MAP[operator.kind];
|
|
|
| @override
|
| @@ -923,6 +1013,9 @@ class IdenticalConstantExpression extends ConstantExpression {
|
| return left == other.left &&
|
| right == other.right;
|
| }
|
| +
|
| + @override
|
| + DartType getKnownType(CoreTypes coreTypes) => coreTypes.boolType;
|
| }
|
|
|
| /// A unary constant expression like `-a`.
|
| @@ -967,6 +1060,11 @@ class UnaryConstantExpression extends ConstantExpression {
|
| expression == other.expression;
|
| }
|
|
|
| + @override
|
| + DartType getKnownType(CoreTypes coreTypes) {
|
| + return expression.getKnownType(coreTypes);
|
| + }
|
| +
|
| static const Map<UnaryOperatorKind, int> PRECEDENCE_MAP = const {
|
| UnaryOperatorKind.NOT: 14,
|
| UnaryOperatorKind.COMPLEMENT: 14,
|
| @@ -1013,6 +1111,9 @@ class StringLengthConstantExpression extends ConstantExpression {
|
| bool _equals(StringLengthConstantExpression other) {
|
| return expression == other.expression;
|
| }
|
| +
|
| + @override
|
| + DartType getKnownType(CoreTypes coreTypes) => coreTypes.intType;
|
| }
|
|
|
| /// A constant conditional expression like `a ? b : c`.
|
| @@ -1071,6 +1172,16 @@ class ConditionalConstantExpression extends ConstantExpression {
|
| return new NonConstantValue();
|
| }
|
| }
|
| +
|
| + @override
|
| + DartType getKnownType(CoreTypes coreTypes) {
|
| + DartType trueType = trueExp.getKnownType(coreTypes);
|
| + DartType falseType = falseExp.getKnownType(coreTypes);
|
| + if (trueType == falseType) {
|
| + return trueType;
|
| + }
|
| + return null;
|
| + }
|
| }
|
|
|
| /// A reference to a position parameter.
|
| @@ -1203,6 +1314,9 @@ class BoolFromEnvironmentConstantExpression
|
| name.apply(arguments),
|
| defaultValue != null ? defaultValue.apply(arguments) : null);
|
| }
|
| +
|
| + @override
|
| + DartType getKnownType(CoreTypes coreTypes) => coreTypes.boolType;
|
| }
|
|
|
| /// A `const int.fromEnvironment` constant.
|
| @@ -1256,6 +1370,9 @@ class IntFromEnvironmentConstantExpression
|
| name.apply(arguments),
|
| defaultValue != null ? defaultValue.apply(arguments) : null);
|
| }
|
| +
|
| + @override
|
| + DartType getKnownType(CoreTypes coreTypes) => coreTypes.intType;
|
| }
|
|
|
| /// A `const String.fromEnvironment` constant.
|
| @@ -1305,6 +1422,9 @@ class StringFromEnvironmentConstantExpression
|
| name.apply(arguments),
|
| defaultValue != null ? defaultValue.apply(arguments) : null);
|
| }
|
| +
|
| + @override
|
| + DartType getKnownType(CoreTypes coreTypes) => coreTypes.stringType;
|
| }
|
|
|
| /// A constant expression referenced with a deferred prefix.
|
|
|