Fix to make Detector.findPausableMethod work with generic types #12

Closed
tstockwell opened this Issue Oct 22, 2012 · 1 comment

Comments

Projects
None yet
2 participants
@tstockwell

I have a generic base class and a subclass that both implement a pausable method, like so...


public abstract class Base<T> {
    public abstract T run() throws Pausable;
}

public class Sub extends Base<Void> {
    public void run() throws Pausable {
        // do stuff....
    }
}

The problem is that currently Kilim will report an error that says "Base class method is not pausable, but derived class is".

I tracked the source of the problem to the Detector.findPausableMethod method.
This method attempts to find a pausable method using class name, method name, and a method descriptor.
The problem is that in this case the method decriptors return types are different for the base class and the subclass.
There is no reason to compare return types when attempting to identify methods, since Java identifies methods based only on method name and argument types.
Therefore I changed the code to only use the beginning of the method descriptor (with the argument types) when comparing descriptors.

Here is the fixed version of Detector.findPausableMethod...


    private MethodMirror findPausableMethod(String className, String methodName, String desc)
            throws ClassMirrorNotFoundException {
        
        if (isNonPausableClass(className) || isNonPausableMethod(methodName)) 
            return null;

        ClassMirror cl = classForName(className);
        if (cl == null) return null;
        
        for (MethodMirror om : cl.getDeclaredMethods()) {
            if (om.getName().equals(methodName)) {
                String omDesc= om.getMethodDescriptor();
                
                // when comparing descriptors only compare arguments, not return types
                if (omDesc.substring(0,omDesc.indexOf(")")).equals(desc.substring(0,desc.indexOf(")")))) {
                    if (om.isBridge())
                        continue;
                    return om;
                }
            }
        }

        if (OBJECT.equals(cl))
            return null;

        MethodMirror m = findPausableMethod(cl.getSuperclass(), methodName, desc);
        if (m != null)
            return m;
        
        for (String ifname : cl.getInterfaces()) {
            if (isNonPausableClass(ifname)) continue;
            m = findPausableMethod(ifname, methodName, desc);
            if (m != null)
                return m;
        }
        return null;
    }
@kilim

This comment has been minimized.

Show comment Hide comment
@kilim

kilim Oct 28, 2012

Owner

Fixed in commit 125d6f8

Owner

kilim commented Oct 28, 2012

Fixed in commit 125d6f8

@kilim kilim closed this Oct 28, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment