| Index: pkg/compiler/lib/src/resolution/send_resolver.dart
|
| diff --git a/pkg/compiler/lib/src/resolution/send_resolver.dart b/pkg/compiler/lib/src/resolution/send_resolver.dart
|
| index 5910234a3252c6f13811bf11d901444710070896..ea3bcd5d9258bbfa88012f64eb3596d144478067 100644
|
| --- a/pkg/compiler/lib/src/resolution/send_resolver.dart
|
| +++ b/pkg/compiler/lib/src/resolution/send_resolver.dart
|
| @@ -541,6 +541,7 @@ abstract class SendResolverMixin {
|
|
|
| ConstructorAccessSemantics computeConstructorAccessSemantics(
|
| ConstructorElement constructor,
|
| + CallStructure callStructure,
|
| DartType type,
|
| {bool mustBeConstant: false}) {
|
| if (mustBeConstant && !constructor.isConst) {
|
| @@ -557,48 +558,57 @@ abstract class SendResolverMixin {
|
| }
|
| return new ConstructorAccessSemantics(
|
| ConstructorAccessKind.UNRESOLVED_TYPE, constructor, type);
|
| - } else if (constructor.isRedirectingFactory) {
|
| - ConstructorElement effectiveTarget = constructor.effectiveTarget;
|
| - if (effectiveTarget == constructor ||
|
| - effectiveTarget.isErroneous ||
|
| - (mustBeConstant && !effectiveTarget.isConst)) {
|
| + } else {
|
| + if (!callStructure.signatureApplies(constructor)) {
|
| return new ConstructorAccessSemantics(
|
| - ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY,
|
| + ConstructorAccessKind.INCOMPATIBLE,
|
| constructor,
|
| type);
|
| }
|
| - ConstructorAccessSemantics effectiveTargetSemantics =
|
| - computeConstructorAccessSemantics(
|
| - effectiveTarget,
|
| - constructor.computeEffectiveTargetType(type));
|
| - if (effectiveTargetSemantics.isErroneous) {
|
| + if (constructor.isRedirectingFactory) {
|
| + ConstructorElement effectiveTarget = constructor.effectiveTarget;
|
| + if (effectiveTarget == constructor ||
|
| + effectiveTarget.isErroneous ||
|
| + (mustBeConstant && !effectiveTarget.isConst)) {
|
| + return new ConstructorAccessSemantics(
|
| + ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY,
|
| + constructor,
|
| + type);
|
| + }
|
| + ConstructorAccessSemantics effectiveTargetSemantics =
|
| + computeConstructorAccessSemantics(
|
| + effectiveTarget,
|
| + callStructure,
|
| + constructor.computeEffectiveTargetType(type));
|
| + if (effectiveTargetSemantics.isErroneous) {
|
| + return new RedirectingFactoryConstructorAccessSemantics(
|
| + ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY,
|
| + constructor,
|
| + type,
|
| + effectiveTargetSemantics);
|
| + }
|
| return new RedirectingFactoryConstructorAccessSemantics(
|
| - ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY,
|
| + ConstructorAccessKind.REDIRECTING_FACTORY,
|
| constructor,
|
| type,
|
| effectiveTargetSemantics);
|
| + } else if (constructor.isFactoryConstructor) {
|
| + return new ConstructorAccessSemantics(
|
| + ConstructorAccessKind.FACTORY, constructor, type);
|
| + } else if (constructor.isRedirectingGenerative) {
|
| + if (constructor.enclosingClass.isAbstract) {
|
| + return new ConstructorAccessSemantics(
|
| + ConstructorAccessKind.ABSTRACT, constructor, type);
|
| + }
|
| + return new ConstructorAccessSemantics(
|
| + ConstructorAccessKind.REDIRECTING_GENERATIVE, constructor, type);
|
| + } else if (constructor.enclosingClass.isAbstract) {
|
| + return new ConstructorAccessSemantics(
|
| + ConstructorAccessKind.ABSTRACT, constructor, type);
|
| + } else {
|
| + return new ConstructorAccessSemantics(
|
| + ConstructorAccessKind.GENERATIVE, constructor, type);
|
| }
|
| - return new RedirectingFactoryConstructorAccessSemantics(
|
| - ConstructorAccessKind.REDIRECTING_FACTORY,
|
| - constructor,
|
| - type,
|
| - effectiveTargetSemantics);
|
| - } else if (constructor.isFactoryConstructor) {
|
| - return new ConstructorAccessSemantics(
|
| - ConstructorAccessKind.FACTORY, constructor, type);
|
| - } else if (constructor.isRedirectingGenerative) {
|
| - if (constructor.enclosingClass.isAbstract) {
|
| - return new ConstructorAccessSemantics(
|
| - ConstructorAccessKind.ABSTRACT, constructor, type);
|
| - }
|
| - return new ConstructorAccessSemantics(
|
| - ConstructorAccessKind.REDIRECTING_GENERATIVE, constructor, type);
|
| - } else if (constructor.enclosingClass.isAbstract) {
|
| - return new ConstructorAccessSemantics(
|
| - ConstructorAccessKind.ABSTRACT, constructor, type);
|
| - } else {
|
| - return new ConstructorAccessSemantics(
|
| - ConstructorAccessKind.GENERATIVE, constructor, type);
|
| }
|
| }
|
|
|
| @@ -609,17 +619,37 @@ abstract class SendResolverMixin {
|
|
|
| ConstructorAccessSemantics constructorAccessSemantics =
|
| computeConstructorAccessSemantics(
|
| - element, type, mustBeConstant: node.isConst);
|
| + element, selector.callStructure, type,
|
| + mustBeConstant: node.isConst);
|
| if (node.isConst) {
|
| ConstantExpression constant = elements.getConstant(node);
|
| if (constructorAccessSemantics.isErroneous ||
|
| - constant is! ConstructedConstantExpression) {
|
| + constant == null ||
|
| + constant.kind == ConstantExpressionKind.ERRONEOUS) {
|
| // This is a non-constant constant constructor invocation, like
|
| // `const Const(method())`.
|
| constructorAccessSemantics = new ConstructorAccessSemantics(
|
| ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, element, type);
|
| } else {
|
| - return new ConstInvokeStructure(constant);
|
| + ConstantInvokeKind kind;
|
| + switch (constant.kind) {
|
| + case ConstantExpressionKind.CONSTRUCTED:
|
| + kind = ConstantInvokeKind.CONSTRUCTED;
|
| + break;
|
| + case ConstantExpressionKind.BOOL_FROM_ENVIRONMENT:
|
| + kind = ConstantInvokeKind.BOOL_FROM_ENVIRONMENT;
|
| + break;
|
| + case ConstantExpressionKind.INT_FROM_ENVIRONMENT:
|
| + kind = ConstantInvokeKind.INT_FROM_ENVIRONMENT;
|
| + break;
|
| + case ConstantExpressionKind.STRING_FROM_ENVIRONMENT:
|
| + kind = ConstantInvokeKind.STRING_FROM_ENVIRONMENT;
|
| + break;
|
| + default:
|
| + return internalError(
|
| + node, "Unexpected constant kind $kind: ${constant.getText()}");
|
| + }
|
| + return new ConstInvokeStructure(kind, constant);
|
| }
|
| }
|
| return new NewInvokeStructure(constructorAccessSemantics, selector);
|
|
|