Chromium Code Reviews| 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..7af15fff35a5d4194779d15a5b7488cc2b567d96 100644 |
| --- a/compiler/java/com/google/dart/compiler/backend/js/RuntimeTypeInjector.java |
| +++ b/compiler/java/com/google/dart/compiler/backend/js/RuntimeTypeInjector.java |
| @@ -251,17 +251,23 @@ public class RuntimeTypeInjector { |
| List<JsExpression> callArgs = invokeCreate.getArguments(); |
| if (hasRTTImplements(classElement)) { |
| callArgs.add(getRTTImplementsMethodName(classElement)); |
| - } else if (hasTypeParams) { |
|
mmendez
2011/12/14 20:48:13
Nit: Alternatively, you could still only pass null
codefu
2011/12/15 13:01:53
We don't know if it will be named until runtime, s
|
| + } else { |
| // need a placeholder param if the typeArgs are needed. |
| callArgs.add(program.getNullLiteral()); |
| } |
| + JsName typeArgs = scope.declareName("typeArgs"); |
| + lookupFn.getParameters().add(new JsParameter(typeArgs)); |
| if (hasTypeParams) { |
| - JsName typeArgs = scope.declareName("typeArgs"); |
| - lookupFn.getParameters().add(new JsParameter(typeArgs)); |
| callArgs.add(typeArgs.makeRef()); |
| + } else { |
| + callArgs.add(program.getNullLiteral()); |
| } |
| + JsName named = scope.declareName("named"); |
| + lookupFn.getParameters().add(new JsParameter(named)); |
| + callArgs.add(named.makeRef()); |
| + |
| body.add(new JsReturn(invokeCreate)); |
| // Finally, Add the function |
| @@ -486,29 +492,12 @@ public class RuntimeTypeInjector { |
| // Finally, Add the lookup function to the global block. |
| JsExpression fnDecl; |
| if (overrideName == null) { |
| + JsNameRef methodToCall = getRTTLookupMethodName(methodElement); |
| if (methodElement.getEnclosingElement().getKind().equals(ElementKind.CLASS)) { |
| - JsNameRef classJsNameRef = getJsName(methodElement.getEnclosingElement()).makeRef(); |
| - String getterName = mangler.createGetterSyntax(methodElement, unitLibrary); |
| - String methodName = methodElement.getName(); |
| - JsName getterJsName = globalScope.declareName(getterName, getterName, methodName); |
| - String mangledMethodName = mangler.mangleNamedMethod(methodElement, unitLibrary) |
| - + "_$lookupRTT"; |
| - JsNameRef methodToCall; |
| - JsNameRef getterJsNameRef; |
| - if (methodElement.getModifiers().isStatic()) { |
| - getterJsNameRef = AstUtil.newNameRef(classJsNameRef, getterJsName); |
| - methodToCall = AstUtil.newNameRef(classJsNameRef, mangledMethodName); |
| - } else { |
| - JsNameRef prototypeRef = AstUtil.newPrototypeNameRef(classJsNameRef); |
| - getterJsNameRef = AstUtil.newNameRef(prototypeRef, getterJsName); |
| - methodToCall = AstUtil.newNameRef(prototypeRef, mangledMethodName); |
| - } |
| fnDecl = assign(null, methodToCall, lookupFn); |
| } else { |
| // Top level method |
| - String mangledMethodName = mangler.mangleNamedMethod(methodElement, unitLibrary) |
| - + "_$lookupRTT"; |
| - lookupFn.setName(scope.declareName(mangledMethodName)); |
| + lookupFn.setName(scope.declareFreshName(methodToCall.getIdent())); |
| fnDecl = lookupFn; |
| } |
| } else { |
| @@ -526,14 +515,14 @@ public class RuntimeTypeInjector { |
| * No lookup method exists for the type "int bar(double x)", hence the in-line creation of: |
| * RTT.createFunction([RTT Parameter Types],RTT ReturnType)) |
| */ |
| - private JsExpression generateRTTCreate(VariableElement element, ClassElement classElement) { |
| + private JsInvocation generateRTTCreate(VariableElement element, ClassElement classElement) { |
| boolean hasTypes = false; |
| FunctionType type = (FunctionType) element.getType(); |
| if (ElementKind.of(element).equals(ElementKind.CONSTRUCTOR) |
| || element.getModifiers().isNative()) { |
| // No type lookups for constructors or natives |
| - return AstUtil.newQualifiedNameRef("RTT.dynamicType"); |
| + return newInvocation(newQualifiedNameRef("RTT.dynamicType.$lookupRTT")); |
|
mmendez
2011/12/14 20:48:13
Nit: not part of your patch, but you could refacto
codefu
2011/12/15 13:01:53
Done.
|
| } |
| hasTypes = classElement != null ? hasTypeParameters(classElement) : false; |
| @@ -545,7 +534,7 @@ public class RuntimeTypeInjector { |
| JsArrayLiteral arr = generateTypeArrayFromTypes(type.getParameterTypes(), classElement, |
| typeArgContextExpr); |
| if (arr == null) { |
| - return AstUtil.newQualifiedNameRef("RTT.dynamicType"); |
| + return newInvocation(newQualifiedNameRef("RTT.dynamicType.$lookupRTT")); |
| } |
| JsExpression returnExpr = generateRTTLookupForType(element, type.getReturnType(), classElement, |
| @@ -563,9 +552,6 @@ public class RuntimeTypeInjector { |
| JsExpression elementExpr; |
| elementExpr = generateRTTLookupForType(param.getElement(), param, classElement, |
| typeArgContextExpr); |
| - if (elementExpr == null) { |
| - return null; |
| - } |
| jsTypeArray.getExpressions().add(elementExpr); |
| } |
| return jsTypeArray; |
| @@ -575,14 +561,10 @@ public class RuntimeTypeInjector { |
| ClassElement classElement, JsExpression typeArgContextExpr) { |
| JsArrayLiteral jsTypeArray = new JsArrayLiteral(); |
| for (DartParameter param : params) { |
| - JsExpression elementExpr; |
| - if (param.getTypeNode() == null) { |
| - elementExpr = AstUtil.newQualifiedNameRef("RTT.dynamicType"); |
| - } else { |
| - elementExpr = generateRTTLookupForType(param.getSymbol(), param.getTypeNode().getType(), |
| - classElement, typeArgContextExpr); |
| - } |
| - jsTypeArray.getExpressions().add(elementExpr); |
| + Type paramType = param.getTypeNode() == null ? null : param.getTypeNode().getType(); |
| + JsInvocation elementInvoke = generateRTTLookupForType(param.getSymbol(), paramType, classElement, |
| + typeArgContextExpr); |
| + jsTypeArray.getExpressions().add(elementInvoke); |
| } |
| return jsTypeArray; |
| } |
| @@ -598,38 +580,49 @@ public class RuntimeTypeInjector { |
| return jsTypeArray; |
| } |
| - private JsExpression generateRTTLookupForType(Element element, Type elementType, |
| + private JsInvocation generateRTTLookupForType(Element element, Type elementType, |
| ClassElement classElement, JsExpression typeArgContextExpr) { |
| - JsExpression elementExpr = null; |
| + return generateRTTLookupForType(element, elementType, classElement, typeArgContextExpr, |
| + element.getModifiers().isNamed() ? element.getName() : null); |
| + } |
| + |
| + private JsInvocation generateRTTLookupForType(Element element, Type elementType, |
| + ClassElement classElement, JsExpression typeArgContextExpr, String named) { |
| + JsInvocation elementInvoke = null; |
| switch (TypeKind.of(elementType)) { |
| case VARIABLE: |
| - elementExpr = buildTypeLookupExpression(elementType, classElement.getTypeParameters(), |
| + elementInvoke = buildTypeLookupExpression(elementType, classElement.getTypeParameters(), |
| typeArgContextExpr); |
| break; |
| case INTERFACE: |
| - elementExpr = generateRTTLookup((ClassElement) elementType.getElement(), |
| + elementInvoke = generateRTTLookup((ClassElement) elementType.getElement(), |
| (InterfaceType) elementType, classElement); |
| break; |
| case FUNCTION: |
| - elementExpr = generateRTTCreate((VariableElement) element, classElement); |
| + elementInvoke = generateRTTCreate((VariableElement) element, classElement); |
| break; |
| case FUNCTION_ALIAS: |
| - elementExpr = buildTypeLookupExpression(elementType, |
| + elementInvoke = buildTypeLookupExpression(elementType, |
| classElement != null ? classElement.getTypeParameters() : null, typeArgContextExpr); |
| break; |
| case DYNAMIC: |
| - elementExpr = AstUtil.newQualifiedNameRef("RTT.dynamicType"); |
| - break; |
| case VOID: |
| case NONE: |
| - elementExpr = translationContext.getProgram().getNullLiteral(); |
| + elementInvoke = newInvocation(newQualifiedNameRef("RTT.dynamicType.$lookupRTT")); |
| break; |
| default: |
| - elementExpr = buildTypeLookupExpression(elementType, classElement.getTypeParameters(), |
| + elementInvoke = buildTypeLookupExpression(elementType, classElement.getTypeParameters(), |
| typeArgContextExpr); |
| break; |
| } |
| - return elementExpr; |
| + if (named != null) { |
| + if (elementInvoke.getArguments().size() == 0) { |
| + elementInvoke.getArguments().add(translationContext.getProgram().getNullLiteral()); |
| + } |
| + elementInvoke.getArguments().add( |
| + translationContext.getProgram().getStringLiteral(named)); |
| + } |
| + return elementInvoke; |
|
mmendez
2011/12/14 20:48:13
Nit: could assert not null here.
codefu
2011/12/15 13:01:53
Done.
|
| } |
| private JsName getJsName(Symbol symbol) { |
| @@ -649,7 +642,7 @@ public class RuntimeTypeInjector { |
| * } |
| */ |
| private void generateRTTLookupMethod(DartFunctionTypeAlias x) { |
| - FunctionAliasElementImplementation classElement = |
| + FunctionAliasElementImplementation classElement = |
| (FunctionAliasElementImplementation) x.getSymbol(); |
| FunctionType funcType = classElement.getFunctionType(); |
| boolean hasTypeParams = hasTypeParameters(classElement); |
| @@ -675,6 +668,10 @@ public class RuntimeTypeInjector { |
| funcType.getReturnType(), classElement, typeArgsExpr); |
| callArgs.add(returnExpr); |
| + JsName named = scope.declareName("named"); |
|
mmendez
2011/12/14 20:48:13
Nit: refactor string into constant.
codefu
2011/12/15 13:01:53
Done.
|
| + lookupFn.getParameters().add(new JsParameter(named)); |
| + callArgs.add(named.makeRef()); |
| + |
| body.add(new JsReturn(invokeCreate)); |
| // Finally, Add the function to the global block of statements. |
| @@ -698,6 +695,26 @@ public class RuntimeTypeInjector { |
| return nameref(null, translationContext.getNames().getName(classElement), "$lookupRTT"); |
| } |
| + public JsNameRef getRTTLookupMethodName(MethodElement methodElement) { |
|
mmendez
2011/12/14 20:48:13
Nit: could rename to getRTTLookupMethodNameRef.
codefu
2011/12/15 13:01:53
Done.
|
| + JsNameRef methodToCall; |
| + |
| + if (methodElement.getEnclosingElement().getKind().equals(ElementKind.CLASS)) { |
|
mmendez
2011/12/14 20:48:13
Nit: Could use ElementKind.of(methodElement.getEnc
codefu
2011/12/15 13:01:53
Done.
|
| + JsNameRef classJsNameRef = getJsName(methodElement.getEnclosingElement()).makeRef(); |
| + String mangledMethodName = mangler.mangleRttLookupMethod(methodElement, unitLibrary); |
| + if (methodElement.getModifiers().isStatic()) { |
| + methodToCall = AstUtil.newNameRef(classJsNameRef, mangledMethodName); |
| + } else { |
| + JsNameRef prototypeRef = AstUtil.newPrototypeNameRef(classJsNameRef); |
| + methodToCall = AstUtil.newNameRef(prototypeRef, mangledMethodName); |
| + } |
| + } else { |
| + // Top level method |
| + methodToCall = AstUtil.newQualifiedNameRef(mangler.mangleRttLookupMethod(methodElement, |
| + unitLibrary)); |
| + } |
| + return methodToCall; |
| + } |
| + |
| private JsNameRef getRTTImplementsMethodName(ClassElement classElement) { |
| return nameref(null, translationContext.getNames().getName(classElement), "$RTTimplements"); |
| } |
| @@ -793,7 +810,7 @@ public class RuntimeTypeInjector { |
| return generateRTTLookup(instanceType.getElement(), instanceType, contextClassElement); |
| } |
| - private JsExpression generateRTTLookup( |
| + private JsInvocation generateRTTLookup( |
| ClassElement classElement, InterfaceType instanceType, ClassElement contextClassElement) { |
| JsInvocation invokeLookup = call(null, getRTTLookupMethodName(classElement)); |
| if (hasTypeParameters(instanceType.getElement()) && !instanceType.hasDynamicTypeArgs()) { |
| @@ -889,7 +906,7 @@ public class RuntimeTypeInjector { |
| /** |
| * @return js The expression used to lookup the RTT for the given type. |
| */ |
| - private JsExpression buildTypeLookupExpression( |
| + private JsInvocation buildTypeLookupExpression( |
| Type type, List<? extends Type> list, JsExpression contextTypeArgs) { |
| switch (TypeKind.of(type)) { |
| case INTERFACE: |
| @@ -1269,7 +1286,7 @@ public class RuntimeTypeInjector { |
| TypeVariable typeVar = (TypeVariable) type; |
| return getReifiedTypeVariableRTT(typeVar, enclosingClass); |
| case FUNCTION: |
| - // TODO: do we need a more detailed RTT than just a generic function? |
| + // TODO: We need a more detailed RTT than just a generic function. |
|
codefu
2011/12/14 16:12:13
Issue 847 clarification.
|
| return generateRTTLookup(typeProvider.getFunctionType(), enclosingClass); |
| case VOID: |
| case FUNCTION_ALIAS: |