| Index: pkg/compiler/lib/src/resolution/send_structure.dart
|
| diff --git a/pkg/compiler/lib/src/resolution/send_structure.dart b/pkg/compiler/lib/src/resolution/send_structure.dart
|
| index 06c58deb90ea0e7a7ce8b3f1745cb58351331959..5daa7bd117401973d362cf46e85b67630d440038 100644
|
| --- a/pkg/compiler/lib/src/resolution/send_structure.dart
|
| +++ b/pkg/compiler/lib/src/resolution/send_structure.dart
|
| @@ -8,6 +8,8 @@ import '../common.dart';
|
| import '../constants/expressions.dart';
|
| import '../dart_types.dart';
|
| import '../elements/elements.dart';
|
| +import '../resolution/tree_elements.dart' show
|
| + TreeElements;
|
| import '../tree/tree.dart';
|
| import '../universe/call_structure.dart' show
|
| CallStructure;
|
| @@ -2642,22 +2644,45 @@ class NewInvokeStructure<R, A> extends NewStructure<R, A> {
|
| R dispatch(SemanticSendVisitor<R, A> visitor, NewExpression node, A arg) {
|
| switch (semantics.kind) {
|
| case ConstructorAccessKind.GENERATIVE:
|
| + ConstructorElement constructor = semantics.element;
|
| + if (constructor.isRedirectingGenerative) {
|
| + return visitor.visitRedirectingGenerativeConstructorInvoke(
|
| + node, constructor, semantics.type,
|
| + node.send.argumentsNode, callStructure, arg);
|
| + }
|
| return visitor.visitGenerativeConstructorInvoke(
|
| - node, semantics.element, semantics.type,
|
| - node.send.argumentsNode, callStructure, arg);
|
| - case ConstructorAccessKind.REDIRECTING_GENERATIVE:
|
| - return visitor.visitRedirectingGenerativeConstructorInvoke(
|
| - node, semantics.element, semantics.type,
|
| + node, constructor, semantics.type,
|
| node.send.argumentsNode, callStructure, arg);
|
| case ConstructorAccessKind.FACTORY:
|
| - return visitor.visitFactoryConstructorInvoke(
|
| - node, semantics.element, semantics.type,
|
| - node.send.argumentsNode, callStructure, arg);
|
| - case ConstructorAccessKind.REDIRECTING_FACTORY:
|
| - return visitor.visitRedirectingFactoryConstructorInvoke(
|
| - node, semantics.element, semantics.type,
|
| - semantics.effectiveTargetSemantics.element,
|
| - semantics.effectiveTargetSemantics.type,
|
| + ConstructorElement constructor = semantics.element;
|
| + if (constructor.isRedirectingFactory) {
|
| + if (constructor.isEffectiveTargetMalformed) {
|
| + return visitor.visitUnresolvedRedirectingFactoryConstructorInvoke(
|
| + node, semantics.element, semantics.type,
|
| + node.send.argumentsNode, callStructure, arg);
|
| + }
|
| + ConstructorElement effectiveTarget = constructor.effectiveTarget;
|
| + InterfaceType effectiveTargetType =
|
| + constructor.computeEffectiveTargetType(semantics.type);
|
| + if (callStructure.signatureApplies(
|
| + effectiveTarget.functionSignature)) {
|
| + return visitor.visitRedirectingFactoryConstructorInvoke(
|
| + node, semantics.element, semantics.type,
|
| + effectiveTarget, effectiveTargetType,
|
| + node.send.argumentsNode, callStructure, arg);
|
| + } else {
|
| + return visitor.visitUnresolvedRedirectingFactoryConstructorInvoke(
|
| + node, semantics.element, semantics.type,
|
| + node.send.argumentsNode, callStructure, arg);
|
| + }
|
| + }
|
| + if (callStructure.signatureApplies(constructor.functionSignature)) {
|
| + return visitor.visitFactoryConstructorInvoke(
|
| + node, constructor, semantics.type,
|
| + node.send.argumentsNode, callStructure, arg);
|
| + }
|
| + return visitor.visitConstructorIncompatibleInvoke(
|
| + node, constructor, semantics.type,
|
| node.send.argumentsNode, callStructure, arg);
|
| case ConstructorAccessKind.ABSTRACT:
|
| return visitor.visitAbstractClassConstructorInvoke(
|
| @@ -2675,10 +2700,6 @@ class NewInvokeStructure<R, A> extends NewStructure<R, A> {
|
| return visitor.errorNonConstantConstructorInvoke(
|
| node, semantics.element, semantics.type,
|
| node.send.argumentsNode, callStructure, arg);
|
| - case ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY:
|
| - return visitor.visitUnresolvedRedirectingFactoryConstructorInvoke(
|
| - node, semantics.element, semantics.type,
|
| - node.send.argumentsNode, callStructure, arg);
|
| case ConstructorAccessKind.INCOMPATIBLE:
|
| return visitor.visitConstructorIncompatibleInvoke(
|
| node, semantics.element, semantics.type,
|
| @@ -2723,6 +2744,50 @@ class ConstInvokeStructure<R, A> extends NewStructure<R, A> {
|
| }
|
| }
|
|
|
| +/// A constant constructor invocation that couldn't be determined fully during
|
| +/// resolution.
|
| +// TODO(johnniwinther): Remove this when all constants are computed during
|
| +// resolution.
|
| +class LateConstInvokeStructure<R, A> extends NewStructure<R, A> {
|
| + final TreeElements elements;
|
| +
|
| + LateConstInvokeStructure(this.elements);
|
| +
|
| + R dispatch(SemanticSendVisitor<R, A> visitor, NewExpression node, A arg) {
|
| + Element element = elements[node.send];
|
| + Selector selector = elements.getSelector(node.send);
|
| + DartType type = elements.getType(node);
|
| + ConstantExpression constant = elements.getConstant(node);
|
| + if (element.isMalformed ||
|
| + constant == null ||
|
| + constant.kind == ConstantExpressionKind.ERRONEOUS) {
|
| + // This is a non-constant constant constructor invocation, like
|
| + // `const Const(method())`.
|
| + return visitor.errorNonConstantConstructorInvoke(
|
| + node, element, type,
|
| + node.send.argumentsNode, selector.callStructure, arg);
|
| + } else {
|
| + ConstantInvokeKind kind;
|
| + switch (constant.kind) {
|
| + case ConstantExpressionKind.CONSTRUCTED:
|
| + return visitor.visitConstConstructorInvoke(node, constant, arg);
|
| + case ConstantExpressionKind.BOOL_FROM_ENVIRONMENT:
|
| + return visitor.visitBoolFromEnvironmentConstructorInvoke(
|
| + node, constant, arg);
|
| + case ConstantExpressionKind.INT_FROM_ENVIRONMENT:
|
| + return visitor.visitIntFromEnvironmentConstructorInvoke(
|
| + node, constant, arg);
|
| + case ConstantExpressionKind.STRING_FROM_ENVIRONMENT:
|
| + return visitor.visitStringFromEnvironmentConstructorInvoke(
|
| + node, constant, arg);
|
| + default:
|
| + throw new SpannableAssertionFailure(
|
| + node, "Unexpected constant kind $kind: ${constant.getText()}");
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| /// The structure of a parameter declaration.
|
| abstract class ParameterStructure<R, A> {
|
| final VariableDefinitions definitions;
|
|
|