Index: compiler/java/com/google/dart/compiler/backend/js/RuntimeTypeInjector.java |
diff --git a/compiler/java/com/google/dart/compiler/backend/js/RuntimeTypeInjector.java b/compiler/java/com/google/dart/compiler/backend/js/RuntimeTypeInjector.java |
index 58206bddc6f5488a9f4183fc32d192355d8d90d0..acb467ffe8c0789d86e4b73ebe9979afb42273a1 100644 |
--- a/compiler/java/com/google/dart/compiler/backend/js/RuntimeTypeInjector.java |
+++ b/compiler/java/com/google/dart/compiler/backend/js/RuntimeTypeInjector.java |
@@ -649,7 +649,7 @@ public class RuntimeTypeInjector { |
* } |
*/ |
private void generateRTTLookupMethod(DartFunctionTypeAlias x) { |
- FunctionAliasElementImplementation classElement = |
+ FunctionAliasElementImplementation classElement = |
(FunctionAliasElementImplementation) x.getSymbol(); |
FunctionType funcType = classElement.getFunctionType(); |
boolean hasTypeParams = hasTypeParameters(classElement); |
@@ -711,12 +711,22 @@ public class RuntimeTypeInjector { |
* @param classElement The class whose type arguments to refer to. |
*/ |
private JsExpression buildTypeArgsReference(ClassElement classElement) { |
- // build: $getTypeArgsFor(this, 'class') |
- // Here build a reference to the type parameter for this class instance, this needs |
- // be looked up on a per-class basis. |
- return call(null, |
- newQualifiedNameRef( |
- "RTT.getTypeArgsFor"), new JsThisRef(), getRTTClassId(classElement)); |
+ JsExpression typeArgs; |
+ if (inFactory()) { |
+ if (classElement.getTypeParameters().isEmpty()) { |
+ typeArgs = new JsArrayLiteral(); |
+ } else { |
+ typeArgs = new JsNameRef("$typeArgs"); |
+ } |
+ } else { |
+ // build: $getTypeArgsFor(this, 'class') |
+ // Here build a reference to the type parameter for this class instance, this needs |
+ // be looked up on a per-class basis. |
+ typeArgs = call(null, |
+ newQualifiedNameRef( |
+ "RTT.getTypeArgsFor"), new JsThisRef(), getRTTClassId(classElement)); |
+ } |
+ return typeArgs; |
} |
private JsExpression buildFactoryTypeInfoReference() { |
@@ -762,7 +772,7 @@ public class RuntimeTypeInjector { |
InterfaceType instanceType, |
List<? extends Type> listTypeVars, |
JsExpression contextTypeArgs) { |
- if (functionType.getTypeVariables().size() == 0) { |
+ if (instanceType.getElement().getTypeParameters().size() == 0) { |
return null; |
} |
@@ -807,25 +817,13 @@ public class RuntimeTypeInjector { |
private JsExpression generateTypeArgsArray( |
InterfaceType instanceType, ClassElement contextClassElement) { |
JsExpression typeArgs; |
- if (inFactoryOrStatic(contextClassElement)) { |
- if (inFactory()) { |
- // When building a type list in a static context like a factory, type variables are |
- // resolved from the type parameters to the static method. |
- DartClassMember<?> member = context.getCurrentClassMember(); |
- DartMethodDefinition containingMethod = (DartMethodDefinition)member; |
- ConstructorElement contextElement = (ConstructorElement)containingMethod.getSymbol(); |
- typeArgs = buildTypeArgs( |
- instanceType, |
- ((FunctionType)contextElement.getType()).getTypeVariables(), |
- buildFactoryTypeInfoReference()); |
+ if (inStaticNotFactory(contextClassElement)) { |
+ if( ElementKind.of(contextClassElement) == ElementKind.FUNCTION_TYPE_ALIAS) { |
+ // Special case for FunctionAlias as they can have generic types. |
+ typeArgs = buildTypeArgs(instanceType, contextClassElement.getTypeParameters(), |
+ new JsNameRef("typeArgs")); |
} else { |
- if( ElementKind.of(contextClassElement) == ElementKind.FUNCTION_TYPE_ALIAS) { |
- // Special case for FunctionAlias as they can have generic types. |
- typeArgs = buildTypeArgs(instanceType, contextClassElement.getTypeParameters(), |
- new JsNameRef("typeArgs")); |
- } else { |
- typeArgs = buildTypeArgs(instanceType, null, null); |
- } |
+ typeArgs = buildTypeArgs(instanceType, null, null); |
} |
} else { |
// Build type args in a class context: |
@@ -844,21 +842,8 @@ public class RuntimeTypeInjector { |
InterfaceType instanceType, |
ClassElement contextClassElement) { |
JsExpression typeArgs; |
- if (inFactoryOrStatic(contextClassElement)) { |
- if (inFactory()) { |
- // When building a type list in a static context like a factory, type |
- // variables are |
- // resolved from the type parameters to the static method. |
- DartClassMember<?> member = context.getCurrentClassMember(); |
- DartMethodDefinition containingMethod = (DartMethodDefinition) member; |
- ConstructorElement contextElement = (ConstructorElement) containingMethod |
- .getSymbol(); |
- typeArgs = buildTypeArgsForFactory(functionType, instanceType, |
- ((FunctionType) contextElement.getType()).getTypeVariables(), |
- buildFactoryTypeInfoReference()); |
- } else { |
- typeArgs = buildTypeArgsForFactory(functionType, instanceType, null, null); |
- } |
+ if (inStaticNotFactory(contextClassElement)) { |
+ typeArgs = buildTypeArgsForFactory(functionType, instanceType, null, null); |
} else { |
// Build type args in a class context: |
// When building a type list in a class instance, type variables are |
@@ -912,9 +897,6 @@ public class RuntimeTypeInjector { |
getRTTLookupMethodName(functionType.getElement())); |
if (hasTypeParameters(functionType.getElement())) { |
JsArrayLiteral typeArgs = new JsArrayLiteral(); |
- for (Type arg : functionType.getTypeVariables()) { |
- typeArgs.getExpressions().add(buildTypeLookupExpression(arg, list, contextTypeArgs)); |
- } |
functionTypeCallLookup.getArguments().add(typeArgs); |
} |
return functionTypeCallLookup; |
@@ -926,11 +908,12 @@ public class RuntimeTypeInjector { |
for (Type t : list) { |
if (t.equals(type)) { |
return call(null, newQualifiedNameRef("RTT.getTypeArg"), |
- Cloner.clone(contextTypeArgs), |
- program.getNumberLiteral(varIndex)); |
+ contextTypeArgs, |
+ program.getNumberLiteral(varIndex)); |
} |
varIndex++; |
} |
+ |
throw new AssertionError("unresolved type variable:" + var); |
default: |
@@ -973,7 +956,12 @@ public class RuntimeTypeInjector { |
private boolean isParameterizedFactoryMethod(DartMethodDefinition method) { |
assert method.getModifiers().isFactory(); |
- return !method.getTypeParameters().isEmpty(); |
+ Element enclosingElement = method.getSymbol().getEnclosingElement(); |
+ if (ElementKind.of(enclosingElement).equals(ElementKind.CLASS)) { |
+ ClassElement enclosingClass = (ClassElement) enclosingElement; |
+ return !enclosingClass.getTypeParameters().isEmpty(); |
+ } |
+ return false; |
} |
/** |
@@ -1143,6 +1131,10 @@ public class RuntimeTypeInjector { |
return member != null && member.getModifiers().isFactory(); |
} |
+ private boolean inStaticNotFactory(ClassElement containingClass) { |
+ return !inFactory() && inFactoryOrStatic(containingClass); |
+ } |
+ |
private boolean inFactoryOrStatic(ClassElement containingClass) { |
DartClassMember<?> member = context.getCurrentClassMember(); |
return containingClass == null |