Example usage for com.google.gwt.core.ext.typeinfo JMethod getErasedParameterTypes

List of usage examples for com.google.gwt.core.ext.typeinfo JMethod getErasedParameterTypes

Introduction

In this page you can find the example usage for com.google.gwt.core.ext.typeinfo JMethod getErasedParameterTypes.

Prototype

JType[] getErasedParameterTypes();

Source Link

Usage

From source file:org.senchalabs.gwt.gwtdriver.SeExporterGenerator.java

License:Apache License

@Override
public String generate(TreeLogger logger, GeneratorContext context, String typeName)
        throws UnableToCompleteException {
    TypeOracle oracle = context.getTypeOracle();

    JClassType jso = oracle.findType(Name.getSourceNameForClass(JavaScriptObject.class));

    JClassType toGenerate = oracle.findType(typeName).isClass();

    String packageName = toGenerate.getPackage().getName();
    String simpleSourceName = toGenerate.getName().replace('.', '_') + "Impl";
    PrintWriter pw = context.tryCreate(logger, packageName, simpleSourceName);
    if (pw == null) {
        return packageName + "." + simpleSourceName;
    }/*from w w  w .  ja va2  s .  com*/

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

    List<String> exportedTypes;
    try {
        exportedTypes = context.getPropertyOracle().getConfigurationProperty(SELENIUM_METHODS).getValues();
    } catch (BadPropertyValueException e) {
        logger.log(TreeLogger.Type.ERROR,
                "Can't find any config property for " + SELENIUM_METHODS + " declared", e);
        throw new UnableToCompleteException();
    }
    sw.println("protected void exportRegisteredTypes() {");
    sw.indent();
    //for each type set up in a config property,
    for (String exportedType : exportedTypes) {
        JClassType toExport = oracle.findType(exportedType);
        if (toExport == null) {
            logger.log(TreeLogger.Type.ERROR,
                    "Cannot find " + exportedType + " be sure it is a valid GWT type");
            throw new UnableToCompleteException();
        }
        MethodsFor refersToType = toExport.getAnnotation(MethodsFor.class);
        if (refersToType == null) {
            logger.log(Type.ERROR, "Type " + exportedType
                    + " is declared as having webdriver methods, but has no @MethodsFor annotation");
            throw new UnableToCompleteException();
        }
        //verify a default ctor - if not, methods must be static
        boolean requireStatic = toExport.getConstructors().length != 0
                && toExport.findConstructor(new JType[] {}) == null;
        if (requireStatic) {
            logger.log(Type.INFO, "No default constructor found, all marked methods must be static");
        }
        TreeLogger typeLogger = logger.branch(TreeLogger.Type.DEBUG, "Exporting methods in " + exportedType);
        //iterate through the methods
        for (JMethod m : toExport.getInheritableMethods()) {
            Method refersToMethod = m.getAnnotation(Method.class);
            if (refersToMethod == null) {
                continue;
            }
            TreeLogger methodLogger = typeLogger.branch(Type.DEBUG, "Examining " + m.getName());
            if (requireStatic && !m.isStatic()) {
                typeLogger.log(Type.ERROR, "No default constructor found for " + exportedType
                        + ", can't export instance method" + m.getName());
                typeLogger.log(Type.ERROR,
                        "Either mark the method as static, or ensure there is a default constructor.");
                throw new UnableToCompleteException();
            }
            //verify that the method matches exactly one method in the webdriver side
            //TODO make this a little faster
            String matchingMethod = null;
            for (java.lang.reflect.Method exportableMethod : refersToType.value().getMethods()) {
                if (refersToMethod.value().equals(exportableMethod.getName())) {
                    if (matchingMethod != null) {
                        methodLogger.log(Type.ERROR,
                                "Multiple methods found that match " + refersToMethod.value());
                        throw new UnableToCompleteException();
                    }
                    matchingMethod = refersToMethod.value();
                }
            }
            if (matchingMethod == null) {
                methodLogger.log(Type.ERROR, "Can't find a method that matches " + refersToMethod.value());
                throw new UnableToCompleteException();
            }

            //emit a registerFunction call wrapping it
            sw.println("registerFunction(\"%1$s\", \"%2$s\", new %3$s() {",
                    escape(refersToType.value().getName()), escape(matchingMethod),
                    Name.getSourceNameForClass(Function.class));
            sw.indent();
            sw.println("public Object apply(%1$s<?> args) {", Name.getSourceNameForClass(JsArray.class));
            sw.indent();
            JType retType = m.getReturnType();
            if (retType.isPrimitive() != null) {
                switch (retType.isPrimitive()) {
                case VOID:
                    //do nothing
                    break;
                case INT:
                case DOUBLE:
                case BOOLEAN:
                    sw.print("return \"\" + ");
                    break;
                default:
                    methodLogger.log(Type.ERROR, "Can't return primitive " + retType + " from exported method");
                    throw new UnableToCompleteException();
                }
            } else if (retType.isClass() != null && retType.getQualifiedSourceName().equals("java.lang.String")
                    || ((retType.isClass() != null) && retType.isClass().isAssignableTo(jso))
                    || ((retType.isInterface() != null)
                            && oracle.getSingleJsoImplInterfaces().contains(retType))) {
                sw.print("return ");
            } else {
                methodLogger.log(Type.ERROR,
                        "Can't return non-jso, non-supported primitive " + retType + " from exported method");
                throw new UnableToCompleteException();
            }
            if (m.isStatic()) {
                sw.print(exportedType);
            } else {
                sw.print("%1$s.<%2$s>create(%2$s.class)", GWT.class.getName(), exportedType);
            }
            sw.print(".%1$s(", matchingMethod);
            //iterate through the arguments
            //verify the arg type is legal
            JType[] erasedParameterTypes = m.getErasedParameterTypes();
            for (int i = 0; i < erasedParameterTypes.length; i++) {
                JType type = erasedParameterTypes[i];

                if (type.isPrimitive() != null || type.getQualifiedSourceName().equals("java.lang.String")) {
                    //cast uglyness
                    sw.print("args.<%2$s>cast().get(%1$d)", i, getJsArray(type));
                } else if (type.isClass() != null && type.isClass().isAssignableTo(jso)) {
                    //normal array plus cast() trickery
                    sw.print("args.get(%1$d).<%2$s>cast()", i, type.getQualifiedSourceName());
                } else if (type.isInterface() != null
                        && oracle.getSingleJsoImplInterfaces().contains(type.isInterface())) {
                    //single jso cast thing
                    sw.print("args.get(%1$d).<%2$s>cast()", i,
                            oracle.getSingleJsoImpl(type.isInterface()).getQualifiedSourceName());
                } else {//TODO goktug's magic new jsinterface
                    methodLogger.log(Type.ERROR, "Can't handle argument of type " + type);
                    throw new UnableToCompleteException();
                }
                if (i != erasedParameterTypes.length - 1) {
                    sw.println(",");
                }
            }
            sw.println(");");

            if (m.getReturnType() == JPrimitiveType.VOID) {
                sw.println("return null;");
            }

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

    sw.commit(logger);

    return factory.getCreatedClassName();
}