Example #1
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());
  }
Example #2
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);
  }
Example #3
0
 private void injectInterfaceMarkers(ClassElement classElement, SourceInfo srcRef) {
   JsProgram program = translationContext.getProgram();
   JsName classJsName = translationContext.getNames().getName(classElement);
   for (InterfaceType iface : getAllInterfaces(classElement)) {
     JsStatement assignment =
         (JsStatement)
             newAssignment(
                     newNameRef(
                         newNameRef(new JsNameRef(classJsName), "prototype"),
                         "$implements$"
                             + translationContext
                                 .getMangler()
                                 .mangleClassName(iface.getElement())),
                     program.getNumberLiteral(1))
                 .makeStmt()
                 .setSourceRef(srcRef);
     globalBlock.getStatements().add(assignment);
   }
 }
Example #4
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());
  }
Example #5
0
  private JsNode map(Node node) throws JsParserException {
    switch (node.getType()) {
      case TokenStream.SCRIPT:
        {
          JsBlock block = new JsBlock();
          mapStatements(block.getStatements(), node);
          return block;
        }

      case TokenStream.DEBUGGER:
        return mapDebuggerStatement(node);

      case TokenStream.VOID:
        // VOID = nothing was parsed for this node
        return null;

      case TokenStream.EXPRSTMT:
        return mapExpressionStatement(node);

      case TokenStream.REGEXP:
        return mapRegExp(node);

      case TokenStream.ADD:
        return mapBinaryOperation(JsBinaryOperator.ADD, node);

      case TokenStream.SUB:
        return mapBinaryOperation(JsBinaryOperator.SUB, node);

      case TokenStream.MUL:
        return mapBinaryOperation(JsBinaryOperator.MUL, node);

      case TokenStream.DIV:
        return mapBinaryOperation(JsBinaryOperator.DIV, node);

      case TokenStream.MOD:
        return mapBinaryOperation(JsBinaryOperator.MOD, node);

      case TokenStream.AND:
        return mapBinaryOperation(JsBinaryOperator.AND, node);

      case TokenStream.OR:
        return mapBinaryOperation(JsBinaryOperator.OR, node);

      case TokenStream.BITAND:
        return mapBinaryOperation(JsBinaryOperator.BIT_AND, node);

      case TokenStream.BITOR:
        return mapBinaryOperation(JsBinaryOperator.BIT_OR, node);

      case TokenStream.BITXOR:
        return mapBinaryOperation(JsBinaryOperator.BIT_XOR, node);

      case TokenStream.ASSIGN:
        return mapAssignmentVariant(node);

      case TokenStream.RELOP:
        return mapRelationalVariant(node);

      case TokenStream.EQOP:
        return mapEqualityVariant(node);

      case TokenStream.SHOP:
        return mapShiftVariant(node);

      case TokenStream.UNARYOP:
        return mapUnaryVariant(node);

      case TokenStream.INC:
        return mapIncDecFixity(JsUnaryOperator.INC, node);

      case TokenStream.DEC:
        return mapIncDecFixity(JsUnaryOperator.DEC, node);

      case TokenStream.HOOK:
        return mapConditional(node);

      case TokenStream.STRING:
        return program.getStringLiteral(node.getString());

      case TokenStream.NUMBER_INT:
        return mapIntNumber(node);

      case TokenStream.NUMBER:
        return mapDoubleNumber(node);

      case TokenStream.CALL:
        return mapCall(node);

      case TokenStream.GETPROP:
        return mapGetProp(node);

      case TokenStream.SETPROP:
        return mapSetProp(node);

      case TokenStream.DELPROP:
        return mapDeleteProp(node);

      case TokenStream.IF:
        return mapIfStatement(node);

      case TokenStream.WHILE:
        return mapDoOrWhileStatement(true, node);

      case TokenStream.DO:
        return mapDoOrWhileStatement(false, node);

      case TokenStream.FOR:
        return mapForStatement(node);

      case TokenStream.WITH:
        return mapWithStatement(node);

      case TokenStream.GETELEM:
        return mapGetElem(node);

      case TokenStream.SETELEM:
        return mapSetElem(node);

      case TokenStream.FUNCTION:
        return mapFunction(node);

      case TokenStream.BLOCK:
        return mapBlock(node);

      case TokenStream.SETNAME:
        return mapBinaryOperation(JsBinaryOperator.ASG, node);

      case TokenStream.NAME:
      case TokenStream.BINDNAME:
        return scopeContext.globalNameFor(node.getString()).makeRef();

      case TokenStream.RETURN:
        return mapReturn(node);

      case TokenStream.BREAK:
        return mapBreak(node);

      case TokenStream.CONTINUE:
        return mapContinue(node);

      case TokenStream.OBJLIT:
        return mapObjectLit(node);

      case TokenStream.ARRAYLIT:
        return mapArrayLit(node);

      case TokenStream.VAR:
        return mapVar(node);

      case TokenStream.PRIMARY:
        return mapPrimary(node);

      case TokenStream.COMMA:
        return mapBinaryOperation(JsBinaryOperator.COMMA, node);

      case TokenStream.NEW:
        return mapNew(node);

      case TokenStream.THROW:
        return mapThrowStatement(node);

      case TokenStream.TRY:
        return mapTryStatement(node);

      case TokenStream.SWITCH:
        return mapSwitchStatement(node);

      case TokenStream.LABEL:
        return mapLabel(node);

      default:
        int tokenType = node.getType();
        throw createParserException("Unexpected top-level token type: " + tokenType, node);
    }
  }
Example #6
0
 private JsBlock mapBlock(Node nodeStmts) throws JsParserException {
   JsBlock block = new JsBlock();
   mapStatements(block.getStatements(), nodeStmts);
   return block;
 }
Example #7
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());
  }