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 1263ada4303f29dfe8727df36ec7bb1221e5be16..356721d3cdcdeba18fecf23297ef04c2ef872ce4 100644 |
--- a/pkg/compiler/lib/src/constants/expressions.dart |
+++ b/pkg/compiler/lib/src/constants/expressions.dart |
@@ -9,6 +9,7 @@ import '../dart_types.dart'; |
import '../elements/elements.dart' show |
ConstructorElement, |
Element, |
+ FieldElement, |
FunctionElement, |
VariableElement; |
import '../resolution/operators.dart'; |
@@ -18,6 +19,7 @@ import 'values.dart'; |
enum ConstantExpressionKind { |
BINARY, |
BOOL, |
+ BOOL_FROM_ENVIRONMENT, |
CONCATENATE, |
CONDITIONAL, |
CONSTRUCTED, |
@@ -26,14 +28,209 @@ enum ConstantExpressionKind { |
FUNCTION, |
IDENTICAL, |
INT, |
+ INT_FROM_ENVIRONMENT, |
LIST, |
MAP, |
NULL, |
STRING, |
+ STRING_FROM_ENVIRONMENT, |
SYMBOL, |
TYPE, |
UNARY, |
VARIABLE, |
+ |
+ POSITIONAL_REFERENCE, |
+ NAMED_REFERENCE, |
+} |
+ |
+/// The normalized arguments passed to a const constructor computed from the |
+/// actual [arguments] and the [defaultValues] of the called construrctor. |
+class NormalizedArguments { |
+ final Map<dynamic/*int|String*/, ConstantExpression> defaultValues; |
+ final CallStructure callStructure; |
+ final List<ConstantExpression> arguments; |
+ |
+ NormalizedArguments(this.defaultValues, this.callStructure, this.arguments); |
+ |
+ /// Returns the normalized named argument [name]. |
+ ConstantExpression getNamedArgument(String name) { |
+ int index = callStructure.namedArguments.indexOf(name); |
+ if (index == -1) { |
+ // The named argument is not provided. |
+ return defaultValues[name]; |
+ } |
+ return arguments[index + callStructure.positionalArgumentCount]; |
+ } |
+ |
+ /// Returns the normalized [index]th positional argument. |
+ ConstantExpression getPositionalArgument(int index) { |
+ if (index >= callStructure.positionalArgumentCount) { |
+ // The positional argument is not provided. |
+ return defaultValues[index]; |
+ } |
+ return arguments[index]; |
+ } |
+} |
+ |
+enum ConstantConstructorKind { |
+ GENERATIVE, |
+ REDIRECTING_GENERATIVE, |
+ REDIRECTING_FACTORY, |
+} |
+ |
+/// Definition of a constant constructor. |
+abstract class ConstantConstructor { |
+ ConstantConstructorKind get kind; |
+ |
+ /// Computes the type of the instance created in a const constructor |
+ /// invocation with type [newType]. |
+ InterfaceType computeInstanceType(InterfaceType newType); |
+ |
+ /// Computes the constant expressions of the fields of the created instance |
+ /// in a const constructor invocation with [arguments]. |
+ Map<FieldElement, ConstantExpression> computeInstanceFields( |
+ List<ConstantExpression> arguments, |
+ CallStructure callStructure); |
+} |
+ |
+/// A generative constant constructor. |
+class GenerativeConstantConstructor implements ConstantConstructor{ |
+ final InterfaceType type; |
+ final Map<dynamic/*int|String*/, ConstantExpression> defaultValues; |
+ final Map<FieldElement, ConstantExpression> fieldMap; |
+ final ConstructedConstantExpression superConstructorInvocation; |
+ |
+ GenerativeConstantConstructor( |
+ this.type, |
+ this.defaultValues, |
+ this.fieldMap, |
+ this.superConstructorInvocation); |
+ |
+ ConstantConstructorKind get kind => ConstantConstructorKind.GENERATIVE; |
+ |
+ InterfaceType computeInstanceType(InterfaceType newType) { |
+ return type.substByContext(newType); |
+ } |
+ |
+ Map<FieldElement, ConstantExpression> computeInstanceFields( |
+ List<ConstantExpression> arguments, |
+ CallStructure callStructure) { |
+ NormalizedArguments args = new NormalizedArguments( |
+ defaultValues, callStructure, arguments); |
+ Map<FieldElement, ConstantExpression> appliedFieldMap = |
+ applyFields(args, superConstructorInvocation); |
+ fieldMap.forEach((FieldElement field, ConstantExpression constant) { |
+ appliedFieldMap[field] = constant.apply(args); |
+ }); |
+ return appliedFieldMap; |
+ } |
+ |
+ String toString() { |
+ StringBuffer sb = new StringBuffer(); |
+ sb.write("{'type': $type"); |
+ defaultValues.forEach((key, ConstantExpression expression) { |
+ sb.write(",\n 'default:${key}': ${expression.getText()}"); |
+ }); |
+ fieldMap.forEach((FieldElement field, ConstantExpression expression) { |
+ sb.write(",\n 'field:${field}': ${expression.getText()}"); |
+ }); |
+ if (superConstructorInvocation != null) { |
+ sb.write(",\n 'constructor: ${superConstructorInvocation.getText()}"); |
+ } |
+ sb.write("}"); |
+ return sb.toString(); |
+ } |
+ |
+ /// Creates the field-to-constant map from applying [args] to |
+ /// [constructorInvocation]. If [constructorInvocation] is `null`, an empty |
+ /// map is created. |
+ static Map<FieldElement, ConstantExpression> applyFields( |
+ NormalizedArguments args, |
+ ConstructedConstantExpression constructorInvocation) { |
+ Map<FieldElement, ConstantExpression> appliedFieldMap = |
+ <FieldElement, ConstantExpression>{}; |
+ if (constructorInvocation != null) { |
+ Map<FieldElement, ConstantExpression> fieldMap = |
+ constructorInvocation.computeInstanceFields(); |
+ fieldMap.forEach((FieldElement field, ConstantExpression constant) { |
+ appliedFieldMap[field] = constant.apply(args); |
+ }); |
+ } |
+ return appliedFieldMap; |
+ } |
+} |
+ |
+/// A redirecting generative constant constructor. |
+class RedirectingGenerativeConstantConstructor implements ConstantConstructor { |
+ final Map<dynamic/*int|String*/, ConstantExpression> defaultValues; |
+ final ConstructedConstantExpression thisConstructorInvocation; |
+ |
+ RedirectingGenerativeConstantConstructor( |
+ this.defaultValues, |
+ this.thisConstructorInvocation); |
+ |
+ ConstantConstructorKind get kind { |
+ return ConstantConstructorKind.REDIRECTING_GENERATIVE; |
+ } |
+ |
+ InterfaceType computeInstanceType(InterfaceType newType) { |
+ return thisConstructorInvocation.computeInstanceType() |
+ .substByContext(newType); |
+ } |
+ |
+ Map<FieldElement, ConstantExpression> computeInstanceFields( |
+ List<ConstantExpression> arguments, |
+ CallStructure callStructure) { |
+ NormalizedArguments args = |
+ new NormalizedArguments(defaultValues, callStructure, arguments); |
+ Map<FieldElement, ConstantExpression> appliedFieldMap = |
+ GenerativeConstantConstructor.applyFields( |
+ args, thisConstructorInvocation); |
+ return appliedFieldMap; |
+ } |
+ |
+ String toString() { |
+ StringBuffer sb = new StringBuffer(); |
+ sb.write("{'type': ${thisConstructorInvocation.type}"); |
+ defaultValues.forEach((key, ConstantExpression expression) { |
+ sb.write(",\n 'default:${key}': ${expression.getText()}"); |
+ }); |
+ sb.write(",\n 'constructor': ${thisConstructorInvocation.getText()}"); |
+ sb.write("}"); |
+ return sb.toString(); |
+ } |
+} |
+ |
+/// A redirecting factory constant constructor. |
+class RedirectingFactoryConstantConstructor implements ConstantConstructor { |
+ final ConstructedConstantExpression targetConstructorInvocation; |
+ |
+ RedirectingFactoryConstantConstructor(this.targetConstructorInvocation); |
+ |
+ ConstantConstructorKind get kind { |
+ return ConstantConstructorKind.REDIRECTING_FACTORY; |
+ } |
+ |
+ InterfaceType computeInstanceType(InterfaceType newType) { |
+ return targetConstructorInvocation.computeInstanceType() |
+ .substByContext(newType); |
+ } |
+ |
+ Map<FieldElement, ConstantExpression> computeInstanceFields( |
+ List<ConstantExpression> arguments, |
+ CallStructure callStructure) { |
+ ConstantConstructor constantConstructor = |
+ targetConstructorInvocation.target.constantConstructor; |
+ return constantConstructor.computeInstanceFields(arguments, callStructure); |
+ } |
+ |
+ String toString() { |
+ StringBuffer sb = new StringBuffer(); |
+ sb.write("{"); |
+ sb.write("'constructor': ${targetConstructorInvocation.getText()}"); |
+ sb.write("}"); |
+ return sb.toString(); |
+ } |
} |
/// An expression that is a compile-time constant. |
@@ -51,6 +248,8 @@ abstract class ConstantExpression { |
ConstantExpressionKind get kind; |
/// Returns the value of this constant expression. |
+ // TODO(johnniwinther): Replace this with an evaluation method that takes |
+ // a constant system and an environment. |
ConstantValue get value; |
// TODO(johnniwinther): Unify precedence handled between constants, front-end |
@@ -59,6 +258,9 @@ abstract class ConstantExpression { |
accept(ConstantExpressionVisitor visitor, [context]); |
+ /// Substitute free variables using arguments. |
+ ConstantExpression apply(NormalizedArguments arguments) => this; |
+ |
String getText() { |
ConstExpPrinter printer = new ConstExpPrinter(); |
accept(printer); |
@@ -116,10 +318,6 @@ abstract class PrimitiveConstantExpression extends ConstantExpression { |
/// The primitive value of this contant expression. |
get primitiveValue; |
- |
- accept(ConstantExpressionVisitor visitor, [context]) { |
- return visitor.visitPrimitive(this, context); |
- } |
} |
/// Boolean literal constant. |
@@ -131,6 +329,10 @@ class BoolConstantExpression extends PrimitiveConstantExpression { |
ConstantExpressionKind get kind => ConstantExpressionKind.BOOL; |
+ accept(ConstantExpressionVisitor visitor, [context]) { |
+ return visitor.visitBool(this, context); |
+ } |
+ |
@override |
int _computeHashCode() => 13 * primitiveValue.hashCode; |
@@ -149,6 +351,10 @@ class IntConstantExpression extends PrimitiveConstantExpression { |
ConstantExpressionKind get kind => ConstantExpressionKind.INT; |
+ accept(ConstantExpressionVisitor visitor, [context]) { |
+ return visitor.visitInt(this, context); |
+ } |
+ |
@override |
int _computeHashCode() => 17 * primitiveValue.hashCode; |
@@ -167,6 +373,10 @@ class DoubleConstantExpression extends PrimitiveConstantExpression { |
ConstantExpressionKind get kind => ConstantExpressionKind.DOUBLE; |
+ accept(ConstantExpressionVisitor visitor, [context]) { |
+ return visitor.visitDouble(this, context); |
+ } |
+ |
@override |
int _computeHashCode() => 19 * primitiveValue.hashCode; |
@@ -185,6 +395,10 @@ class StringConstantExpression extends PrimitiveConstantExpression { |
ConstantExpressionKind get kind => ConstantExpressionKind.STRING; |
+ accept(ConstantExpressionVisitor visitor, [context]) { |
+ return visitor.visitString(this, context); |
+ } |
+ |
@override |
int _computeHashCode() => 23 * primitiveValue.hashCode; |
@@ -200,6 +414,10 @@ class NullConstantExpression extends PrimitiveConstantExpression { |
ConstantExpressionKind get kind => ConstantExpressionKind.NULL; |
+ accept(ConstantExpressionVisitor visitor, [context]) { |
+ return visitor.visitNull(this, context); |
+ } |
+ |
get primitiveValue => null; |
@override |
@@ -224,6 +442,11 @@ class ListConstantExpression extends ConstantExpression { |
} |
@override |
+ ConstantExpression apply(NormalizedArguments arguments) { |
+ return new ListConstantExpression(null, type, |
+ values.map((v) => v.apply(arguments)).toList()); |
+ } |
+ |
int _computeHashCode() { |
int hashCode = 13 * type.hashCode + 17 * values.length; |
for (ConstantExpression value in values) { |
@@ -259,6 +482,12 @@ class MapConstantExpression extends ConstantExpression { |
} |
@override |
+ ConstantExpression apply(NormalizedArguments arguments) { |
+ return new MapConstantExpression(null, type, |
+ keys.map((k) => k.apply(arguments)).toList(), |
+ values.map((v) => v.apply(arguments)).toList()); |
+ } |
+ |
int _computeHashCode() { |
int hashCode = 13 * type.hashCode + 17 * values.length; |
for (ConstantExpression value in values) { |
@@ -294,6 +523,7 @@ class ConstructedConstantExpression extends ConstantExpression { |
this.callStructure, |
this.arguments) { |
assert(type.element == target.enclosingClass); |
+ assert(!arguments.contains(null)); |
} |
ConstantExpressionKind get kind => ConstantExpressionKind.CONSTRUCTED; |
@@ -302,6 +532,21 @@ class ConstructedConstantExpression extends ConstantExpression { |
return visitor.visitConstructed(this, context); |
} |
+ Map<FieldElement, ConstantExpression> computeInstanceFields() { |
+ return target.constantConstructor.computeInstanceFields( |
+ arguments, callStructure); |
+ } |
+ |
+ InterfaceType computeInstanceType() { |
+ return target.constantConstructor.computeInstanceType(type); |
+ } |
+ |
+ ConstructedConstantExpression apply(NormalizedArguments arguments) { |
+ return new ConstructedConstantExpression(null, |
+ type, target, callStructure, |
+ this.arguments.map((a) => a.apply(arguments)).toList()); |
+ } |
+ |
@override |
int _computeHashCode() { |
int hashCode = |
@@ -329,9 +574,9 @@ class ConstructedConstantExpression extends ConstantExpression { |
/// String literal with juxtaposition and/or interpolations. |
class ConcatenateConstantExpression extends ConstantExpression { |
final StringConstantValue value; |
- final List<ConstantExpression> arguments; |
+ final List<ConstantExpression> expressions; |
- ConcatenateConstantExpression(this.value, this.arguments); |
+ ConcatenateConstantExpression(this.value, this.expressions); |
ConstantExpressionKind get kind => ConstantExpressionKind.CONCATENATE; |
@@ -339,10 +584,15 @@ class ConcatenateConstantExpression extends ConstantExpression { |
return visitor.visitConcatenate(this, context); |
} |
+ ConstantExpression apply(NormalizedArguments arguments) { |
+ return new ConcatenateConstantExpression(null, |
+ expressions.map((a) => a.apply(arguments)).toList()); |
+ } |
+ |
@override |
int _computeHashCode() { |
- int hashCode = 17 * arguments.length; |
- for (ConstantExpression value in arguments) { |
+ int hashCode = 17 * expressions.length; |
+ for (ConstantExpression value in expressions) { |
hashCode ^= 19 * value.hashCode; |
} |
return hashCode; |
@@ -350,9 +600,9 @@ class ConcatenateConstantExpression extends ConstantExpression { |
@override |
bool _equals(ConcatenateConstantExpression other) { |
- if (arguments.length != other.arguments.length) return false; |
- for (int i = 0; i < arguments.length; i++) { |
- if (arguments[i] != other.arguments[i]) return false; |
+ if (expressions.length != other.expressions.length) return false; |
+ for (int i = 0; i < expressions.length; i++) { |
+ if (expressions[i] != other.expressions[i]) return false; |
} |
return true; |
} |
@@ -466,6 +716,14 @@ class BinaryConstantExpression extends ConstantExpression { |
return visitor.visitBinary(this, context); |
} |
+ ConstantExpression apply(NormalizedArguments arguments) { |
+ return new BinaryConstantExpression( |
+ value, |
+ left.apply(arguments), |
+ operator, |
+ right.apply(arguments)); |
+ } |
+ |
int get precedence => PRECEDENCE_MAP[operator.kind]; |
@override |
@@ -519,6 +777,13 @@ class IdenticalConstantExpression extends ConstantExpression { |
return visitor.visitIdentical(this, context); |
} |
+ ConstantExpression apply(NormalizedArguments arguments) { |
+ return new IdenticalConstantExpression( |
+ value, |
+ left.apply(arguments), |
+ right.apply(arguments)); |
+ } |
+ |
int get precedence => 15; |
@override |
@@ -550,6 +815,13 @@ class UnaryConstantExpression extends ConstantExpression { |
return visitor.visitUnary(this, context); |
} |
+ ConstantExpression apply(NormalizedArguments arguments) { |
+ return new UnaryConstantExpression( |
+ value, |
+ operator, |
+ expression.apply(arguments)); |
+ } |
+ |
int get precedence => PRECEDENCE_MAP[operator.kind]; |
@override |
@@ -589,6 +861,14 @@ class ConditionalConstantExpression extends ConstantExpression { |
return visitor.visitConditional(this, context); |
} |
+ ConstantExpression apply(NormalizedArguments arguments) { |
+ return new ConditionalConstantExpression( |
+ value, |
+ condition.apply(arguments), |
+ trueExp.apply(arguments), |
+ falseExp.apply(arguments)); |
+ } |
+ |
int get precedence => 3; |
@override |
@@ -606,26 +886,190 @@ class ConditionalConstantExpression extends ConstantExpression { |
} |
} |
-abstract class ConstantExpressionVisitor<C, R> { |
+/// A reference to a position parameter. |
+class PositionalArgumentReference extends ConstantExpression { |
+ final int index; |
+ |
+ PositionalArgumentReference(this.index); |
+ |
+ ConstantExpressionKind get kind { |
+ return ConstantExpressionKind.POSITIONAL_REFERENCE; |
+ } |
+ |
+ accept(ConstantExpressionVisitor visitor, [context]) { |
+ return visitor.visitPositional(this, context); |
+ } |
+ |
+ ConstantValue get value { |
+ throw new UnsupportedError('PositionalArgumentReference.value'); |
+ } |
+ |
+ ConstantExpression apply(NormalizedArguments arguments) { |
+ return arguments.getPositionalArgument(index); |
+ } |
+ |
+ @override |
+ int _computeHashCode() => 13 * index.hashCode; |
+ |
+ @override |
+ bool _equals(PositionalArgumentReference other) => index == other.index; |
+} |
+ |
+/// A reference to a named parameter. |
+class NamedArgumentReference extends ConstantExpression { |
+ final String name; |
+ |
+ NamedArgumentReference(this.name); |
+ |
+ ConstantExpressionKind get kind { |
+ return ConstantExpressionKind.NAMED_REFERENCE; |
+ } |
+ |
+ accept(ConstantExpressionVisitor visitor, [context]) { |
+ return visitor.visitNamed(this, context); |
+ } |
+ |
+ ConstantValue get value { |
+ throw new UnsupportedError('NamedArgumentReference.value'); |
+ } |
+ |
+ ConstantExpression apply(NormalizedArguments arguments) { |
+ return arguments.getNamedArgument(name); |
+ } |
+ |
+ @override |
+ int _computeHashCode() => 13 * name.hashCode; |
+ |
+ @override |
+ bool _equals(NamedArgumentReference other) => name == other.name; |
+} |
+ |
+abstract class FromEnvironmentConstantExpression extends ConstantExpression { |
+ final ConstantValue value; |
+ final String name; |
+ final ConstantExpression defaultValue; |
+ |
+ FromEnvironmentConstantExpression(this.value, this.name, this.defaultValue); |
+ |
+ @override |
+ int _computeHashCode() { |
+ return 13 * name.hashCode + |
+ 17 * defaultValue.hashCode; |
+ } |
+ |
+ @override |
+ bool _equals(FromEnvironmentConstantExpression other) { |
+ return name == other.name && |
+ defaultValue == other.defaultValue; |
+ } |
+} |
+ |
+/// A `const bool.fromEnvironment` constant. |
+class BoolFromEnvironmentConstantExpression |
+ extends FromEnvironmentConstantExpression { |
+ |
+ BoolFromEnvironmentConstantExpression( |
+ ConstantValue value, |
+ String name, |
+ ConstantExpression defaultValue) |
+ : super(value, name, defaultValue); |
+ |
+ ConstantExpressionKind get kind { |
+ return ConstantExpressionKind.BOOL_FROM_ENVIRONMENT; |
+ } |
+ |
+ accept(ConstantExpressionVisitor visitor, [context]) { |
+ return visitor.visitBoolFromEnvironment(this, context); |
+ } |
+ |
+ ConstantExpression apply(NormalizedArguments arguments) { |
+ return new BoolFromEnvironmentConstantExpression( |
+ null, name, defaultValue.apply(arguments)); |
+ } |
+} |
+ |
+/// A `const int.fromEnvironment` constant. |
+class IntFromEnvironmentConstantExpression |
+ extends FromEnvironmentConstantExpression { |
+ |
+ IntFromEnvironmentConstantExpression( |
+ ConstantValue value, |
+ String name, |
+ ConstantExpression defaultValue) |
+ : super(value, name, defaultValue); |
+ |
+ ConstantExpressionKind get kind { |
+ return ConstantExpressionKind.INT_FROM_ENVIRONMENT; |
+ } |
+ |
+ accept(ConstantExpressionVisitor visitor, [context]) { |
+ return visitor.visitIntFromEnvironment(this, context); |
+ } |
+ |
+ ConstantExpression apply(NormalizedArguments arguments) { |
+ return new IntFromEnvironmentConstantExpression( |
+ null, name, defaultValue.apply(arguments)); |
+ } |
+} |
+ |
+/// A `const String.fromEnvironment` constant. |
+class StringFromEnvironmentConstantExpression |
+ extends FromEnvironmentConstantExpression { |
+ |
+ StringFromEnvironmentConstantExpression( |
+ ConstantValue value, |
+ String name, |
+ ConstantExpression defaultValue) |
+ : super(value, name, defaultValue); |
+ |
+ ConstantExpressionKind get kind { |
+ return ConstantExpressionKind.STRING_FROM_ENVIRONMENT; |
+ } |
+ |
+ accept(ConstantExpressionVisitor visitor, [context]) { |
+ return visitor.visitStringFromEnvironment(this, context); |
+ } |
+ |
+ |
+ ConstantExpression apply(NormalizedArguments arguments) { |
+ return new StringFromEnvironmentConstantExpression( |
+ null, name, defaultValue.apply(arguments)); |
+ } |
+} |
+ |
+abstract class ConstantExpressionVisitor<R, A> { |
const ConstantExpressionVisitor(); |
- R visit(ConstantExpression constant, C context) { |
+ R visit(ConstantExpression constant, A context) { |
return constant.accept(this, context); |
} |
- R visitPrimitive(PrimitiveConstantExpression exp, C context); |
- R visitList(ListConstantExpression exp, C context); |
- R visitMap(MapConstantExpression exp, C context); |
- R visitConstructed(ConstructedConstantExpression exp, C context); |
- R visitConcatenate(ConcatenateConstantExpression exp, C context); |
- R visitSymbol(SymbolConstantExpression exp, C context); |
- R visitType(TypeConstantExpression exp, C context); |
- R visitVariable(VariableConstantExpression exp, C context); |
- R visitFunction(FunctionConstantExpression exp, C context); |
- R visitBinary(BinaryConstantExpression exp, C context); |
- R visitIdentical(IdenticalConstantExpression exp, C context); |
- R visitUnary(UnaryConstantExpression exp, C context); |
- R visitConditional(ConditionalConstantExpression exp, C context); |
+ R visitBool(BoolConstantExpression exp, A context); |
+ R visitInt(IntConstantExpression exp, A context); |
+ R visitDouble(DoubleConstantExpression exp, A context); |
+ R visitString(StringConstantExpression exp, A context); |
+ R visitNull(NullConstantExpression exp, A context); |
+ R visitList(ListConstantExpression exp, A context); |
+ R visitMap(MapConstantExpression exp, A context); |
+ R visitConstructed(ConstructedConstantExpression exp, A context); |
+ R visitConcatenate(ConcatenateConstantExpression exp, A context); |
+ R visitSymbol(SymbolConstantExpression exp, A context); |
+ R visitType(TypeConstantExpression exp, A context); |
+ R visitVariable(VariableConstantExpression exp, A context); |
+ R visitFunction(FunctionConstantExpression exp, A context); |
+ R visitBinary(BinaryConstantExpression exp, A context); |
+ R visitIdentical(IdenticalConstantExpression exp, A context); |
+ R visitUnary(UnaryConstantExpression exp, A context); |
+ R visitConditional(ConditionalConstantExpression exp, A context); |
+ R visitBoolFromEnvironment(BoolFromEnvironmentConstantExpression exp, |
+ A context); |
+ R visitIntFromEnvironment(IntFromEnvironmentConstantExpression exp, |
+ A context); |
+ R visitStringFromEnvironment(StringFromEnvironmentConstantExpression exp, |
+ A context); |
+ |
+ R visitPositional(PositionalArgumentReference exp, A context); |
+ R visitNamed(NamedArgumentReference exp, A context); |
} |
/// Represents the declaration of a constant [element] with value [expression]. |
@@ -672,9 +1116,34 @@ class ConstExpPrinter extends ConstantExpressionVisitor { |
return constant.accept(this, null); |
} |
+ void visitPrimitive(PrimitiveConstantExpression exp) { |
+ sb.write(exp.primitiveValue); |
+ } |
+ |
@override |
- void visitPrimitive(PrimitiveConstantExpression exp, [_]) { |
- sb.write(exp.value.unparse()); |
+ void visitBool(BoolConstantExpression exp, [_]) { |
+ visitPrimitive(exp); |
+ } |
+ |
+ @override |
+ void visitDouble(DoubleConstantExpression exp, [_]) { |
+ visitPrimitive(exp); |
+ } |
+ |
+ @override |
+ void visitInt(IntConstantExpression exp, [_]) { |
+ visitPrimitive(exp); |
+ } |
+ |
+ @override |
+ void visitNull(NullConstantExpression exp, [_]) { |
+ visitPrimitive(exp); |
+ } |
+ |
+ @override |
+ void visitString(StringConstantExpression exp, [_]) { |
+ // TODO(johnniwinther): Ensure correct escaping. |
+ sb.write('"${exp.primitiveValue}"'); |
} |
@override |
@@ -808,5 +1277,38 @@ class ConstExpPrinter extends ConstantExpressionVisitor { |
write(exp, exp.falseExp); |
} |
+ @override |
+ void visitPositional(PositionalArgumentReference exp, [_]) { |
+ // TODO(johnniwinther): Maybe this should throw. |
+ sb.write('args[${exp.index}]'); |
+ } |
+ |
+ @override |
+ void visitNamed(NamedArgumentReference exp, [_]) { |
+ // TODO(johnniwinther): Maybe this should throw. |
+ sb.write('args[${exp.name}]'); |
+ } |
+ |
String toString() => sb.toString(); |
+ |
+ @override |
+ visitBoolFromEnvironment(BoolFromEnvironmentConstantExpression exp, [_]) { |
+ sb.write('const bool.fromEnvironment("${exp.name}", defaultValue: '); |
+ visit(exp.defaultValue); |
+ sb.write(')'); |
+ } |
+ |
+ @override |
+ visitIntFromEnvironment(IntFromEnvironmentConstantExpression exp, [_]) { |
+ sb.write('const int.fromEnvironment("${exp.name}", defaultValue: '); |
+ visit(exp.defaultValue); |
+ sb.write(')'); |
+ } |
+ |
+ @override |
+ visitStringFromEnvironment(StringFromEnvironmentConstantExpression exp, [_]) { |
+ sb.write('const String.fromEnvironment("${exp.name}", defaultValue: '); |
+ visit(exp.defaultValue); |
+ sb.write(')'); |
+ } |
} |