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..3ac36dc5bf268950696c75e9c430fc91636a5bbe 100644 |
--- a/compiler/java/com/google/dart/compiler/backend/js/RuntimeTypeInjector.java |
+++ b/compiler/java/com/google/dart/compiler/backend/js/RuntimeTypeInjector.java |
@@ -649,10 +649,9 @@ public class RuntimeTypeInjector { |
* } |
*/ |
private void generateRTTLookupMethod(DartFunctionTypeAlias x) { |
- FunctionAliasElementImplementation classElement = |
+ FunctionAliasElementImplementation classElement = |
(FunctionAliasElementImplementation) x.getSymbol(); |
FunctionType funcType = classElement.getFunctionType(); |
- boolean hasTypeParams = hasTypeParameters(classElement); |
// Build the function |
JsFunction lookupFn = new JsFunction(globalScope); |
@@ -711,12 +710,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 +771,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 +816,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 +841,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 +896,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,8 +907,8 @@ public class RuntimeTypeInjector { |
for (Type t : list) { |
if (t.equals(type)) { |
return call(null, newQualifiedNameRef("RTT.getTypeArg"), |
- Cloner.clone(contextTypeArgs), |
- program.getNumberLiteral(varIndex)); |
+ Cloner.clone(contextTypeArgs), |
+ program.getNumberLiteral(varIndex)); |
} |
varIndex++; |
} |
@@ -973,7 +954,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,12 +1129,15 @@ public class RuntimeTypeInjector { |
return member != null && member.getModifiers().isFactory(); |
} |
- private boolean inFactoryOrStatic(ClassElement containingClass) { |
+ private boolean inStaticNotFactory(ClassElement containingClass) { |
+ return !inFactory() && inStatic(containingClass); |
+ } |
+ |
+ private boolean inStatic(ClassElement containingClass) { |
DartClassMember<?> member = context.getCurrentClassMember(); |
return containingClass == null |
|| containingClass.getKind() != ElementKind.CLASS |
|| member == null |
- || member.getModifiers().isFactory() |
|| member.getModifiers().isStatic(); |
} |