Browse Source

Merge pull request #466 from shifujun/pr-fix-lookupMethod

Fix MemberResolver.lookupMethod bug when super class has more precise…
tags/rel_3_30_0_ga
Shigeru Chiba 5 months ago
parent
commit
310fb8fe71
No account linked to committer's email address

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



if (onlyExact) if (onlyExact)
maybe = null; maybe = null;
else
if (maybe != null)
return maybe;
//else maybe super class has more precise match


int mod = clazz.getModifiers(); int mod = clazz.getModifiers();
boolean isIntf = Modifier.isInterface(mod); boolean isIntf = Modifier.isInterface(mod);
if (pclazz != null) { if (pclazz != null) {
Method r = lookupMethod(pclazz, methodName, argTypes, Method r = lookupMethod(pclazz, methodName, argTypes,
argDims, argClassNames, onlyExact); argDims, argClassNames, onlyExact);
if (r != null)
return r;
if (r != null) {
if (maybe == null || maybe.notmatch > r.notmatch) {
maybe = r;
}
}
} }
} }
} }
Method r = lookupMethod(intf, methodName, Method r = lookupMethod(intf, methodName,
argTypes, argDims, argClassNames, argTypes, argDims, argClassNames,
onlyExact); onlyExact);
if (r != null)
return r;
if (r != null) {
if (maybe == null || maybe.notmatch > r.notmatch) {
maybe = r;
}
}
} }


if (isIntf) { if (isIntf) {
if (pclazz != null) { if (pclazz != null) {
Method r = lookupMethod(pclazz, methodName, argTypes, Method r = lookupMethod(pclazz, methodName, argTypes,
argDims, argClassNames, onlyExact); 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

import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.TypeVariable; import java.lang.reflect.TypeVariable;


import javassist.bytecode.AccessFlag; import javassist.bytecode.AccessFlag;
CtClass cc = sloader.makeClass("test5.JIRA256"); CtClass cc = sloader.makeClass("test5.JIRA256");
ClassFile ccFile = cc.getClassFile(); ClassFile ccFile = cc.getClassFile();
ConstPool constpool = ccFile.getConstPool(); ConstPool constpool = ccFile.getConstPool();
AnnotationsAttribute attr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag); AnnotationsAttribute attr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
javassist.bytecode.annotation.Annotation entityAnno javassist.bytecode.annotation.Annotation entityAnno
= new javassist.bytecode.annotation.Annotation("test5.Entity", constpool); = new javassist.bytecode.annotation.Annotation("test5.Entity", constpool);
assertTrue(o.getClass().getName().equals("test5.JIRA256")); assertTrue(o.getClass().getName().equals("test5.JIRA256"));


java.lang.annotation.Annotation[] annotations = o.getClass().getDeclaredAnnotations(); java.lang.annotation.Annotation[] annotations = o.getClass().getDeclaredAnnotations();
assertEquals(1, annotations.length);
assertEquals(1, annotations.length);
} }


public void testJIRA250() throws Exception { public void testJIRA250() throws Exception {
assertEquals(1, attr.size()); assertEquals(1, attr.size());
assertNull(attr.parameterName(0)); 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

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