<p>-version 3.19 | <p>-version 3.19 | ||||
<ul> | <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> | </ul> | ||||
</p> | </p> | ||||
* | * | ||||
* @return null if this class is not a local class or an anonymous | * @return null if this class is not a local class or an anonymous | ||||
* class. | * 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; | return null; | ||||
} | } | ||||
return null; | return null; | ||||
} | } | ||||
public CtMethod getEnclosingMethod() throws NotFoundException { | |||||
public CtBehavior getEnclosingBehavior() throws NotFoundException { | |||||
ClassFile cf = getClassFile2(); | ClassFile cf = getClassFile2(); | ||||
EnclosingMethodAttribute ema | EnclosingMethodAttribute ema | ||||
= (EnclosingMethodAttribute)cf.getAttribute( | = (EnclosingMethodAttribute)cf.getAttribute( | ||||
EnclosingMethodAttribute.tag); | EnclosingMethodAttribute.tag); | ||||
if (ema != null) { | |||||
if (ema == null) | |||||
return null; | |||||
else { | |||||
CtClass enc = classPool.get(ema.className()); | 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) { | public CtClass makeNestedClass(String name, boolean isStatic) { |
import java.io.IOException; | import java.io.IOException; | ||||
import java.util.Map; | import java.util.Map; | ||||
import javassist.CtConstructor; | |||||
/** | /** | ||||
* <code>EnclosingMethod_attribute</code>. | * <code>EnclosingMethod_attribute</code>. | ||||
*/ | */ | ||||
/** | /** | ||||
* Returns the method name specified by <code>method_index</code>. | * 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() { | public String methodName() { | ||||
ConstPool cp = getConstPool(); | ConstPool cp = getConstPool(); | ||||
int mi = methodIndex(); | 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); | |||||
} | |||||
} | } | ||||
/** | /** |
} | } | ||||
ClassPool cp = ClassPool.getDefault(); | 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"); | CtClass cc = cp.get("Test"); | ||||
cc.getClassFile().setMajorVersion(javassist.bytecode.ClassFile.JAVA_4); | cc.getClassFile().setMajorVersion(javassist.bytecode.ClassFile.JAVA_4); | ||||
CtMethod m = cc.getDeclaredMethod("bar"); | CtMethod m = cc.getDeclaredMethod("bar"); | ||||
m.insertAfter(" dismiss( aVar );" , true); | m.insertAfter(" dismiss( aVar );" , true); | ||||
cc.getClassFile().setMajorVersion(javassist.bytecode.ClassFile.JAVA_7); | cc.getClassFile().setMajorVersion(javassist.bytecode.ClassFile.JAVA_7); | ||||
m.insertBefore("aVar = initVar();"); | m.insertBefore("aVar = initVar();"); | ||||
cc.writeFile(); | |||||
cc.writeFile();*/ | |||||
} | } | ||||
public void bar(int i) { foo(i); } | public void bar(int i) { foo(i); } |
assertEquals(out, | assertEquals(out, | ||||
inner.getEnclosingMethod().getDeclaringClass()); | 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 { | public void testMethodInInner() throws Exception { |
public Object make() { | public Object make() { | ||||
return new Object() { int k; }; | 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; }; | |||||
} | |||||
} | } |