Ejemplo n.º 1
0
 private boolean hasRTTImplements(ClassElement classElement) {
   InterfaceType superType = classElement.getSupertype();
   return ((superType != null && !superType.getElement().isObject())
       || !classElement.getInterfaces().isEmpty());
 }
Ejemplo n.º 2
0
 private InterfaceType checkedAsInstanceOf(
     Type t, ClassElement element, Set<TypeVariable> variablesReferenced, Set<Type> checkedTypes) {
   // check for recursion
   if (checkedTypes.contains(t)) {
     return null;
   }
   checkedTypes.add(t);
   // check current Type
   switch (TypeKind.of(t)) {
     case FUNCTION_ALIAS:
     case INTERFACE:
       {
         if (t.getElement().equals(element)) {
           return (InterfaceType) t;
         }
         InterfaceType ti = (InterfaceType) t;
         ClassElement tElement = ti.getElement();
         InterfaceType supertype = tElement.getSupertype();
         // super type
         if (supertype != null) {
           InterfaceType result =
               checkedAsInstanceOf(
                   asSupertype(ti, supertype), element, variablesReferenced, checkedTypes);
           if (result != null) {
             return result;
           }
         }
         // interfaces
         for (InterfaceType intf : tElement.getInterfaces()) {
           InterfaceType result =
               checkedAsInstanceOf(
                   asSupertype(ti, intf), element, variablesReferenced, checkedTypes);
           if (result != null) {
             return result;
           }
         }
         // mixins
         for (InterfaceType mixin : tElement.getMixins()) {
           if (mixin.getElement().equals(element)) {
             return asSupertype(ti, mixin);
           }
         }
         // no
         return null;
       }
     case FUNCTION:
       {
         Element e = t.getElement();
         switch (e.getKind()) {
           case CLASS:
             // e should be the interface Function in the core library. See the
             // documentation comment on FunctionType.
             InterfaceType ti = (InterfaceType) e.getType();
             return checkedAsInstanceOf(ti, element, variablesReferenced, checkedTypes);
           default:
             return null;
         }
       }
     case VARIABLE:
       {
         TypeVariable v = (TypeVariable) t;
         Type bound = v.getTypeVariableElement().getBound();
         // Check for previously encountered variables to avoid getting stuck in an infinite loop.
         if (variablesReferenced.contains(v)) {
           if (bound instanceof InterfaceType) {
             return (InterfaceType) bound;
           }
           return typeProvider.getObjectType();
         }
         variablesReferenced.add(v);
         return checkedAsInstanceOf(bound, element, variablesReferenced, checkedTypes);
       }
     default:
       return null;
   }
 }
Ejemplo n.º 3
0
  private void generateRTTAddToMethod(DartClass x) {
    ClassElement classElement = x.getSymbol();

    // 2) create "addTo" method
    // Foo$Type$addTo(target, typeargs) {
    //   var rtt = Foo$lookupOrCreateRTT(typeargs)
    //   target.implementedTypes[rtt.classkey] = rtt;
    // }

    // Build the function
    JsFunction addToFn = new JsFunction(globalScope);
    addToFn.setBody(new JsBlock());
    JsScope scope = new JsScope(globalScope, "temp");

    JsName targetType = scope.declareName("target");
    addToFn.getParameters().add(new JsParameter(targetType));

    // Get the RTT info object
    JsName rtt = scope.declareName("rtt");
    List<JsStatement> body = addToFn.getBody().getStatements();
    JsInvocation callLookup = newInvocation(getRTTLookupMethodName(classElement));

    if (hasTypeParameters(classElement)) {
      JsName typeArgs = scope.declareName("typeArgs");
      addToFn.getParameters().add(new JsParameter(typeArgs));
      callLookup.getArguments().add(new JsNameRef(typeArgs));
    }

    JsStatement rttLookup = newVar((SourceInfo) null, rtt, callLookup);
    body.add(rttLookup);

    // store it.
    JsExpression addToTypes =
        newAssignment(
            new JsArrayAccess(
                newNameRef(targetType.makeRef(), "implementedTypes"),
                newNameRef(rtt.makeRef(), "classKey")),
            rtt.makeRef());
    body.add(addToTypes.makeStmt());

    InterfaceType superType = classElement.getSupertype();
    if (superType != null && !superType.getElement().isObject()) {
      ClassElement interfaceElement = superType.getElement();
      JsInvocation callAddTo =
          newInvocation(getRTTAddToMethodName(interfaceElement), targetType.makeRef());
      if (hasTypeParameters(interfaceElement) && !superType.hasDynamicTypeArgs()) {
        JsArrayLiteral superTypeArgs = new JsArrayLiteral();
        List<? extends Type> typeParams = classElement.getTypeParameters();
        for (Type arg : superType.getArguments()) {
          superTypeArgs
              .getExpressions()
              .add(
                  buildTypeLookupExpression(
                      arg, typeParams, nameref(null, targetType.makeRef(), "typeArgs")));
        }
        callAddTo.getArguments().add(superTypeArgs);
      }
      body.add(callAddTo.makeStmt());
    }

    // Add the interfaces

    for (InterfaceType interfaceType : classElement.getInterfaces()) {
      ClassElement interfaceElement = interfaceType.getElement();
      JsInvocation callAddTo =
          call(null, getRTTAddToMethodName(interfaceElement), targetType.makeRef());
      if (hasTypeParameters(interfaceElement) && !interfaceType.hasDynamicTypeArgs()) {
        JsArrayLiteral interfaceTypeArgs = new JsArrayLiteral();
        List<? extends Type> typeParams = classElement.getTypeParameters();
        for (Type arg : interfaceType.getArguments()) {
          interfaceTypeArgs
              .getExpressions()
              .add(
                  buildTypeLookupExpression(
                      arg, typeParams, nameref(null, targetType.makeRef(), "typeArgs")));
        }
        callAddTo.getArguments().add(interfaceTypeArgs);
      }
      body.add(callAddTo.makeStmt());
    }

    // Add the function statement
    JsExpression fnDecl = newAssignment(getRTTAddToMethodName(classElement), addToFn);
    globalBlock.getStatements().add(fnDecl.makeStmt());
  }