Exemple #1
0
  public JsFunction mapFunction(Node fnNode) throws JsParserException {
    int nodeType = fnNode.getType();
    assert nodeType == TokenStream.FUNCTION
        : "Expected function node, got: " + TokenStream.tokenToName(nodeType);
    Node fromFnNameNode = fnNode.getFirstChild();
    Node fromParamNode = fnNode.getFirstChild().getNext().getFirstChild();
    Node fromBodyNode = fnNode.getFirstChild().getNext().getNext();
    JsFunction toFn = scopeContext.enterFunction();

    // Decide the function's name, if any.
    //
    String fnNameIdent = fromFnNameNode.getString();
    if (fnNameIdent != null && fnNameIdent.length() > 0) {
      scopeContext.globalNameFor(fnNameIdent);
    }

    while (fromParamNode != null) {
      String fromParamName = fromParamNode.getString();
      JsName name = scopeContext.localNameFor(fromParamName);
      toFn.getParameters().add(new JsParameter(name));
      fromParamNode = fromParamNode.getNext();
    }

    // Map the function's body.
    //
    JsBlock toBody = mapBlock(fromBodyNode);
    toFn.setBody(toBody);

    scopeContext.exitFunction();
    return toFn;
  }
Exemple #2
0
 /** Add a type arguments parameter to a factory method, if necessary. */
 void maybeAddTypeParameterToFactory(DartMethodDefinition method, JsFunction factory) {
   // TODO(johnlenz):in optimized mode, only add this where it is needed.
   if (isParameterizedFactoryMethod(method)) {
     JsScope scope = factory.getScope();
     JsName typeArgs = scope.declareName("$typeArgs");
     factory.getParameters().add(0, new JsParameter(typeArgs));
   }
 }
Exemple #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());
  }
Exemple #4
0
  @NotNull
  @Override
  public JsFunction deepCopy() {
    JsFunction functionCopy = new JsFunction(scope.getParent(), scope.getDescription(), name);
    functionCopy.getScope().copyOwnNames(scope);
    functionCopy.setBody(body.deepCopy());
    functionCopy.params = AstUtil.deepCopy(params);

    return functionCopy.withMetadataFrom(this);
  }
  @Nullable
  public JsPropertyInitializer translate(
      @NotNull JetClassOrObject declaration, TranslationContext context) {
    ClassDescriptor descriptor = getClassDescriptor(context().bindingContext(), declaration);
    JsExpression value;
    if (descriptor.getModality() == Modality.FINAL) {
      value =
          new ClassTranslator(declaration, classDescriptorToQualifiedLabel, context).translate();
    } else {
      String label = createNameForClass(descriptor);
      JsName name = dummyFunction.getScope().declareName(label);
      JsNameRef qualifiedLabel = openClassDescriptorToQualifiedLabel.get(descriptor);
      if (qualifiedLabel == null) {
        qualifiedLabel = new JsNameRef(name);
        openClassDescriptorToQualifiedLabel.put(descriptor, qualifiedLabel);
      } else {
        qualifiedLabel.resolve(name);
      }
      qualifiedLabel.setQualifier(declarationsObjectRef);

      OpenClassInfo item = new OpenClassInfo((JetClass) declaration, descriptor, name.makeRef());

      openList.add(item);
      openClassDescriptorToItem.put(descriptor, item);

      value = qualifiedLabel;

      // not public api classes referenced to internal var _c
      if (!descriptor.getVisibility().isPublicAPI()) {
        return null;
      }
    }

    return InitializerUtils.createPropertyInitializer(descriptor, value, context());
  }
Exemple #6
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());
 }
Exemple #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());
  }
  public void generateDeclarations() {
    List<JsVar> vars = new SmartList<JsVar>();
    List<JsPropertyInitializer> propertyInitializers = new SmartList<JsPropertyInitializer>();

    generateOpenClassDeclarations(vars, propertyInitializers);
    fixUnresolvedClassReferences();

    if (vars.isEmpty()) {
      if (!propertyInitializers.isEmpty()) {
        classesVar.setInitExpression(new JsObjectLiteral(propertyInitializers, true));
      }
      return;
    }

    dummyFunction.setBody(
        new JsBlock(
            new JsVars(vars, true), new JsReturn(new JsObjectLiteral(propertyInitializers))));
    classesVar.setInitExpression(new JsInvocation(dummyFunction));
  }
Exemple #9
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());
  }