コード例 #1
0
ファイル: MenuEmitter.java プロジェクト: nlhartman/rstudio
  private void emitMenu(SourceWriter writer, Element el) throws UnableToCompleteException {
    for (Node n = el.getFirstChild(); n != null; n = n.getNextSibling()) {
      if (n.getNodeType() != Node.ELEMENT_NODE) continue;

      Element child = (Element) n;

      if (child.getTagName().equals("cmd")) {
        String cmdId = child.getAttribute("refid");
        writer.print("callback.addCommand(");
        writer.print("\"" + Generator.escape(cmdId) + "\", ");
        writer.println("this.cmds." + cmdId + "());");
      } else if (child.getTagName().equals("separator")) {
        writer.println("callback.addSeparator();");
      } else if (child.getTagName().equals("menu")) {
        String label = child.getAttribute("label");
        writer.println("callback.beginMenu(\"" + Generator.escape(label) + "\");");
        emitMenu(writer, child);
        writer.println("callback.endMenu();");
      } else if (child.getTagName().equals("dynamic")) {
        String dynamicClass = child.getAttribute("class");
        writer.println("new " + dynamicClass + "().execute(callback);");
      } else {
        logger_.log(TreeLogger.Type.ERROR, "Unexpected tag " + el.getTagName() + " in menu");
        throw new UnableToCompleteException();
      }
    }
  }
コード例 #2
0
  private void writeMethod(TreeLogger logger, MethodWrapper method, SourceWriter writer) {
    JType ptype = this.resolveType(method.getDeclaringType());

    writer.println("new Method(){ ");
    writer.indent();
    writer.println("public String getName() {");
    writer.indentln("return \"" + method.getBaseMethod().getName() + "\";");
    writer.println(" }");
    writer.println("public Object invoke( Object target, Object[] args ) throws Exception {");
    writer.indent();
    writer.println(ptype.getQualifiedSourceName() + " casted =");
    writer.println("(" + ptype.getQualifiedSourceName() + ") target;");
    logger.log(
        TreeLogger.SPAM,
        "Method: "
            + method.getBaseMethod().getName()
            + " "
            + method.getBaseMethod().getReturnType().getQualifiedSourceName(),
        null);

    if (!(method.getBaseMethod().getReturnType().isPrimitive() == JPrimitiveType.VOID)) {
      writer.print("return ");
    }

    JType type = this.resolveType(method.getBaseMethod().getReturnType());

    boolean boxed = this.box(type, writer);
    writer.print("casted." + method.getBaseMethod().getName() + "(");

    if (method.getBaseMethod().getParameters() != null) {
      for (int j = 0; j < method.getBaseMethod().getParameters().length; j++) {
        JType arg = this.resolveType(method.getBaseMethod().getParameters()[j].getType());

        this.unbox(arg, "args[" + j + "]", writer);

        if (j != (method.getBaseMethod().getParameters().length - 1)) {
          writer.print(", ");
        }
      }
    }

    writer.print(")");

    if (boxed) {
      writer.print(")");
    }

    writer.println(";");

    if (method.getBaseMethod().getReturnType().getQualifiedSourceName().equals("void")) {
      writer.println("return null;");
    }

    writer.outdent();
    writer.println("}");
    writer.outdent();
    writer.println("};");
  }
コード例 #3
0
  public static boolean ensureProviderClass(
      TreeLogger logger,
      String packageName,
      String simpleName0,
      String canonical,
      String qualifiedSourceName,
      GeneratorContext ctx) {
    String simpleName = SourceUtil.toSourceName(simpleName0);
    String generatedName = InjectionUtils.generatedProviderName(simpleName);
    String cleanedCanonical = SourceUtil.toSourceName(canonical);
    logger.log(Type.DEBUG, "Creating provider for " + packageName + "." + generatedName);

    PrintWriter printWriter = ctx.tryCreate(logger, packageName, generatedName);
    if (printWriter == null) {
      logger.log(Type.TRACE, "Already generated " + generatedName);
      return false;
    }
    logger.log(
        Type.TRACE, "Newly Generating provider " + generatedName + " <- " + qualifiedSourceName);

    ClassSourceFileComposerFactory composer =
        new ClassSourceFileComposerFactory(packageName, generatedName);
    composer.setSuperclass(SingletonInitializer.class.getName() + "<" + simpleName0 + ">");
    composer.addImport(cleanedCanonical);
    composer.addImport(GWT.class.getName());
    composer.addImport(SingletonProvider.class.getName());

    SourceWriter sw = composer.createSourceWriter(ctx, printWriter);

    sw.println("@Override");
    sw.println("public " + simpleName + " initialValue(){");
    sw.indent();

    sw.print("return GWT.<" + cleanedCanonical + ">create(");
    sw.print(SourceUtil.toSourceName(qualifiedSourceName) + ".class");
    sw.println(");");

    sw.outdent();
    sw.println("}");
    sw.println();
    // now, print a static final provider instance
    sw.print("public static final SingletonProvider<");
    sw.print(simpleName0 + "> ");
    sw.print("theProvider = ");
    sw.println("new " + generatedName + "();");
    sw.commit(logger);
    return true;
  }
コード例 #4
0
  @Override
  void toJS(FragmentGeneratorContext context) throws UnableToCompleteException {
    TreeLogger logger =
        context.parentLogger.branch(
            TreeLogger.DEBUG, "Writing function() wrapper for JSFunction", null);

    SourceWriter sw = context.sw;
    TypeOracle typeOracle = context.typeOracle;
    JClassType functionClass = context.returnType.isClassOrInterface();

    if (functionClass.equals(typeOracle.findType(JSFunction.class.getName()))) {
      logger.log(
          TreeLogger.ERROR,
          "You must use a subinterface of JSFunction"
              + " so that the generator can extract a method signature.",
          null);
      throw new UnableToCompleteException();
    }

    // This is to support the JSFunction having the same lifetime as the
    // JSFunction object without having to use GWT.create on every JSFunction
    // object as that would discourage anonymous classes.

    sw.print("(");
    sw.print(context.parameterName);
    //  sw.print("[email protected]::exportedFunction || (");
    sw.print(".@" + JSFunction.class.getName() + "::exportedFunction || (");
    sw.print(context.parameterName);
    //    sw.print("[email protected]::exportedFunction = ");
    sw.print(".@" + JSFunction.class.getName() + "::exportedFunction = ");
    writeFunctionForMethod(context, findExportedMethod(logger, functionClass));
    sw.print("))");
  }
コード例 #5
0
  private void writeIntrospectables(
      TreeLogger logger, List introspectables, MethodWrapper[] methods, SourceWriter writer) {
    for (Iterator it = introspectables.iterator(); it.hasNext(); ) {
      BeanResolver bean = (BeanResolver) it.next();

      logger.branch(
          TreeLogger.DEBUG, "Introspecting: " + bean.getType().getQualifiedSourceName(), null);

      try {
        if (bean.getProperties().size() == 0) {
          continue;
        }

        writer.print("private static BeanDescriptor ");
        writer.print(bean.getType().getQualifiedSourceName().replaceAll("\\.", "_"));

        writer.println(" = null;");
      } catch (Exception e) {
        logger.log(TreeLogger.ERROR, "Unable to introspect class. Is class a bean?", e);
      }
    }
  }
コード例 #6
0
  private boolean unbox(JType type, String reference, SourceWriter writer) {
    if ((type.isPrimitive() != null) && (type.isPrimitive() == JPrimitiveType.INT)) {
      writer.print("((Integer) " + reference + ").intValue()");

      return true;
    }

    if ((type.isPrimitive() != null) && (type.isPrimitive() == JPrimitiveType.LONG)) {
      writer.print("((Long) " + reference + ").longValue()");

      return true;
    }

    if ((type.isPrimitive() != null) && (type.isPrimitive() == JPrimitiveType.FLOAT)) {
      writer.print("((Float) " + reference + ").floatValue()");

      return true;
    }

    if ((type.isPrimitive() != null) && (type.isPrimitive() == JPrimitiveType.DOUBLE)) {
      writer.print("((Double) " + reference + ").doubleValue()");

      return true;
    }

    if ((type.isPrimitive() != null) && (type.isPrimitive() == JPrimitiveType.CHAR)) {
      writer.print("((Character) " + reference + ").charValue()");

      return true;
    }

    if ((type.isPrimitive() != null) && (type.isPrimitive() == JPrimitiveType.BYTE)) {
      writer.print("((Byte) " + reference + ").byteValue()");

      return true;
    }

    if ((type.isPrimitive() != null) && (type.isPrimitive() == JPrimitiveType.BOOLEAN)) {
      writer.print("((Boolean) " + reference + ").booleanValue()");

      return true;
    }

    writer.print("(" + type.getQualifiedSourceName() + ") " + reference);

    return false;
  }
コード例 #7
0
  private boolean box(JType type, SourceWriter writer) {
    if ((type.isPrimitive() != null) && (type.isPrimitive() == JPrimitiveType.INT)) {
      writer.print("new Integer( ");

      return true;
    }

    if ((type.isPrimitive() != null) && (type.isPrimitive() == JPrimitiveType.LONG)) {
      writer.print("new Long( ");

      return true;
    }

    if ((type.isPrimitive() != null) && (type.isPrimitive() == JPrimitiveType.FLOAT)) {
      writer.print("new Float( ");

      return true;
    }

    if ((type.isPrimitive() != null) && (type.isPrimitive() == JPrimitiveType.DOUBLE)) {
      writer.print("new Double( ");

      return true;
    }

    if ((type.isPrimitive() != null) && (type.isPrimitive() == JPrimitiveType.CHAR)) {
      writer.print("new Character( ");

      return true;
    }

    if ((type.isPrimitive() != null) && (type.isPrimitive() == JPrimitiveType.BYTE)) {
      writer.print("new Byte( ");

      return true;
    }

    if ((type.isPrimitive() != null) && (type.isPrimitive() == JPrimitiveType.BOOLEAN)) {
      writer.print("new Boolean( ");

      return true;
    }

    return false;
  }
コード例 #8
0
  /** Simply prints a JSNI reference to the exported function. */
  private static void writeIdentityInvocation(FragmentGeneratorContext context, JMethod m)
      throws UnableToCompleteException {
    SourceWriter sw = context.sw;
    JParameter[] parameters = m.getParameters();

    sw.print("@");
    sw.print(m.getEnclosingType().getQualifiedSourceName());
    sw.print("::");
    sw.print(m.getName());
    sw.print("(");

    // Argument list for the Java invocation
    for (int i = 0; i < parameters.length; i++) {
      sw.print(parameters[i].getType().getJNISignature());
    }

    sw.print(")");
  }
コード例 #9
0
 /**
  * Generate a class which can select between alternate implementations at runtime based on the
  * runtime locale.
  *
  * @param logger TreeLogger instance for log messages
  * @param context GeneratorContext for generating source files
  * @param targetClass class to generate
  * @param compileLocale the compile-time locale we are generating for
  * @param locales set of all locales to generate
  * @return fully-qualified class name that was generated
  */
 private String generateRuntimeSelection(
     TreeLogger logger,
     GeneratorContext context,
     JClassType targetClass,
     GwtLocale compileLocale,
     Set<GwtLocale> locales) {
   String packageName = targetClass.getPackage().getName();
   String className =
       targetClass.getName().replace('.', '_')
           + "_"
           + compileLocale.getAsString()
           + "_runtimeSelection";
   PrintWriter pw = context.tryCreate(logger, packageName, className);
   if (pw != null) {
     ClassSourceFileComposerFactory factory =
         new ClassSourceFileComposerFactory(packageName, className);
     factory.setSuperclass(targetClass.getQualifiedSourceName());
     factory.addImport(CURRENCY_DATA);
     factory.addImport(JAVASCRIPTOBJECT);
     factory.addImport(HASHMAP);
     factory.addImport("com.google.gwt.i18n.client.LocaleInfo");
     SourceWriter writer = factory.createSourceWriter(context, pw);
     writer.println("private CurrencyList instance;");
     writer.println();
     writer.println("@Override");
     writer.println("protected CurrencyData getDefaultJava() {");
     writer.println("  ensureInstance();");
     writer.println("  return instance.getDefaultJava();");
     writer.println("}");
     writer.println();
     writer.println("@Override");
     writer.println("protected CurrencyData getDefaultNative() {");
     writer.println("  ensureInstance();");
     writer.println("  return instance.getDefaultNative();");
     writer.println("}");
     writer.println();
     writer.println("@Override");
     writer.println("protected HashMap<String, CurrencyData> loadCurrencyMapJava() {");
     writer.println("  ensureInstance();");
     writer.println("  return instance.loadCurrencyMapJava();");
     writer.println("}");
     writer.println();
     writer.println("@Override");
     writer.println("protected JavaScriptObject loadCurrencyMapNative() {");
     writer.println("  ensureInstance();");
     writer.println("  return instance.loadCurrencyMapNative();");
     writer.println("}");
     writer.println();
     writer.println("@Override");
     writer.println("protected HashMap<String, String> loadNamesMapJava() {");
     writer.println("  ensureInstance();");
     writer.println("  return instance.loadNamesMapJava();");
     writer.println("}");
     writer.println();
     writer.println("@Override");
     writer.println("protected JavaScriptObject loadNamesMapNative() {");
     writer.println("  ensureInstance();");
     writer.println("  return instance.loadNamesMapNative();");
     writer.println("}");
     writer.println();
     writer.println("private void ensureInstance() {");
     writer.indent();
     writer.println("if (instance != null) {");
     writer.println("  return;");
     writer.println("}");
     boolean fetchedLocale = false;
     Map<String, Set<GwtLocale>> localeMap = new TreeMap<String, Set<GwtLocale>>();
     String compileLocaleClass =
         processChildLocale(logger, context, targetClass, localeMap, compileLocale);
     if (compileLocaleClass == null) {
       // already gave warning, just use default implementation
       return null;
     }
     for (GwtLocale runtimeLocale : locales) {
       processChildLocale(logger, context, targetClass, localeMap, runtimeLocale);
     }
     for (Entry<String, Set<GwtLocale>> entry : localeMap.entrySet()) {
       if (!fetchedLocale) {
         writer.println("String runtimeLocale = LocaleInfo.getCurrentLocale().getLocaleName();");
         fetchedLocale = true;
       }
       boolean firstLocale = true;
       String generatedClass = entry.getKey();
       if (compileLocaleClass.equals(generatedClass)) {
         // The catch-all will handle this
         continue;
       }
       writer.print("if (");
       for (GwtLocale locale : entry.getValue()) {
         if (firstLocale) {
           firstLocale = false;
         } else {
           writer.println();
           writer.print("    || ");
         }
         writer.print("\"" + locale.toString() + "\".equals(runtimeLocale)");
       }
       writer.println(") {");
       writer.println("  instance = new " + generatedClass + "();");
       writer.println("  return;");
       writer.println("}");
     }
     writer.println("instance = new " + compileLocaleClass + "();");
     writer.outdent();
     writer.println("}");
     writer.commit(logger);
   }
   return packageName + "." + className;
 }
コード例 #10
0
ファイル: ProxyCreator.java プロジェクト: epuidokas/gwt-2.4
  /**
   * Generates the client's asynchronous proxy method.
   *
   * @param serializableTypeOracle the type oracle
   */
  protected void generateProxyMethod(
      SourceWriter w,
      SerializableTypeOracle serializableTypeOracle,
      TypeOracle typeOracle,
      JMethod syncMethod,
      JMethod asyncMethod) {

    w.println();

    // Write the method signature
    JType asyncReturnType = asyncMethod.getReturnType().getErasedType();
    w.print("public ");
    w.print(asyncReturnType.getQualifiedSourceName());
    w.print(" ");
    w.print(asyncMethod.getName() + "(");

    boolean needsComma = false;
    NameFactory nameFactory = new NameFactory();
    JParameter[] asyncParams = asyncMethod.getParameters();
    for (int i = 0; i < asyncParams.length; ++i) {
      JParameter param = asyncParams[i];

      if (needsComma) {
        w.print(", ");
      } else {
        needsComma = true;
      }

      /*
       * Ignoring the AsyncCallback parameter, if any method requires a call to
       * SerializationStreamWriter.writeObject we need a try catch block
       */
      JType paramType = param.getType();
      paramType = paramType.getErasedType();

      w.print(paramType.getQualifiedSourceName());
      w.print(" ");

      String paramName = param.getName();
      nameFactory.addName(paramName);
      w.print(paramName);
    }

    w.println(") {");
    w.indent();

    String helperName = nameFactory.createName("helper");
    String helperClassName = RemoteServiceProxy.ServiceHelper.class.getCanonicalName();
    w.println(
        "%s %s = new %s(\"%s\", \"%s\");",
        helperClassName, helperName, helperClassName, getProxySimpleName(), syncMethod.getName());

    w.println("try {");
    w.indent();

    // Write the parameter count followed by the parameter values
    JParameter[] syncParams = syncMethod.getParameters();

    String streamWriterName = nameFactory.createName("streamWriter");
    w.println(
        "%s %s = %s.start(REMOTE_SERVICE_INTERFACE_NAME, %s);",
        SerializationStreamWriter.class.getSimpleName(),
        streamWriterName,
        helperName,
        syncParams.length);

    for (JParameter param : syncParams) {
      JType paramType = param.getType().getErasedType();
      String typeNameExpression = computeTypeNameExpression(paramType);
      assert typeNameExpression != null
          : "Could not compute a type name for " + paramType.getQualifiedSourceName();
      w.println(streamWriterName + ".writeString(" + typeNameExpression + ");");
    }

    // Encode all of the arguments to the asynchronous method, but exclude the
    // last argument which is the callback instance.
    //
    for (int i = 0; i < asyncParams.length - 1; ++i) {
      JParameter asyncParam = asyncParams[i];
      w.print(streamWriterName + ".");
      w.print(Shared.getStreamWriteMethodNameFor(asyncParam.getType()));
      w.println("(" + asyncParam.getName() + ");");
    }

    /*
     * Depending on the return type for the async method, return a
     * RequestBuilder, a Request, or nothing at all.
     */
    JParameter callbackParam = asyncParams[asyncParams.length - 1];
    JType returnType = syncMethod.getReturnType();
    String callbackName = callbackParam.getName();

    if (asyncReturnType == JPrimitiveType.VOID) {
      w.println(
          "%s.finish(%s, ResponseReader.%s);",
          helperName, callbackName, getResponseReaderFor(returnType).name());
    } else if (asyncReturnType.getQualifiedSourceName().equals(RequestBuilder.class.getName())) {
      w.println(
          "return %s.finishForRequestBuilder(%s, ResponseReader.%s);",
          helperName, callbackName, getResponseReaderFor(returnType).name());
    } else if (asyncReturnType.getQualifiedSourceName().equals(Request.class.getName())) {
      w.println(
          "return %s.finish(%s, ResponseReader.%s);",
          helperName, callbackName, getResponseReaderFor(returnType).name());
    } else {
      // This method should have been caught by RemoteServiceAsyncValidator
      throw new RuntimeException(
          "Unhandled return type " + asyncReturnType.getQualifiedSourceName());
    }

    w.outdent();
    w.print("} catch (SerializationException ");
    String exceptionName = nameFactory.createName("ex");
    w.println(exceptionName + ") {");
    w.indent();
    if (!asyncReturnType.getQualifiedSourceName().equals(RequestBuilder.class.getName())) {
      /*
       * If the method returns void or Request, signal the serialization error
       * immediately. If the method returns RequestBuilder, the error will be
       * signaled whenever RequestBuilder.send() is invoked.
       */
      w.println(callbackName + ".onFailure(" + exceptionName + ");");
    }
    if (asyncReturnType.getQualifiedSourceName().equals(RequestBuilder.class.getName())) {
      w.println(
          "return new "
              + FailingRequestBuilder.class.getName()
              + "("
              + exceptionName
              + ", "
              + callbackName
              + ");");
    } else if (asyncReturnType.getQualifiedSourceName().equals(Request.class.getName())) {
      w.println("return new " + FailedRequest.class.getName() + "();");
    } else {
      assert asyncReturnType == JPrimitiveType.VOID;
    }
    w.outdent();
    w.println("}");

    w.outdent();
    w.println("}");
  }
コード例 #11
0
 private void writeMethods(TreeLogger logger, MethodWrapper[] methods, SourceWriter writer) {
   for (int i = 0; i < methods.length; i++) {
     writer.print("public static final Method METHOD_" + i + " = ");
     writeMethod(logger, methods[i], writer);
   }
 }
コード例 #12
0
  public String generate(TreeLogger logger, GeneratorContext context, String typeName)
      throws UnableToCompleteException {
    // .println("Introspector Generate.");
    try {
      this.objectType = context.getTypeOracle().getType("java.lang.Object");
    } catch (NotFoundException ex) {
      logger.log(TreeLogger.ERROR, typeName, ex);

      return null;
    }

    List<BeanResolver> introspectables =
        this.getIntrospectableTypes(logger, context.getTypeOracle());

    MethodWrapper[] methods = this.findMethods(logger, introspectables);

    ClassSourceFileComposerFactory mcf =
        new ClassSourceFileComposerFactory(this.packageName, this.methodsImplementationName);
    mcf.addImport(Method.class.getCanonicalName());

    PrintWriter methodsPrintWriter =
        context.tryCreate(logger, this.packageName, this.methodsImplementationName);

    if (methodsPrintWriter != null) {
      SourceWriter methodsWriter = mcf.createSourceWriter(context, methodsPrintWriter);
      this.writeMethods(logger, methods, methodsWriter);
      methodsWriter.println("}");
      context.commit(logger, methodsPrintWriter);
    }

    ClassSourceFileComposerFactory cfcf =
        new ClassSourceFileComposerFactory(this.packageName, this.implementationName);
    cfcf.addImplementedInterface(typeName);
    cfcf.addImport("java.util.HashMap");
    cfcf.addImport(Method.class.getCanonicalName());
    cfcf.addImport(com.totsp.gwittir.introspection.Property.class.getCanonicalName());
    cfcf.addImport(com.totsp.gwittir.introspection.BeanDescriptor.class.getCanonicalName());

    PrintWriter printWriter = context.tryCreate(logger, packageName, implementationName);

    if (printWriter == null) {
      // .println( "Introspector Generate skipped.");
      return packageName + "." + implementationName;
    }

    SourceWriter writer = cfcf.createSourceWriter(context, printWriter);
    this.writeIntrospectables(logger, introspectables, methods, writer);
    this.writeResolver(introspectables, writer);

    writer.println(
        "private HashMap<Class,BeanDescriptor> beanDescriptorLookup = new HashMap<Class,BeanDescriptor>();");
    writer.println();
    writer.println("public BeanDescriptor getDescriptor( Object object ){ ");
    writer.indent();
    writer.println(
        "if( object == null ) throw new NullPointerException(\"Attempt to introspect null object\");");
    writer.println(
        "if( object instanceof "
            + SelfDescribed.class.getCanonicalName()
            + " ) return ((SelfDescribed)object).__descriptor();");
    writer.println("BeanDescriptor descriptor = beanDescriptorLookup.get(object.getClass());");
    writer.println("if (descriptor!=null){");
    writer.indentln("return descriptor;");
    writer.outdent();
    writer.println("}");

    writer.println("descriptor=_getDescriptor(object);");
    writer.println("beanDescriptorLookup.put(object.getClass(),descriptor);");
    writer.println("return descriptor;");
    writer.outdent();
    writer.println("}");

    writer.println("private BeanDescriptor _getDescriptor( Object object ){ ");
    writer.indent();

    for (BeanResolver resolver : introspectables) {
      writer.println(
          "if( object instanceof " + resolver.getType().getQualifiedSourceName() + " ) {");
      writer.indent();

      String name = resolver.getType().getQualifiedSourceName().replaceAll("\\.", "_");
      logger.log(TreeLogger.DEBUG, "Writing : " + name, null);
      writer.print("return " + name + " == null ? " + name + " = ");
      this.writeBeanDescriptor(logger, resolver, methods, writer);
      writer.print(": " + name + ";");
      writer.outdent();
      writer.println("}");
    }

    writer.println(" throw new IllegalArgumentException(\"Unknown type\" + object.getClass() ); ");
    writer.outdent();
    writer.println("}");
    writer.println("public Object createInstance(Class clazz) {");
    writer.indent();
    for (BeanResolver resolver : introspectables) {
      boolean hasPNA = false;
      for (JConstructor constructor : resolver.getType().getConstructors()) {
        if (constructor.getParameters() == null
            || constructor.getParameters().length == 0 && constructor.isPublic()) {
          hasPNA = true;
          break;
        }
        if (hasPNA) {
          break;
        }
      }

      writer.println(
          "if(clazz.equals(" + resolver.getType().getQualifiedSourceName() + ".class)){");
      writer.indent();
      logger.log(
          TreeLogger.Type.TRACE,
          resolver.getType().getQualifiedSourceName()
              + " abstract "
              + resolver.getType().isAbstract()
              + " intf "
              + (resolver.getType().isInterface() != null)
              + " def "
              + resolver.getType().isDefaultInstantiable());
      if (resolver.getType().isAbstract() || resolver.getType().isInterface() != null) {
        writer.println("throw new IllegalArgumentException(clazz+\" is abstract\");");
      } else if (hasPNA) {
        writer.println("return new " + resolver.getType().getQualifiedSourceName() + "();");
      } else {
        writer.println(
            "throw new IllegalArgumentException(clazz+\" has no public no args constructor\");");
      }
      writer.outdent();
      writer.println("}");
    }
    writer.println(" throw new IllegalArgumentException(\"Unknown type\" +clazz ); ");
    writer.outdent();
    writer.println("}");

    writer.println("HashMap<String, Class> classes = new HashMap<String, Class>();");
    writer.println("public Class forName(String className){");
    writer.indent();
    writer.println("Class clazz = classes.get(className);");
    writer.println("if(clazz != null) return clazz;");
    for (BeanResolver resolver : introspectables) {
      writer.println(
          "if(className.equals(\"" + resolver.getType().getQualifiedSourceName() + "\")){");
      writer.indent();
      writer.println("clazz = " + resolver.getType().getQualifiedSourceName() + ".class;");
      writer.println("classes.put(className, clazz);");
      writer.println("return clazz;");
      writer.outdent();
      writer.println("}");
    }
    writer.println("throw new IllegalArgumentException(className+\" is not introspecable.\");");
    writer.outdent();
    writer.println("}");
    writer.outdent();
    writer.println("}");

    context.commit(logger, printWriter);

    // .println( "Introspector Generate completed.");
    return packageName + "." + implementationName;
  }
コード例 #13
0
  /** Writes a linkage function object that will invoke the exported function. */
  private static void writeLinkageInvocation(FragmentGeneratorContext context, JMethod m)
      throws UnableToCompleteException {
    TreeLogger logger =
        context.parentLogger.branch(
            TreeLogger.DEBUG, "Writing function() for " + m.getName(), null);

    SourceWriter sw = context.sw;
    JParameter[] parameters = m.getParameters();
    FragmentGeneratorOracle fgo = context.fragmentGeneratorOracle;
    FragmentGenerator returnFragmentGenerator =
        fgo.findFragmentGenerator(logger, context.typeOracle, m.getReturnType());

    sw.print("function(");
    for (int i = 0; i < parameters.length; i++) {
      sw.print("arg");
      sw.print(String.valueOf(i));
      if (i < parameters.length - 1) {
        sw.print(", ");
      }
    }
    sw.println(") {");
    sw.indent();

    if (returnFragmentGenerator.isIdentity()) {
      sw.print("return ");
    } else {
      sw.print("var javaReturn = ");
    }

    // Don't need to reference the instance on a static method
    if (!m.isStatic()) {
      sw.print(context.parameterName);
      sw.print(".");
    }

    sw.print("@");
    sw.print(m.getEnclosingType().getQualifiedSourceName());
    sw.print("::");
    sw.print(m.getName());
    sw.print("(");

    // Argument list for the Java invocation
    for (int i = 0; i < parameters.length; i++) {
      sw.print(parameters[i].getType().getJNISignature());
    }

    sw.println(")(");
    // Indent the parameters, each on its own like to improve readability
    sw.indent();
    sw.indent();

    for (int i = 0; i < parameters.length; i++) {
      // Create a sub-context to generate the wrap/unwrap logic
      JType returnType = parameters[i].getType();
      FragmentGeneratorContext subParams = new FragmentGeneratorContext(context);
      subParams.returnType = returnType;
      subParams.parameterName = "arg" + i;

      FragmentGenerator fragmentGenerator =
          fgo.findFragmentGenerator(logger, context.typeOracle, returnType);
      if (fragmentGenerator == null) {
        logger.log(
            TreeLogger.ERROR,
            "No fragment generator for " + returnType.getQualifiedSourceName(),
            null);
        throw new UnableToCompleteException();
      }

      fragmentGenerator.fromJS(subParams);

      if (i < parameters.length - 1) {
        sw.println(", ");
      }
    }

    sw.outdent();
    sw.outdent();
    sw.println(");");

    if (!returnFragmentGenerator.isIdentity()) {
      FragmentGeneratorContext returnContext = new FragmentGeneratorContext(context);
      returnContext.parameterName = "javaReturn";
      returnContext.returnType = m.getReturnType();
      sw.print("return ");
      returnFragmentGenerator.toJS(returnContext);
      sw.println(";");
    }

    sw.outdent();
    sw.print("}");
  }
コード例 #14
0
  private void writeBeanDescriptor(
      TreeLogger logger, BeanResolver info, MethodWrapper[] methods, SourceWriter writer) {
    writer.println("new BeanDescriptor() { ");
    writer.indent();
    writer.println("private HashMap lookup;");
    writer.println("private Property[] properties;");
    writer.println("public Property[] getProperties(){");
    writer.indent();

    {
      writer.println("if( this.properties != null ) ");
      writer.indentln("return this.properties;");
      writer.println("this.properties = new Property[" + (info.getProperties().size()) + "];");

      Collection pds = info.getProperties().values();
      String[] propertyNames = new String[pds.size()];
      logger.log(TreeLogger.SPAM, "" + (pds == null), null);

      if (pds != null) {
        int i = 0;

        for (Iterator it = pds.iterator(); it.hasNext(); i++) {
          RProperty p = (RProperty) it.next();
          propertyNames[i] = p.getName();
          writer.println("{");
          writer.indent();

          writer.print("Method readMethod = ");

          if (p.getReadMethod() == null) {
            writer.println("null;");
          } else {
            writer.println(
                this.packageName
                    + "."
                    + this.methodsImplementationName
                    + ".METHOD_"
                    + +this.find(methods, p.getReadMethod())
                    + ";");
          }

          writer.print("Method writeMethod = ");

          if (p.getWriteMethod() == null) {
            writer.println("null;");
          } else {
            writer.println(
                this.packageName
                    + "."
                    + this.methodsImplementationName
                    + ".METHOD_"
                    + +this.find(methods, p.getWriteMethod())
                    + ";");
          }

          logger.log(
              TreeLogger.DEBUG, p.getName() + " " + p.getType().getQualifiedSourceName(), null);

          JType ptype = this.resolveType(p.getType());

          logger.log(
              TreeLogger.DEBUG, p.getName() + " (Erased) " + ptype.getQualifiedSourceName(), null);
          writer.println(
              "this.properties["
                  + (i)
                  + "] = new Property( \""
                  + p.getName()
                  + "\", "
                  + ((p.getType() != null) ? ptype.getQualifiedSourceName() : "Object")
                  + ".class,  readMethod, writeMethod );");
          writer.outdent();
          writer.println("}");
        }
      }

      writer.println("return this.properties;");
    }

    writer.outdent();
    writer.println("} //end getProperties()");
    writer.println("public Property getProperty( String name ) {");
    writer.indent();
    // TODO Rewrite this to a nested if loop using the propertyNames parameter.
    writer.println("Property p = null;");
    writer.println("if( this.lookup != null ) {");
    writer.indentln("p = (Property) lookup.get(name); ");
    writer.println("} else {");
    writer.indent();
    writer.println("this.lookup = new HashMap();");
    writer.println("Property[] props = this.getProperties(); ");
    writer.println("for( int i=0; i < props.length; i++ ) {");
    writer.indent();
    writer.println("this.lookup.put( props[i].getName(), props[i] );");
    writer.outdent();
    writer.println("}");
    writer.println("p = (Property) this.lookup.get(name);");
    writer.outdent();
    writer.println("}");
    writer.println(
        "if( p == null ) throw new RuntimeException(\"Couldn't find property \"+name+\" for "
            + info.getType().getQualifiedSourceName()
            + "\");");
    writer.println("else return p;");
    writer.outdent();
    writer.println("}");

    writer.outdent();
    writer.print("}");
  }
コード例 #15
0
  /**
   * Write an entry in the methodMapNative for one type.
   *
   * @param type type to generate entry for
   */
  private void writeTypeMethodsNative(JType type) {
    srcWriter.indent();
    String serializerName = SerializationUtils.getFieldSerializerName(typeOracle, type);
    JClassType customSerializer =
        SerializableTypeOracleBuilder.findCustomFieldSerializer(typeOracle, type);

    // First the initialization method
    if (deserializationOracle.maybeInstantiated(type)) {
      srcWriter.print("@");
      if (customSerializer != null) {
        if (hasInstantiateMethod(customSerializer, type)) {
          srcWriter.print(serializerName);
        } else {
          srcWriter.print(SerializationUtils.getStandardSerializerName((JClassType) type));
        }
      } else {
        srcWriter.print(serializerName);
      }
      srcWriter.print("::instantiate");
      srcWriter.print("(L" + SerializationStreamReader.class.getName().replace('.', '/') + ";)");
    }
    srcWriter.println(",");

    // Now the deserialization method
    if (deserializationOracle.isSerializable(type)) {
      // Assume param type is the concrete type of the serialized type.
      JType paramType = type;
      if (customSerializer != null) {
        // But a custom serializer may specify a looser type.
        JMethod deserializationMethod =
            CustomFieldSerializerValidator.getDeserializationMethod(
                customSerializer, (JClassType) type);
        paramType = deserializationMethod.getParameters()[1].getType();
      }
      srcWriter.print("@" + serializerName);
      srcWriter.print(
          "::deserialize(L"
              + SerializationStreamReader.class.getName().replace('.', '/')
              + ";"
              + paramType.getJNISignature()
              + ")");
    }
    srcWriter.println(",");

    // Now the serialization method
    if (serializationOracle.isSerializable(type)) {
      // Assume param type is the concrete type of the serialized type.
      JType paramType = type;
      if (customSerializer != null) {
        // But a custom serializer may specify a looser type.
        JMethod serializationMethod =
            CustomFieldSerializerValidator.getSerializationMethod(
                customSerializer, (JClassType) type);
        paramType = serializationMethod.getParameters()[1].getType();
      }
      srcWriter.print("@" + serializerName);
      srcWriter.print(
          "::serialize(L"
              + SerializationStreamWriter.class.getName().replace('.', '/')
              + ";"
              + paramType.getJNISignature()
              + ")");
      srcWriter.println();
    }
    srcWriter.outdent();
  }
コード例 #16
0
  private String buildRpcInterfaces(
      TreeLogger logger, GeneratorContext context, RequestQueueModel model) {
    String rqType = model.getRequestQueueInterfaceName();
    int lastDot = rqType.lastIndexOf('.');
    String packageName = rqType.substring(0, lastDot - 1);
    String serviceSourceName = rqType.substring(lastDot).replace('.', '_') + "_ImplRPC";
    String asyncSourceName = serviceSourceName + "Async";
    PrintWriter pw = context.tryCreate(logger, packageName, asyncSourceName);
    if (pw == null) {
      return packageName + "." + serviceSourceName;
    }

    // Create async class
    ClassSourceFileComposerFactory factory =
        new ClassSourceFileComposerFactory(packageName, asyncSourceName);
    factory.addImplementedInterface(ServiceQueueBaseAsync.class.getName());
    factory.makeInterface();
    SourceWriter asyncSw = factory.createSourceWriter(context, pw);

    // Create service class
    pw = context.tryCreate(logger, packageName, serviceSourceName);
    assert pw != null;
    factory = new ClassSourceFileComposerFactory(packageName, serviceSourceName);
    factory.addImplementedInterface(ServiceQueueBase.class.getName());
    factory.makeInterface();
    SourceWriter serviceSw = factory.createSourceWriter(context, pw);

    // write out service and async
    int i = 0;
    for (AsyncServiceModel service : model.getServices()) {
      for (AsyncServiceMethodModel method : service.getMethods()) {
        String methodName = "a" + ++i;
        asyncSw.println("void %1$s(", methodName);
        serviceSw.println("%2$s %1$s(", methodName, method.getReturnTypeName());
        asyncSw.indent();
        serviceSw.indent();

        boolean firstArgument = true;
        int argIndex = 0;
        for (JType arg : method.getArgTypes()) {
          if (!firstArgument) {
            asyncSw.println(",");
            serviceSw.println(",");
          }
          firstArgument = false;

          if (arg.isPrimitive() != null) {
            JPrimitiveType t = arg.isPrimitive();
            asyncSw.println("%2$s arg%1$d", argIndex, t.getQualifiedBoxedSourceName());
            serviceSw.println("%2$s arg%1$d", argIndex, t.getQualifiedBoxedSourceName());
          } else {
            asyncSw.println("%2$s arg%1$d", argIndex, arg.getParameterizedQualifiedSourceName());
            serviceSw.println("%2$s arg%1$d", argIndex, arg.getParameterizedQualifiedSourceName());
          }

          argIndex++;
        }
        if (!firstArgument) {
          asyncSw.print(", ");
        }
        // TODO return type boxing
        asyncSw.println(
            "%1$s<%2$s>callback);", AsyncCallback.class.getName(), method.getReturnTypeName());
        serviceSw.print(")");
        if (!method.getThrowables().isEmpty()) {
          serviceSw.print(" throws ");
          boolean firstThrowable = true;
          for (JClassType throwable : method.getThrowables()) {
            if (!firstThrowable) {
              serviceSw.print(", ");
            }
            firstThrowable = false;
            serviceSw.print(throwable.getQualifiedSourceName());
          }
        }
        serviceSw.println(";");
        asyncSw.outdent();
        serviceSw.outdent();
      }
    }

    asyncSw.commit(logger);
    serviceSw.commit(logger);

    return factory.getCreatedClassName();
  }
コード例 #17
0
  public static InjectionCallbackArtifact ensureAsyncInjected(
      TreeLogger logger,
      String packageName,
      String className,
      String outputClass,
      GeneratorContext ctx)
      throws UnableToCompleteException {

    GwtInjectionMap gwtInjectionMap = getInjectionMap(logger, ctx);
    InjectionCallbackArtifact artifact =
        gwtInjectionMap.getOrCreateArtifact(ctx, packageName, className);
    if (artifact.isTargetUnbound()) {
      artifact.bindTo(outputClass);
      ensureProviderClass(
          logger,
          packageName,
          artifact.getSimpleName(),
          artifact.getCanonicalName(),
          artifact.getBoundTarget(),
          ctx);
      logger =
          logger.branch(
              Type.TRACE,
              "Creating asynchronous callback for "
                  + artifact.getCanonicalName()
                  + " -> "
                  + outputClass);
      String generatedName = InjectionUtils.generatedAsyncProviderName(artifact.getGeneratedName());
      String implPackage = artifact.getImplementationPackage();
      PrintWriter printWriter = ctx.tryCreate(logger, implPackage, generatedName);
      if (printWriter == null) {
        logger.log(
            Type.WARN,
            "Could not create the source writer for " + implPackage + "." + generatedName);
        return artifact;
      }
      artifact.addCallback(implPackage + "." + generatedName + ".Deproxy");
      ctx.commitArtifact(logger, artifact);

      ClassSourceFileComposerFactory composer =
          new ClassSourceFileComposerFactory(implPackage, generatedName);
      composer.setPrivacy("public final");

      composer.addImport(com.google.gwt.core.client.GWT.class.getName());
      composer.addImport(RunAsyncCallback.class.getName());
      composer.addImport(Fifo.class.getName());
      composer.addImport(JsFifo.class.getName());
      composer.addImport(AsyncProxy.class.getName());
      composer.addImport(ApplyMethod.class.getName());
      composer.addImport(ReceivesValue.class.getName());
      composer.addImport(ReceiverAdapter.class.getCanonicalName());
      composer.addImport(artifact.getCanonicalName());

      String simpleName = artifact.getSimpleName();
      SourceWriter sw = composer.createSourceWriter(ctx, printWriter);

      sw.println();
      sw.println("static final class Callbacks implements ApplyMethod{");
      sw.indent();
      sw.println("public void apply(Object ... args){");
      sw.println("}");
      sw.outdent();
      sw.println("}");
      sw.println();

      sw.println("static final class Deproxy implements ReceivesValue<" + simpleName + ">{");
      sw.indent();
      sw.println("public final void set(final " + simpleName + " value){");
      sw.indentln("getter = new ReceiverAdapter<" + simpleName + ">(value);");
      sw.println("}");
      sw.outdent();
      sw.println("}");
      sw.println();

      sw.println(
          "private static final class Proxy implements ReceivesValue<ReceivesValue<"
              + simpleName
              + ">>{");
      sw.indent();
      sw.println("public final void set(final ReceivesValue<" + simpleName + "> receiver){");
      sw.indent();

      sw.print("GWT.runAsync(");
      sw.println(artifact.getCanonicalName() + ".class,new Request(receiver));");

      sw.outdent();
      sw.println("}");
      sw.outdent();
      sw.println("}");
      sw.println();

      sw.println("private static final class Request");
      sw.indent();
      sw.println("extends AsyncProxy<" + simpleName + "> ");
      sw.println("implements RunAsyncCallback{");

      DefermentWriter defer = new DefermentWriter(sw);
      defer.setStrategy(DefermentStrategy.NONE);

      sw.println("private static final Fifo<ReceivesValue<" + simpleName + ">> pending =");
      sw.indentln("JsFifo.newFifo();");
      sw.println();

      sw.println("protected Request(ReceivesValue<" + simpleName + "> receiver){");
      sw.indentln("accept(receiver);");
      sw.println("}");
      sw.println();

      sw.println("@Override");
      sw.println("protected final Fifo<ReceivesValue<" + simpleName + ">> pending(){");
      sw.indentln("return pending;");
      sw.println("}");
      sw.println();

      sw.println("protected final void dispatch(){");
      sw.indentln("go();");
      sw.println("}");
      sw.println();

      sw.println("public final void onSuccess(){");
      sw.indent();
      defer.printStart();

      sw.println("final " + simpleName + " value = ");
      sw.print(packageName + "." + InjectionUtils.generatedProviderName(simpleName));
      sw.println(".theProvider.get();");
      sw.println();

      sw.print("final ApplyMethod callbacks = GWT.create(");
      sw.print(packageName + ".impl." + generatedName + ".Callbacks.class");
      sw.println(");");
      sw.println("callbacks.apply(value);");
      sw.println();

      sw.println("apply(value);");
      sw.outdent();
      sw.println("}");
      sw.outdent();
      defer.printFinish();
      sw.println("}");
      sw.println();

      sw.println(
          "private static ReceivesValue<ReceivesValue<" + simpleName + ">> getter = new Proxy();");
      sw.println();

      sw.println("static void request(final ReceivesValue<" + simpleName + "> request){");
      sw.indentln("getter.set(request);");
      sw.println("}");
      sw.println();

      sw.println("static void go(){");
      sw.indentln("request(null);");
      sw.println("}");
      sw.println();

      sw.println("private " + generatedName + "(){}");

      sw.commit(logger);

    } else {
      assert artifact.getBoundTarget().equals(outputClass)
          : "The injection target "
              + artifact.getCanonicalName()
              + " was bound "
              + "to "
              + artifact.getBoundTarget()
              + ", but you tried to bind it again, "
              + "to a different class: "
              + outputClass;
    }
    return artifact;
  }
コード例 #18
0
    private void emitBody(SourceWriter w) throws NotFoundException {
      JClassType baseClass =
          context_.getTypeOracle().getType("org.rstudio.core.client.js.JsObjectInjector");
      JClassType c = baseType_.asParameterizationOf(baseClass.isGenericType());
      JType typeToInject = c.isParameterized().getTypeArgs()[0];

      w.print("public native final void injectObject(");
      w.print(typeToInject.getQualifiedSourceName());
      w.println(" value) /*-{");
      w.indent();

      w.println(baseExpression_ + " = {");
      w.indent();

      JMethod[] methods = typeToInject.isClassOrInterface().getMethods();
      for (int i = 0; i < methods.length; i++) {
        JMethod method = methods[i];
        final JParameter[] jParameters = method.getParameters();

        StringBuilder argString = new StringBuilder();
        for (int j = 0; j < jParameters.length; j++) {
          argString.append("_").append(j);
          if (j < jParameters.length - 1) argString.append(", ");
        }

        w.println(method.getName() + ": function(" + argString + ") {");
        w.indent();

        if (!method.getReturnType().getQualifiedSourceName().equals("void")) w.print("return ");
        w.print("value.@");
        w.print(typeToInject.getQualifiedSourceName());
        w.print("::");
        w.print(method.getName());
        w.print("(");
        for (JParameter param : jParameters) w.print(param.getType().getJNISignature());
        w.print(")(");
        w.print(argString.toString());
        w.println(");");

        w.outdent();
        w.print("}");
        w.println((i < methods.length - 1) ? "," : "");
      }

      w.outdent();
      w.println("};");

      w.outdent();
      w.println("}-*/;");
    }
コード例 #19
0
  @Override
  public String generate(TreeLogger logger, GeneratorContext context, String typeName)
      throws UnableToCompleteException {
    TypeOracle oracle = context.getTypeOracle();

    // JClassType requestQueue = oracle.findType(RequestQueue.class.getName());
    JClassType toGenerate = oracle.findType(typeName);

    if (toGenerate == null) {
      logger.log(TreeLogger.ERROR, typeName + " is not an interface type");
      throw new UnableToCompleteException();
    }

    String packageName = toGenerate.getPackage().getName();
    String simpleSourceName = toGenerate.getName().replace('.', '_') + "_Impl";
    PrintWriter pw = context.tryCreate(logger, packageName, simpleSourceName);
    if (pw == null) {
      return packageName + "." + simpleSourceName;
    }

    ClassSourceFileComposerFactory factory =
        new ClassSourceFileComposerFactory(packageName, simpleSourceName);
    factory.setSuperclass(AbstractRequestQueueImpl.class.getName());
    factory.addImplementedInterface(typeName);
    SourceWriter sw = factory.createSourceWriter(context, pw);

    // Collect async services we need to provide access to, and the rpc calls they'll make
    RequestQueueModel model =
        collectModel(logger.branch(Type.DEBUG, "Collecting service info"), context, toGenerate);

    // Build a pair of RPC interfaces for serialization
    String realRpcInterfaceName =
        buildRpcInterfaces(logger.branch(Type.DEBUG, "Writing RPC interfaces"), context, model);

    // Build the getRealService() method
    String serviceQueueAsync = ServiceQueueBaseAsync.class.getName();
    sw.println("public %1$s getRealService() {", serviceQueueAsync);
    sw.indentln(
        "return %3$s.<%1$s>create(%2$s.class);",
        serviceQueueAsync, realRpcInterfaceName, GWT.class.getName());
    sw.println("}");

    // Build the methods (and maybe types?) that call addRequest()
    for (AsyncServiceModel service : model.getServices()) {
      sw.println(
          "public %1$s %2$s() {",
          service.getAsyncServiceInterfaceName(), service.getDeclaredMethodName());
      sw.indent();

      sw.println("return new %1$s() {", service.getAsyncServiceInterfaceName());
      sw.indent();

      for (AsyncServiceMethodModel method : service.getMethods()) {
        sw.println("public void %1$s(", method.getMethodName());
        StringBuilder argList = new StringBuilder();
        StringBuilder types = new StringBuilder("new String[]{");
        for (int i = 0; i < method.getArgTypes().size(); i++) {
          if (i != 0) {
            sw.print(", ");
            argList.append(", ");
            types.append(", ");
          }
          JType arg = method.getArgTypes().get(i);

          sw.print("%1$s arg%2$d", arg.getParameterizedQualifiedSourceName(), i);
          argList.append("arg").append(i);
          types.append("\"").append(escape(SerializationUtils.getRpcTypeName(arg))).append("\"");
        }
        types.append("}");
        if (method.hasCallback()) {
          if (method.getArgTypes().size() != 0) {
            sw.print(", ");
          }
          sw.print(
              "%1$s<%2$s> callback", AsyncCallback.class.getName(), method.getReturnTypeName());
        }
        sw.println(") {");
        sw.indent();

        sw.println(
            "addRequest(\"%1$s\", \"%2$s\",\n%3$s,\n",
            escape(service.getServiceName()), escape(method.getMethodName()), types.toString());
        if (method.hasCallback()) {
          sw.indentln("callback,");
        } else {
          sw.indentln("null,");
        }
        sw.indentln("new Object[]{%1$s});", argList.toString());

        sw.outdent();
        sw.println("}");
      }

      sw.outdent();
      sw.println("};");

      sw.outdent();
      sw.println("}");
    }

    sw.commit(logger);

    return factory.getCreatedClassName();
  }