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

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

Issue 1118423003: Handle default values on constant redirecting factories. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 8 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/type_variable_handler.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 c16a09ceba8378ce060892a619fe6d0c31164acc..e3f0c50d6c7c445e561919e3d76f1e8ba1bff13d 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -12,6 +12,7 @@ import 'dart_types.dart';
import 'dart2jslib.dart' show Compiler, CompilerTask, MessageKind, invariant;
import 'elements/elements.dart';
import 'elements/modelx.dart' show FunctionElementX;
+import 'helpers/helpers.dart';
import 'resolution/resolution.dart';
import 'resolution/operators.dart';
import 'tree/tree.dart';
@@ -461,10 +462,10 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
new StringConstantExpression(
text,
constantSystem.createString(new LiteralDartString(text))))];
- AstConstant constant = makeConstructedConstant(
- compiler, handler, context, node, type, compiler.symbolConstructor,
- CallStructure.ONE_ARG,
- arguments, arguments);
+ ConstructorElement constructor = compiler.symbolConstructor;
+ AstConstant constant = createConstructorInvocation(
+ node, type, constructor, CallStructure.ONE_ARG,
+ normalizedArguments: arguments);
return new AstConstant(
context, node, new SymbolConstantExpression(constant.value, text));
}
@@ -713,7 +714,7 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
}
Send send = node.send;
- FunctionElement constructor = elements[send];
+ ConstructorElement constructor = elements[send];
if (Elements.isUnresolved(constructor)) {
return signalNotCompileTimeConstant(node);
}
@@ -725,119 +726,168 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
message: MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION);
}
+ InterfaceType type = elements.getType(node);
+ CallStructure callStructure = elements.getSelector(send).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}) {
// 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.
compiler.analyzeElement(constructor.declaration);
- InterfaceType type = elements.getType(node);
- CallStructure callStructure = elements.getSelector(send).callStructure;
+ // The redirection chain of this element may not have been resolved through
+ // a post-process action, so we have to make sure it is done here.
+ compiler.resolver.resolveRedirectionChain(constructor, node);
+ InterfaceType constructedType =
+ constructor.computeEffectiveTargetType(type);
+ ConstructorElement target = constructor.effectiveTarget;
+ // The constructor must be an implementation to ensure that field
+ // initializers are handled correctly.
+ ConstructorElement implementation = target.implementation;
- Map<Node, AstConstant> concreteArgumentMap =
- <Node, AstConstant>{};
- for (Link<Node> link = send.arguments; !link.isEmpty; link = link.tail) {
- Node argument = link.head;
- NamedArgument namedArgument = argument.asNamedArgument();
- if (namedArgument != null) {
- argument = namedArgument.expression;
- }
- concreteArgumentMap[argument] = evaluateConstant(argument);
+ if (implementation.isErroneous) {
+ return new AstConstant(
+ context, node, new ConstructedConstantExpression(
+ new ConstructedConstantValue(
+ constructedType, const <FieldElement, ConstantValue>{}),
+ type,
+ constructor,
+ callStructure,
+ const <ConstantExpression>[]));
}
- List<AstConstant> normalizedArguments =
- evaluateArgumentsToConstructor(
- node, callStructure, send.arguments, constructor.implementation,
- compileArgument: (node) => concreteArgumentMap[node]);
- List<AstConstant> concreteArguments =
- concreteArgumentMap.values.toList();
+ List<AstConstant> concreteArguments;
+ if (arguments != null) {
+ Map<Node, AstConstant> concreteArgumentMap =
+ <Node, AstConstant>{};
+ for (Link<Node> link = arguments; !link.isEmpty; link = link.tail) {
+ Node argument = link.head;
+ NamedArgument namedArgument = argument.asNamedArgument();
+ if (namedArgument != null) {
+ argument = namedArgument.expression;
+ }
+ concreteArgumentMap[argument] = evaluateConstant(argument);
+ }
- if (constructor == compiler.intEnvironment ||
- constructor == compiler.boolEnvironment ||
- constructor == compiler.stringEnvironment) {
+ normalizedArguments = evaluateArgumentsToConstructor(
+ node, callStructure, arguments, implementation,
+ compileArgument: (node) => concreteArgumentMap[node]);
+ concreteArguments = concreteArgumentMap.values.toList();
+ } else {
+ assert(normalizedArguments != null);
+ concreteArguments = normalizedArguments;
+ }
- AstConstant createEvaluatedConstant(ConstantValue value) {
- return new AstConstant(
- context, node, new ConstructedConstantExpression(
- value,
- type,
- constructor,
- elements.getSelector(send).callStructure,
- concreteArguments.map((e) => e.expression).toList()));
- }
+ if (target == compiler.intEnvironment ||
+ target == compiler.boolEnvironment ||
+ target == compiler.stringEnvironment) {
+ return createFromEnvironmentConstant(
+ node, constructedType, target,
+ callStructure, normalizedArguments, concreteArguments);
+ } else {
+ return makeConstructedConstant(
+ compiler, handler, context, node,
+ type, constructor,
+ constructedType, implementation,
+ callStructure, concreteArguments, normalizedArguments);
+ }
+ }
- var firstArgument = normalizedArguments[0].value;
- ConstantValue defaultValue = normalizedArguments[1].value;
+ AstConstant createFromEnvironmentConstant(
+ Node node,
+ InterfaceType type,
+ ConstructorElement constructor,
+ CallStructure callStructure,
+ List<AstConstant> normalizedArguments,
+ List<AstConstant> concreteArguments) {
+ AstConstant createEvaluatedConstant(ConstantValue value) {
+ return new AstConstant(
+ context, node, new ConstructedConstantExpression(
+ value,
+ type,
+ constructor,
+ callStructure,
+ concreteArguments.map((e) => e.expression).toList()));
+ }
- if (firstArgument.isNull) {
- compiler.reportError(
- send.arguments.head, MessageKind.NULL_NOT_ALLOWED);
- return null;
- }
+ var firstArgument = normalizedArguments[0].value;
+ ConstantValue defaultValue = normalizedArguments[1].value;
- if (!firstArgument.isString) {
- DartType type = defaultValue.getType(compiler.coreTypes);
- compiler.reportError(
- send.arguments.head, MessageKind.NOT_ASSIGNABLE,
- {'fromType': type, 'toType': compiler.stringClass.rawType});
- return null;
- }
+ if (firstArgument.isNull) {
+ compiler.reportError(
+ normalizedArguments[0].node, MessageKind.NULL_NOT_ALLOWED);
+ return null;
+ }
- if (constructor == compiler.intEnvironment &&
- !(defaultValue.isNull || defaultValue.isInt)) {
- DartType type = defaultValue.getType(compiler.coreTypes);
- compiler.reportError(
- send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE,
- {'fromType': type, 'toType': compiler.intClass.rawType});
- return null;
- }
+ if (!firstArgument.isString) {
+ DartType type = defaultValue.getType(compiler.coreTypes);
+ compiler.reportError(
+ normalizedArguments[0].node, MessageKind.NOT_ASSIGNABLE,
+ {'fromType': type, 'toType': compiler.stringClass.rawType});
+ return null;
+ }
- if (constructor == compiler.boolEnvironment &&
- !(defaultValue.isNull || defaultValue.isBool)) {
- DartType type = defaultValue.getType(compiler.coreTypes);
- compiler.reportError(
- send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE,
- {'fromType': type, 'toType': compiler.boolClass.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});
+ return null;
+ }
- if (constructor == compiler.stringEnvironment &&
- !(defaultValue.isNull || defaultValue.isString)) {
- DartType type = defaultValue.getType(compiler.coreTypes);
- compiler.reportError(
- send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE,
- {'fromType': type, 'toType': compiler.stringClass.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});
+ return null;
+ }
- String value =
- compiler.fromEnvironment(firstArgument.primitiveValue.slowToString());
+ 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});
+ return null;
+ }
- if (value == null) {
- return createEvaluatedConstant(defaultValue);
- } else if (constructor == compiler.intEnvironment) {
- int number = int.parse(value, onError: (_) => null);
- return createEvaluatedConstant(
- (number == null)
- ? defaultValue
- : constantSystem.createInt(number));
- } else if (constructor == compiler.boolEnvironment) {
- if (value == 'true') {
- return createEvaluatedConstant(constantSystem.createBool(true));
- } else if (value == 'false') {
- return createEvaluatedConstant(constantSystem.createBool(false));
- } else {
- return createEvaluatedConstant(defaultValue);
- }
+ String value =
+ compiler.fromEnvironment(firstArgument.primitiveValue.slowToString());
+
+ if (value == null) {
+ return createEvaluatedConstant(defaultValue);
+ } else if (constructor == compiler.intEnvironment) {
+ int number = int.parse(value, onError: (_) => null);
+ return createEvaluatedConstant(
+ (number == null)
+ ? defaultValue
+ : constantSystem.createInt(number));
+ } else if (constructor == compiler.boolEnvironment) {
+ if (value == 'true') {
+ return createEvaluatedConstant(constantSystem.createBool(true));
+ } else if (value == 'false') {
+ return createEvaluatedConstant(constantSystem.createBool(false));
} else {
- assert(constructor == compiler.stringEnvironment);
- return createEvaluatedConstant(
- constantSystem.createString(new DartString.literal(value)));
+ return createEvaluatedConstant(defaultValue);
}
} else {
- return makeConstructedConstant(
- compiler, handler, context,
- node, type, constructor, callStructure,
- concreteArguments, normalizedArguments);
+ assert(constructor == compiler.stringEnvironment);
+ return createEvaluatedConstant(
+ constantSystem.createString(new DartString.literal(value)));
}
}
@@ -848,31 +898,24 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
Node node,
InterfaceType type,
ConstructorElement constructor,
+ InterfaceType constructedType,
+ ConstructorElement target,
CallStructure callStructure,
List<AstConstant> concreteArguments,
List<AstConstant> normalizedArguments) {
+ assert(invariant(node, !target.isRedirectingFactory,
+ message: "makeConstructedConstant can only be called with the "
+ "effective target: $constructor"));
assert(invariant(node, callStructure.signatureApplies(constructor) ||
compiler.compilationFailed,
message: "Call structure $callStructure does not apply to constructor "
"$constructor."));
- // The redirection chain of this element may not have been resolved through
- // a post-process action, so we have to make sure it is done here.
- compiler.resolver.resolveRedirectionChain(constructor, node);
- InterfaceType constructedType =
- constructor.computeEffectiveTargetType(type);
- ConstructorElement target = constructor.effectiveTarget;
- ClassElement classElement = target.enclosingClass;
- // The constructor must be an implementation to ensure that field
- // initializers are handled correctly.
- target = target.implementation;
- assert(invariant(node, target.isImplementation));
-
ConstructorEvaluator evaluator = new ConstructorEvaluator(
constructedType, target, handler, compiler);
evaluator.evaluateConstructorFieldValues(normalizedArguments);
Map<FieldElement, AstConstant> fieldConstants =
- evaluator.buildFieldConstants(classElement);
+ evaluator.buildFieldConstants(target.enclosingClass);
Map<FieldElement, ConstantValue> fieldValues =
<FieldElement, ConstantValue>{};
fieldConstants.forEach((FieldElement field, AstConstant astConstant) {
« no previous file with comments | « no previous file | pkg/compiler/lib/src/js_backend/type_variable_handler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698