From: chiba Date: Mon, 3 May 2004 17:38:30 +0000 (+0000) Subject: added CtClass#getDeclaringClass() X-Git-Tag: rel_3_17_1_ga~515 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=1d249157debacc92bc2e4a833ed67dcdc8bad95c;p=javassist.git added CtClass#getDeclaringClass() git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@96 30ef5769-5b8d-40dd-aea6-55b5d6557bb3 --- 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 @@ -480,6 +480,16 @@ public abstract class CtClass { checkModify(); } + /** + * 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 CtField objects * representing all the public fields of the class. 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,24 +46,66 @@ public class InnerClassesAttribute extends AttributeInfo { /** * Returns classes[nth].inner_class_info_index. */ - public int innerClass(int nth) { + public int innerClassIndex(int nth) { return ByteArray.readU16bit(get(), nth * 8 + 2); } + /** + * Returns the class name indicated + * by classes[nth].inner_class_info_index. + * + * @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 classes[nth].outer_class_info_index. */ - public int outerClass(int nth) { + public int outerClassIndex(int nth) { return ByteArray.readU16bit(get(), nth * 8 + 4); } + /** + * Returns the class name indicated + * by classes[nth].outer_class_info_index. + * + * @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 classes[nth].inner_name_index. */ - public int innerName(int nth) { + public int innerNameIndex(int nth) { return ByteArray.readU16bit(get(), nth * 8 + 6); } + /** + * Returns the simple class name indicated + * by classes[nth].inner_name_index. + * + * @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 classes[nth].inner_class_access_flags. */ 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); }