Check whether arg unwrapping will result in a cast to a generic type and in

that case, suppress unchecked warnings. We do this on the whole method because
doing it for each argument would vastly complicate things and we can be fairly
confident that this generated code will not have other dangerous casts added to
it that would be hidden by the suppression.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@5291 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2008-08-04 21:02:15 +00:00
parent d3d3528d83
commit beadc8745c
3 changed files with 56 additions and 29 deletions
@@ -31,6 +31,9 @@ import java.util.HashSet;
import org.apache.velocity.VelocityContext;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.samskivert.util.ComparableArrayList;
import com.samskivert.util.StringUtil;
@@ -89,6 +92,27 @@ public class GenServiceTask extends InvocationTask
methods.sort();
}
/**
* Checks whether any of our methods have parameterized types.
*/
public boolean hasParameterizedMethodArgs ()
{
return Iterables.any(methods, new Predicate<ServiceMethod>() {
public boolean apply (ServiceMethod sm) {
return sm.hasParameterizedArgs();
}
});
}
public String getName ()
{
String name = GenUtil.simpleName(listener);
name = StringUtil.replace(name, "Listener", "");
int didx = name.indexOf(".");
return name.substring(didx+1);
}
// from interface Comparable<ServiceListener>
public int compareTo (ServiceListener other)
{
return getName().compareTo(other.getName());
@@ -106,14 +130,6 @@ public class GenServiceTask extends InvocationTask
{
return listener.getName().hashCode();
}
public String getName ()
{
String name = GenUtil.simpleName(listener);
name = StringUtil.replace(name, "Listener", "");
int didx = name.indexOf(".");
return name.substring(didx+1);
}
}
/** Used to track services for which we should not generate a provider interface. */
@@ -148,8 +164,7 @@ public class GenServiceTask extends InvocationTask
// verify that the service class name is as we expect it to be
if (!service.getName().endsWith("Service")) {
System.err.println("Cannot process '" + service.getName() + "':");
System.err.println(
"Service classes must be named SomethingService.");
System.err.println("Service classes must be named SomethingService.");
return;
}
@@ -170,8 +185,7 @@ public class GenServiceTask extends InvocationTask
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");
String mpackage = StringUtil.replace(sdesc.spackage, ".client", ".data");
// ----------- Part I - java marshaller
@@ -231,8 +245,8 @@ public class GenServiceTask extends InvocationTask
e.printStackTrace(System.err);
}
// if we're not configured with an ActionScript source root, don't
// generate the ActionScript versions
// if we're not configured with an ActionScript source root, don't generate the
// ActionScript versions
if (_asroot == null) {
return;
}
@@ -308,7 +322,6 @@ public class GenServiceTask extends InvocationTask
// now generate ActionScript versions of our listener marshallers
// because those have to be in separate files
for (ServiceListener listener : sdesc.listeners) {
// start imports with just those used by listener methods
imports = listener.imports.clone();
@@ -435,8 +448,7 @@ public class GenServiceTask extends InvocationTask
ctx.put("listener", listener);
sw = new StringWriter();
_velocity.mergeTemplate(
AS_LISTENER_SERVICE_TMPL, "UTF-8", ctx, sw);
_velocity.mergeTemplate(AS_LISTENER_SERVICE_TMPL, "UTF-8", ctx, sw);
String amlpath = _asroot + File.separator + sppath +
File.separator + sname + "_" +
listener.getName() + "Listener.as";
@@ -637,12 +649,11 @@ public class GenServiceTask extends InvocationTask
*/
public boolean hasAnyListenerArgs ()
{
for (ServiceMethod sm : methods) {
if (!sm.listenerArgs.isEmpty()) {
return true;
return Iterables.any(methods, new Predicate<ServiceMethod>() {
public boolean apply (ServiceMethod sm) {
return !sm.listenerArgs.isEmpty();
}
}
return false;
});
}
/**
@@ -26,9 +26,11 @@ import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.io.FileUtils;
@@ -44,6 +46,9 @@ import org.apache.tools.ant.util.ClasspathUtils;
import org.apache.velocity.app.VelocityEngine;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.samskivert.util.StringUtil;
import com.samskivert.velocity.VelocityUtil;
@@ -92,14 +97,12 @@ 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<ServiceMethod>
{
public Method method;
public ArrayList<ListenerArgument> listenerArgs =
new ArrayList<ListenerArgument>();
public List<ListenerArgument> listenerArgs = new ArrayList<ListenerArgument>();
/**
* Creates a new service method.
@@ -209,6 +212,17 @@ public abstract class InvocationTask extends Task
return (method.getParameterTypes().length > (skipFirst ? 1 : 0));
}
public boolean hasParameterizedArgs ()
{
return Iterables.any(
Arrays.asList(method.getGenericParameterTypes()), new Predicate<Type>() {
public boolean apply (Type type) {
// TODO: might eventually need to handle generic arrays and wildcard types
return (type instanceof ParameterizedType);
}
});
}
public int compareTo (ServiceMethod other)
{
return getCode().compareTo(other.getCode());
@@ -240,8 +254,7 @@ public abstract class InvocationTask extends Task
if (listenerMode && _ilistener.isAssignableFrom(args[ii])) {
arg = "listener" + argidx;
} else {
arg = GenUtil.unboxASArgument(
args[ii], "args[" + argidx + "]");
arg = GenUtil.unboxASArgument(args[ii], "args[" + argidx + "]");
}
buf.append(arg);
}
@@ -415,7 +428,7 @@ public abstract class InvocationTask extends Task
}
/** A list of filesets that contain tile images. */
protected ArrayList<FileSet> _filesets = new ArrayList<FileSet>();
protected List<FileSet> _filesets = new ArrayList<FileSet>();
/** A header to put on all generated source files. */
protected String _header;
@@ -37,6 +37,9 @@ public class ${name}Marshaller extends InvocationMarshaller
#end
@Override // from InvocationMarshaller
#if ($l.hasParameterizedMethodArgs())
@SuppressWarnings("unchecked")
#end
public void dispatchResponse (int methodId, Object[] args)
{
switch (methodId) {