Fix MemberResolver.lookupMethod bug when super class has more precise…tags/rel_3_30_0_ga
@@ -130,9 +130,7 @@ public class MemberResolver implements TokenId { | |||
if (onlyExact) | |||
maybe = null; | |||
else | |||
if (maybe != null) | |||
return maybe; | |||
//else maybe super class has more precise match | |||
int mod = clazz.getModifiers(); | |||
boolean isIntf = Modifier.isInterface(mod); | |||
@@ -143,8 +141,11 @@ public class MemberResolver implements TokenId { | |||
if (pclazz != null) { | |||
Method r = lookupMethod(pclazz, methodName, argTypes, | |||
argDims, argClassNames, onlyExact); | |||
if (r != null) | |||
return r; | |||
if (r != null) { | |||
if (maybe == null || maybe.notmatch > r.notmatch) { | |||
maybe = r; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
@@ -156,8 +157,11 @@ public class MemberResolver implements TokenId { | |||
Method r = lookupMethod(intf, methodName, | |||
argTypes, argDims, argClassNames, | |||
onlyExact); | |||
if (r != null) | |||
return r; | |||
if (r != null) { | |||
if (maybe == null || maybe.notmatch > r.notmatch) { | |||
maybe = r; | |||
} | |||
} | |||
} | |||
if (isIntf) { | |||
@@ -166,8 +170,11 @@ public class MemberResolver implements TokenId { | |||
if (pclazz != null) { | |||
Method r = lookupMethod(pclazz, methodName, argTypes, | |||
argDims, argClassNames, onlyExact); | |||
if (r != null) | |||
return r; | |||
if (r != null) { | |||
if (maybe == null || maybe.notmatch > r.notmatch) { | |||
maybe = r; | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -4,6 +4,7 @@ import java.io.File; | |||
import java.io.FileInputStream; | |||
import java.io.IOException; | |||
import java.lang.annotation.Annotation; | |||
import java.lang.reflect.Method; | |||
import java.lang.reflect.TypeVariable; | |||
import javassist.bytecode.AccessFlag; | |||
@@ -166,7 +167,7 @@ public class JvstTest5 extends JvstTestRoot { | |||
CtClass cc = sloader.makeClass("test5.JIRA256"); | |||
ClassFile ccFile = cc.getClassFile(); | |||
ConstPool constpool = ccFile.getConstPool(); | |||
AnnotationsAttribute attr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag); | |||
javassist.bytecode.annotation.Annotation entityAnno | |||
= new javassist.bytecode.annotation.Annotation("test5.Entity", constpool); | |||
@@ -181,7 +182,7 @@ public class JvstTest5 extends JvstTestRoot { | |||
assertTrue(o.getClass().getName().equals("test5.JIRA256")); | |||
java.lang.annotation.Annotation[] annotations = o.getClass().getDeclaredAnnotations(); | |||
assertEquals(1, annotations.length); | |||
assertEquals(1, annotations.length); | |||
} | |||
public void testJIRA250() throws Exception { | |||
@@ -625,4 +626,24 @@ public class JvstTest5 extends JvstTestRoot { | |||
assertEquals(1, attr.size()); | |||
assertNull(attr.parameterName(0)); | |||
} | |||
public void testSuperCall() throws Exception { | |||
String javacResult = new BearKeeper().javacResult(); | |||
assertEquals("Man feed(Bear)", javacResult); | |||
CtClass cc = sloader.get("javassist.BearKeeper"); | |||
CtMethod cm = CtMethod.make( | |||
"public String javassistResult() {return super.feed(new javassist.Bear());}", | |||
cc); | |||
cc.addMethod(cm); | |||
cc.setModifiers(Modifier.PUBLIC); | |||
cc.writeFile(); | |||
Object obj = make(cc.getName()); | |||
Method m = obj.getClass().getMethod("javassistResult"); | |||
Object javassistResult = m.invoke(obj); | |||
//before this fix | |||
//expected:<Man feed(Bear)> but was:<Keeper feed(Animal)> | |||
assertEquals(javacResult, javassistResult); | |||
} | |||
} |
@@ -0,0 +1,38 @@ | |||
package javassist; | |||
class Animal { | |||
} | |||
class Bear extends Animal { | |||
} | |||
/** | |||
* Base class has a method with precise type. | |||
*/ | |||
class Man { | |||
String feed(Bear bear) { | |||
return "Man feed(Bear)"; | |||
} | |||
} | |||
/** | |||
* Derived class has a method which has same name with base class's and more imprecise type. | |||
*/ | |||
class Keeper extends Man { | |||
String feed(Animal animal) { | |||
return "Keeper feed(Animal)"; | |||
} | |||
} | |||
/** | |||
* Derived class has a method which call super method with precise type. | |||
*/ | |||
class BearKeeper extends Keeper { | |||
public BearKeeper() { | |||
} | |||
String javacResult() { | |||
return super.feed(new Bear()); | |||
} | |||
} |