Index: pkg/compiler/lib/src/ssa/kernel_impact.dart |
diff --git a/pkg/compiler/lib/src/ssa/kernel_impact.dart b/pkg/compiler/lib/src/ssa/kernel_impact.dart |
index 4da2b684f4de47b5d1293d501cc3dc322f111dac..15efe23e8b2da8e019c868e3dae9b1b49672008c 100644 |
--- a/pkg/compiler/lib/src/ssa/kernel_impact.dart |
+++ b/pkg/compiler/lib/src/ssa/kernel_impact.dart |
@@ -195,8 +195,44 @@ class KernelImpactBuilder extends ir.Visitor { |
void visitStaticInvocation(ir.StaticInvocation invocation) { |
_visitArguments(invocation.arguments); |
Element target = astAdapter.getElement(invocation.target).declaration; |
- impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
- target, astAdapter.getCallStructure(invocation.arguments))); |
+ if (target.isFactoryConstructor) { |
+ impactBuilder.registerStaticUse(new StaticUse.constructorInvoke( |
+ target, astAdapter.getCallStructure(invocation.arguments))); |
+ // TODO(johnniwinther): We should not mark the type as instantiated but |
+ // rather follow the type arguments directly. |
+ // |
+ // Consider this: |
+ // |
+ // abstract class A<T> { |
+ // factory A.regular() => new B<T>(); |
+ // factory A.redirect() = B<T>; |
+ // } |
+ // |
+ // class B<T> implements A<T> {} |
+ // |
+ // main() { |
+ // print(new A<int>.regular() is B<int>); |
+ // print(new A<String>.redirect() is B<String>); |
+ // } |
+ // |
+ // To track that B is actually instantiated as B<int> and B<String> we |
+ // need to follow the type arguments passed to A.regular and A.redirect |
+ // to B. Currently, we only do this soundly if we register A<int> and |
+ // A<String> as instantiated. We should instead register that A.T is |
+ // instantiated as int and String. |
+ ClassElement cls = |
+ astAdapter.getElement(invocation.target.enclosingClass); |
+ List<DartType> typeArguments = |
+ astAdapter.getDartTypes(invocation.arguments.types); |
+ impactBuilder.registerTypeUse( |
+ new TypeUse.instantiation(new InterfaceType(cls, typeArguments))); |
+ if (typeArguments.any((DartType type) => !type.isDynamic)) { |
+ impactBuilder.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK); |
+ } |
+ } else { |
+ impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
+ target, astAdapter.getCallStructure(invocation.arguments))); |
+ } |
} |
@override |