예제 #1
0
 @NotNull
 private JsInvocation getNamespaceDeclaration() {
   JsInvocation namespaceDeclaration = namespaceCreateMethodInvocation();
   namespaceDeclaration.getArguments().add(translateNamespaceMemberDeclarations());
   namespaceDeclaration.getArguments().add(getClassesAndNestedNamespaces());
   return namespaceDeclaration;
 }
예제 #2
0
  /** Add runtime type information to a "new" expression, if necessary. */
  void mayAddRuntimeTypeToConstrutorOrFactoryCall(
      ClassElement enclosingClass, DartNewExpression x, JsInvocation invoke) {
    // TODO(johnlenz):in optimized mode, only add this where it is needed.

    InterfaceType instanceType = Types.constructorType(x);
    if (instanceType == null) {
      // TODO(johnlenz): HackHack. Currently the "new FallThroughError" injected by the
      // Normalizer does not have the instance type attached. But in this
      // case we know it does not have any type parameters.
      // reportError(x.getParent().getParent(), new AssertionError("missing type information"));
      assert typeProvider
          .getFallThroughError()
          .getElement()
          .lookupConstructor("")
          .equals(x.getSymbol());
    } else if (constructorHasTypeParameters(x)) {
      ConstructorElement constructor = x.getSymbol();
      ClassElement containingClassElement = enclosingClass;
      if (constructor.getModifiers().isFactory()) {
        // We are calling a factory, this is either in a class
        FunctionType functionType = (FunctionType) constructor.getType();
        JsExpression typeArgs =
            generateTypeArgsArrayForFactory(functionType, instanceType, containingClassElement);
        assert typeArgs != null;
        invoke.getArguments().add(0, typeArgs);
      } else {
        ClassElement constructorClassElement = constructor.getConstructorType();
        invoke
            .getArguments()
            .add(
                0,
                generateRTTLookup(constructorClassElement, instanceType, containingClassElement));
      }
    }
  }
예제 #3
0
  private void generateRTTImplementsMethod(DartClass x) {
    ClassElement classElement = x.getSymbol();

    // 1) create static type information construction function
    // function Foo$lookupOrCreateRTT(rtt, typeArgs) {
    //
    //   // superclass
    //   FooSuper$addTo(rtt, superTypeArg1, ...);
    //   // interfaces
    //   FooInterface1$addTo(rtt, interface1TypeArg1, ...);
    //
    //   // fill in derived types
    //   rtt.derivedTypes = [
    //      FirstRef$lookupOrCreateRTT(typearg1, ...),
    //      ...
    //      ]
    // }

    boolean hasTypeParams = classElement.getTypeParameters().size() > 0;

    // Build the function
    JsFunction implementsFn = new JsFunction(globalScope);
    implementsFn.setBody(new JsBlock());
    List<JsStatement> body = implementsFn.getBody().getStatements();
    JsScope scope = new JsScope(globalScope, "temp");

    JsName rtt = scope.declareName("rtt");
    implementsFn.getParameters().add(new JsParameter(rtt));
    JsName typeArgs = null;
    if (hasTypeParams) {
      typeArgs = scope.declareName("typeArgs");
      implementsFn.getParameters().add(new JsParameter(typeArgs));
    }

    JsInvocation callAddTo = newInvocation(getRTTAddToMethodName(classElement), rtt.makeRef());
    if (hasTypeParams) {
      typeArgs = scope.declareName("typeArgs");
      callAddTo.getArguments().add(typeArgs.makeRef());
    }
    body.add(callAddTo.makeStmt());

    // Add the derived types

    if (hasTypeParams) {
      // Populated the list of derived types
      JsArrayLiteral derivedTypesArray = new JsArrayLiteral();
      // TODO(johnlenz): Add needed types here.
      JsExpression addDerivedTypes =
          assign(null, nameref(null, rtt.makeRef(), "derivedTypes"), derivedTypesArray);
      body.add(addDerivedTypes.makeStmt());
    }

    // Finally, Add the function
    JsExpression fnDecl = assign(null, getRTTImplementsMethodName(classElement), implementsFn);
    globalBlock.getStatements().add(fnDecl.makeStmt());
  }
예제 #4
0
 private JsExpression generateRTTLookup(
     ClassElement classElement, InterfaceType instanceType, ClassElement contextClassElement) {
   JsInvocation invokeLookup = call(null, getRTTLookupMethodName(classElement));
   if (hasTypeParameters(instanceType.getElement()) && !instanceType.hasDynamicTypeArgs()) {
     JsExpression typeArgs = generateTypeArgsArray(instanceType, contextClassElement);
     assert typeArgs != null;
     invokeLookup.getArguments().add(typeArgs);
   }
   return invokeLookup;
 }
예제 #5
0
  /** Add a runtime type information to a map literal, if necessary. */
  void maybeAddRuntimeTypeToMapLiteralConstructor(
      ClassElement enclosingClass, DartMapLiteral x, JsInvocation invoke) {
    // TODO(johnlenz):in optimized mode, only add this where it is needed.

    // Fixup the type for map literal type to be the implementing type.
    List<? extends Type> typeArgs = x.getType().getArguments();
    InterfaceType instanceType = typeProvider.getMapLiteralType(typeArgs.get(0), typeArgs.get(1));
    JsExpression rtt = generateRTTLookup(instanceType, enclosingClass);
    invoke.getArguments().add(rtt);
  }
예제 #6
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());
    }
  }
예제 #7
0
  private void generateRTTLookupMethod(DartClass x) {
    ClassElement classElement = x.getSymbol();
    boolean hasTypeParams = hasTypeParameters(classElement);

    // 1) create static type information construction function
    // function Foo$lookupOrCreateRTT(typeargs) {
    //   return $createRTT(name, Foo$RTTimplements, typeargs) ;
    // }

    // Build the function
    JsFunction lookupFn = new JsFunction(globalScope);
    lookupFn.setBody(new JsBlock());
    List<JsStatement> body = lookupFn.getBody().getStatements();
    JsScope scope = new JsScope(globalScope, "temp");

    JsProgram program = translationContext.getProgram();

    JsInvocation invokeCreate =
        call(null, newQualifiedNameRef("RTT.create"), getRTTClassId(classElement));
    List<JsExpression> callArgs = invokeCreate.getArguments();
    if (hasRTTImplements(classElement)) {
      callArgs.add(getRTTImplementsMethodName(classElement));
    } else if (hasTypeParams) {
      // need a placeholder param if the typeArgs are needed.
      callArgs.add(program.getNullLiteral());
    }

    if (hasTypeParams) {
      JsName typeArgs = scope.declareName("typeArgs");
      lookupFn.getParameters().add(new JsParameter(typeArgs));
      callArgs.add(typeArgs.makeRef());
    }

    body.add(new JsReturn(invokeCreate));

    // Finally, Add the function
    JsExpression fnDecl = assign(null, getRTTLookupMethodName(classElement), lookupFn);
    globalBlock.getStatements().add(fnDecl.makeStmt());
  }
예제 #8
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());
  }