From 248795ba570bb43df579d5d39740955d950a9feb Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Sat, 2 Apr 2011 00:47:50 +0000 Subject: [PATCH] Handle service methods with forall types. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6582 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../presents/tools/InvocationTask.java | 30 +++++++++++++++++++ .../threerings/presents/tools/marshaller.tmpl | 2 +- .../threerings/presents/tools/provider.tmpl | 2 +- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/threerings/presents/tools/InvocationTask.java b/src/main/java/com/threerings/presents/tools/InvocationTask.java index d3bc6be63..11325a5d2 100644 --- a/src/main/java/com/threerings/presents/tools/InvocationTask.java +++ b/src/main/java/com/threerings/presents/tools/InvocationTask.java @@ -25,6 +25,7 @@ import java.lang.reflect.GenericArrayType; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; import java.io.File; @@ -138,6 +139,15 @@ public abstract class InvocationTask extends GenTask } } + public String typeParams () { + List params = Lists.newArrayList(); + for (Type type : method.getGenericParameterTypes()) { + collectTypeParams(type, params); + } + // the trailing space in '> ' is needed + return params.isEmpty() ? "" : StringUtil.toString(params, "<", "> "); + } + public String getArgList () { StringBuilder buf = new StringBuilder(); Type[] ptypes = method.getGenericParameterTypes(); @@ -319,6 +329,8 @@ public abstract class InvocationTask extends GenTask } } else if (type instanceof GenericArrayType) { addImportsForType(((GenericArrayType)type).getGenericComponentType(), imports); + } else if (type instanceof TypeVariable) { + // nothing needed } else { System.err.println(Logger.format( "Unhandled Type in adding imports for a service", "type", type, "typeClass", @@ -326,6 +338,24 @@ public abstract class InvocationTask extends GenTask } } + protected void collectTypeParams (Type type, List params) { + if (type instanceof TypeVariable) { + String tvar = ((TypeVariable)type).getName(); + if (!params.contains(tvar)) params.add(tvar); + } else if (type instanceof ParameterizedType) { + for (Type pt : ((ParameterizedType)type).getActualTypeArguments()) { + collectTypeParams(pt, params); + } + } else if (type instanceof WildcardType) { + for (Type lb : ((WildcardType)type).getLowerBounds()) { + collectTypeParams(lb, params); + } + for (Type ub : ((WildcardType)type).getUpperBounds()) { + collectTypeParams(ub, params); + } + } // else nada + } + protected String boxArgument (Class clazz, int index) { if (_ilistener.isAssignableFrom(clazz)) { return GenUtil.boxArgument(clazz, "listener" + index); diff --git a/src/main/resources/com/threerings/presents/tools/marshaller.tmpl b/src/main/resources/com/threerings/presents/tools/marshaller.tmpl index 9ce61bfc8..f5dea922f 100644 --- a/src/main/resources/com/threerings/presents/tools/marshaller.tmpl +++ b/src/main/resources/com/threerings/presents/tools/marshaller.tmpl @@ -63,7 +63,7 @@ public class {{name}}Marshaller extends InvocationMarshaller public static final int {{code}} = {{-index}}; // from interface {{name}}Service - public void {{method.name}} ({{getArgList}}) + public {{typeParams}}void {{method.name}} ({{getArgList}}) { {{#listenerArgs}} {{marshaller}} listener{{index}} = new {{marshaller}}(); diff --git a/src/main/resources/com/threerings/presents/tools/provider.tmpl b/src/main/resources/com/threerings/presents/tools/provider.tmpl index f3d4e3383..43ea18c5a 100644 --- a/src/main/resources/com/threerings/presents/tools/provider.tmpl +++ b/src/main/resources/com/threerings/presents/tools/provider.tmpl @@ -19,7 +19,7 @@ public interface {{name}}Provider extends InvocationProvider /** * Handles a {@link {{name}}Service#{{method.name}}} request. */ - void {{method.name}} (ClientObject caller{{#hasArgs}}, {{/hasArgs}}{{getArgList}}){{^listenerArgs.isEmpty}} + {{typeParams}}void {{method.name}} (ClientObject caller{{#hasArgs}}, {{/hasArgs}}{{getArgList}}){{^listenerArgs.isEmpty}} throws InvocationException{{/listenerArgs.isEmpty}}; {{/methods}}