Browse Source

Fix MemberResolver.lookupMethod bug when super class has more precise match

When onlyExact=false and super class have a more precise match,
it should not return with current class's maybe result.

New added testSuperCall reveals the problem.
tags/rel_3_30_0_ga
shifujun 4 months ago
parent
commit
c04c375e81

+ 16
- 9
src/main/javassist/compiler/MemberResolver.java View File

@@ -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;
}
}
}
}
}

+ 23
- 2
src/test/javassist/JvstTest5.java View File

@@ -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);
}
}

+ 38
- 0
src/test/javassist/SuperCallCase.java View File

@@ -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());
}
}

Loading…
Cancel
Save