public static boolean isAsyncResultHandler(TypeInfo type) { return type.getKind() == ClassKind.HANDLER && ((ParameterizedTypeInfo)type).getArg(0).getKind() == ClassKind.ASYNC_RESULT; }
/** * @return true when the param callback value is nullable: when the parameter type is an * handler or an async result handler it returns the nullable boolean of the corresponding * parameter, otherwise it returns null */ public Boolean isNullableCallback() { switch (type.getKind()) { case HANDLER: TypeInfo handler = ((ParameterizedTypeInfo)type).getArg(0); switch (handler.getKind()) { case ASYNC_RESULT: TypeInfo asyncResult = ((ParameterizedTypeInfo)handler).getArg(0); return asyncResult.isNullable(); default: return handler.isNullable(); } default: return null; } }
private TypeInfo assertHandler(TypeInfo type, String name) { String handlerName = "io.vertx.core.Handler<" + name + ">"; ParameterizedTypeInfo handlerType = assertParameterized(type, handlerName, ClassKind.HANDLER); return handlerType.getArg(0); }
private boolean isSameType(TypeInfo type, MethodInfo method) { ClassKind kind = type.getKind(); if (kind.basic || kind.json || kind == DATA_OBJECT || kind == ENUM || kind == OTHER || kind == THROWABLE || kind == VOID) { return true; } else if (kind == OBJECT) { if (type.isVariable()) { return !isReified((TypeVariableInfo) type, method); } else { return true; } } else if (type.isParameterized()) { ParameterizedTypeInfo parameterizedTypeInfo = (ParameterizedTypeInfo) type; if (kind == LIST || kind == SET || kind == ASYNC_RESULT) { return isSameType(parameterizedTypeInfo.getArg(0), method); } else if (kind == MAP) { return isSameType(parameterizedTypeInfo.getArg(1), method); } else if (kind == HANDLER) { return isSameType(parameterizedTypeInfo.getArg(0), method); } else if (kind == FUNCTION) { return isSameType(parameterizedTypeInfo.getArg(0), method) && isSameType(parameterizedTypeInfo.getArg(1), method); } } return false; }
public boolean isResultHandler(ParamInfo param) { return param != null && param.getType().getKind() == ClassKind.HANDLER && ((ParameterizedTypeInfo)param.getType()).getArg(0).getKind() == ClassKind.ASYNC_RESULT; }
private boolean isLegalClassTypeParam(ExecutableElement elt, TypeInfo type) { if (type.getKind() == ClassKind.CLASS_TYPE && type.isParameterized()) { ParameterizedTypeInfo parameterized = (ParameterizedTypeInfo) type; TypeInfo arg = parameterized.getArg(0); if (arg.isVariable()) { TypeVariableInfo variable = (TypeVariableInfo) arg; for (TypeParameterElement typeParamElt : elt.getTypeParameters()) { if (typeParamElt.getSimpleName().toString().equals(variable.getName())) { return true; } } } } return false; }
private MethodInfo genFutureMethod(MethodInfo method) { String futMethodName = genFutureMethodName(method); List<ParamInfo> futParams = new ArrayList<>(); int count = 0; int size = method.getParams().size() - 1; while (count < size) { ParamInfo param = method.getParam(count); /* Transform ReadStream -> Flowable */ futParams.add(param); count = count + 1; } ParamInfo futParam = method.getParam(size); TypeInfo futType = ((ParameterizedTypeInfo) ((ParameterizedTypeInfo) futParam.getType()).getArg(0)).getArg(0); TypeInfo futUnresolvedType = ((ParameterizedTypeInfo) ((ParameterizedTypeInfo) futParam.getUnresolvedType()).getArg(0)).getArg(0); TypeInfo futReturnType; if (futUnresolvedType.getKind() == VOID) { futReturnType = io.vertx.codegen.type.TypeReflectionFactory.create(io.reactivex.Completable.class); } else if (futUnresolvedType.isNullable()) { futReturnType = new io.vertx.codegen.type.ParameterizedTypeInfo(io.vertx.codegen.type.TypeReflectionFactory.create(io.reactivex.Maybe.class).getRaw(), false, Collections.singletonList(futType)); } else { futReturnType = new io.vertx.codegen.type.ParameterizedTypeInfo(io.vertx.codegen.type.TypeReflectionFactory.create(io.reactivex.Single.class).getRaw(), false, Collections.singletonList(futType)); } return method.copy().setName(futMethodName).setReturnType(futReturnType).setParams(futParams); }
@Test public void testAsync() throws Exception { doTest(AsyncHolder.class, map -> { assertClass(assertAsync(map.get("asyncVoid"), "java.lang.Void"), "java.lang.Void", ClassKind.VOID); assertClass(assertAsync(map.get("asyncString"), "java.lang.String"), "java.lang.String", ClassKind.STRING); assertClass(assertParameterized(assertAsync(map.get("asyncListString"), "java.util.List<java.lang.String>"), "java.util.List<java.lang.String>", ClassKind.LIST).getArg(0), "java.lang.String", ClassKind.STRING); assertApi(assertParameterized(assertAsync(map.get("asyncListApi"), "java.util.List<" + ApiObject.class.getName() + ">"), "java.util.List<" + ApiObject.class.getName() + ">", ClassKind.LIST).getArg(0), ApiObject.class.getName()); assertTypeVariable(assertParameterized(assertAsync(map.get("asyncParameterizedByClassTypeParam"), GenericInterface.class.getName() + "<ClassTypeParam>"), GenericInterface.class.getName() + "<ClassTypeParam>", ClassKind.API).getArg(0), "ClassTypeParam"); assertTypeVariable(assertParameterized(assertAsync(map.get("asyncParameterizedByMethodTypeParam"), GenericInterface.class.getName() + "<MethodTypeParam>"), GenericInterface.class.getName() + "<MethodTypeParam>", ClassKind.API).getArg(0), "MethodTypeParam"); }); }
@Test public void testHandler() throws Exception { doTest(HandlerHolder.class, map -> { assertClass(assertHandler(map.get("handlerVoid"), "java.lang.Void"), "java.lang.Void", ClassKind.VOID); assertClass(assertHandler(map.get("handlerString"), "java.lang.String"), "java.lang.String", ClassKind.STRING); assertClass(assertParameterized(assertHandler(map.get("handlerListString"), "java.util.List<java.lang.String>"), "java.util.List<java.lang.String>", ClassKind.LIST).getArg(0), "java.lang.String", ClassKind.STRING); assertApi(assertParameterized(assertHandler(map.get("handlerListApi"), "java.util.List<" + ApiObject.class.getName() + ">"), "java.util.List<" + ApiObject.class.getName() + ">", ClassKind.LIST).getArg(0), ApiObject.class.getName()); assertTypeVariable(assertParameterized(assertHandler(map.get("handlerParameterizedByClassTypeParam"), GenericInterface.class.getName() + "<ClassTypeParam>"), GenericInterface.class.getName() + "<ClassTypeParam>", ClassKind.API).getArg(0), "ClassTypeParam"); assertTypeVariable(assertParameterized(assertHandler(map.get("handlerParameterizedByMethodTypeParam"), GenericInterface.class.getName() + "<MethodTypeParam>"), GenericInterface.class.getName() + "<MethodTypeParam>", ClassKind.API).getArg(0), "MethodTypeParam"); }); }
@Test public void testClass() throws Exception { doTest(OtherHolder.class, map -> { assertClass(map.get("classType"), "java.util.Locale", ClassKind.OTHER); assertClass(map.get("interfaceType"), "java.lang.Runnable", ClassKind.OTHER); assertClass(map.get("genericInterface"), "java.util.concurrent.Callable", ClassKind.OTHER); assertClass(assertParameterized(map.get("interfaceParameterizedByInterface"), "java.util.concurrent.Callable<java.lang.Runnable>", ClassKind.OTHER).getArg(0), "java.lang.Runnable", ClassKind.OTHER); assertClass(assertParameterized(map.get("interfaceParameterizedByClass"), "java.util.concurrent.Callable<java.util.Locale>", ClassKind.OTHER).getArg(0), "java.util.Locale", ClassKind.OTHER); assertTypeVariable(assertParameterized(map.get("interfaceParameterizedByClassTypeParam"), "java.util.concurrent.Callable<ClassTypeParam>", ClassKind.OTHER).getArg(0), "ClassTypeParam"); assertTypeVariable(assertParameterized(map.get("interfaceParameterizedByMethodTypeParam"), "java.util.concurrent.Callable<MethodTypeParam>", ClassKind.OTHER).getArg(0), "MethodTypeParam"); assertClass(assertParameterized(map.get("classParameterizedByInterface"), "java.util.Vector<java.lang.Runnable>", ClassKind.OTHER).getArg(0), "java.lang.Runnable", ClassKind.OTHER); assertClass(assertParameterized(map.get("classParameterizedByClass"), "java.util.Vector<java.util.Locale>", ClassKind.OTHER).getArg(0), "java.util.Locale", ClassKind.OTHER); assertTypeVariable(assertParameterized(map.get("classParameterizedByClassTypeParam"), "java.util.Vector<ClassTypeParam>", ClassKind.OTHER).getArg(0), "ClassTypeParam"); assertTypeVariable(assertParameterized(map.get("classParameterizedByMethodTypeParam"), "java.util.Vector<MethodTypeParam>", ClassKind.OTHER).getArg(0), "MethodTypeParam"); }); }
private TypeInfo assertAsync(TypeInfo type, String name) { String asyncName = "io.vertx.core.AsyncResult<" + name + ">"; ParameterizedTypeInfo handlerType = assertParameterized(assertHandler(type, asyncName), asyncName, ClassKind.ASYNC_RESULT); ParameterizedTypeInfo resultType = assertParameterized(handlerType, asyncName, ClassKind.ASYNC_RESULT); return resultType.getArg(0); }
@Test public void testApi() throws Exception { doTest(ApiHolder.class, map -> { ApiTypeInfo api = assertApi(map.get("api"), ApiObject.class.getName()); assertEquals(ApiObject.class.getName(), api.getName()); ParameterizedTypeInfo apiParameterizedByClass = assertParameterized(map.get("apiParameterizedByClass"), GenericInterface.class.getName() + "<java.lang.String>", ClassKind.API); assertClass(apiParameterizedByClass.getArg(0), "java.lang.String", ClassKind.STRING); ParameterizedTypeInfo apiParameterizedByClassTypeParam = assertParameterized(map.get("apiParameterizedByClassTypeParam"), GenericInterface.class.getName() + "<ClassTypeParam>", ClassKind.API); TypeParamInfo.Class classTypeParam = (TypeParamInfo.Class) assertTypeVariable(apiParameterizedByClassTypeParam.getArg(0), "ClassTypeParam").getParam(); assertEquals("ClassTypeParam", classTypeParam.getName()); ParameterizedTypeInfo apiParameterizedByMethodTypeParam = assertParameterized(map.get("apiParameterizedByMethodTypeParam"), GenericInterface.class.getName() + "<MethodTypeParam>", ClassKind.API); TypeParamInfo.Method methodTypeParam = (TypeParamInfo.Method) assertTypeVariable(apiParameterizedByMethodTypeParam.getArg(0), "MethodTypeParam").getParam(); assertEquals("MethodTypeParam", methodTypeParam.getName()); }); }
@Test public void testMethodWithHandlerNullable() throws Exception { for (Class<?> clazz : Arrays.asList( MethodWithHandlerNullable.class, MethodWithNullableTypeVariableHandler.class, MethodWithHandlerNullableVoid.class)) { generateClass(model -> { List<MethodInfo> methods = model.getMethods(); assertEquals(1, methods.size()); MethodInfo mi1 = methods.get(0); assertTrue(((ParameterizedTypeInfo) mi1.getParams().get(0).getType()).getArg(0).isNullable()); }, clazz); } }
@Test public void testMethodWithNullableInheritedParams() throws Exception { Consumer<ClassModel> check = model -> { List<MethodInfo> methods = model.getMethods(); assertEquals(1, methods.size()); MethodInfo mi2 = methods.get(0); assertTrue(mi2.getParams().get(0).getType().isNullable()); assertTrue(((ParameterizedTypeInfo) mi2.getParams().get(1).getType()).getArg(0).isNullable()); assertTrue(((ParameterizedTypeInfo) ((ParameterizedTypeInfo) mi2.getParams().get(2).getType()).getArg(0)).getArg(0).isNullable()); }; generateClass(check, MethodWithNullableInheritedParams.class, MethodWithNullableParams.class); generateClass(check, MethodWithNullableInheritedParams.class); }
@Test public void testInterfaceWithListNullableParamOverride() throws Exception { generateClass(model -> { List<MethodInfo> methods = model.getMethods(); assertEquals(1, methods.size()); MethodInfo mi2 = methods.get(0); assertTrue(((ParameterizedTypeInfo) mi2.getParams().get(0).getType()).getArg(0).isNullable()); }, MethodWithListNullableParamOverride.class, MethodWithListNullableParam.class); }
@Test public void testValidHandlerAsyncResultReturn() throws Exception { ClassModel model = new GeneratorHelper().generateClass(MethodWithHandlerAsyncResultReturn.class); assertEquals(MethodWithHandlerAsyncResultReturn.class.getName(), model.getIfaceFQCN()); assertEquals(MethodWithHandlerAsyncResultReturn.class.getSimpleName(), model.getIfaceSimpleName()); assertTrue(model.getReferencedTypes().isEmpty()); assertTrue(model.getSuperTypes().isEmpty()); assertEquals(1, model.getMethods().size()); checkMethod(model.getMethods().get(0), "methodWithHandlerAsyncResultStringReturn", 0, new TypeLiteral<Handler<AsyncResult<String>>>() {}, MethodKind.OTHER); TypeInfo returnType = model.getMethods().get(0).getReturnType(); assertEquals(ClassKind.HANDLER, returnType.getKind()); assertEquals(ClassKind.ASYNC_RESULT, ((ParameterizedTypeInfo)returnType).getArg(0).getKind()); assertEquals(ClassKind.STRING, ((ParameterizedTypeInfo)((ParameterizedTypeInfo)returnType).getArg(0)).getArg(0).getKind()); }
@Test public void testMethodWithTypeVarParamByGenericType() throws Exception { Runnable test = () -> { try { ClassModel model = new GeneratorHelper().generateClass(MethodWithTypeVarParamByGenericType.class); MethodInfo meth = model.getMethods().get(0); ParamInfo param = meth.getParam(0); ParameterizedTypeInfo handler = (ParameterizedTypeInfo) param.getType(); assertEquals(Handler.class.getName(), handler.getRaw().getName()); ParameterizedTypeInfo genericInt2 = (ParameterizedTypeInfo) handler.getArg(0); assertEquals(GenericInterface2.class.getName(), genericInt2.getRaw().getName()); TypeVariableInfo k = (TypeVariableInfo) genericInt2.getArg(0); assertEquals("K", k.getName()); TypeVariableInfo v = (TypeVariableInfo) genericInt2.getArg(1); assertEquals("V", v.getName()); } catch (Exception e) { throw new AssertionError(e); } }; blacklist(test, Stream.of(WriteStream.class)); test.run(); }
private void generateAddToJsonStmt(ParamInfo param, CodeWriter writer) { TypeInfo t = param.getType(); String name = param.getName(); if ("char".equals(t.getName())) writer.stmt("_json.put(\"" + name + "\", (int)" + name + ")"); else if ("java.lang.Character".equals(t.getName())) writer.stmt("_json.put(\"" + name + "\", " + name + " == null ? null : (int)" + name + ")"); else if (t.getKind() == ClassKind.ENUM) writer.stmt("_json.put(\"" + name + "\", " + name + " == null ? null : " + name + ".toString())"); else if (t.getKind() == ClassKind.LIST) { if (((ParameterizedTypeInfo)t).getArg(0).getKind() == ClassKind.DATA_OBJECT) writer.stmt("_json.put(\"" + name + "\", new JsonArray(" + name + " == null ? java.util.Collections.emptyList() : " + name + ".stream().map(r -> r == null ? null : r.toJson()).collect(Collectors.toList())))"); else writer.stmt("_json.put(\"" + name + "\", new JsonArray(" + name + "))"); } else if (t.getKind() == ClassKind.SET) { if (((ParameterizedTypeInfo)t).getArg(0).getKind() == ClassKind.DATA_OBJECT) writer.stmt("_json.put(\"" + name + "\", new JsonArray(" + name + " == null ? java.util.Collections.emptyList() : " + name + ".stream().map(r -> r == null ? null : r.toJson()).collect(Collectors.toList())))"); else writer.stmt("_json.put(\"" + name + "\", new JsonArray(new ArrayList<>(" + name + ")))"); } else if (t.getKind() == ClassKind.MAP) writer.stmt("_json.put(\"" + name + "\", new JsonObject(ProxyUtils.convertMap(" + name + ")))"); else if (t.getKind() == ClassKind.DATA_OBJECT) writer.stmt("_json.put(\"" + name + "\", " + name + " == null ? null : " + name + ".toJson())"); else writer.stmt("_json.put(\"" + name + "\", " + name + ")"); }
@Test public void testValidHandlerReturn() throws Exception { ClassModel model = new GeneratorHelper().generateClass(MethodWithHandlerReturn.class); assertEquals(MethodWithHandlerReturn.class.getName(), model.getIfaceFQCN()); assertEquals(MethodWithHandlerReturn.class.getSimpleName(), model.getIfaceSimpleName()); assertTrue(model.getReferencedTypes().isEmpty()); assertTrue(model.getSuperTypes().isEmpty()); assertEquals(1, model.getMethods().size()); checkMethod(model.getMethods().get(0), "methodWithHandlerStringReturn", 0, new TypeLiteral<Handler<String>>() {}, MethodKind.OTHER); TypeInfo returnType = model.getMethods().get(0).getReturnType(); assertEquals(ClassKind.HANDLER, returnType.getKind()); assertEquals(ClassKind.STRING, ((ParameterizedTypeInfo)returnType).getArg(0).getKind()); }