aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2004-05-03 17:38:30 +0000
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2004-05-03 17:38:30 +0000
commit1d249157debacc92bc2e4a833ed67dcdc8bad95c (patch)
treedcb6aa81dc9761490ac1e0062eedcc9264b7304d /src
parentb25388461bd32f33f3a4a188b5eeae957cbb080d (diff)
downloadjavassist-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.java7
-rw-r--r--src/main/javassist/CtClass.java10
-rw-r--r--src/main/javassist/CtClassType.java16
-rw-r--r--src/main/javassist/bytecode/InnerClassesAttribute.java48
-rw-r--r--src/main/javassist/compiler/MemberCodeGen.java35
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);
}