Browse Source

fixed a bug in CtClass.getMethods() and javassist.reflect package


git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@126 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
tags/rel_3_17_1_ga
chiba 20 years ago
parent
commit
5d5407d0af

+ 1
- 1
src/main/javassist/CtClassType.java View File

@@ -666,7 +666,7 @@ class CtClassType extends CtClass {
CtMethod cm = ((CtClassType)cc).getMethodsCache();
while (cm != null) {
if (Modifier.isPublic(cm.getModifiers()))
h.put(cm, cm);
h.put(cm.getStringRep(), cm);

cm = cm.next;
}

+ 12
- 12
src/main/javassist/CtMethod.java View File

@@ -28,12 +28,12 @@ import javassist.bytecode.*;
*/
public final class CtMethod extends CtBehavior {
protected CtMethod next;
protected int cachedHashCode;
protected String cachedStringRep;

CtMethod(MethodInfo minfo, CtClass declaring) {
super(declaring, minfo);
next = null;
cachedHashCode = 0;
cachedStringRep = null;
}

/**
@@ -163,17 +163,17 @@ public final class CtMethod extends CtBehavior {
* the hash codes for the two methods are equal.
*/
public int hashCode() {
/* This method is overridden in ExistingMethod for optimization.
*/
if (cachedHashCode == 0) {
String signature
= methodInfo.getName() + ':' + methodInfo.getDescriptor();
return getStringRep().hashCode();
}

// System.identityHashCode() returns 0 only for null.
cachedHashCode = System.identityHashCode(signature.intern());
}
/* This method is also called by CtClassType.getMethods0().
*/
final String getStringRep() {
if (cachedStringRep == null)
cachedStringRep = methodInfo.getName()
+ Descriptor.getParamDescriptor(methodInfo.getDescriptor());

return cachedHashCode;
return cachedStringRep;
}

/**
@@ -182,7 +182,7 @@ public final class CtMethod extends CtBehavior {
*/
public boolean equals(Object obj) {
return obj != null && obj instanceof CtMethod
&& obj.hashCode() == hashCode();
&& ((CtMethod)obj).getStringRep().equals(getStringRep());
}

/**

+ 1
- 1
src/main/javassist/bytecode/ClassFile.java View File

@@ -452,7 +452,7 @@ public final class ClassFile {
while (it.hasNext()) {
MethodInfo minfo = (MethodInfo)it.next();
if (minfo.getName().equals(name)
&& Descriptor.eqSignature(minfo.getDescriptor(), descriptor))
&& Descriptor.eqParamTypes(minfo.getDescriptor(), descriptor))
throw new CannotCompileException("duplicate method: " + name);
}
}

+ 13
- 2
src/main/javassist/bytecode/Descriptor.java View File

@@ -337,9 +337,11 @@ public class Descriptor {
}

/**
* Returns true if desc1 and desc2 has the same signature.
* Returns true if the list of the parameter types of desc1 is equal to
* that of desc2.
* For example, "(II)V" and "(II)I" are equal.
*/
public static boolean eqSignature(String desc1, String desc2) {
public static boolean eqParamTypes(String desc1, String desc2) {
if (desc1.charAt(0) != '(')
return false;

@@ -353,6 +355,15 @@ public class Descriptor {
}
}

/**
* Returns the signature of the given descriptor. The signature does
* not include the return type. For example, the signature of "(I)V"
* is "(I)".
*/
public static String getParamDescriptor(String decl) {
return decl.substring(0, decl.indexOf(')') + 1);
}

/**
* Returns the <code>CtClass</code> object representing the return
* type specified by the given descriptor.

+ 12
- 14
src/main/javassist/reflect/ClassMetaobject.java View File

@@ -249,25 +249,23 @@ public class ClassMetaobject implements Serializable {
return methods;

Class baseclass = getJavaClass();
Method[] allmethods = baseclass.getMethods();
Method[] allmethods = baseclass.getDeclaredMethods();
int n = allmethods.length;
methods = new Method[n];
for (int i = 0; i < n; ++i) {
Method m = allmethods[i];
if (m.getDeclaringClass() == baseclass) {
String mname = m.getName();
if (mname.startsWith(methodPrefix)) {
int k = 0;
for (int j = methodPrefixLen;; ++j) {
char c = mname.charAt(j);
if ('0' <= c && c <= '9')
k = k * 10 + c - '0';
else
break;
}

methods[k] = m;
String mname = m.getName();
if (mname.startsWith(methodPrefix)) {
int k = 0;
for (int j = methodPrefixLen;; ++j) {
char c = mname.charAt(j);
if ('0' <= c && c <= '9')
k = k * 10 + c - '0';
else
break;
}

methods[k] = m;
}
}


+ 9
- 2
src/main/javassist/reflect/Reflection.java View File

@@ -24,8 +24,11 @@ import javassist.CtMethod.ConstParameter;
* <p>If a class is reflective,
* then all the method invocations on every
* instance of that class are intercepted by the runtime
* metaobject controlling that instance.
* To do this, the original class file representing a reflective class:
* metaobject controlling that instance. The methods inherited from the
* super classes are also intercepted except final methods. To intercept
* a final method in a super class, that super class must be also reflective.
*
* <p>To do this, the original class file representing a reflective class:
*
* <ul><pre>
* class Person {
@@ -298,6 +301,10 @@ public class Reflection implements Translator {
return;

m2 = m;
if (Modifier.isFinal(mod)) {
mod &= ~Modifier.FINAL;
m2.setModifiers(mod);
}
}
else {
if (Modifier.isFinal(mod))

Loading…
Cancel
Save