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

Unified Diff: pkg/compiler/lib/src/compile_time_constants.dart

Issue 1182663008: Typecheck const classes in the context of the constructor call. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: address comments Created 5 years, 4 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 | « no previous file | pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 063653733088cc706e018863d7b6e861bb3f5597..8de6aae1d2e298b0788f5273dbcf8bd901ba625a 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -10,7 +10,8 @@ import 'constants/evaluation.dart';
import 'constants/expressions.dart';
import 'constants/values.dart';
import 'dart_types.dart';
-import 'dart2jslib.dart' show Compiler, CompilerTask, MessageKind, WorldImpact, invariant;
+import 'dart2jslib.dart'
+ show Compiler, CompilerTask, MessageKind, WorldImpact, invariant;
import 'elements/elements.dart';
import 'elements/modelx.dart' show FunctionElementX;
import 'resolution/resolution.dart';
@@ -66,7 +67,7 @@ abstract class ConstantCompiler extends ConstantEnvironment {
///
/// The returned constant is always of the frontend interpretation.
ConstantExpression compileNode(Node node, TreeElements elements,
- {bool enforceConst: true});
+ {bool enforceConst: true});
/// Compiles the compile-time constant for the value [metadata], or reports an
/// error if the value is not a compile-time constant.
@@ -159,7 +160,7 @@ abstract class ConstantCompilerBase implements ConstantCompiler {
}
ConstantExpression compileConstant(VariableElement element) {
- return compileVariable(element, isConst: true);
+ return internalCompileVariable(element, true, true);
}
@override
@@ -171,9 +172,15 @@ abstract class ConstantCompilerBase implements ConstantCompiler {
});
}
- ConstantExpression compileVariable(VariableElement element,
- {bool isConst: false}) {
+ ConstantExpression compileVariable(VariableElement element) {
+ return internalCompileVariable(element, false, true);
+ }
+ /// Compile [element] into a constant expression. If [isConst] is true,
+ /// then [element] is a constant variable. If [checkType] is true, then
+ /// report an error if [element] does not typecheck.
+ ConstantExpression internalCompileVariable(
+ VariableElement element, bool isConst, bool checkType) {
if (initialVariableValues.containsKey(element.declaration)) {
ConstantExpression result = initialVariableValues[element.declaration];
return result;
@@ -184,7 +191,8 @@ abstract class ConstantCompilerBase implements ConstantCompiler {
_analyzeElementEagerly(compiler, currentElement);
ConstantExpression constant = compileVariableWithDefinitions(
- element, currentElement.resolvedAst.elements, isConst: isConst);
+ element, currentElement.resolvedAst.elements,
+ isConst: isConst, checkType: checkType);
return constant;
});
}
@@ -195,14 +203,13 @@ abstract class ConstantCompilerBase implements ConstantCompiler {
* If the variable is `const` but cannot be compiled eagerly reports an
* error.
*/
- ConstantExpression compileVariableWithDefinitions(VariableElement element,
- TreeElements definitions,
- {bool isConst: false}) {
+ ConstantExpression compileVariableWithDefinitions(
+ VariableElement element, TreeElements definitions,
+ {bool isConst: false, bool checkType: true}) {
Node node = element.node;
if (pendingVariables.contains(element)) {
if (isConst) {
- compiler.reportError(
- node, MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS);
+ compiler.reportError(node, MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS);
ConstantExpression expression = new ErroneousConstantExpression();
constantValueMap[expression] = constantSystem.createNull();
return expression;
@@ -218,9 +225,10 @@ abstract class ConstantCompilerBase implements ConstantCompiler {
expression = new NullConstantExpression();
constantValueMap[expression] = constantSystem.createNull();
} else {
- expression = compileNodeWithDefinitions(
- initializer, definitions, isConst: isConst);
+ expression = compileNodeWithDefinitions(initializer, definitions,
+ isConst: isConst);
if (compiler.enableTypeAssertions &&
+ checkType &&
expression != null &&
element.isField) {
DartType elementType = element.type;
@@ -236,12 +244,13 @@ abstract class ConstantCompilerBase implements ConstantCompiler {
}
} else {
DartType constantType = value.getType(compiler.coreTypes);
- if (!constantSystem.isSubtype(compiler.types,
- constantType, elementType)) {
+ if (!constantSystem.isSubtype(
+ compiler.types, constantType, elementType)) {
if (isConst) {
- compiler.reportError(
- node, MessageKind.NOT_ASSIGNABLE,
- {'fromType': constantType, 'toType': elementType});
+ compiler.reportError(node, MessageKind.NOT_ASSIGNABLE, {
+ 'fromType': constantType,
+ 'toType': elementType
+ });
} else {
// If the field cannot be lazily initialized, we will throw
// the exception at runtime.
@@ -255,7 +264,7 @@ abstract class ConstantCompilerBase implements ConstantCompiler {
initialVariableValues[element.declaration] = expression;
} else {
assert(invariant(element, !isConst,
- message: "Variable $element does not compile to a constant."));
+ message: "Variable $element does not compile to a constant."));
}
pendingVariables.remove(element);
return expression;
@@ -265,9 +274,8 @@ abstract class ConstantCompilerBase implements ConstantCompiler {
constantValueMap[expression] = value;
}
- ConstantExpression compileNodeWithDefinitions(Node node,
- TreeElements definitions,
- {bool isConst: true}) {
+ ConstantExpression compileNodeWithDefinitions(
+ Node node, TreeElements definitions, {bool isConst: true}) {
assert(node != null);
CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator(
this, definitions, compiler, isConst: isConst);
@@ -284,13 +292,12 @@ abstract class ConstantCompilerBase implements ConstantCompiler {
}
ConstantExpression compileNode(Node node, TreeElements elements,
- {bool enforceConst: true}) {
+ {bool enforceConst: true}) {
return compileNodeWithDefinitions(node, elements, isConst: enforceConst);
}
- ConstantExpression compileMetadata(MetadataAnnotation metadata,
- Node node,
- TreeElements elements) {
+ ConstantExpression compileMetadata(
+ MetadataAnnotation metadata, Node node, TreeElements elements) {
return compileNodeWithDefinitions(node, elements);
}
@@ -315,9 +322,8 @@ class DartConstantCompiler extends ConstantCompilerBase {
return definitions.getConstant(node);
}
- ConstantExpression compileNodeWithDefinitions(Node node,
- TreeElements definitions,
- {bool isConst: true}) {
+ ConstantExpression compileNodeWithDefinitions(
+ Node node, TreeElements definitions, {bool isConst: true}) {
ConstantExpression constant = definitions.getConstant(node);
if (constant != null && getConstantValue(constant) != null) {
return constant;
@@ -341,10 +347,8 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
Element get context => elements.analyzedElement;
- CompileTimeConstantEvaluator(this.handler,
- this.elements,
- this.compiler,
- {bool isConst: false})
+ CompileTimeConstantEvaluator(this.handler, this.elements, this.compiler,
+ {bool isConst: false})
: this.isEvaluatingConstant = isConst;
ConstantSystem get constantSystem => handler.constantSystem;
@@ -369,38 +373,31 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
}
AstConstant visitLiteralBool(LiteralBool node) {
- return new AstConstant(
- context,
- node,
+ return new AstConstant(context, node,
new BoolConstantExpression(node.value),
constantSystem.createBool(node.value));
}
AstConstant visitLiteralDouble(LiteralDouble node) {
- return new AstConstant(
- context,
- node,
+ return new AstConstant(context, node,
new DoubleConstantExpression(node.value),
constantSystem.createDouble(node.value));
}
AstConstant visitLiteralInt(LiteralInt node) {
- return new AstConstant(
- context,
- node,
- new IntConstantExpression(node.value),
+ return new AstConstant(context, node, new IntConstantExpression(node.value),
constantSystem.createInt(node.value));
}
AstConstant visitLiteralList(LiteralList node) {
- if (!node.isConst) {
+ if (!node.isConst) {
return signalNotCompileTimeConstant(node);
}
List<ConstantExpression> argumentExpressions = <ConstantExpression>[];
List<ConstantValue> argumentValues = <ConstantValue>[];
for (Link<Node> link = node.elements.nodes;
- !link.isEmpty;
- link = link.tail) {
+ !link.isEmpty;
+ link = link.tail) {
AstConstant argument = evaluateConstant(link.head);
if (argument == null) {
return null;
@@ -409,9 +406,7 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
argumentValues.add(argument.value);
}
DartType type = elements.getType(node);
- return new AstConstant(
- context,
- node,
+ return new AstConstant(context, node,
new ListConstantExpression(type, argumentExpressions),
constantSystem.createList(type, argumentValues));
}
@@ -425,8 +420,8 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
List<ConstantValue> keyValues = <ConstantValue>[];
Map<ConstantValue, ConstantValue> map = <ConstantValue, ConstantValue>{};
for (Link<Node> link = node.entries.nodes;
- !link.isEmpty;
- link = link.tail) {
+ !link.isEmpty;
+ link = link.tail) {
LiteralMapEntry entry = link.head;
AstConstant key = evaluateConstant(entry.key);
if (key == null) {
@@ -446,29 +441,19 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
map[key.value] = value.value;
}
InterfaceType type = elements.getType(node);
- return new AstConstant(
- context,
- node,
- new MapConstantExpression(
- type,
- keyExpressions,
- valueExpressions),
+ return new AstConstant(context, node,
+ new MapConstantExpression(type, keyExpressions, valueExpressions),
constantSystem.createMap(
compiler, type, keyValues, map.values.toList()));
}
AstConstant visitLiteralNull(LiteralNull node) {
- return new AstConstant(
- context,
- node,
- new NullConstantExpression(),
+ return new AstConstant(context, node, new NullConstantExpression(),
constantSystem.createNull());
}
AstConstant visitLiteralString(LiteralString node) {
- return new AstConstant(
- context,
- node,
+ return new AstConstant(context, node,
new StringConstantExpression(node.dartString.slowToString()),
constantSystem.createString(node.dartString));
}
@@ -479,13 +464,10 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
if (left == null || right == null) return null;
StringConstantValue leftValue = left.value;
StringConstantValue rightValue = right.value;
- return new AstConstant(
- context,
- node,
+ return new AstConstant(context, node,
new ConcatenateConstantExpression([left.expression, right.expression]),
- constantSystem.createString(
- new DartString.concat(
- leftValue.primitiveValue, rightValue.primitiveValue)));
+ constantSystem.createString(new DartString.concat(
+ leftValue.primitiveValue, rightValue.primitiveValue)));
}
AstConstant visitStringInterpolation(StringInterpolation node) {
@@ -524,10 +506,9 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
StringConstantValue partStringValue = partString.value;
accumulator =
new DartString.concat(accumulator, partStringValue.primitiveValue);
- };
- return new AstConstant(
- context,
- node,
+ }
+ ;
+ return new AstConstant(context, node,
new ConcatenateConstantExpression(subexpressions),
constantSystem.createString(accumulator));
}
@@ -535,12 +516,10 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
AstConstant visitLiteralSymbol(LiteralSymbol node) {
InterfaceType type = compiler.symbolClass.rawType;
String text = node.slowNameString;
- List<AstConstant> arguments =
- <AstConstant>[new AstConstant(
- context,
- node,
- new StringConstantExpression(text),
- constantSystem.createString(new LiteralDartString(text)))];
+ List<AstConstant> arguments = <AstConstant>[
+ new AstConstant(context, node, new StringConstantExpression(text),
+ constantSystem.createString(new LiteralDartString(text)))
+ ];
ConstructorElement constructor = compiler.symbolConstructor;
AstConstant constant = createConstructorInvocation(
node, type, constructor, CallStructure.ONE_ARG,
@@ -557,8 +536,8 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
/// prefix.
bool isDeferredUse(Send send) {
if (send == null) return false;
- return compiler.deferredLoadTask
- .deferredPrefixElement(send, elements) != null;
+ return compiler.deferredLoadTask.deferredPrefixElement(send, elements) !=
+ null;
}
AstConstant visitIdentifier(Identifier node) {
@@ -566,8 +545,8 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
if (Elements.isClass(element) || Elements.isTypedef(element)) {
TypeDeclarationElement typeDeclarationElement = element;
DartType type = typeDeclarationElement.rawType;
- return new AstConstant(element, node,
- new TypeConstantExpression(type), makeTypeConstant(type));
+ return new AstConstant(element, node, new TypeConstantExpression(type),
+ makeTypeConstant(type));
}
return signalNotCompileTimeConstant(node);
}
@@ -580,9 +559,7 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
if (Elements.isStaticOrTopLevelFunction(element)) {
FunctionElementX function = element;
function.computeType(compiler);
- result = new AstConstant(
- context,
- send,
+ result = new AstConstant(context, send,
new FunctionConstantExpression(function),
new FunctionConstantValue(function));
} else if (Elements.isStaticOrTopLevelField(element)) {
@@ -593,18 +570,14 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
elementExpression = handler.compileVariable(element);
}
if (elementExpression != null) {
- result = new AstConstant(
- context,
- send,
+ result = new AstConstant(context, send,
new VariableConstantExpression(element),
handler.getConstantValue(elementExpression));
}
} else if (Elements.isClass(element) || Elements.isTypedef(element)) {
assert(elements.isTypeLiteral(send));
DartType elementType = elements.getTypeLiteralType(send);
- result = new AstConstant(
- context,
- send,
+ result = new AstConstant(context, send,
new TypeConstantExpression(elementType),
makeTypeConstant(elementType));
} else if (send.receiver != null) {
@@ -614,23 +587,18 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
StringConstantValue stringConstantValue = left.value;
DartString string = stringConstantValue.primitiveValue;
IntConstantValue length = constantSystem.createInt(string.length);
- result = new AstConstant(
- context,
- send,
- new StringLengthConstantExpression(left.expression),
- length);
+ result = new AstConstant(context, send,
+ new StringLengthConstantExpression(left.expression), length);
}
}
// Fall through to error handling.
- } else if (!Elements.isUnresolved(element)
- && element.isVariable
- && element.isConst) {
+ } else if (!Elements.isUnresolved(element) &&
+ element.isVariable &&
+ element.isConst) {
ConstantExpression variableExpression =
handler.compileConstant(element);
if (variableExpression != null) {
- result = new AstConstant(
- context,
- send,
+ result = new AstConstant(context, send,
new VariableConstantExpression(element),
handler.getConstantValue(variableExpression));
}
@@ -642,22 +610,17 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
if (isEvaluatingConstant) {
error(send, MessageKind.DEFERRED_COMPILE_TIME_CONSTANT);
}
- PrefixElement prefix = compiler.deferredLoadTask
- .deferredPrefixElement(send, elements);
- result = new AstConstant(
- context,
- send,
- new DeferredConstantExpression(
- result.expression,
- prefix),
+ PrefixElement prefix =
+ compiler.deferredLoadTask.deferredPrefixElement(send, elements);
+ result = new AstConstant(context, send,
+ new DeferredConstantExpression(result.expression, prefix),
new DeferredConstantValue(result.value, prefix));
- compiler.deferredLoadTask
- .registerConstantDeferredUse(result.value, prefix);
+ compiler.deferredLoadTask.registerConstantDeferredUse(
+ result.value, prefix);
}
return result;
} else if (send.isCall) {
- if (element == compiler.identicalFunction
- && send.argumentCount() == 2) {
+ if (element == compiler.identicalFunction && send.argumentCount() == 2) {
AstConstant left = evaluate(send.argumentsNode.nodes.head);
AstConstant right = evaluate(send.argumentsNode.nodes.tail.head);
if (left == null || right == null) {
@@ -666,12 +629,8 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
ConstantValue result =
constantSystem.identity.fold(left.value, right.value);
if (result != null) {
- return new AstConstant(
- context,
- send,
- new IdenticalConstantExpression(
- left.expression, right.expression),
- result);
+ return new AstConstant(context, send, new IdenticalConstantExpression(
+ left.expression, right.expression), result);
}
}
return signalNotCompileTimeConstant(send);
@@ -691,11 +650,8 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
if (folded == null) {
return signalNotCompileTimeConstant(send);
}
- return new AstConstant(
- context,
- send,
- new UnaryConstantExpression(
- operator, receiverConstant.expression),
+ return new AstConstant(context, send,
+ new UnaryConstantExpression(operator, receiverConstant.expression),
folded);
} else if (send.isOperator && !send.isPostfix) {
assert(send.argumentCount() == 1);
@@ -738,12 +694,8 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
if (folded == null) {
return signalNotCompileTimeConstant(send);
}
- return new AstConstant(
- context,
- send,
- new BinaryConstantExpression(
- left.expression, operator, right.expression),
- folded);
+ return new AstConstant(context, send, new BinaryConstantExpression(
+ left.expression, operator, right.expression), folded);
}
return signalNotCompileTimeConstant(send);
}
@@ -755,9 +707,10 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
} else if (!condition.value.isBool) {
DartType conditionType = condition.value.getType(compiler.coreTypes);
if (isEvaluatingConstant) {
- compiler.reportError(
- node.condition, MessageKind.NOT_ASSIGNABLE,
- {'fromType': conditionType, 'toType': compiler.boolClass.rawType});
+ compiler.reportError(node.condition, MessageKind.NOT_ASSIGNABLE, {
+ 'fromType': conditionType,
+ 'toType': compiler.boolClass.rawType
+ });
return new ErroneousAstConstant(context, node);
}
return null;
@@ -768,16 +721,11 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
return null;
}
BoolConstantValue boolCondition = condition.value;
- return new AstConstant(
- context,
- node,
- new ConditionalConstantExpression(
- condition.expression,
- thenExpression.expression,
- elseExpression.expression),
- boolCondition.primitiveValue
- ? thenExpression.value
- : elseExpression.value);
+ return new AstConstant(context, node, new ConditionalConstantExpression(
+ condition.expression, thenExpression.expression,
+ elseExpression.expression), boolCondition.primitiveValue
+ ? thenExpression.value
+ : elseExpression.value);
}
AstConstant visitSendSet(SendSet node) {
@@ -791,12 +739,9 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
*
* Invariant: [target] must be an implementation element.
*/
- List<AstConstant> evaluateArgumentsToConstructor(
- Node node,
- CallStructure callStructure,
- Link<Node> arguments,
- ConstructorElement target,
- {AstConstant compileArgument(Node node)}) {
+ List<AstConstant> evaluateArgumentsToConstructor(Node node,
+ CallStructure callStructure, Link<Node> arguments,
+ ConstructorElement target, {AstConstant compileArgument(Node node)}) {
assert(invariant(node, target.isImplementation));
AstConstant compileDefaultValue(VariableElement element) {
@@ -810,20 +755,16 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
if (!callStructure.signatureApplies(signature)) {
String name = Elements.constructorNameForDiagnostics(
target.enclosingClass.name, target.name);
- compiler.reportError(
- node,
- MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS,
- {'constructorName': name});
+ compiler.reportError(node, MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS, {
+ 'constructorName': name
+ });
return new List<AstConstant>.filled(
target.functionSignature.parameterCount,
new ErroneousAstConstant(context, node));
}
return callStructure.makeArgumentsList(
- arguments,
- target,
- compileArgument,
- compileDefaultValue);
+ arguments, target, compileArgument, compileDefaultValue);
}
AstConstant visitNewExpression(NewExpression node) {
@@ -847,18 +788,13 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
InterfaceType type = elements.getType(node);
CallStructure callStructure = elements.getSelector(send).callStructure;
- return createConstructorInvocation(
- node, type, constructor, callStructure,
+ return createConstructorInvocation(node, type, constructor, callStructure,
arguments: node.send.arguments);
}
- AstConstant createConstructorInvocation(
- Node node,
- InterfaceType type,
- ConstructorElement constructor,
- CallStructure callStructure,
- {Link<Node> arguments,
- List<AstConstant> normalizedArguments}) {
+ AstConstant createConstructorInvocation(Node node, InterfaceType type,
+ ConstructorElement constructor, CallStructure callStructure,
+ {Link<Node> arguments, List<AstConstant> normalizedArguments}) {
// TODO(ahe): This is nasty: we must eagerly analyze the
// constructor to ensure the redirectionTarget has been computed
// correctly. Find a way to avoid this.
@@ -876,22 +812,15 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
if (implementation.isErroneous) {
// TODO(johnniwinther): This should probably be an [ErroneousAstConstant].
- return new AstConstant(
- context,
- node,
- new ConstructedConstantExpression(
- type,
- constructor,
- callStructure,
- const <ConstantExpression>[]),
+ return new AstConstant(context, node, new ConstructedConstantExpression(
+ type, constructor, callStructure, const <ConstantExpression>[]),
new ConstructedConstantValue(
constructedType, const <FieldElement, ConstantValue>{}));
}
List<AstConstant> concreteArguments;
if (arguments != null) {
- Map<Node, AstConstant> concreteArgumentMap =
- <Node, AstConstant>{};
+ Map<Node, AstConstant> concreteArgumentMap = <Node, AstConstant>{};
for (Link<Node> link = arguments; !link.isEmpty; link = link.tail) {
Node argument = link.head;
NamedArgument namedArgument = argument.asNamedArgument();
@@ -913,26 +842,19 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
if (target == compiler.intEnvironment ||
target == compiler.boolEnvironment ||
target == compiler.stringEnvironment) {
- return createFromEnvironmentConstant(
- node, constructedType, target,
+ return createFromEnvironmentConstant(node, constructedType, target,
callStructure, normalizedArguments, concreteArguments);
} else {
- return makeConstructedConstant(
- compiler, handler, context, node,
- type, constructor,
- constructedType, implementation,
- callStructure, concreteArguments, normalizedArguments);
+ return makeConstructedConstant(compiler, handler, context, node, type,
+ constructor, constructedType, implementation, callStructure,
+ concreteArguments, normalizedArguments);
}
}
- AstConstant createFromEnvironmentConstant(
- Node node,
- InterfaceType type,
- ConstructorElement constructor,
- CallStructure callStructure,
+ AstConstant createFromEnvironmentConstant(Node node, InterfaceType type,
+ ConstructorElement constructor, CallStructure callStructure,
List<AstConstant> normalizedArguments,
List<AstConstant> concreteArguments) {
-
var firstArgument = normalizedArguments[0].value;
ConstantValue defaultValue = normalizedArguments[1].value;
@@ -944,46 +866,51 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
if (!firstArgument.isString) {
DartType type = defaultValue.getType(compiler.coreTypes);
- compiler.reportError(
- normalizedArguments[0].node, MessageKind.NOT_ASSIGNABLE,
- {'fromType': type, 'toType': compiler.stringClass.rawType});
+ compiler.reportError(normalizedArguments[0].node,
+ MessageKind.NOT_ASSIGNABLE, {
+ 'fromType': type,
+ 'toType': compiler.stringClass.rawType
+ });
return null;
}
if (constructor == compiler.intEnvironment &&
!(defaultValue.isNull || defaultValue.isInt)) {
DartType type = defaultValue.getType(compiler.coreTypes);
- compiler.reportError(
- normalizedArguments[1].node, MessageKind.NOT_ASSIGNABLE,
- {'fromType': type, 'toType': compiler.intClass.rawType});
+ compiler.reportError(normalizedArguments[1].node,
+ MessageKind.NOT_ASSIGNABLE, {
+ 'fromType': type,
+ 'toType': compiler.intClass.rawType
+ });
return null;
}
if (constructor == compiler.boolEnvironment &&
!(defaultValue.isNull || defaultValue.isBool)) {
DartType type = defaultValue.getType(compiler.coreTypes);
- compiler.reportError(
- normalizedArguments[1].node, MessageKind.NOT_ASSIGNABLE,
- {'fromType': type, 'toType': compiler.boolClass.rawType});
+ compiler.reportError(normalizedArguments[1].node,
+ MessageKind.NOT_ASSIGNABLE, {
+ 'fromType': type,
+ 'toType': compiler.boolClass.rawType
+ });
return null;
}
if (constructor == compiler.stringEnvironment &&
!(defaultValue.isNull || defaultValue.isString)) {
DartType type = defaultValue.getType(compiler.coreTypes);
- compiler.reportError(
- normalizedArguments[1].node, MessageKind.NOT_ASSIGNABLE,
- {'fromType': type, 'toType': compiler.stringClass.rawType});
+ compiler.reportError(normalizedArguments[1].node,
+ MessageKind.NOT_ASSIGNABLE, {
+ 'fromType': type,
+ 'toType': compiler.stringClass.rawType
+ });
return null;
}
- String name =
- firstArgument.primitiveValue.slowToString();
- String value =
- compiler.fromEnvironment(name);
+ String name = firstArgument.primitiveValue.slowToString();
+ String value = compiler.fromEnvironment(name);
AstConstant createEvaluatedConstant(ConstantValue value) {
-
ConstantExpression expression;
ConstantExpression name = concreteArguments[0].expression;
ConstantExpression defaultValue;
@@ -991,14 +918,14 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
defaultValue = concreteArguments[1].expression;
}
if (constructor == compiler.intEnvironment) {
- expression = new IntFromEnvironmentConstantExpression(
- name, defaultValue);
+ expression =
+ new IntFromEnvironmentConstantExpression(name, defaultValue);
} else if (constructor == compiler.boolEnvironment) {
- expression = new BoolFromEnvironmentConstantExpression(
- name, defaultValue);
+ expression =
+ new BoolFromEnvironmentConstantExpression(name, defaultValue);
} else if (constructor == compiler.stringEnvironment) {
- expression = new StringFromEnvironmentConstantExpression(
- name, defaultValue);
+ expression =
+ new StringFromEnvironmentConstantExpression(name, defaultValue);
}
return new AstConstant(context, node, expression, value);
}
@@ -1008,9 +935,7 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
} else if (constructor == compiler.intEnvironment) {
int number = int.parse(value, onError: (_) => null);
return createEvaluatedConstant(
- (number == null)
- ? defaultValue
- : constantSystem.createInt(number));
+ (number == null) ? defaultValue : constantSystem.createInt(number));
} else if (constructor == compiler.boolEnvironment) {
if (value == 'true') {
return createEvaluatedConstant(constantSystem.createBool(true));
@@ -1026,34 +951,27 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
}
}
- static AstConstant makeConstructedConstant(
- Compiler compiler,
- ConstantCompilerBase handler,
- Element context,
- Node node,
- InterfaceType type,
- ConstructorElement constructor,
- InterfaceType constructedType,
- ConstructorElement target,
- CallStructure callStructure,
- List<AstConstant> concreteArguments,
+ static AstConstant makeConstructedConstant(Compiler compiler,
+ ConstantCompilerBase handler, Element context, Node node,
+ InterfaceType type, ConstructorElement constructor,
+ InterfaceType constructedType, ConstructorElement target,
+ CallStructure callStructure, List<AstConstant> concreteArguments,
List<AstConstant> normalizedArguments) {
if (target.isRedirectingFactory) {
// This happens is case of cyclic redirection.
assert(invariant(node, compiler.compilationFailed,
message: "makeConstructedConstant can only be called with the "
- "effective target: $constructor"));
+ "effective target: $constructor"));
return new ErroneousAstConstant(context, node);
}
- assert(invariant(
- node,
+ assert(invariant(node,
callStructure.signatureApplies(constructor.functionSignature) ||
compiler.compilationFailed,
message: "Call structure $callStructure does not apply to constructor "
- "$constructor."));
+ "$constructor."));
- ConstructorEvaluator evaluator = new ConstructorEvaluator(
- constructedType, target, handler, compiler);
+ ConstructorEvaluator evaluator =
+ new ConstructorEvaluator(constructedType, target, handler, compiler);
evaluator.evaluateConstructorFieldValues(normalizedArguments);
Map<FieldElement, AstConstant> fieldConstants =
evaluator.buildFieldConstants(target.enclosingClass);
@@ -1062,13 +980,8 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
fieldConstants.forEach((FieldElement field, AstConstant astConstant) {
fieldValues[field] = astConstant.value;
});
- return new AstConstant(
- context,
- node,
- new ConstructedConstantExpression(
- type,
- constructor,
- callStructure,
+ return new AstConstant(context, node, new ConstructedConstantExpression(
+ type, constructor, callStructure,
concreteArguments.map((e) => e.expression).toList()),
new ConstructedConstantValue(constructedType, fieldValues));
}
@@ -1088,10 +1001,7 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
if (isEvaluatingConstant) {
error(node, message);
- return new AstConstant(
- context,
- node,
- new ErroneousConstantExpression(),
+ return new AstConstant(context, node, new ErroneousConstantExpression(),
new NullConstantValue());
}
// Else we don't need to do anything. The final handler is only
@@ -1115,16 +1025,12 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
* Invariant: [constructor] must be an implementation element.
*/
ConstructorEvaluator(InterfaceType this.constructedType,
- FunctionElement constructor,
- ConstantCompiler handler,
- Compiler compiler)
+ FunctionElement constructor, ConstantCompiler handler, Compiler compiler)
: this.constructor = constructor,
this.definitions = new Map<Element, AstConstant>(),
this.fieldValues = new Map<Element, AstConstant>(),
- super(handler,
- _analyzeElementEagerly(compiler, constructor),
- compiler,
- isConst: true) {
+ super(handler, _analyzeElementEagerly(compiler, constructor), compiler,
+ isConst: true) {
assert(invariant(constructor, constructor.isImplementation));
}
@@ -1140,27 +1046,24 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
return super.visitSend(send);
}
- void potentiallyCheckType(Node node,
- TypedElement element,
- AstConstant constant) {
+ void potentiallyCheckType(TypedElement element, AstConstant constant) {
if (compiler.enableTypeAssertions) {
DartType elementType = element.type.substByContext(constructedType);
DartType constantType = constant.value.getType(compiler.coreTypes);
- if (!constantSystem.isSubtype(compiler.types,
- constantType, elementType)) {
+ if (!constantSystem.isSubtype(
+ compiler.types, constantType, elementType)) {
compiler.withCurrentElement(constant.element, () {
- compiler.reportError(
- constant.node, MessageKind.NOT_ASSIGNABLE,
- {'fromType': constantType, 'toType': elementType});
+ compiler.reportError(constant.node, MessageKind.NOT_ASSIGNABLE, {
+ 'fromType': constantType,
+ 'toType': elementType
+ });
});
}
}
}
- void updateFieldValue(Node node,
- TypedElement element,
- AstConstant constant) {
- potentiallyCheckType(node, element, constant);
+ void updateFieldValue(Node node, TypedElement element, AstConstant constant) {
+ potentiallyCheckType(element, constant);
fieldValues[element] = constant;
}
@@ -1181,14 +1084,14 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
InitializingFormalElement initializingFormal = parameter;
updateFieldValue(node, initializingFormal.fieldElement, argument);
} else {
- potentiallyCheckType(node, parameter, argument);
+ potentiallyCheckType(parameter, argument);
definitions[parameter] = argument;
}
});
}
- void evaluateSuperOrRedirectSend(List<AstConstant> compiledArguments,
- FunctionElement targetConstructor) {
+ void evaluateSuperOrRedirectSend(
+ List<AstConstant> compiledArguments, FunctionElement targetConstructor) {
ConstructorEvaluator evaluator = new ConstructorEvaluator(
constructedType.asInstanceOf(targetConstructor.enclosingClass),
targetConstructor, handler, compiler);
@@ -1210,12 +1113,8 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
Function compileArgument = (element) => definitions[element];
Function compileConstant = handler.compileConstant;
FunctionElement target = constructor.definingConstructor.implementation;
- CallStructure.addForwardingElementArgumentsToList(
- constructor,
- compiledArguments,
- target,
- compileArgument,
- compileConstant);
+ CallStructure.addForwardingElementArgumentsToList(constructor,
+ compiledArguments, target, compileArgument, compileConstant);
evaluateSuperOrRedirectSend(compiledArguments, target);
return;
}
@@ -1226,18 +1125,16 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
if (initializerList != null) {
for (Link<Node> link = initializerList.nodes;
- !link.isEmpty;
- link = link.tail) {
+ !link.isEmpty;
+ link = link.tail) {
assert(link.head is Send);
- if (link.head is !SendSet) {
+ if (link.head is! SendSet) {
// A super initializer or constructor redirection.
Send call = link.head;
FunctionElement target = elements[call];
- List<AstConstant> compiledArguments =
- evaluateArgumentsToConstructor(
- call, elements.getSelector(call).callStructure,
- call.arguments, target,
- compileArgument: evaluateConstant);
+ List<AstConstant> compiledArguments = evaluateArgumentsToConstructor(
+ call, elements.getSelector(call).callStructure, call.arguments,
+ target, compileArgument: evaluateConstant);
evaluateSuperOrRedirectSend(compiledArguments, target);
foundSuperOrRedirect = true;
} else {
@@ -1266,8 +1163,8 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
// already and compilation will fail anyway. So just ignore that case.
if (targetConstructor != null) {
List<AstConstant> compiledArguments = evaluateArgumentsToConstructor(
- functionNode, CallStructure.NO_ARGS,
- const Link<Node>(), targetConstructor);
+ functionNode, CallStructure.NO_ARGS, const Link<Node>(),
+ targetConstructor);
evaluateSuperOrRedirectSend(compiledArguments, targetConstructor);
}
}
@@ -1291,22 +1188,24 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
/// inheritance chain of [classElement].
Map<FieldElement, AstConstant> buildFieldConstants(
ClassElement classElement) {
- Map<FieldElement, AstConstant> fieldConstants =
- <FieldElement, AstConstant>{};
- classElement.implementation.forEachInstanceField(
- (ClassElement enclosing, FieldElement field) {
- AstConstant fieldValue = fieldValues[field];
- if (fieldValue == null) {
- // Use the default value.
- ConstantExpression fieldExpression = handler.compileConstant(field);
- fieldValue = new AstConstant.fromDefaultValue(
- field,
- fieldExpression,
- handler.getConstantValue(fieldExpression));
- }
- fieldConstants[field] = fieldValue;
- },
- includeSuperAndInjectedMembers: true);
+ Map<FieldElement, AstConstant> fieldConstants = <FieldElement, AstConstant>{
+ };
+ classElement.implementation
+ .forEachInstanceField((ClassElement enclosing, FieldElement field) {
+ AstConstant fieldValue = fieldValues[field];
+ if (fieldValue == null) {
+ // Use the default value.
+ ConstantExpression fieldExpression =
+ handler.internalCompileVariable(field, true, false);
+ fieldValue = new AstConstant.fromDefaultValue(
+ field, fieldExpression, handler.getConstantValue(fieldExpression));
+ // TODO(het): If the field value doesn't typecheck due to the type
+ // variable in the constructor invocation, then report the error on the
+ // invocation rather than the field.
+ potentiallyCheckType(field, fieldValue);
+ }
+ fieldConstants[field] = fieldValue;
+ }, includeSuperAndInjectedMembers: true);
return fieldConstants;
}
}
@@ -1328,15 +1227,11 @@ class AstConstant {
AstConstant(this.element, this.node, this.expression, this.value);
- factory AstConstant.fromDefaultValue(
- VariableElement element,
- ConstantExpression constant,
- ConstantValue value) {
- return new AstConstant(
- element,
- element.initializer != null ? element.initializer : element.node,
- constant,
- value);
+ factory AstConstant.fromDefaultValue(VariableElement element,
+ ConstantExpression constant, ConstantValue value) {
+ return new AstConstant(element, element.initializer != null
+ ? element.initializer
+ : element.node, constant, value);
}
String toString() => expression.toString();
@@ -1344,8 +1239,7 @@ class AstConstant {
/// A synthetic constant used to recover from errors.
class ErroneousAstConstant extends AstConstant {
- ErroneousAstConstant(Element element, Node node)
- : super(element, node,
+ ErroneousAstConstant(Element element, Node node) : super(element, node,
// TODO(johnniwinther): Return a [NonConstantValue] instead.
new ErroneousConstantExpression(), new NullConstantValue());
}
« no previous file with comments | « no previous file | pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698