From 61b1f23303b0147367aeb05542047010e7a6d4c6 Mon Sep 17 00:00:00 2001 From: Jamie Doornbos Date: Tue, 6 May 2008 22:44:36 +0000 Subject: [PATCH] Narya.abc work - refactored GenServiceTask import mechanism in order to generate clean action script files with no unnecessary imports * New class ImportSet to facilitate the operations being performed manually throughout the code. Also removes the need for rawimports * Threaded ImportSet through all places where imports and rawimports were used and removed magic parameters to control import generation * Added an ImportSet instance to ServiceListener, this was key to the action script fixes * Moved all the import tweaking and munging logic into the generate* methods and made specific to code being generated (removed overreaching stuff from ServiceMethod, this was part of the problem) * Removed blanket imports from tmpl files * Removed unused methods * Fixed tabs from last commit * Quick and dirty script to check for unused imports git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@5041 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../presents/tools/GenReceiverTask.java | 11 +- .../presents/tools/GenServiceTask.java | 370 +++++++++++------- .../threerings/presents/tools/ImportSet.java | 202 ++++++++++ .../presents/tools/InvocationTask.java | 68 +--- .../presents/tools/marshaller_as.tmpl | 4 - .../tools/marshaller_listener_as.tmpl | 4 - .../threerings/presents/tools/service_as.tmpl | 2 - .../presents/tools/service_listener_as.tmpl | 4 - tests/bin/check_genservice.sh | 37 ++ 9 files changed, 483 insertions(+), 219 deletions(-) create mode 100644 src/java/com/threerings/presents/tools/ImportSet.java create mode 100755 tests/bin/check_genservice.sh diff --git a/src/java/com/threerings/presents/tools/GenReceiverTask.java b/src/java/com/threerings/presents/tools/GenReceiverTask.java index 59ac679ee..a726a1095 100644 --- a/src/java/com/threerings/presents/tools/GenReceiverTask.java +++ b/src/java/com/threerings/presents/tools/GenReceiverTask.java @@ -27,7 +27,6 @@ import java.io.StringWriter; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -67,12 +66,12 @@ public class GenReceiverTask extends InvocationTask return; } - HashMap imports = new HashMap(); + ImportSet imports = new ImportSet(); ComparableArrayList methods = new ComparableArrayList(); // we need to import the receiver itself - imports.put(importify(receiver.getName()), Boolean.TRUE); + imports.add(receiver); // look through and locate our receiver methods Method[] methdecls = receiver.getDeclaredMethods(); @@ -83,14 +82,14 @@ public class GenReceiverTask extends InvocationTask !Modifier.isAbstract(m.getModifiers())) { continue; } - methods.add(new ServiceMethod(receiver, m, imports, null, 0, true)); + methods.add(new ServiceMethod(m, imports)); } methods.sort(); generateSender(source, rname, rpackage, methods, - imports.keySet().iterator()); + imports.toList().iterator()); generateDecoder(source, rname, rpackage, methods, - imports.keySet().iterator()); + imports.toList().iterator()); } protected void generateSender (File source, String rname, String rpackage, diff --git a/src/java/com/threerings/presents/tools/GenServiceTask.java b/src/java/com/threerings/presents/tools/GenServiceTask.java index 8742594fa..a89cf0d36 100644 --- a/src/java/com/threerings/presents/tools/GenServiceTask.java +++ b/src/java/com/threerings/presents/tools/GenServiceTask.java @@ -27,9 +27,6 @@ import java.io.StringWriter; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; import java.util.HashSet; import org.apache.velocity.VelocityContext; @@ -59,11 +56,11 @@ public class GenServiceTask extends InvocationTask public ComparableArrayList methods = new ComparableArrayList(); + + /** Contains all imports required for the parameters of the methods in this listener. */ + public ImportSet imports = new ImportSet(); - public ServiceListener (Class service, Class listener, - HashMap imports, - HashMap rawimports, - boolean importArguments) + public ServiceListener (Class service, Class listener) { this.listener = listener; Method[] methdecls = listener.getDeclaredMethods(); @@ -75,15 +72,13 @@ public class GenServiceTask extends InvocationTask continue; } if (_verbose) { - System.out.println("Adding " + m + ", imports are " + - StringUtil.toString(imports.keySet())); + System.out.println("Adding " + m + ", imports are " + + StringUtil.toString(imports)); } - methods.add(new ServiceMethod( - service, m, imports, rawimports, importArguments ? 0 : 999, - true)); + methods.add(new ServiceMethod(m, imports)); if (_verbose) { - System.out.println("Added " + m + ", imports are " + - StringUtil.toString(imports.keySet())); + System.out.println("Added " + m + ", imports are " + + StringUtil.toString(imports)); } } methods.sort(); @@ -146,46 +141,59 @@ public class GenServiceTask extends InvocationTask return; } - generateMarshaller(source, service); - generateDispatcher(source, service); + ServiceDescription desc = new ServiceDescription(service); + generateMarshaller(source, desc); + generateDispatcher(source, desc); if (!_providerless.contains(service.getSimpleName())) { - generateProvider(source, service); + generateProvider(source, desc); } } - protected void generateMarshaller (File source, Class service) + protected void generateMarshaller (File source, ServiceDescription sdesc) { if (_verbose) { - System.out.println("Generating marshaller"); + System.out.println("Generating marshaller"); } - ServiceDescription sdesc = new ServiceDescription(service, true, true); - - // Marshallers always require the service - sdesc.addServiceImport(); - String sname = sdesc.sname; String name = StringUtil.replace(sname, "Service", ""); String mname = StringUtil.replace(sname, "Service", "Marshaller"); String mpackage = StringUtil.replace( - sdesc.spackage, ".client", ".data"); + sdesc.spackage, ".client", ".data"); - // construct our imports list - ComparableArrayList implist = new ComparableArrayList(); - implist.addAll(sdesc.imports.keySet()); - checkedAdd(implist, Client.class.getName()); - checkedAdd(implist, InvocationMarshaller.class.getName()); + // ----------- Part I - java marshaller + + // start with all imports (service methods and listener methods) + ImportSet imports = sdesc.constructAllImports(); + + // import things marshaller will always need + imports.add(sdesc.service); + imports.add(Client.class); + imports.add(InvocationMarshaller.class); + + // if any listeners are to be present, they need the response event if (sdesc.listeners.size() > 0) { - checkedAdd(implist, InvocationResponseEvent.class.getName()); + imports.add(InvocationResponseEvent.class); } - implist.sort(); + + // get rid of java.lang stuff and primitives + imports.removeGlobals(); + + // for each listener type, also import the corresponding marshaller + imports.duplicateAndMunge("Listener", + "Service", "Marshaller", + "Listener", "Marshaller", + ".client.", ".data."); + + // import the parent class of Foo$Bar + imports.swapInnerClassesForParents(); VelocityContext ctx = new VelocityContext(); ctx.put("name", name); ctx.put("package", mpackage); ctx.put("methods", sdesc.methods); ctx.put("listeners", sdesc.listeners); - ctx.put("imports", implist); + ctx.put("imports", imports.toList()); // determine the path to our marshaller file String mpath = source.getPath(); @@ -208,22 +216,35 @@ public class GenServiceTask extends InvocationTask return; } - // convert the raw imports into ActionScript versions (inner-classes - // become Foo_Bar) - Collection asimports = new ArrayList(); - for (String impy : sdesc.rawimports.keySet()) { - asimports.add(impy.replace("$", "_")); - } + // ----------- Part II - as marshaller - // recreate our service imports using those - implist = new ComparableArrayList(); - implist.addAll(asimports); - checkedAdd(implist, Client.class.getName()); - checkedAdd(implist, InvocationMarshaller.class.getName()); - Class imlm = InvocationMarshaller.ListenerMarshaller.class; - checkedAdd(implist, imlm.getName().replace("$", "_")); - implist.sort(); - ctx.put("imports", implist); + // start with the service method imports + imports = sdesc.imports.clone(); + + // add some things that marshallers just need + imports.add(sdesc.service); + imports.add(Client.class); + imports.add(InvocationMarshaller.class); + + // replace inner classes with action script equivalents + imports.translateInnerClasses(); + + // replace primitive types with OOO types (required for unboxing) + imports.replace("byte", "com.threerings.util.Byte"); + imports.replace("int", "com.threerings.util.Integer"); + imports.replace("boolean", "com.threerings.util.langBoolean"); + + // ye olde special case - any method that uses a default listener + // causes the need for the default listener marshaller + imports.duplicateAndMunge("InvocationService_InvocationListener", + "InvocationService_InvocationListener", + "InvocationMarshaller_ListenerMarshaller", + ".client.", ".data."); + + // get rid of java.lang stuff and any remaining primitives + imports.removeGlobals(); + + ctx.put("imports", imports.toList()); // now generate ActionScript versions of our marshaller try { @@ -238,18 +259,32 @@ public class GenServiceTask extends InvocationTask _velocity.mergeTemplate(AS_MARSHALLER_TMPL, "UTF-8", ctx, sw); writeFile(ampath, sw.toString()); + // ----------- Part III - as listener marshallers + + Class imlm = InvocationMarshaller.ListenerMarshaller.class; + // now generate ActionScript versions of our listener marshallers // because those have to be in separate files for (ServiceListener listener : sdesc.listeners) { - // recreate our imports with just what we need here - implist = new ComparableArrayList(); - implist.addAll(sdesc.imports.keySet()); - checkedAdd(implist, imlm.getName().replace("$", "_")); - String lname = listener.listener.getName(); - checkedAdd(implist, lname.replace("$", "_")); - implist.sort(); - ctx.put("imports", implist); + // start imports with just those used by listener methods + imports = listener.imports.clone(); + + // always need the super class and the listener class + imports.add(imlm); + imports.add(listener.listener); + + // replace '$' with '_' for action script naming convention + imports.translateInnerClasses(); + + // convert primitive java types to ooo util types + // TODO: will future listener marshallers need more primitives? + imports.replace("long", "com.threerings.util.Long"); + + // get rid of remaining primitives and java.lang types + imports.removeGlobals(); + + ctx.put("imports", imports.toList()); ctx.put("listener", listener); sw = new StringWriter(); _velocity.mergeTemplate( @@ -265,16 +300,25 @@ public class GenServiceTask extends InvocationTask e.printStackTrace(System.err); } + // ----------- Part IV - as service + // then make some changes to the context and generate ActionScript // versions of the service interface itself - implist = new ComparableArrayList(); - implist.addAll(asimports); - checkedAdd(implist, Client.class.getName()); - checkedAdd(implist, InvocationService.class.getName()); - Class isil = InvocationService.InvocationListener.class; - checkedAdd(implist, isil.getName().replace("$", "_")); - implist.sort(); - ctx.put("imports", implist); + + // start with the service methods' imports + imports = sdesc.imports.clone(); + + // add some things required by action script + imports.add(Client.class); + imports.add(InvocationService.class); + + // get rid of primitives and java.lang classes + imports.removeGlobals(); + + // change imports of Foo$Bar to Foo_Bar + imports.translateInnerClasses(); + + ctx.put("imports", imports.toList()); ctx.put("package", sdesc.spackage); try { @@ -289,19 +333,34 @@ public class GenServiceTask extends InvocationTask _velocity.mergeTemplate(AS_SERVICE_TMPL, "UTF-8", ctx, sw); writeFile(aspath, sw.toString()); + // ----------- Part V - as service listeners + + Class isil = InvocationService.InvocationListener.class; + // also generate ActionScript versions of any inner listener // interfaces because those have to be in separate files for (ServiceListener listener : sdesc.listeners) { - // recreate our imports with just what we need here - implist = new ComparableArrayList(); - implist.addAll(asimports); - checkedAdd(implist, isil.getName().replace("$", "_")); - String lname = listener.listener.getName(); - checkedAdd(implist, lname.replace("$", "_")); - implist.sort(); - ctx.put("imports", implist); + // start with just the imports needed by listener methods + imports = listener.imports.clone(); + + // add things needed by all listeners + imports.add(isil); + imports.add(listener.listener); + + // change Foo$Bar to Foo_Bar + imports.translateInnerClasses(); + + // convert java primitive types to ooo util types + // TODO: will future listeners need more primitives? + imports.replace("long", "com.threerings.util.Long"); + + // get rid of remaining primitives and java.lang types + imports.removeGlobals(); + + ctx.put("imports", imports.toList()); ctx.put("listener", listener); + sw = new StringWriter(); _velocity.mergeTemplate( AS_LISTENER_SERVICE_TMPL, "UTF-8", ctx, sw); @@ -317,41 +376,49 @@ public class GenServiceTask extends InvocationTask } } - protected void generateDispatcher (File source, Class service) + protected void generateDispatcher (File source, ServiceDescription sdesc) { if (_verbose) { - System.out.println("Generating dispatcher"); - } - - ServiceDescription sdesc = new ServiceDescription(service, false, false); - - // If any listeners are to be used in dispatches, we need to import the service - if (sdesc.listeners.size() > 0) { - sdesc.addServiceImport(); + System.out.println("Generating dispatcher"); } String name = StringUtil.replace(sdesc.sname, "Service", ""); String dpackage = StringUtil.replace( - sdesc.spackage, ".client", ".server"); + sdesc.spackage, ".client", ".server"); - // construct our imports list - ComparableArrayList implist = new ComparableArrayList(); - implist.addAll(sdesc.imports.keySet()); - checkedAdd(implist, ClientObject.class.getName()); - checkedAdd(implist, InvocationMarshaller.class.getName()); - checkedAdd(implist, InvocationDispatcher.class.getName()); - checkedAdd(implist, InvocationException.class.getName()); - String mname = StringUtil.replace(sdesc.sname, "Service", "Marshaller"); - String mpackage = StringUtil.replace( - sdesc.spackage, ".client", ".data"); - checkedAdd(implist, mpackage + "." + mname); - implist.sort(); + // start with the imports required by service methods + ImportSet imports = sdesc.imports.clone(); + + // If any listeners are to be used in dispatches, we need to import the service + if (sdesc.listeners.size() > 0) { + imports.add(sdesc.service); + } + + // swap Client for ClientObject + imports.add(ClientObject.class); + imports.remove(Client.class); + + // add some classes required for all dispatchers + imports.add(InvocationMarshaller.class); + imports.add(InvocationDispatcher.class); + imports.add(InvocationException.class); + + // get rid of primitives and java.lang types + imports.removeGlobals(); + + // import the Marshaller corresponding to the service + imports.addMunged(sdesc.service, + "Service", "Marshaller", + ".client.", ".data."); + + // import Foo instead of Foo$Bar + imports.swapInnerClassesForParents(); VelocityContext ctx = new VelocityContext(); ctx.put("name", name); ctx.put("package", dpackage); ctx.put("methods", sdesc.methods); - ctx.put("imports", implist); + ctx.put("imports", imports.toList()); try { StringWriter sw = new StringWriter(); @@ -370,34 +437,43 @@ public class GenServiceTask extends InvocationTask } } - protected void generateProvider (File source, Class service) + protected void generateProvider (File source, ServiceDescription sdesc) { if (_verbose) { - System.out.println("Generating provider"); + System.out.println("Generating provider"); } - ServiceDescription sdesc = new ServiceDescription(service, false, false); - String name = StringUtil.replace(sdesc.sname, "Service", ""); String mpackage = StringUtil.replace( - sdesc.spackage, ".client", ".server"); + sdesc.spackage, ".client", ".server"); - // construct our imports list - ComparableArrayList implist = new ComparableArrayList(); - implist.addAll(sdesc.imports.keySet()); - checkedAdd(implist, ClientObject.class.getName()); - checkedAdd(implist, InvocationProvider.class.getName()); + // start with imports required by service methods + ImportSet imports = sdesc.imports.clone(); + + // swap Client for ClientObject + imports.add(ClientObject.class); + imports.remove(Client.class); + + // import superclass + imports.add(InvocationProvider.class); + + // any method that takes a listener may throw this if (sdesc.hasAnyListenerArgs()) { - checkedAdd(implist, InvocationException.class.getName()); + imports.add(InvocationException.class); } - implist.sort(); + + // get rid of primitives and java.lang types + imports.removeGlobals(); + + // import Foo instead of Foo$Bar + imports.swapInnerClassesForParents(); VelocityContext ctx = new VelocityContext(); ctx.put("name", name); ctx.put("package", mpackage); ctx.put("methods", sdesc.methods); ctx.put("listeners", sdesc.listeners); - ctx.put("imports", implist); + ctx.put("imports", imports.toList()); try { StringWriter sw = new StringWriter(); @@ -419,14 +495,11 @@ public class GenServiceTask extends InvocationTask // rolls up everything needed for the generate* methods protected class ServiceDescription { - ServiceDescription ( - Class service, - boolean importServiceMethodsFirstArgument, - boolean importListenerArguments) - { - this.service = service; - sname = service.getSimpleName(); - spackage = service.getPackage().getName(); + ServiceDescription (Class service) + { + this.service = service; + sname = service.getSimpleName(); + spackage = service.getPackage().getName(); // look through and locate our service methods, also locating any // custom InvocationListener derivations along the way @@ -445,47 +518,52 @@ public class GenServiceTask extends InvocationTask GenUtil.simpleName( args[aa], null).startsWith(sname + ".")) { checkedAdd(listeners, new ServiceListener( - service, args[aa], imports, rawimports, - importListenerArguments)); + service, args[aa])); } } if (_verbose) { - System.out.println("Adding " + m + ", imports are " + - StringUtil.toString(imports.keySet())); + System.out.println("Adding " + m + ", imports are " + + StringUtil.toString(imports)); } - methods.add(new ServiceMethod(service, m, imports, rawimports, - importServiceMethodsFirstArgument ? 0 : 1, - importListenerArguments)); + methods.add(new ServiceMethod(m, imports)); if (_verbose) { - System.out.println("Added " + m + ", imports are " + - StringUtil.toString(imports.keySet())); + System.out.println("Added " + m + ", imports are " + + StringUtil.toString(imports)); } } listeners.sort(); methods.sort(); - } - - boolean hasAnyListenerArgs () - { - for (ServiceMethod sm : methods) { - if (!sm.listenerArgs.isEmpty()) { - return true; - } - } - return false; - } - - void addServiceImport () - { - imports.put(importify(service.getName()), Boolean.TRUE); - rawimports.put(service.getName(), Boolean.TRUE); - } + } + + /** + * Checks if any of the service method arguments are listener types. + */ + boolean hasAnyListenerArgs () + { + for (ServiceMethod sm : methods) { + if (!sm.listenerArgs.isEmpty()) { + return true; + } + } + return false; + } - Class service; - String sname; + /** + * Constructs a union of the imports of the service methods and all listener methods. + */ + ImportSet constructAllImports () + { + ImportSet allimports = imports.clone(); + for (ServiceListener listener : listeners) { + allimports.addAll(listener.imports); + } + return allimports; + } + + Class service; + String sname; String spackage; - HashMap imports = new HashMap(); - HashMap rawimports = new HashMap(); + ImportSet imports = new ImportSet(); ComparableArrayList methods = new ComparableArrayList(); ComparableArrayList listeners = diff --git a/src/java/com/threerings/presents/tools/ImportSet.java b/src/java/com/threerings/presents/tools/ImportSet.java new file mode 100644 index 000000000..72dfa56bb --- /dev/null +++ b/src/java/com/threerings/presents/tools/ImportSet.java @@ -0,0 +1,202 @@ +package com.threerings.presents.tools; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; + +import com.samskivert.util.ComparableArrayList; +import com.samskivert.util.StringUtil; + +/** + * Manages a set of strings to be used as a set of imports. Provides useful functions for + * manipulating the set and sorts results. + * + *

Some methods in this class use a variable length String parameter 'replace'. This is a + * convenience for easily specifying multiple find/replace pairs. For example, to replace "Foo" + * with "Bar" and "123" with "ABC", a function can be called with the 4 arguments "Foo", "Bar", + * "123", "ABC" for the String... replace argument. + */ +public class ImportSet +{ + /** + * Adds the given class' name to the set of imports. + * @param clazz the class to add + */ + public void add (Class clazz) + { + _imports.add(clazz.getName()); + } + + /** + * Adds the given name to the set of imports. + * @param name the name to add + */ + public void add (String name) + { + _imports.add(name); + } + + /** + * Adds all the imports from another import set into this one. + * @param other the import set whose imports should be added + */ + public void addAll (ImportSet other) + { + _imports.addAll(other._imports); + } + + /** + * Adds a class' name to the imports but first performs the given list of search/replaces as + * described above. + * @param clazz the class whose name is munged and added + * @param replace array of pairs to search/replace on the name before adding + */ + public void addMunged (Class clazz, String... replace) + { + String name = clazz.getName(); + for (int i = 0 ; i < replace.length; i+=2) { + name = name.replace(replace[i], replace[i + 1]); + } + _imports.add(name); + } + + /** + * Makes a copy of this import set. + */ + public ImportSet clone () + { + ImportSet newset = new ImportSet(); + newset.addAll(this); + return newset; + } + + /** + * Gets rid of primitive and java.lang imports. + */ + public void removeGlobals () + { + Iterator i = _imports.iterator(); + while (i.hasNext()) { + String name = i.next(); + if (name.indexOf('.') == -1) { + i.remove(); + } + else if (name.startsWith("java.lang")) { + i.remove(); + } + } + } + + /** + * Replaces inner class imports (those with a '$') with an import of the parent class. + */ + public void swapInnerClassesForParents () + { + ImportSet declarers = new ImportSet(); + Iterator i = _imports.iterator(); + while (i.hasNext()) { + String name = i.next(); + int dollar = name.indexOf('$'); + if (dollar >= 0) { + i.remove(); + declarers.add(name.substring(0, dollar)); + } + } + + addAll(declarers); + } + + /** + * Replace all inner classes' separator characters ('$') with an underscore ('_') for use + * when generating ActionScript. + */ + public void translateInnerClasses () + { + ImportSet inner = new ImportSet(); + Iterator i = _imports.iterator(); + while (i.hasNext()) { + String name = i.next(); + int dollar = name.indexOf('$'); + if (dollar >= 0) { + i.remove(); + inner.add(name.replace("$", "_")); + } + } + + addAll(inner); + } + + /** + * Removes the name of a class from the imports. + * @param clazz the class whose name should be removed + */ + public void remove (Class clazz) + { + _imports.remove(clazz.getName()); + } + + /** + * Replaces any import exactly matching the 0th argument with the 1st argument and so on. + * See the description above. + * @param replace array of pairs for search/replace + */ + public void replace (String... replace) + { + HashSet toAdd = new HashSet(); + Iterator i = _imports.iterator(); + while (i.hasNext()) { + String name = i.next(); + for (int j = 0; j < replace.length; j += 2) { + if (name.equals(replace[j])) { + toAdd.add(replace[j + 1]); + i.remove(); + break; + } + } + } + _imports.addAll(toAdd); + } + + /** + * Adds a new munged import for each existing import that matches a suffix. The new entry is + * a copy of the old entry but modified according to the "replace" pattern described above. + * @param suffix to filter the search for imports to duplicate + * @param replace array of string pairs to search/replace on the duplicated import + */ + public void duplicateAndMunge (String suffix, String... replace) + { + HashSet toMunge = new HashSet(); + for (String name : _imports) { + if (name.endsWith(suffix)) { + toMunge.add(name); + } + } + for (String name : toMunge) { + String newname = name; + for (int i = 0; i < replace.length; i+=2) { + newname = newname.replace(replace[i], replace[i + 1]); + } + _imports.add(newname); + } + } + + /** + * Convert the set of imports to a sorted list, ready to be output to a generated file. + * @return the sorted list of imports + */ + public List toList () + { + ComparableArrayList list = new ComparableArrayList(); + list.addAll(_imports); + list.sort(); + return list; + } + + @Override // from Object + public String toString () + { + return StringUtil.toString(_imports); + } + + protected HashSet _imports = new HashSet(); +} diff --git a/src/java/com/threerings/presents/tools/InvocationTask.java b/src/java/com/threerings/presents/tools/InvocationTask.java index 6e6d2a707..28e6d76cc 100644 --- a/src/java/com/threerings/presents/tools/InvocationTask.java +++ b/src/java/com/threerings/presents/tools/InvocationTask.java @@ -29,7 +29,6 @@ import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import org.apache.commons.io.FileUtils; @@ -44,7 +43,6 @@ import org.apache.tools.ant.util.ClasspathUtils; import org.apache.velocity.app.VelocityEngine; -import com.samskivert.util.ObjectUtil; import com.samskivert.util.StringUtil; import com.samskivert.velocity.VelocityUtil; @@ -92,8 +90,8 @@ public abstract class InvocationTask extends Task } } - /** Used to keep track of invocation service methods (or listener - * methods). */ + /** Used to keep track of invocation service methods or listener + * methods. */ public class ServiceMethod implements Comparable { public Method method; @@ -101,18 +99,19 @@ public abstract class InvocationTask extends Task public ArrayList listenerArgs = new ArrayList(); - public ServiceMethod (Class service, Method method, - HashMap imports, - HashMap rawimports, - int ignoreArguments, - boolean importMarshallerListeners) + /** + * Creates a new service method. + * @param method the method to inspect + * @param imports will be filled with the types required by the method + */ + public ServiceMethod (Method method, ImportSet imports) { this.method = method; - + // we need to look through our arguments and note any needed // imports in the supplied table Class[] args = method.getParameterTypes(); - for (int ii = ignoreArguments; ii < args.length; ii++) { + for (int ii = 0; ii < args.length; ii++) { Class arg = args[ii]; while (arg.isArray()) { arg = arg.getComponentType(); @@ -124,41 +123,7 @@ public abstract class InvocationTask extends Task listenerArgs.add(new ListenerArgument(ii, arg)); } - // if it's primitive or global we don't need an import - if (arg.isPrimitive() || - arg.getName().startsWith("java.lang")) { - continue; - } - - // if it's in our same package, we don't need a normal import - // but we may need a raw import - boolean samepkg = - ObjectUtil.equals(arg.getPackage(), service.getPackage()); - if (!samepkg) { - imports.put(importify(arg.getName()), Boolean.TRUE); - } - if (rawimports != null) { - rawimports.put(arg.getName(), Boolean.TRUE); - } - - // if it's a listener and not one of the special - // InvocationService listeners, we need to import its - // marshaller as well - String sname = GenUtil.simpleName(arg, null); - if (importMarshallerListeners && - _ilistener.isAssignableFrom(arg)) { - String mname = arg.getName(); - mname = StringUtil.replace(mname, "Service", "Marshaller"); - mname = StringUtil.replace(mname, "Listener", "Marshaller"); - mname = StringUtil.replace(mname, ".client.", ".data."); - if (!samepkg && !sname.startsWith("InvocationService")) { - imports.put(importify(mname), Boolean.TRUE); - } - if (rawimports != null && - !sname.equals("InvocationService.InvocationListener")) { - rawimports.put(mname, Boolean.TRUE); - } - } + imports.add(arg); } } @@ -333,7 +298,7 @@ public abstract class InvocationTask extends Task */ public void setVerbose (boolean verbose) { - _verbose = verbose; + _verbose = verbose; } /** Configures our classpath which we'll use to load service classes. */ @@ -408,6 +373,9 @@ public abstract class InvocationTask extends Task protected void writeFile (String path, String data) throws IOException { + if (_verbose) { + System.out.println("Writing file " + path); + } if (_header != null) { data = _header + data; } @@ -421,12 +389,6 @@ public abstract class InvocationTask extends Task } } - protected static String importify (String name) - { - int didx = name.indexOf("$"); - return (didx == -1) ? name : name.substring(0, didx); - } - protected static String replacePath ( String source, String oldstr, String newstr) { diff --git a/src/java/com/threerings/presents/tools/marshaller_as.tmpl b/src/java/com/threerings/presents/tools/marshaller_as.tmpl index 8f8b3c7e7..fb1942972 100644 --- a/src/java/com/threerings/presents/tools/marshaller_as.tmpl +++ b/src/java/com/threerings/presents/tools/marshaller_as.tmpl @@ -1,9 +1,5 @@ package $package { -import flash.utils.ByteArray; -import com.threerings.util.*; // for Float, Integer, etc. -import com.threerings.io.TypedArray; - #foreach ($import in $imports) import $import; #end diff --git a/src/java/com/threerings/presents/tools/marshaller_listener_as.tmpl b/src/java/com/threerings/presents/tools/marshaller_listener_as.tmpl index d42c67cc1..ac771ed0a 100644 --- a/src/java/com/threerings/presents/tools/marshaller_listener_as.tmpl +++ b/src/java/com/threerings/presents/tools/marshaller_listener_as.tmpl @@ -1,9 +1,5 @@ package $package { -import flash.utils.ByteArray; -import com.threerings.util.*; // for Float, Integer, etc. -import com.threerings.io.TypedArray; - #foreach ($import in $imports) import $import; #end diff --git a/src/java/com/threerings/presents/tools/service_as.tmpl b/src/java/com/threerings/presents/tools/service_as.tmpl index 25e0db67f..e18e29f3b 100644 --- a/src/java/com/threerings/presents/tools/service_as.tmpl +++ b/src/java/com/threerings/presents/tools/service_as.tmpl @@ -1,7 +1,5 @@ package $package { -import flash.utils.ByteArray; -import com.threerings.io.TypedArray; #foreach ($import in $imports) import $import; #end diff --git a/src/java/com/threerings/presents/tools/service_listener_as.tmpl b/src/java/com/threerings/presents/tools/service_listener_as.tmpl index 6ede9abb0..317911b2c 100644 --- a/src/java/com/threerings/presents/tools/service_listener_as.tmpl +++ b/src/java/com/threerings/presents/tools/service_listener_as.tmpl @@ -1,9 +1,5 @@ package $package { -import flash.utils.ByteArray; -import com.threerings.util.*; // for Float, Integer, etc. -import com.threerings.io.TypedArray; - #foreach ($import in $imports) import $import; #end diff --git a/tests/bin/check_genservice.sh b/tests/bin/check_genservice.sh new file mode 100755 index 000000000..b7bc884f7 --- /dev/null +++ b/tests/bin/check_genservice.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +tmp=/tmp/check_genservices_temp +echo "" > $tmp + +pushd .. > /dev/null +ant genservice +err=$? +popd > /dev/null + +[[ $err -eq 0 ]] || exit $err + +count() +{ + class=$1 + file=$2 + perl -e ' + $count = 0; + while (<>) + { + ++$count if /\b'$class'\b/; + } + print $count + ' $file +} + +find .. \( -name \*.java -o -name \*.as \) -newer $tmp | while read file; do + egrep ^import $file | sed -e 's/;//' | while read import; do + class=${import##*.} + # echo "Checking $class in $file" + if [ $(count $class $file) -lt 2 ]; then + echo "ERROR: ${import} not used in file $file" + fi + done +done + +rm $tmp