| 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 8853b2fec78f9f3f22c8f4f084d810c95f711c54..a65ffaa557c56d8e8b13bfc45e38285769249ed4 100644
|
| --- a/pkg/compiler/lib/src/compile_time_constants.dart
|
| +++ b/pkg/compiler/lib/src/compile_time_constants.dart
|
| @@ -964,6 +964,16 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
|
| if (constructor.isFromEnvironmentConstructor) {
|
| return createFromEnvironmentConstant(node, constructedType, constructor,
|
| callStructure, normalizedArguments, concreteArguments);
|
| + } else if (compiler.serialization.isDeserialized(constructor)) {
|
| + ConstructedConstantExpression expression =
|
| + new ConstructedConstantExpression(type, constructor, callStructure,
|
| + concreteArguments.map((c) => c.expression).toList());
|
| + return new AstConstant(
|
| + context,
|
| + node,
|
| + expression,
|
| + expression.evaluate(
|
| + new _CompilerEnvironment(compiler), constantSystem));
|
| } else {
|
| return makeConstructedConstant(
|
| compiler,
|
| @@ -1088,7 +1098,7 @@ class CompileTimeConstantEvaluator extends Visitor<AstConstant> {
|
| List<AstConstant> concreteArguments,
|
| List<AstConstant> normalizedArguments) {
|
| if (target.isRedirectingFactory) {
|
| - // This happens is case of cyclic redirection.
|
| + // This happens in case of cyclic redirection.
|
| assert(invariant(node, compiler.compilationFailed,
|
| message: "makeConstructedConstant can only be called with the "
|
| "effective target: $constructor"));
|
| @@ -1162,8 +1172,11 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
|
| *
|
| * Invariant: [constructor] must be an implementation element.
|
| */
|
| - ConstructorEvaluator(InterfaceType this.constructedType,
|
| - FunctionElement constructor, ConstantCompiler handler, Compiler compiler)
|
| + ConstructorEvaluator(
|
| + InterfaceType this.constructedType,
|
| + ConstructorElement constructor,
|
| + ConstantCompiler handler,
|
| + Compiler compiler)
|
| : this.constructor = constructor,
|
| this.definitions = new Map<Element, AstConstant>(),
|
| this.fieldValues = new Map<Element, AstConstant>(),
|
| @@ -1174,6 +1187,9 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
|
| }
|
|
|
| @override
|
| + Element get context => resolvedAst.element;
|
| +
|
| + @override
|
| TreeElements get elements => resolvedAst.elements;
|
|
|
| AstConstant visitSend(Send send) {
|
| @@ -1233,18 +1249,33 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
|
| });
|
| }
|
|
|
| - void evaluateSuperOrRedirectSend(
|
| - List<AstConstant> compiledArguments, FunctionElement targetConstructor) {
|
| - ConstructorEvaluator evaluator = new ConstructorEvaluator(
|
| - constructedType.asInstanceOf(targetConstructor.enclosingClass),
|
| - targetConstructor,
|
| - handler,
|
| - compiler);
|
| - evaluator.evaluateConstructorFieldValues(compiledArguments);
|
| - // Copy over the fieldValues from the super/redirect-constructor.
|
| - // No need to go through [updateFieldValue] because the
|
| - // assignments have already been checked in checked mode.
|
| - evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value);
|
| + void evaluateSuperOrRedirectSend(List<AstConstant> compiledArguments,
|
| + CallStructure callStructure, ConstructorElement targetConstructor) {
|
| + InterfaceType type =
|
| + constructedType.asInstanceOf(targetConstructor.enclosingClass);
|
| + if (compiler.serialization.isDeserialized(targetConstructor)) {
|
| + List<ConstantExpression> arguments =
|
| + compiledArguments.map((c) => c.expression).toList();
|
| + ConstructedConstantExpression expression =
|
| + new ConstructedConstantExpression(
|
| + type, targetConstructor, callStructure, arguments);
|
| +
|
| + Map<FieldElement, ConstantExpression> fields =
|
| + expression.computeInstanceFields();
|
| + fields.forEach((FieldElement field, ConstantExpression expression) {
|
| + ConstantValue value = expression.evaluate(
|
| + new _CompilerEnvironment(compiler), constantSystem);
|
| + fieldValues[field] = new AstConstant(context, null, expression, value);
|
| + });
|
| + } else {
|
| + ConstructorEvaluator evaluator =
|
| + new ConstructorEvaluator(type, targetConstructor, handler, compiler);
|
| + evaluator.evaluateConstructorFieldValues(compiledArguments);
|
| + // Copy over the fieldValues from the super/redirect-constructor.
|
| + // No need to go through [updateFieldValue] because the
|
| + // assignments have already been checked in checked mode.
|
| + evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value);
|
| + }
|
| }
|
|
|
| /**
|
| @@ -1261,7 +1292,9 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
|
| FunctionElement target = constructor.definingConstructor.implementation;
|
| CallStructure.addForwardingElementArgumentsToList(constructor,
|
| compiledArguments, target, compileArgument, compileConstant);
|
| - evaluateSuperOrRedirectSend(compiledArguments, target);
|
| + CallStructure callStructure =
|
| + new CallStructure.fromSignature(target.functionSignature);
|
| + evaluateSuperOrRedirectSend(compiledArguments, callStructure, target);
|
| return;
|
| }
|
| FunctionExpression functionNode = resolvedAst.node;
|
| @@ -1279,14 +1312,14 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
|
| Send call = link.head;
|
| FunctionElement target = elements[call];
|
| if (!target.isMalformed) {
|
| + CallStructure callStructure =
|
| + elements.getSelector(call).callStructure;
|
| List<AstConstant> compiledArguments =
|
| evaluateArgumentsToConstructor(
|
| - call,
|
| - elements.getSelector(call).callStructure,
|
| - call.arguments,
|
| - target,
|
| + call, callStructure, call.arguments, target,
|
| compileArgument: evaluateConstant);
|
| - evaluateSuperOrRedirectSend(compiledArguments, target);
|
| + evaluateSuperOrRedirectSend(
|
| + compiledArguments, callStructure, target);
|
| }
|
| foundSuperOrRedirect = true;
|
| } else {
|
| @@ -1314,12 +1347,14 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
|
| // If we do not find a default constructor, an error was reported
|
| // already and compilation will fail anyway. So just ignore that case.
|
| if (targetConstructor != null) {
|
| + CallStructure callStructure = CallStructure.NO_ARGS;
|
| List<AstConstant> compiledArguments = evaluateArgumentsToConstructor(
|
| functionNode,
|
| - CallStructure.NO_ARGS,
|
| + callStructure,
|
| const Link<Node>(),
|
| targetConstructor);
|
| - evaluateSuperOrRedirectSend(compiledArguments, targetConstructor);
|
| + evaluateSuperOrRedirectSend(
|
| + compiledArguments, callStructure, targetConstructor);
|
| }
|
| }
|
| }
|
|
|