aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/javassist
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/javassist')
-rw-r--r--src/main/javassist/CtClass.java2
-rw-r--r--src/main/javassist/bytecode/MethodInfo.java1
-rw-r--r--src/main/javassist/compiler/AccessorMaker.java47
-rw-r--r--src/main/javassist/compiler/MemberCodeGen.java42
-rw-r--r--src/main/javassist/runtime/Inner.java24
5 files changed, 106 insertions, 10 deletions
diff --git a/src/main/javassist/CtClass.java b/src/main/javassist/CtClass.java
index 8641f970..68f63031 100644
--- a/src/main/javassist/CtClass.java
+++ b/src/main/javassist/CtClass.java
@@ -35,7 +35,7 @@ public abstract class CtClass {
/**
* The version number of this release.
*/
- public static final String version = "3.0 RC1";
+ public static final String version = "3.0 RC0";
/**
* Prints the version number and the copyright notice.
diff --git a/src/main/javassist/bytecode/MethodInfo.java b/src/main/javassist/bytecode/MethodInfo.java
index ffe42438..56ef8036 100644
--- a/src/main/javassist/bytecode/MethodInfo.java
+++ b/src/main/javassist/bytecode/MethodInfo.java
@@ -57,6 +57,7 @@ public final class MethodInfo {
/**
* Constructs a <code>method_info</code> structure.
+ * The initial value of <code>access_flags</code> is zero.
*
* @param cp a constant pool table
* @param methodname method name
diff --git a/src/main/javassist/compiler/AccessorMaker.java b/src/main/javassist/compiler/AccessorMaker.java
index bfe59f51..14f46194 100644
--- a/src/main/javassist/compiler/AccessorMaker.java
+++ b/src/main/javassist/compiler/AccessorMaker.java
@@ -28,12 +28,59 @@ public class AccessorMaker {
private int uniqueNumber;
private HashMap accessors;
+ static final String lastParamType = "javassist.runtime.Inner";
+
public AccessorMaker(CtClass c) {
clazz = c;
uniqueNumber = 1;
accessors = new HashMap();
}
+ public String getConstructor(CtClass c, String desc, MethodInfo orig)
+ throws CompileError
+ {
+ String key = "<init>:" + desc;
+ String consDesc = (String)accessors.get(key);
+ if (consDesc != null)
+ return consDesc; // already exists.
+
+ consDesc = Descriptor.appendParameter(lastParamType, desc);
+ ClassFile cf = clazz.getClassFile(); // turn on the modified flag.
+ try {
+ ConstPool cp = cf.getConstPool();
+ ClassPool pool = clazz.getClassPool();
+ MethodInfo minfo
+ = new MethodInfo(cp, MethodInfo.nameInit, consDesc);
+ minfo.setAccessFlags(0);
+ minfo.addAttribute(new SyntheticAttribute(cp));
+ ExceptionsAttribute ea = orig.getExceptionsAttribute();
+ if (ea != null)
+ minfo.addAttribute(ea.copy(cp, null));
+
+ CtClass[] params = Descriptor.getParameterTypes(desc, pool);
+ Bytecode code = new Bytecode(cp);
+ code.addAload(0);
+ int regno = 1;
+ for (int i = 0; i < params.length; ++i)
+ regno += code.addLoad(regno, params[i]);
+ code.setMaxLocals(regno + 1); // the last parameter is added.
+ code.addInvokespecial(clazz, MethodInfo.nameInit, desc);
+
+ code.addReturn(null);
+ minfo.setCodeAttribute(code.toCodeAttribute());
+ cf.addMethod(minfo);
+ }
+ catch (CannotCompileException e) {
+ throw new CompileError(e);
+ }
+ catch (NotFoundException e) {
+ throw new CompileError(e);
+ }
+
+ accessors.put(key, consDesc);
+ return consDesc;
+ }
+
/**
* Returns the name of the method for accessing a private method.
*
diff --git a/src/main/javassist/compiler/MemberCodeGen.java b/src/main/javassist/compiler/MemberCodeGen.java
index 0a58dc97..a70acf84 100644
--- a/src/main/javassist/compiler/MemberCodeGen.java
+++ b/src/main/javassist/compiler/MemberCodeGen.java
@@ -331,6 +331,7 @@ public class MemberCodeGen extends CodeGen {
int stack = bytecode.getStackDepth();
+ // generate code for evaluating arguments.
atMethodArgs(args, types, dims, cnames);
// used by invokeinterface
@@ -370,12 +371,16 @@ public class MemberCodeGen extends CodeGen {
isSpecial = true;
if (declClass != targetClass)
throw new CompileError("no such a constructor");
+
+ if (declClass != thisClass && AccessFlag.isPrivate(acc)) {
+ desc = getAccessibleConstructor(desc, declClass, minfo);
+ bytecode.addOpcode(Opcode.ACONST_NULL); // the last parameter
+ }
}
else if (AccessFlag.isPrivate(acc))
if (declClass == thisClass)
isSpecial = true;
else {
- String orgName = mname;
isSpecial = false;
isStatic = true;
String origDesc = desc;
@@ -386,9 +391,6 @@ public class MemberCodeGen extends CodeGen {
acc = AccessFlag.setPackage(acc) | AccessFlag.STATIC;
mname = getAccessiblePrivate(mname, origDesc, desc,
minfo, declClass);
- if (mname == null)
- throw new CompileError("Method " + orgName
- + " is private");
}
boolean popTarget = false;
@@ -435,14 +437,36 @@ public class MemberCodeGen extends CodeGen {
{
if (isEnclosing(declClass, thisClass)) {
AccessorMaker maker = declClass.getAccessorMaker();
- if (maker == null)
- return null;
- else
+ if (maker != null)
return maker.getMethodAccessor(methodName, desc, newDesc,
minfo);
}
- else
- return null; // cannot access this private method.
+
+ throw new CompileError("Method " + methodName
+ + " is private");
+ }
+
+ /*
+ * Finds (or adds if necessary) a hidden constructor if the given
+ * constructor is in an enclosing class.
+ *
+ * @param desc the descriptor of the constructor.
+ * @param declClass the class declaring the constructor.
+ * @param minfo the method info of the constructor.
+ * @return the descriptor of the hidden constructor.
+ */
+ protected String getAccessibleConstructor(String desc, CtClass declClass,
+ MethodInfo minfo)
+ throws CompileError
+ {
+ if (isEnclosing(declClass, thisClass)) {
+ AccessorMaker maker = declClass.getAccessorMaker();
+ if (maker != null)
+ return maker.getConstructor(declClass, desc, minfo);
+ }
+
+ throw new CompileError("the called constructor is private in "
+ + declClass.getName());
}
private boolean isEnclosing(CtClass outer, CtClass inner) {
diff --git a/src/main/javassist/runtime/Inner.java b/src/main/javassist/runtime/Inner.java
new file mode 100644
index 00000000..2aadf19b
--- /dev/null
+++ b/src/main/javassist/runtime/Inner.java
@@ -0,0 +1,24 @@
+/*
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2004 Shigeru Chiba. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. Alternatively, the contents of this file may be used under
+ * the terms of the GNU Lesser General Public License Version 2.1 or later.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ */
+
+package javassist.runtime;
+
+/**
+ * A support class for compiling a method declared in an inner class.
+ * This support class is required at runtime
+ * only if the method calls a private constructor in the enclosing class.
+ */
+public class Inner {
+}