Browse Source

fixed a bug of accesses to annotation arguments.

If foo.Bar.Baz is a nested class in foo.Bar, then the argument of
@MyAnnotation(foo.bar.Baz.class) could not be obtained.
The test code is javassist.JvstTest4#testAnnArg().
tags/rel_3_19_0_ga
chibash 9 years ago
parent
commit
4cdb575d4e

+ 35
- 0
src/main/javassist/bytecode/SignatureAttribute.java View File

@@ -591,6 +591,13 @@ public class SignatureAttribute extends AttributeInfo {
sbuf.append(ts[i]);
}
}

/**
* Returns the type name in the JVM internal style.
* For example, if the type is a nested class {@code foo.Bar.Baz},
* then {@code foo.Bar$Baz} is returned.
*/
public String jvmTypeName() { return toString(); }
}

/**
@@ -746,6 +753,34 @@ public class SignatureAttribute extends AttributeInfo {
return sbuf.toString();
}

/**
* Returns the type name in the JVM internal style.
* For example, if the type is a nested class {@code foo.Bar.Baz},
* then {@code foo.Bar$Baz} is returned.
*/
public String jvmTypeName() {
StringBuffer sbuf = new StringBuffer();
ClassType parent = getDeclaringClass();
if (parent != null)
sbuf.append(parent.jvmTypeName()).append('$');

sbuf.append(name);
if (arguments != null) {
sbuf.append('<');
int n = arguments.length;
for (int i = 0; i < n; i++) {
if (i > 0)
sbuf.append(", ");

sbuf.append(arguments[i].toString());
}

sbuf.append('>');
}

return sbuf.toString();
}

void encode(StringBuffer sb) {
sb.append('L');
encode2(sb);

+ 2
- 2
src/main/javassist/bytecode/annotation/ClassMemberValue.java View File

@@ -101,7 +101,7 @@ public class ClassMemberValue extends MemberValue {
public String getValue() {
String v = cp.getUtf8Info(valueIndex);
try {
return SignatureAttribute.toTypeSignature(v).toString();
return SignatureAttribute.toTypeSignature(v).jvmTypeName();
} catch (BadBytecode e) {
throw new RuntimeException(e);
}
@@ -121,7 +121,7 @@ public class ClassMemberValue extends MemberValue {
* Obtains the string representation of this object.
*/
public String toString() {
return getValue() + ".class";
return getValue().replace('$', '.') + ".class";
}

/**

+ 19
- 13
src/test/Test.java View File

@@ -2,19 +2,25 @@ import javassist.*;

public class Test {
public static void main(String[] args) throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass newClass = cp.makeClass("test4.TestDeadcode");
addDeadCode(newClass, "public void evaluate5(){ boolean b = !false; b = false && b; b = true && true;"
+ " b = true || b; b = b || false; }");
if (args.length > 1) {
new Test().bar(3);
return;
}

newClass.debugWriteFile();
Class<?> cClass = newClass.toClass();
Object o = cClass.newInstance();
java.lang.reflect.Method m = cClass.getMethod("evaluate5");
m.invoke(o);
}
private static void addDeadCode(CtClass cc, String meth) throws Exception {
CtMethod m = CtNewMethod.make(meth, cc);
cc.addMethod(m);
ClassPool cp = ClassPool.getDefault();
CtClass str = cp.get("java.lang.String");
CtClass cc = cp.get("Test");
cc.getClassFile().setMajorVersion(javassist.bytecode.ClassFile.JAVA_4);
CtMethod m = cc.getDeclaredMethod("bar");
m.addLocalVariable("aVar", str);
m.insertAfter(" dismiss( aVar );" , true);
cc.getClassFile().setMajorVersion(javassist.bytecode.ClassFile.JAVA_7);
m.insertBefore("aVar = initVar();");
cc.writeFile();
}

public void bar(int i) { foo(i); }
public void foo(int i) { System.out.println(i); }
public String initVar() { return "init"; }
public void dismiss(String s) { System.out.println(s); }
}

+ 8
- 0
src/test/javassist/JvstTest4.java View File

@@ -1030,4 +1030,12 @@ public class JvstTest4 extends JvstTestRoot {
CtMethod m = CtNewMethod.make(meth, cc);
cc.addMethod(m);
}

public void testAnnArg() throws Exception {
CtClass cc = sloader.get("test4.AnnoArg");
CtMethod m = cc.getDeclaredMethod("foo");
test4.AnnoArg.AnnoArgAt a = (test4.AnnoArg.AnnoArgAt)m.getAnnotations()[0];
assertEquals("test4.AnnoArg$B", a.value().getName());
System.out.println(a.value().getName());
}
}

+ 18
- 0
src/test/test4/AnnoArg.java View File

@@ -0,0 +1,18 @@
package test4;

public class AnnoArg {
public static @interface AnnoArgAt {
Class<? extends AnnoArg.A> value();
}

public static class A {
int baz() { return 1; }
}

public static class B extends A {
int baz() { return 2; }
}

@AnnoArgAt(B.class)
public int foo(int i) { return i; }
}

Loading…
Cancel
Save