From 0a535664f8b939e6310433496945924e0189d12c Mon Sep 17 00:00:00 2001 From: Tom Daffurn Date: Wed, 16 Oct 2024 14:58:41 +1000 Subject: [PATCH] fix: Drop verb client interfaces (#3110) Drop the `VerbClient`, `VerbClientSink`, `VerbClientSource`, `VerbClientEmpty` interfaces. They conflict with verbs that use primitive params and responses. Fixes #2757 --- .../block/ftl/deployment/VerbProcessor.java | 252 ++++++++---------- .../xyz/block/ftl/deployment/VerbType.java | 8 + .../main/java/xyz/block/ftl/VerbClient.java | 19 +- .../xyz/block/ftl/VerbClientDefinition.java | 18 -- .../java/xyz/block/ftl/VerbClientEmpty.java | 5 - .../java/xyz/block/ftl/VerbClientSink.java | 5 - .../java/xyz/block/ftl/VerbClientSource.java | 5 - .../deployment/JavaCodeGenerator.java | 22 +- .../deployment/KotlinCodeGenerator.java | 30 +-- jvm-runtime/testdata/go/gomodule/server.go | 10 + 10 files changed, 150 insertions(+), 224 deletions(-) create mode 100644 jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/VerbType.java delete mode 100644 jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClientDefinition.java delete mode 100644 jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClientEmpty.java delete mode 100644 jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClientSink.java delete mode 100644 jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClientSource.java diff --git a/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/VerbProcessor.java b/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/VerbProcessor.java index 0fc435ecdc..3242600574 100644 --- a/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/VerbProcessor.java +++ b/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/VerbProcessor.java @@ -10,7 +10,9 @@ import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationValue; +import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; +import org.jboss.jandex.MethodInfo; import org.jboss.jandex.Type; import org.jboss.logging.Logger; @@ -27,20 +29,12 @@ import io.quarkus.gizmo.ClassOutput; import io.quarkus.gizmo.MethodDescriptor; import xyz.block.ftl.VerbClient; -import xyz.block.ftl.VerbClientDefinition; -import xyz.block.ftl.VerbClientEmpty; -import xyz.block.ftl.VerbClientSink; -import xyz.block.ftl.VerbClientSource; import xyz.block.ftl.runtime.VerbClientHelper; import xyz.block.ftl.v1.schema.Metadata; import xyz.block.ftl.v1.schema.MetadataCronJob; public class VerbProcessor { - public static final DotName VERB_CLIENT = DotName.createSimple(VerbClient.class); - public static final DotName VERB_CLIENT_SINK = DotName.createSimple(VerbClientSink.class); - public static final DotName VERB_CLIENT_SOURCE = DotName.createSimple(VerbClientSource.class); - public static final DotName VERB_CLIENT_EMPTY = DotName.createSimple(VerbClientEmpty.class); public static final String TEST_ANNOTATION = "xyz.block.ftl.java.test.FTLManaged"; private static final Logger log = Logger.getLogger(VerbProcessor.class); @@ -49,14 +43,14 @@ VerbClientBuildItem handleVerbClients(CombinedIndexBuildItem index, BuildProduce BuildProducer generatedBeanBuildItemBuildProducer, ModuleNameBuildItem moduleNameBuildItem, LaunchModeBuildItem launchModeBuildItem) { - var clientDefinitions = index.getComputingIndex().getAnnotations(VerbClientDefinition.class); + var clientDefinitions = index.getComputingIndex().getAnnotations(VerbClient.class); log.infof("Processing %d verb clients", clientDefinitions.size()); Map clients = new HashMap<>(); for (var clientDefinition : clientDefinitions) { var iface = clientDefinition.target().asClass(); if (!iface.isInterface()) { throw new RuntimeException( - "@VerbClientDefinition can only be applied to interfaces and " + iface.name() + " is not an interface"); + "@VerbClient can only be applied to interfaces and " + iface.name() + " is not an interface"); } String name = clientDefinition.value("name").asString(); AnnotationValue moduleValue = clientDefinition.value("module"); @@ -74,136 +68,86 @@ VerbClientBuildItem handleVerbClients(CombinedIndexBuildItem index, BuildProduce classOutput = new GeneratedClassGizmoAdaptor(generatedClients, true); } //TODO: map and list return types - for (var i : iface.interfaceTypes()) { - if (i.name().equals(VERB_CLIENT)) { - if (i.kind() == Type.Kind.PARAMETERIZED_TYPE) { - var returnType = i.asParameterizedType().arguments().get(1); - var paramType = i.asParameterizedType().arguments().get(0); - try (ClassCreator cc = new ClassCreator(classOutput, iface.name().toString() + "_fit_verbclient", null, - Object.class.getName(), iface.name().toString())) { - if (launchModeBuildItem.isTest()) { - cc.addAnnotation(TEST_ANNOTATION); - cc.addAnnotation(Singleton.class); - } - LinkedHashSet> signatures = new LinkedHashSet<>(); - signatures.add(Map.entry(returnType.name().toString(), paramType.name().toString())); - signatures.add(Map.entry(Object.class.getName(), Object.class.getName())); - for (var method : iface.methods()) { - if (method.name().equals("call") && method.parameters().size() == 1) { - signatures.add(Map.entry(method.returnType().name().toString(), - method.parameters().get(0).type().name().toString())); - } - } - for (var sig : signatures) { - - var publish = cc.getMethodCreator("call", sig.getKey(), - sig.getValue()); - var helper = publish.invokeStaticMethod( - MethodDescriptor.ofMethod(VerbClientHelper.class, "instance", VerbClientHelper.class)); - var results = publish.invokeVirtualMethod( - MethodDescriptor.ofMethod(VerbClientHelper.class, "call", Object.class, String.class, - String.class, Object.class, Class.class, boolean.class, boolean.class), - helper, publish.load(name), publish.load(module), publish.getMethodParam(0), - publish.loadClass(returnType.name().toString()), publish.load(false), - publish.load(false)); - publish.returnValue(results); + MethodInfo callMethod = getCallMethod(iface); + Type returnType = callMethod.returnType(); + Type paramType = callMethod.parametersCount() > 0 ? callMethod.parameterType(0) : null; + try (ClassCreator cc = new ClassCreator(classOutput, iface.name().toString() + "_fit_verbclient", null, + Object.class.getName(), iface.name().toString())) { + if (launchModeBuildItem.isTest()) { + cc.addAnnotation(TEST_ANNOTATION); + cc.addAnnotation(Singleton.class); + } + switch (getVerbType(callMethod)) { + case VERB: + LinkedHashSet> signatures = new LinkedHashSet<>(); + signatures.add(Map.entry(returnType.name().toString(), paramType.name().toString())); + signatures.add(Map.entry(Object.class.getName(), Object.class.getName())); + for (var method : iface.methods()) { + if (method.name().equals("call") && method.parameters().size() == 1) { + signatures.add(Map.entry(method.returnType().name().toString(), + method.parameters().get(0).type().name().toString())); } - - clients.put(iface.name(), - new VerbClientBuildItem.DiscoveredClients(name, module, cc.getClassName())); } - found = true; + for (var sig : signatures) { + var publish = cc.getMethodCreator("call", sig.getKey(), sig.getValue()); + var helper = publish.invokeStaticMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "instance", VerbClientHelper.class)); + var results = publish.invokeVirtualMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "call", Object.class, String.class, + String.class, Object.class, Class.class, boolean.class, boolean.class), + helper, publish.load(name), publish.load(module), publish.getMethodParam(0), + publish.loadClass(returnType.name().toString()), publish.load(false), + publish.load(false)); + publish.returnValue(results); + } break; - } else { - throw new RuntimeException( - "@VerbClientDefinition can only be applied to interfaces that directly extend a verb client type with concrete type parameters and " - + iface.name() + " does not have concrete type parameters"); - } - } else if (i.name().equals(VERB_CLIENT_SINK)) { - if (i.kind() == Type.Kind.PARAMETERIZED_TYPE) { - var paramType = i.asParameterizedType().arguments().get(0); - try (ClassCreator cc = new ClassCreator(classOutput, iface.name().toString() + "_fit_verbclient", null, - Object.class.getName(), iface.name().toString())) { - if (launchModeBuildItem.isTest()) { - cc.addAnnotation(TEST_ANNOTATION); - cc.addAnnotation(Singleton.class); - } - LinkedHashSet signatures = new LinkedHashSet<>(); - signatures.add(paramType.name().toString()); - signatures.add(Object.class.getName()); - for (var method : iface.methods()) { - if (method.name().equals("call") && method.parameters().size() == 1) { - signatures.add(method.parameters().get(0).type().name().toString()); - } - } - for (var sig : signatures) { - var publish = cc.getMethodCreator("call", void.class, sig); - var helper = publish.invokeStaticMethod( - MethodDescriptor.ofMethod(VerbClientHelper.class, "instance", VerbClientHelper.class)); - publish.invokeVirtualMethod( - MethodDescriptor.ofMethod(VerbClientHelper.class, "call", Object.class, String.class, - String.class, Object.class, Class.class, boolean.class, boolean.class), - helper, publish.load(name), publish.load(module), publish.getMethodParam(0), - publish.loadClass(Void.class), publish.load(false), publish.load(false)); - publish.returnVoid(); + + case SINK: + LinkedHashSet sinkSignatures = new LinkedHashSet<>(); + sinkSignatures.add(paramType.name().toString()); + sinkSignatures.add(Object.class.getName()); + for (var method : iface.methods()) { + if (method.name().equals("call") && method.parameters().size() == 1) { + sinkSignatures.add(method.parameters().get(0).type().name().toString()); } - clients.put(iface.name(), - new VerbClientBuildItem.DiscoveredClients(name, module, cc.getClassName())); } - found = true; + for (var sig : sinkSignatures) { + var publish = cc.getMethodCreator("call", void.class, sig); + var helper = publish.invokeStaticMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "instance", VerbClientHelper.class)); + publish.invokeVirtualMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "call", Object.class, String.class, + String.class, Object.class, Class.class, boolean.class, boolean.class), + helper, publish.load(name), publish.load(module), publish.getMethodParam(0), + publish.loadClass(Void.class), publish.load(false), publish.load(false)); + publish.returnVoid(); + } break; - } else { - throw new RuntimeException( - "@VerbClientDefinition can only be applied to interfaces that directly extend a verb client type with concrete type parameters and " - + iface.name() + " does not have concrete type parameters"); - } - } else if (i.name().equals(VERB_CLIENT_SOURCE)) { - if (i.kind() == Type.Kind.PARAMETERIZED_TYPE) { - var returnType = i.asParameterizedType().arguments().get(0); - try (ClassCreator cc = new ClassCreator(classOutput, iface.name().toString() + "_fit_verbclient", null, - Object.class.getName(), iface.name().toString())) { - if (launchModeBuildItem.isTest()) { - cc.addAnnotation(TEST_ANNOTATION); - cc.addAnnotation(Singleton.class); - } - LinkedHashSet signatures = new LinkedHashSet<>(); - signatures.add(returnType.name().toString()); - signatures.add(Object.class.getName()); - for (var method : iface.methods()) { - if (method.name().equals("call") && method.parameters().size() == 0) { - signatures.add(method.returnType().name().toString()); - } - } - for (var sig : signatures) { - var publish = cc.getMethodCreator("call", sig); - var helper = publish.invokeStaticMethod( - MethodDescriptor.ofMethod(VerbClientHelper.class, "instance", VerbClientHelper.class)); - var results = publish.invokeVirtualMethod( - MethodDescriptor.ofMethod(VerbClientHelper.class, "call", Object.class, String.class, - String.class, Object.class, Class.class, boolean.class, boolean.class), - helper, publish.load(name), publish.load(module), publish.loadNull(), - publish.loadClass(returnType.name().toString()), publish.load(false), - publish.load(false)); - publish.returnValue(results); - } - clients.put(iface.name(), - new VerbClientBuildItem.DiscoveredClients(name, module, cc.getClassName())); + case SOURCE: + LinkedHashSet sourceSignatures = new LinkedHashSet<>(); + sourceSignatures.add(returnType.name().toString()); + sourceSignatures.add(Object.class.getName()); + for (var method : iface.methods()) { + if (method.name().equals("call") && method.parameters().isEmpty()) { + sourceSignatures.add(method.returnType().name().toString()); + } } - found = true; - break; - } else { - throw new RuntimeException( - "@VerbClientDefinition can only be applied to interfaces that directly extend a verb client type with concrete type parameters and " - + iface.name() + " does not have concrete type parameters"); - } - } else if (i.name().equals(VERB_CLIENT_EMPTY)) { - try (ClassCreator cc = new ClassCreator(classOutput, iface.name().toString() + "_fit_verbclient", null, - Object.class.getName(), iface.name().toString())) { - if (launchModeBuildItem.isTest()) { - cc.addAnnotation(TEST_ANNOTATION); - cc.addAnnotation(Singleton.class); + for (var sig : sourceSignatures) { + var publish = cc.getMethodCreator("call", sig); + var helper = publish.invokeStaticMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "instance", VerbClientHelper.class)); + var results = publish.invokeVirtualMethod( + MethodDescriptor.ofMethod(VerbClientHelper.class, "call", Object.class, String.class, + String.class, Object.class, Class.class, boolean.class, boolean.class), + helper, publish.load(name), publish.load(module), publish.loadNull(), + publish.loadClass(returnType.name().toString()), publish.load(false), + publish.load(false)); + publish.returnValue(results); } + break; + + case EMPTY: var publish = cc.getMethodCreator("call", void.class); var helper = publish.invokeStaticMethod( MethodDescriptor.ofMethod(VerbClientHelper.class, "instance", VerbClientHelper.class)); @@ -213,21 +157,36 @@ VerbClientBuildItem handleVerbClients(CombinedIndexBuildItem index, BuildProduce helper, publish.load(name), publish.load(module), publish.loadNull(), publish.loadClass(Void.class), publish.load(false), publish.load(false)); publish.returnVoid(); - clients.put(iface.name(), new VerbClientBuildItem.DiscoveredClients(name, module, cc.getClassName())); - } - found = true; - break; + break; } - } - if (!found) { - throw new RuntimeException( - "@VerbClientDefinition can only be applied to interfaces that directly extend a verb client type with concrete type parameters and " - + iface.name() + " does not extend a verb client type"); + clients.put(iface.name(), new VerbClientBuildItem.DiscoveredClients(name, module, cc.getClassName())); } } return new VerbClientBuildItem(clients); } + private MethodInfo getCallMethod(ClassInfo verbClient) { + for (var call : verbClient.methods()) { + if (call.name().equals("call")) { + return call; + } + } + throw new RuntimeException("@VerbClient can only be applied to interfaces that contain a valid call method"); + } + + private static VerbType getVerbType(MethodInfo call) { + if (call.returnType().kind() == Type.Kind.VOID && call.parametersCount() == 0) { + return VerbType.EMPTY; + } else if (call.returnType().kind() == Type.Kind.VOID) { + return VerbType.SINK; + } + if (call.parametersCount() == 0) { + return VerbType.SOURCE; + } else { + return VerbType.VERB; + } + } + @BuildStep public void verbsAndCron(CombinedIndexBuildItem index, BuildProducer additionalBeanBuildItem, @@ -253,15 +212,12 @@ public void verbsAndCron(CombinedIndexBuildItem index, String className = method.declaringClass().name().toString(); beans.addBeanClass(className); - schemaContributorBuildItemBuildProducer - .produce( - new SchemaContributorBuildItem(moduleBuilder -> moduleBuilder.registerVerbMethod(method, className, - false, ModuleBuilder.BodyType.ALLOWED, (builder -> builder.addMetadata(Metadata.newBuilder() - .setCronJob(MetadataCronJob.newBuilder().setCron(cron.value().asString())) - .build()))))); + schemaContributorBuildItemBuildProducer.produce( + new SchemaContributorBuildItem(moduleBuilder -> moduleBuilder.registerVerbMethod(method, className, + false, ModuleBuilder.BodyType.ALLOWED, (builder -> builder.addMetadata(Metadata.newBuilder() + .setCronJob(MetadataCronJob.newBuilder().setCron(cron.value().asString())) + .build()))))); } additionalBeanBuildItem.produce(beans.build()); - } - } diff --git a/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/VerbType.java b/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/VerbType.java new file mode 100644 index 0000000000..b72a4a0b4c --- /dev/null +++ b/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/VerbType.java @@ -0,0 +1,8 @@ +package xyz.block.ftl.deployment; + +public enum VerbType { + VERB, + SINK, + SOURCE, + EMPTY +} \ No newline at end of file diff --git a/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClient.java b/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClient.java index 7637e5713c..dde1461a57 100644 --- a/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClient.java +++ b/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClient.java @@ -1,15 +1,18 @@ package xyz.block.ftl; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + /** - * A client for a specific verb. - * - * The sink source and empty interfaces allow for different call signatures. - * - * @param

The verb parameter type - * @param The verb return type + * Annotation that is used to define a verb client */ -public interface VerbClient { +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface VerbClient { - R call(P param); + String module() default ""; + String name(); } diff --git a/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClientDefinition.java b/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClientDefinition.java deleted file mode 100644 index 1e258f7fa6..0000000000 --- a/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClientDefinition.java +++ /dev/null @@ -1,18 +0,0 @@ -package xyz.block.ftl; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation that is used to define a verb client - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface VerbClientDefinition { - - String module() default ""; - - String name(); -} diff --git a/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClientEmpty.java b/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClientEmpty.java deleted file mode 100644 index 2d68c8d88d..0000000000 --- a/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClientEmpty.java +++ /dev/null @@ -1,5 +0,0 @@ -package xyz.block.ftl; - -public interface VerbClientEmpty { - void call(); -} diff --git a/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClientSink.java b/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClientSink.java deleted file mode 100644 index cb05af1038..0000000000 --- a/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClientSink.java +++ /dev/null @@ -1,5 +0,0 @@ -package xyz.block.ftl; - -public interface VerbClientSink

{ - void call(P param); -} diff --git a/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClientSource.java b/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClientSource.java deleted file mode 100644 index 95efc04c78..0000000000 --- a/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/VerbClientSource.java +++ /dev/null @@ -1,5 +0,0 @@ -package xyz.block.ftl; - -public interface VerbClientSource { - R call(); -} diff --git a/jvm-runtime/ftl-runtime/java/deployment/src/main/java/xyz/block/ftl/javalang/deployment/JavaCodeGenerator.java b/jvm-runtime/ftl-runtime/java/deployment/src/main/java/xyz/block/ftl/javalang/deployment/JavaCodeGenerator.java index 35fef14c77..d62ca2a2d2 100644 --- a/jvm-runtime/ftl-runtime/java/deployment/src/main/java/xyz/block/ftl/javalang/deployment/JavaCodeGenerator.java +++ b/jvm-runtime/ftl-runtime/java/deployment/src/main/java/xyz/block/ftl/javalang/deployment/JavaCodeGenerator.java @@ -34,10 +34,6 @@ import xyz.block.ftl.TypeAlias; import xyz.block.ftl.TypeAliasMapper; import xyz.block.ftl.VerbClient; -import xyz.block.ftl.VerbClientDefinition; -import xyz.block.ftl.VerbClientEmpty; -import xyz.block.ftl.VerbClientSink; -import xyz.block.ftl.VerbClientSource; import xyz.block.ftl.deployment.JVMCodeGenerator; import xyz.block.ftl.v1.schema.Data; import xyz.block.ftl.v1.schema.Enum; @@ -280,26 +276,24 @@ protected void generateVerb(Module module, Verb verb, String packageName, Map nativeTypeAliasMap, Path outputDir) throws IOException { TypeSpec.Builder typeBuilder = TypeSpec.interfaceBuilder(className(verb.getName()) + CLIENT) - .addAnnotation(AnnotationSpec.builder(VerbClientDefinition.class) + .addAnnotation(AnnotationSpec.builder(VerbClient.class) .addMember("name", "\"" + verb.getName() + "\"") .addMember("module", "\"" + module.getName() + "\"") .build()) - .addModifiers(Modifier.PUBLIC); + .addModifiers(Modifier.PUBLIC) + .addJavadoc("A client for the $L.$L verb", module.getName(), verb.getName()); var comments = String.join("\n", verb.getCommentsList()); if (verb.getRequest().hasUnit() && verb.getResponse().hasUnit()) { - typeBuilder.addSuperinterface(ClassName.get(VerbClientEmpty.class)) + typeBuilder.addMethod(MethodSpec.methodBuilder("call") + .addModifiers(Modifier.ABSTRACT, Modifier.PUBLIC).build()) .addJavadoc(comments); } else if (verb.getRequest().hasUnit()) { - typeBuilder.addSuperinterface(ParameterizedTypeName.get(ClassName.get(VerbClientSource.class), - toJavaTypeName(verb.getResponse(), typeAliasMap, nativeTypeAliasMap, true))); typeBuilder.addMethod(MethodSpec.methodBuilder("call") .returns(toAnnotatedJavaTypeName(verb.getResponse(), typeAliasMap, nativeTypeAliasMap)) .addModifiers(Modifier.ABSTRACT, Modifier.PUBLIC) .addJavadoc(comments) .build()); } else if (verb.getResponse().hasUnit()) { - typeBuilder.addSuperinterface(ParameterizedTypeName.get(ClassName.get(VerbClientSink.class), - toJavaTypeName(verb.getRequest(), typeAliasMap, nativeTypeAliasMap, true))); typeBuilder.addMethod(MethodSpec.methodBuilder("call") .returns(TypeName.VOID) .addParameter(toAnnotatedJavaTypeName(verb.getRequest(), typeAliasMap, nativeTypeAliasMap), "value") @@ -307,9 +301,6 @@ protected void generateVerb(Module module, Verb verb, String packageName, Map