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

Unified Diff: pkg/compiler/lib/src/constants/expressions.dart

Issue 1559233002: WIP: Compute constant expressions in resolution. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 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 | « pkg/compiler/lib/src/constants/evaluation.dart ('k') | pkg/compiler/lib/src/constants/values.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 f1ad90bfae1106d9e36724eb6c7857f3f068b8a2..0b1d4f1a51cceb0222c5096121759d85b656fddc 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -73,6 +73,9 @@ abstract class ConstantExpression {
accept(ConstantExpressionVisitor visitor, [context]);
+ /// `true` if this is an erroneous constant expression.
+ bool get isErroneous => false;
+
/// Substitute free variables using arguments.
ConstantExpression apply(NormalizedArguments arguments) => this;
@@ -137,6 +140,9 @@ class ErroneousConstantExpression extends ConstantExpression {
@override
bool _equals(ErroneousConstantExpression other) => true;
+
+ @override
+ bool get isErroneous => true;
}
// TODO(johnniwinther): Avoid the need for this class.
@@ -387,10 +393,28 @@ class MapConstantExpression extends ConstantExpression {
@override
ConstantValue evaluate(Environment environment,
ConstantSystem constantSystem) {
- return constantSystem.createMap(environment.compiler,
+ /*return constantSystem.createMap(environment.compiler,
type,
keys.map((k) => k.evaluate(environment, constantSystem)).toList(),
- values.map((v) => v.evaluate(environment, constantSystem)).toList());
+ values.map((v) => v.evaluate(environment, constantSystem)).toList());*/
+ Map<ConstantValue, ConstantValue> map = <ConstantValue, ConstantValue>{};
+
+ for (int i = 0; i < keys.length; i++) {
+ ConstantValue key = keys[i].evaluate(environment, constantSystem);
+ if (!key.isConstant) {
+ return new NonConstantValue();
+ }
+ ConstantValue value = values[i].evaluate(environment, constantSystem);
+ if (!value.isConstant) {
+ return new NonConstantValue();
+ }
+ if (map.containsKey(key)) {
+ environment.reportWarning(keys[i], MessageKind.EQUAL_MAP_ENTRY_KEY, {});
+ }
+ map[key] = value;
+ }
+ return constantSystem.createMap(
+ environment.compiler, type, map.keys.toList(), map.values.toList());
}
ConstantExpression apply(NormalizedArguments arguments) {
@@ -438,6 +462,8 @@ class ConstructedConstantExpression extends ConstantExpression {
this.arguments) {
assert(type.element == target.enclosingClass);
assert(!arguments.contains(null));
+ assert(invariant(NO_LOCATION_SPANNABLE, target.isConst,
+ message: "Referenced constructor $target is not constant."));
}
ConstantExpressionKind get kind => ConstantExpressionKind.CONSTRUCTED;
@@ -447,6 +473,8 @@ class ConstructedConstantExpression extends ConstantExpression {
}
Map<FieldElement, ConstantExpression> computeInstanceFields() {
+ assert(invariant(target, target.constantConstructor != null,
+ message: "Constant constructor has not been computed for $target."));
return target.constantConstructor.computeInstanceFields(
arguments, callStructure);
}
@@ -464,13 +492,32 @@ class ConstructedConstantExpression extends ConstantExpression {
@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 environment.evaluateConstructor(target, () {
+ Map<FieldElement, ConstantExpression> fieldMap =
+ computeInstanceFields();
+ if (fieldMap == null) {
+ // An erroneous constant constructor was encountered in the super-chain.
+ return new NonConstantValue();
+ }
+ bool isValidAsConstant = true;
+ Map<FieldElement, ConstantValue> fieldValues =
+ <FieldElement, ConstantValue>{};
+ fieldMap.forEach((FieldElement field, ConstantExpression constant) {
+ ConstantValue value = constant.evaluate(environment, constantSystem);
+ assert(invariant(CURRENT_ELEMENT_SPANNABLE, value != null,
+ message: "No value computed for ${constant.getText()}."));
+ if (value.isConstant) {
+ fieldValues[field] = value;
+ } else {
+ isValidAsConstant = false;
+ }
+ });
+ if (isValidAsConstant) {
+ return new ConstructedConstantValue(computeInstanceType(), fieldValues);
+ } else {
+ return new NonConstantValue();
+ }
});
- return new ConstructedConstantValue(computeInstanceType(), fieldValues);
}
@override
@@ -517,11 +564,15 @@ class ConcatenateConstantExpression extends ConstantExpression {
@override
ConstantValue evaluate(Environment environment,
ConstantSystem constantSystem) {
+ bool isValidAsConstant = true;
DartString accumulator;
for (ConstantExpression expression in expressions) {
ConstantValue value = expression.evaluate(environment, constantSystem);
DartString valueString;
- if (value.isNum || value.isBool) {
+ if (!value.isConstant) {
+ isValidAsConstant = false;
+ continue;
+ } else if (value.isNum || value.isBool) {
PrimitiveConstantValue primitive = value;
valueString =
new DartString.literal(primitive.primitiveValue.toString());
@@ -531,7 +582,13 @@ class ConcatenateConstantExpression extends ConstantExpression {
} else {
// TODO(johnniwinther): Specialize message to indicated that the problem
// is not constness but the types of the const expressions.
- return new NonConstantValue();
+ environment.reportError(
+ expression,
+ MessageKind.INVALID_CONSTANT_INTERPOLATION_TYPE,
+ {'constant': expression,
+ 'type': value.getType(environment.coreTypes)});
+ isValidAsConstant = false;
+ continue;
}
if (accumulator == null) {
accumulator = valueString;
@@ -539,7 +596,10 @@ class ConcatenateConstantExpression extends ConstantExpression {
accumulator = new DartString.concat(accumulator, valueString);
}
}
- return constantSystem.createString(accumulator);
+ if (isValidAsConstant) {
+ return constantSystem.createString(accumulator);
+ }
+ return new NonConstantValue();
}
@override
@@ -587,8 +647,7 @@ class SymbolConstantExpression extends ConstantExpression {
@override
ConstantValue evaluate(Environment environment,
ConstantSystem constantSystem) {
- // TODO(johnniwinther): Implement this.
- throw new UnsupportedError('SymbolConstantExpression.evaluate');
+ return constantSystem.createSymbol(environment.compiler, name);
}
@override
@@ -632,7 +691,10 @@ class TypeConstantExpression extends ConstantExpression {
class VariableConstantExpression extends ConstantExpression {
final VariableElement element;
- VariableConstantExpression(this.element);
+ VariableConstantExpression(this.element) {
+ /*assert(invariant(NO_LOCATION_SPANNABLE, element.isConst,
+ message: "Referenced variable $element is not constant."));*/
+ }
ConstantExpressionKind get kind => ConstantExpressionKind.VARIABLE;
@@ -643,7 +705,9 @@ class VariableConstantExpression extends ConstantExpression {
@override
ConstantValue evaluate(Environment environment,
ConstantSystem constantSystem) {
- return element.constant.evaluate(environment, constantSystem);
+ return environment.evaluateVariable(element, () {
+ return element.constant.evaluate(environment, constantSystem);
+ });
}
@override
@@ -704,9 +768,29 @@ class BinaryConstantExpression extends ConstantExpression {
@override
ConstantValue evaluate(Environment environment,
ConstantSystem constantSystem) {
- return constantSystem.lookupBinary(operator).fold(
- left.evaluate(environment, constantSystem),
- right.evaluate(environment, constantSystem));
+ ConstantValue leftValue = left.evaluate(environment, constantSystem);
+ ConstantValue rightValue = right.evaluate(environment, constantSystem);
+ if (!leftValue.isConstant ||
+ !rightValue.isConstant) {
+ return new NonConstantValue();
+ }
+ ConstantExpressionChecker checker =
+ new ConstantExpressionChecker(environment);
+ bool isValid = checker.checkBinaryExpression(
+ this,
+ checker.createInfo(left, leftValue),
+ operator,
+ checker.createInfo(right, rightValue));
+
+ BinaryOperation operation = constantSystem.lookupBinary(operator);
+ assert(invariant(NO_LOCATION_SPANNABLE, operation != null,
+ message: "No binary operation for $operator."));
+ ConstantValue value = operation.fold(leftValue, rightValue);
+ if (value != null) {
+ return value;
+ }
+ assert(!isValid);
+ return new NonConstantValue();
}
ConstantExpression apply(NormalizedArguments arguments) {
@@ -730,26 +814,32 @@ class BinaryConstantExpression extends ConstantExpression {
case BinaryOperatorKind.LTEQ:
return coreTypes.boolType;
case BinaryOperatorKind.ADD:
- if (knownLeftType == coreTypes.stringType) {
- assert(knownRightType == coreTypes.stringType);
+ if (knownLeftType == coreTypes.stringType &&
+ knownRightType == coreTypes.stringType) {
return coreTypes.stringType;
} else if (knownLeftType == coreTypes.intType &&
knownRightType == coreTypes.intType) {
return coreTypes.intType;
+ } else if ((knownLeftType == coreTypes.intType ||
+ knownLeftType == coreTypes.doubleType) &&
+ (knownRightType == coreTypes.intType ||
+ knownRightType == coreTypes.doubleType)) {
+ return coreTypes.doubleType;
}
- assert(knownLeftType == coreTypes.doubleType ||
- knownRightType == coreTypes.doubleType);
- return coreTypes.doubleType;
+ return null;
case BinaryOperatorKind.SUB:
case BinaryOperatorKind.MUL:
case BinaryOperatorKind.MOD:
if (knownLeftType == coreTypes.intType &&
knownRightType == coreTypes.intType) {
return coreTypes.intType;
+ } else if ((knownLeftType == coreTypes.intType ||
+ knownLeftType == coreTypes.doubleType) &&
+ (knownRightType == coreTypes.intType ||
+ knownRightType == coreTypes.doubleType)) {
+ return coreTypes.doubleType;
}
- assert(knownLeftType == coreTypes.doubleType ||
- knownRightType == coreTypes.doubleType);
- return coreTypes.doubleType;
+ return null;
case BinaryOperatorKind.DIV:
return coreTypes.doubleType;
case BinaryOperatorKind.IDIV:
@@ -767,7 +857,6 @@ class BinaryConstantExpression extends ConstantExpression {
}
}
-
int get precedence => PRECEDENCE_MAP[operator.kind];
@override
@@ -823,9 +912,12 @@ class IdenticalConstantExpression extends ConstantExpression {
@override
ConstantValue evaluate(Environment environment,
ConstantSystem constantSystem) {
- return constantSystem.identity.fold(
- left.evaluate(environment, constantSystem),
- right.evaluate(environment, constantSystem));
+ ConstantValue leftValue = left.evaluate(environment, constantSystem);
+ ConstantValue rightValue = right.evaluate(environment, constantSystem);
+ if (leftValue.isConstant && rightValue.isConstant) {
+ return constantSystem.identity.fold(leftValue, rightValue);
+ }
+ return new NonConstantValue();
}
ConstantExpression apply(NormalizedArguments arguments) {
@@ -870,8 +962,16 @@ class UnaryConstantExpression extends ConstantExpression {
@override
ConstantValue evaluate(Environment environment,
ConstantSystem constantSystem) {
- return constantSystem.lookupUnary(operator).fold(
- expression.evaluate(environment, constantSystem));
+ ConstantValue expressionValue =
+ expression.evaluate(environment, constantSystem);
+ ConstantExpressionChecker checker =
+ new ConstantExpressionChecker(environment);
+ bool isValidAsConstant = checker.checkUnary(
+ operator, checker.createInfo(expression, expressionValue));
+ if (isValidAsConstant) {
+ return constantSystem.lookupUnary(operator).fold(expressionValue);
+ }
+ return new NonConstantValue();
}
ConstantExpression apply(NormalizedArguments arguments) {
@@ -998,12 +1098,17 @@ class ConditionalConstantExpression extends ConstantExpression {
trueExp.evaluate(environment, constantSystem);
ConstantValue falseValue =
falseExp.evaluate(environment, constantSystem);
- if (conditionValue.isTrue) {
+ ConstantExpressionChecker checker =
+ new ConstantExpressionChecker(environment);
+ bool isValidAsConstant = checker.checkConditional(
+ checker.createInfo(condition, conditionValue));
+ if (!isValidAsConstant) {
+ return new NonConstantValue();
+ } else if (conditionValue.isTrue) {
return trueValue;
- } else if (conditionValue.isFalse) {
- return falseValue;
} else {
- return new NonConstantValue();
+ assert(conditionValue.isFalse);
+ return falseValue;
}
}
@@ -1128,7 +1233,12 @@ class BoolFromEnvironmentConstantExpression
} else {
defaultConstantValue = constantSystem.createBool(false);
}
- if (!nameConstantValue.isString) {
+ ConstantExpressionChecker checker =
+ new ConstantExpressionChecker(environment);
+ bool isValidAsConstant = checker.checkBoolFromEnvironment(
+ checker.createInfo(name, nameConstantValue),
+ checker.createInfo(defaultValue, defaultConstantValue));
+ if (!isValidAsConstant) {
return new NonConstantValue();
}
StringConstantValue nameStringConstantValue = nameConstantValue;
@@ -1182,7 +1292,12 @@ class IntFromEnvironmentConstantExpression
} else {
defaultConstantValue = constantSystem.createNull();
}
- if (!nameConstantValue.isString) {
+ ConstantExpressionChecker checker =
+ new ConstantExpressionChecker(environment);
+ bool isValidAsConstant = checker.checkIntFromEnvironment(
+ checker.createInfo(name, nameConstantValue),
+ checker.createInfo(defaultValue, defaultConstantValue));
+ if (!isValidAsConstant) {
return new NonConstantValue();
}
StringConstantValue nameStringConstantValue = nameConstantValue;
@@ -1238,7 +1353,12 @@ class StringFromEnvironmentConstantExpression
} else {
defaultConstantValue = constantSystem.createNull();
}
- if (!nameConstantValue.isString) {
+ ConstantExpressionChecker checker =
+ new ConstantExpressionChecker(environment);
+ bool isValidAsConstant = checker.checkStringFromEnvironment(
+ checker.createInfo(name, nameConstantValue),
+ checker.createInfo(defaultValue, defaultConstantValue));
+ if (!isValidAsConstant) {
return new NonConstantValue();
}
StringConstantValue nameStringConstantValue = nameConstantValue;
@@ -1605,4 +1725,4 @@ class ConstExpPrinter extends ConstantExpressionVisitor {
}
String toString() => sb.toString();
-}
+}
« no previous file with comments | « pkg/compiler/lib/src/constants/evaluation.dart ('k') | pkg/compiler/lib/src/constants/values.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698