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); |