Beispiel #1
0
 /** Add the appropriate code to a class's constructing factory, if necessary. */
 void maybeAddClassRuntimeTypeToConstructor(
     ClassElement classElement, JsFunction factory, JsExpression thisRef) {
   // TODO(johnlenz):in optimized mode, only add this where it is needed.
   JsScope factoryScope = factory.getScope();
   JsExpression typeInfo;
   if (hasTypeParameters(classElement)) {
     JsName typeinfoParameter = factoryScope.declareName("$rtt");
     factory.getParameters().add(0, new JsParameter(typeinfoParameter));
     typeInfo = typeinfoParameter.makeRef();
   } else {
     // TODO(johnlenz): this is a constant value, it only needs to be evaluated once.
     typeInfo = generateRawRTTLookup(classElement);
   }
   JsExpression setTypeInfo =
       assign(null, nameref(null, Cloner.clone(thisRef), "$typeInfo"), typeInfo);
   factory.getBody().getStatements().add(0, setTypeInfo.makeStmt());
 }
Beispiel #2
0
  /** @return js The expression used to lookup the RTT for the given type. */
  private JsExpression buildTypeLookupExpression(
      Type type, List<? extends Type> list, JsExpression contextTypeArgs) {
    switch (TypeKind.of(type)) {
      case INTERFACE:
        InterfaceType interfaceType = (InterfaceType) type;
        JsInvocation callLookup = call(null, getRTTLookupMethodName(interfaceType.getElement()));
        if (hasTypeParameters(interfaceType.getElement()) && !interfaceType.hasDynamicTypeArgs()) {
          JsArrayLiteral typeArgs = new JsArrayLiteral();
          for (Type arg : interfaceType.getArguments()) {
            typeArgs.getExpressions().add(buildTypeLookupExpression(arg, list, contextTypeArgs));
          }
          callLookup.getArguments().add(typeArgs);
        }
        return callLookup;

      case FUNCTION_ALIAS:
        // TODO(johnlenz): implement this
        return newQualifiedNameRef("RTT.placeholderType");

      case VARIABLE:
        TypeVariable var = (TypeVariable) type;
        JsProgram program = translationContext.getProgram();
        int varIndex = 0;
        for (Type t : list) {
          if (t.equals(type)) {
            return call(
                null,
                newQualifiedNameRef("RTT.getTypeArg"),
                Cloner.clone(contextTypeArgs),
                program.getNumberLiteral(varIndex));
          }
          varIndex++;
        }
        throw new AssertionError("unresolved type variable:" + var);

      default:
        throw new AssertionError("unexpected type kind:" + type.getKind());
    }
  }