@@ -283,7 +283,7 @@ see javassist.Dump. | |||
<p>-version 3.19 | |||
<ul> | |||
<li>JIRA JASSIST-158, 205, 206, 207, 211, 212, 216, 220, 223, 224, 227, 230, 234. | |||
<li>JIRA JASSIST-158, 205, 206, 207, 211, 212, 216, 220, 223, 224, 227, 230, 234, 235. | |||
</ul> | |||
</p> | |||
@@ -762,8 +762,29 @@ public abstract class CtClass { | |||
* | |||
* @return null if this class is not a local class or an anonymous | |||
* class. | |||
* @deprecated The enclosing method might be a constructor. | |||
* Use {@link #getEnclosingBehavior()}. | |||
* @see #getEnclosingBehavior() | |||
*/ | |||
public CtMethod getEnclosingMethod() throws NotFoundException { | |||
public final CtMethod getEnclosingMethod() throws NotFoundException { | |||
CtBehavior b = getEnclosingBehavior(); | |||
if (b == null) | |||
return null; | |||
else if (b instanceof CtMethod) | |||
return (CtMethod)b; | |||
else | |||
throw new NotFoundException(b.getLongName() + " is enclosing " + getName()); | |||
} | |||
/** | |||
* Returns the immediately enclosing method of this class. | |||
* It might be not a method but a constructor. | |||
* This method works only with JDK 1.5 or later. | |||
* | |||
* @return null if this class is not a local class or an anonymous | |||
* class. | |||
*/ | |||
public CtBehavior getEnclosingBehavior() throws NotFoundException { | |||
return null; | |||
} | |||
@@ -772,17 +772,25 @@ class CtClassType extends CtClass { | |||
return null; | |||
} | |||
public CtMethod getEnclosingMethod() throws NotFoundException { | |||
public CtBehavior getEnclosingBehavior() throws NotFoundException { | |||
ClassFile cf = getClassFile2(); | |||
EnclosingMethodAttribute ema | |||
= (EnclosingMethodAttribute)cf.getAttribute( | |||
EnclosingMethodAttribute.tag); | |||
if (ema != null) { | |||
if (ema == null) | |||
return null; | |||
else { | |||
CtClass enc = classPool.get(ema.className()); | |||
return enc.getMethod(ema.methodName(), ema.methodDescriptor()); | |||
String name = ema.methodName(); | |||
switch (name) { | |||
case MethodInfo.nameInit: | |||
return enc.getConstructor(ema.methodDescriptor()); | |||
case MethodInfo.nameClinit: | |||
return enc.getClassInitializer(); | |||
default: | |||
return enc.getMethod(name, ema.methodDescriptor()); | |||
} | |||
} | |||
return null; | |||
} | |||
public CtClass makeNestedClass(String name, boolean isStatic) { |
@@ -20,6 +20,8 @@ import java.io.DataInputStream; | |||
import java.io.IOException; | |||
import java.util.Map; | |||
import javassist.CtConstructor; | |||
/** | |||
* <code>EnclosingMethod_attribute</code>. | |||
*/ | |||
@@ -98,12 +100,18 @@ public class EnclosingMethodAttribute extends AttributeInfo { | |||
/** | |||
* Returns the method name specified by <code>method_index</code>. | |||
* If the method is a class initializer (static constructor), | |||
* {@link MethodInfo#nameClinit} is returned. | |||
*/ | |||
public String methodName() { | |||
ConstPool cp = getConstPool(); | |||
int mi = methodIndex(); | |||
int ni = cp.getNameAndTypeName(mi); | |||
return cp.getUtf8Info(ni); | |||
if (mi == 0) | |||
return MethodInfo.nameClinit; | |||
else { | |||
int ni = cp.getNameAndTypeName(mi); | |||
return cp.getUtf8Info(ni); | |||
} | |||
} | |||
/** |
@@ -8,7 +8,9 @@ public class Test { | |||
} | |||
ClassPool cp = ClassPool.getDefault(); | |||
CtClass str = cp.get("java.lang.String"); | |||
CtClass inner3 = cp.get("test2.Anon$Anon2.1"); | |||
CtBehavior ct = inner3.getEnclosingBehavior(); | |||
/* 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"); | |||
@@ -16,7 +18,7 @@ public class Test { | |||
m.insertAfter(" dismiss( aVar );" , true); | |||
cc.getClassFile().setMajorVersion(javassist.bytecode.ClassFile.JAVA_7); | |||
m.insertBefore("aVar = initVar();"); | |||
cc.writeFile(); | |||
cc.writeFile();*/ | |||
} | |||
public void bar(int i) { foo(i); } |
@@ -523,6 +523,17 @@ public class JvstTest2 extends JvstTestRoot { | |||
assertEquals(out, | |||
inner.getEnclosingMethod().getDeclaringClass()); | |||
} | |||
assertNull(out.getEnclosingMethod()); | |||
assertNull(out.getEnclosingBehavior()); | |||
CtClass inner2 = sloader.get("test2.Anon$Anon2$1"); | |||
assertTrue(inner2.getEnclosingBehavior() instanceof CtConstructor); | |||
assertEquals(sloader.get("test2.Anon$Anon2"), inner2.getEnclosingBehavior().getDeclaringClass()); | |||
CtClass inner3 = sloader.get("test2.Anon$Anon3$1"); | |||
assertTrue(inner3.getEnclosingBehavior() instanceof CtConstructor); | |||
assertTrue(((CtConstructor)inner3.getEnclosingBehavior()).isClassInitializer()); | |||
assertEquals(sloader.get("test2.Anon$Anon3"), inner3.getEnclosingBehavior().getDeclaringClass()); | |||
} | |||
public void testMethodInInner() throws Exception { |
@@ -4,4 +4,15 @@ public class Anon { | |||
public Object make() { | |||
return new Object() { int k; }; | |||
} | |||
public static class Anon2 { | |||
Object obj; | |||
public Anon2() { | |||
obj = new Object() { int k; }; | |||
} | |||
} | |||
public static class Anon3 { | |||
public static Object sobj = new Object() { int p; }; | |||
} | |||
} |