diff options
author | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2004-05-03 17:38:30 +0000 |
---|---|---|
committer | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2004-05-03 17:38:30 +0000 |
commit | 1d249157debacc92bc2e4a833ed67dcdc8bad95c (patch) | |
tree | dcb6aa81dc9761490ac1e0062eedcc9264b7304d /src | |
parent | b25388461bd32f33f3a4a188b5eeae957cbb080d (diff) | |
download | javassist-1d249157debacc92bc2e4a833ed67dcdc8bad95c.tar.gz javassist-1d249157debacc92bc2e4a833ed67dcdc8bad95c.zip |
added CtClass#getDeclaringClass()
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@96 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
Diffstat (limited to 'src')
-rw-r--r-- | src/main/javassist/ClassPool.java | 7 | ||||
-rw-r--r-- | src/main/javassist/CtClass.java | 10 | ||||
-rw-r--r-- | src/main/javassist/CtClassType.java | 16 | ||||
-rw-r--r-- | src/main/javassist/bytecode/InnerClassesAttribute.java | 48 | ||||
-rw-r--r-- | src/main/javassist/compiler/MemberCodeGen.java | 35 |
5 files changed, 109 insertions, 7 deletions
diff --git a/src/main/javassist/ClassPool.java b/src/main/javassist/ClassPool.java index 054b56e1..8067940e 100644 --- a/src/main/javassist/ClassPool.java +++ b/src/main/javassist/ClassPool.java @@ -362,7 +362,12 @@ public class ClassPool { * @param classname a fully-qualified class name. */ public CtClass get(String classname) throws NotFoundException { - CtClass clazz = get0(classname, true); + CtClass clazz; + if (classname == null) + clazz = null; + else + clazz = get0(classname, true); + if (clazz == null) throw new NotFoundException(classname); else diff --git a/src/main/javassist/CtClass.java b/src/main/javassist/CtClass.java index c5c86ba5..f3e8963e 100644 --- a/src/main/javassist/CtClass.java +++ b/src/main/javassist/CtClass.java @@ -481,6 +481,16 @@ public abstract class CtClass { } /** + * If this class is a member class or interface of another class, + * then the class enclosing this class is returned. + * + * @return null if this class is a top-level class. + */ + public CtClass getDeclaringClass() throws NotFoundException { + return null; + } + + /** * Returns an array containing <code>CtField</code> objects * representing all the public fields of the class. * That array includes public fields inherited from the diff --git a/src/main/javassist/CtClassType.java b/src/main/javassist/CtClassType.java index d206b62f..e503abcb 100644 --- a/src/main/javassist/CtClassType.java +++ b/src/main/javassist/CtClassType.java @@ -316,6 +316,22 @@ class CtClassType extends CtClass { getClassFile2().addInterface(anInterface.getName()); } + public CtClass getDeclaringClass() throws NotFoundException { + ClassFile cf = getClassFile2(); + InnerClassesAttribute ica = (InnerClassesAttribute)cf.getAttribute( + InnerClassesAttribute.tag); + if (ica == null) + return null; + + String name = getName(); + int n = ica.tableLength(); + for (int i = 0; i < n; ++i) + if (name.equals(ica.innerClass(i))) + return classPool.get(ica.outerClass(i)); + + return null; + } + public CtField[] getFields() { ArrayList alist = new ArrayList(); getFields(alist, this); diff --git a/src/main/javassist/bytecode/InnerClassesAttribute.java b/src/main/javassist/bytecode/InnerClassesAttribute.java index 3f3de406..400a53ca 100644 --- a/src/main/javassist/bytecode/InnerClassesAttribute.java +++ b/src/main/javassist/bytecode/InnerClassesAttribute.java @@ -46,25 +46,67 @@ public class InnerClassesAttribute extends AttributeInfo { /** * Returns <code>classes[nth].inner_class_info_index</code>. */ - public int innerClass(int nth) { + public int innerClassIndex(int nth) { return ByteArray.readU16bit(get(), nth * 8 + 2); } /** + * Returns the class name indicated + * by <code>classes[nth].inner_class_info_index</code>. + * + * @return null or the class name. + */ + public String innerClass(int nth) { + int i = innerClassIndex(nth); + if (i == 0) + return null; + else + return constPool.getClassInfo(i); + } + + /** * Returns <code>classes[nth].outer_class_info_index</code>. */ - public int outerClass(int nth) { + public int outerClassIndex(int nth) { return ByteArray.readU16bit(get(), nth * 8 + 4); } /** + * Returns the class name indicated + * by <code>classes[nth].outer_class_info_index</code>. + * + * @return null or the class name. + */ + public String outerClass(int nth) { + int i = outerClassIndex(nth); + if (i == 0) + return null; + else + return constPool.getClassInfo(i); + } + + /** * Returns <code>classes[nth].inner_name_index</code>. */ - public int innerName(int nth) { + public int innerNameIndex(int nth) { return ByteArray.readU16bit(get(), nth * 8 + 6); } /** + * Returns the simple class name indicated + * by <code>classes[nth].inner_name_index</code>. + * + * @return null or the class name. + */ + public String innerName(int nth) { + int i = innerNameIndex(nth); + if (i == 0) + return null; + else + return constPool.getUtf8Info(i); + } + + /** * Returns <code>classes[nth].inner_class_access_flags</code>. */ public int accessFlags(int nth) { diff --git a/src/main/javassist/compiler/MemberCodeGen.java b/src/main/javassist/compiler/MemberCodeGen.java index c35765ef..e8c5ba3b 100644 --- a/src/main/javassist/compiler/MemberCodeGen.java +++ b/src/main/javassist/compiler/MemberCodeGen.java @@ -308,7 +308,12 @@ public class MemberCodeGen extends CodeGen { throw new CompileError("bad method"); } - // atMethodCallCore() is also called by doit() in NewExpr.ProceedForNew + /* + * atMethodCallCore() is also called by doit() in NewExpr.ProceedForNew + * + * @param targetClass the class at which method lookup starts. + * @param found not null if the method look has been already done. + */ public void atMethodCallCore(CtClass targetClass, String mname, ASTList args, boolean isStatic, boolean isSpecial, int aload0pos, MemberResolver.Method found) @@ -358,8 +363,10 @@ public class MemberCodeGen extends CodeGen { } else if ((acc & AccessFlag.PRIVATE) != 0) { isSpecial = true; - if (declClass != targetClass) - throw new CompileError("Method " + mname + "is private"); + String orgName = mname; + mname = getAccessiblePrivate(mname, declClass); + if (mname == null) + throw new CompileError("Method " + orgName + " is private"); } boolean popTarget = false; @@ -392,6 +399,28 @@ public class MemberCodeGen extends CodeGen { setReturnType(desc, isStatic, popTarget); } + protected String getAccessiblePrivate(String methodName, + CtClass declClass) { + if (declClass == thisClass) + return methodName; + else if (isEnclosing(declClass, thisClass)) + return null; + else + return null; // cannot access this private method. + } + + private boolean isEnclosing(CtClass outer, CtClass inner) { + try { + while (inner != null) { + inner = inner.getDeclaringClass(); + if (inner == outer) + return true; + } + } + catch (NotFoundException e) {} + return false; + } + public int getMethodArgsLength(ASTList args) { return ASTList.length(args); } |