git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@320 30ef5769-5b8d-40dd-aea6-55b5d6557bb3tags/rel_3_17_1_ga
@@ -18,7 +18,7 @@ package javassist; | |||
import javassist.bytecode.Descriptor; | |||
/** | |||
* A hashtable associating class names with different names. | |||
* A hash table associating class names with different names. | |||
* | |||
* <p>This hashtable is used for replacing class names in a class | |||
* definition or a method body. Define a subclass of this class | |||
@@ -45,6 +45,15 @@ import javassist.bytecode.Descriptor; | |||
* @see CtNewMethod#copy(CtMethod,String,CtClass,ClassMap) | |||
*/ | |||
public class ClassMap extends java.util.HashMap { | |||
private ClassMap parent; | |||
/** | |||
* Constructs a hash table. | |||
*/ | |||
public ClassMap() { parent = null; } | |||
ClassMap(ClassMap map) { parent = map; } | |||
/** | |||
* Maps a class name to another name in this hashtable. | |||
* The names are obtained with calling <code>Class.getName()</code>. | |||
@@ -87,33 +96,6 @@ public class ClassMap extends java.util.HashMap { | |||
super.put(oldname2, toJvmName(newname)); | |||
} | |||
/** | |||
* Maps a class name to another name unless another mapping | |||
* has been already recorded. | |||
* This method translates the given class names into the | |||
* internal form used in the JVM before putting it in | |||
* the hashtable. | |||
* | |||
* <p>If <code>oldname</code> is equivalent to | |||
* <code>newname</code>, then this method does not | |||
* perform anything; it does not record the mapping from | |||
* <code>oldname</code> to <code>newname</code>. See | |||
* <code>fix</code> method. | |||
* | |||
* @param oldname the original class name | |||
* @param newname the substituted class name. | |||
* @see #fix(String) | |||
*/ | |||
public void add(String oldname, String newname) { | |||
if (oldname == newname) | |||
return; | |||
String oldname2 = toJvmName(oldname); | |||
String s = (String)get(oldname2); | |||
if (s == null) | |||
super.put(oldname2, toJvmName(newname)); | |||
} | |||
protected final void put0(Object oldname, Object newname) { | |||
super.put(oldname, newname); | |||
} | |||
@@ -129,7 +111,11 @@ public class ClassMap extends java.util.HashMap { | |||
* @see #toJavaName(String) | |||
*/ | |||
public Object get(Object jvmClassName) { | |||
return super.get(jvmClassName); | |||
Object found = super.get(jvmClassName); | |||
if (found == null && parent != null) | |||
return parent.get(jvmClassName); | |||
else | |||
return found; | |||
} | |||
/** |
@@ -44,10 +44,9 @@ public abstract class CtBehavior extends CtMember { | |||
MethodInfo srcInfo = src.methodInfo; | |||
CtClass srcClass = src.getDeclaringClass(); | |||
ConstPool cp = declaring.getClassFile2().getConstPool(); | |||
if (map == null) | |||
map = new ClassMap(); | |||
map.add(srcClass.getName(), declaring.getName()); | |||
map = new ClassMap(map); | |||
map.put(srcClass.getName(), declaring.getName()); | |||
try { | |||
boolean patch = false; | |||
CtClass srcSuper = srcClass.getSuperclass(); | |||
@@ -60,7 +59,7 @@ public abstract class CtBehavior extends CtMember { | |||
if (srcSuperName.equals(CtClass.javaLangObject)) | |||
patch = true; | |||
else | |||
map.add(srcSuperName, destSuperName); | |||
map.put(srcSuperName, destSuperName); | |||
} | |||
methodInfo = new MethodInfo(cp, srcInfo.getName(), srcInfo, map); | |||
@@ -356,9 +355,7 @@ public abstract class CtBehavior extends CtMember { | |||
{ | |||
destClass.checkModify(); | |||
if (map == null) | |||
map = new ClassMap(); | |||
map = new ClassMap(map); | |||
map.put(srcClass.getName(), destClass.getName()); | |||
try { | |||
CodeAttribute cattr = srcInfo.getCodeAttribute(); |
@@ -287,9 +287,39 @@ public final class CtConstructor extends CtBehavior { | |||
*/ | |||
public CtMethod toMethod(String name, CtClass declaring) | |||
throws CannotCompileException | |||
{ | |||
return toMethod(name, declaring, null); | |||
} | |||
/** | |||
* Makes a copy of this constructor and converts it into a method. | |||
* The signature of the mehtod is the same as the that of this constructor. | |||
* The return type is <code>void</code>. The resulting method must be | |||
* appended to the class specified by <code>declaring</code>. | |||
* If this constructor is a static initializer, the resulting method takes | |||
* no parameter. | |||
* | |||
* <p>An occurrence of another constructor call <code>this()</code> | |||
* or a super constructor call <code>super()</code> is | |||
* eliminated from the resulting method. | |||
* | |||
* <p>The immediate super class of the class declaring this constructor | |||
* must be also a super class of the class declaring the resulting method. | |||
* If the constructor accesses a field, the class declaring the resulting method | |||
* must also declare a field with the same name and type. | |||
* | |||
* @param name the name of the resulting method. | |||
* @param declaring the class declaring the resulting method. | |||
* @param map the hash table associating original class names | |||
* with substituted names. The original class names will be | |||
* replaced while making a copy. | |||
* <code>map</code> can be <code>null</code>. | |||
*/ | |||
public CtMethod toMethod(String name, CtClass declaring, ClassMap map) | |||
throws CannotCompileException | |||
{ | |||
CtMethod method = new CtMethod(null, declaring); | |||
method.copy(this, false, null); | |||
method.copy(this, false, map); | |||
if (isConstructor()) { | |||
MethodInfo minfo = method.getMethodInfo2(); | |||
CodeAttribute ca = minfo.getCodeAttribute(); |