git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@103 30ef5769-5b8d-40dd-aea6-55b5d6557bb3tags/rel_3_17_1_ga
@@ -255,22 +255,19 @@ see javassist.Dump. | |||
<h2>Changes</h2> | |||
<p>- version 3.0 | |||
<p>- version 3.0 RC1 | |||
<ul> | |||
<li>ClassPool has been largely modified. | |||
<ul><li>write(), writeFile(), .. in ClassPool were moved to CtClass. | |||
<li>The host of javassist.Translator was changed from ClassPool | |||
to javassist.Loader. | |||
</ul> | |||
<li>javassist.bytecode.annotation has been added. | |||
<li>The ClassPool framework has been redesigned. | |||
<ul> | |||
<li>writeFile(), write(), ... in ClassPool have been moved to CtClass. | |||
<li>The design of javassist.Translator has been changed. | |||
</ul> | |||
<li>javassist.bytecode.annotation has been added for meta tags. | |||
<li>CtClass.makeNestedClass() has been added. | |||
<li>The methods declared in javassist.bytecode.InnerClassesAttribute | |||
have been renamed a bit. | |||
<li>Now local variables were made available in the source text passed to | |||
CtBehavior.insertBefore(), MethodCall.replace(), etc. | |||
<li>CtClass.main(), which prints the version number, has been added. | |||
@@ -279,6 +276,7 @@ see javassist.Dump. | |||
<li>javassist.bytecode.LocalVariableAttribute has been added. | |||
<li>CtClass.getURL() and javassist.ClassPath.find() has been added. | |||
<li>CtBehavior.insertAt() has been added. | |||
<li>CtClass.detach() has been added. | |||
</ul> | |||
<p>- version 2.6 in August, 2003. |
@@ -577,6 +577,20 @@ public class ClassPool { | |||
return clazz; | |||
} | |||
/** | |||
* Creates a new nested class. | |||
* This method is called by CtClassType.makeNestedClass(). | |||
* | |||
* @param classname a fully-qualified class name. | |||
* @return the nested class. | |||
*/ | |||
synchronized CtClass makeNestedClass(String classname) { | |||
checkNotFrozen(classname); | |||
CtClass clazz = new CtNewNestedClass(classname, this, false, null); | |||
cacheCtClass(classname, clazz); | |||
return clazz; | |||
} | |||
/** | |||
* Creates a new public interface. | |||
* If there already exists a class/interface with the same name, |
@@ -497,6 +497,20 @@ public abstract class CtClass { | |||
return null; | |||
} | |||
/** | |||
* Makes a new nested class. Making a nested class modifies the | |||
* data in this <code>CtClass</code>. | |||
* | |||
* <p>The current implementation only supports a static nested class. | |||
* <code>isStatic</code> must be true. | |||
* | |||
* @param name the simple name of the nested class. | |||
* @param isStatic true if the nested class is static. | |||
*/ | |||
public CtClass makeNestedClass(String name, boolean isStatic) { | |||
throw new RuntimeException(getName() + " is not a class"); | |||
} | |||
/** | |||
* Returns an array containing <code>CtField</code> objects | |||
* representing all the public fields of the class. | |||
@@ -884,6 +898,8 @@ public abstract class CtClass { | |||
/** | |||
* Removes this <code>CtClass</code> from the <code>ClassPool</code>. | |||
* After this method is called, any method cannot be called on the | |||
* removed <code>CtClass</code> object. | |||
* | |||
* <p>If needed, | |||
* the <code>ClassPool</code> will read the class file again |
@@ -343,6 +343,27 @@ class CtClassType extends CtClass { | |||
return null; | |||
} | |||
public CtClass makeNestedClass(String name, boolean isStatic) { | |||
if (!isStatic) | |||
throw new RuntimeException( | |||
"sorry, only nested static class is supported"); | |||
checkModify(); | |||
CtClass c = classPool.makeNestedClass(getName() + "$" + name); | |||
ClassFile cf = getClassFile2(); | |||
InnerClassesAttribute ica = (InnerClassesAttribute)cf.getAttribute( | |||
InnerClassesAttribute.tag); | |||
if (ica == null) { | |||
ica = new InnerClassesAttribute(cf.getConstPool()); | |||
cf.addAttribute(ica); | |||
} | |||
ica.append(c.getName(), this.getName(), name, AccessFlag.STATIC); | |||
ClassFile cf2 = c.getClassFile2(); | |||
cf2.addAttribute(ica.copy(cf2.getConstPool(), null)); | |||
return c; | |||
} | |||
public CtField[] getFields() { | |||
ArrayList alist = new ArrayList(); | |||
getFields(alist, this); |
@@ -0,0 +1,31 @@ | |||
/* | |||
* 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; | |||
/** | |||
* A newly created nested class. | |||
*/ | |||
class CtNewNestedClass extends CtNewClass { | |||
CtNewNestedClass(String realName, ClassPool cp, boolean isInterface, | |||
CtClass superclass) { | |||
super(realName, cp, isInterface, superclass); | |||
} | |||
public void setModifiers(int mod) { | |||
super.setModifiers(Modifier.clear(mod, | |||
Modifier.STATIC | Modifier.PRIVATE)); | |||
} | |||
} |
@@ -38,6 +38,16 @@ public class InnerClassesAttribute extends AttributeInfo { | |||
super(cp, tag, info); | |||
} | |||
/** | |||
* Constructs an empty InnerClasses attribute. | |||
* | |||
* @see #append(String, String, String, int) | |||
*/ | |||
public InnerClassesAttribute(ConstPool cp) { | |||
super(cp, tag, new byte[2]); | |||
ByteArray.write16bit(0, get(), 0); | |||
} | |||
/** | |||
* Returns <code>number_of_classes</code>. | |||
*/ | |||
@@ -64,6 +74,14 @@ public class InnerClassesAttribute extends AttributeInfo { | |||
return constPool.getClassInfo(i); | |||
} | |||
/** | |||
* Sets <code>classes[nth].inner_class_info_index</code> to | |||
* the given index. | |||
*/ | |||
public void setInnerClassIndex(int nth, int index) { | |||
ByteArray.write16bit(index, get(), nth * 8 + 2); | |||
} | |||
/** | |||
* Returns <code>classes[nth].outer_class_info_index</code>. | |||
*/ | |||
@@ -85,6 +103,14 @@ public class InnerClassesAttribute extends AttributeInfo { | |||
return constPool.getClassInfo(i); | |||
} | |||
/** | |||
* Sets <code>classes[nth].outer_class_info_index</code> to | |||
* the given index. | |||
*/ | |||
public void setOuterClassIndex(int nth, int index) { | |||
ByteArray.write16bit(index, get(), nth * 8 + 4); | |||
} | |||
/** | |||
* Returns <code>classes[nth].inner_name_index</code>. | |||
*/ | |||
@@ -106,6 +132,14 @@ public class InnerClassesAttribute extends AttributeInfo { | |||
return constPool.getUtf8Info(i); | |||
} | |||
/** | |||
* Sets <code>classes[nth].inner_name_index</code> to | |||
* the given index. | |||
*/ | |||
public void setInnerNameIndex(int nth, int index) { | |||
ByteArray.write16bit(index, get(), nth * 8 + 6); | |||
} | |||
/** | |||
* Returns <code>classes[nth].inner_class_access_flags</code>. | |||
*/ | |||
@@ -113,6 +147,55 @@ public class InnerClassesAttribute extends AttributeInfo { | |||
return ByteArray.readU16bit(get(), nth * 8 + 8); | |||
} | |||
/** | |||
* Sets <code>classes[nth].inner_class_access_flags</code> to | |||
* the given index. | |||
*/ | |||
public void setAccessFlags(int nth, int flags) { | |||
ByteArray.write16bit(flags, get(), nth * 8 + 8); | |||
} | |||
/** | |||
* Appends a new entry. | |||
* | |||
* @param inner <code>inner_class_info_index</code> | |||
* @param outer <code>outer_class_info_index</code> | |||
* @param name <code>inner_name_index</code> | |||
* @param flags <code>inner_class_access_flags</code> | |||
*/ | |||
public void append(String inner, String outer, String name, int flags) { | |||
int i = constPool.addClassInfo(inner); | |||
int o = constPool.addClassInfo(outer); | |||
int n = constPool.addUtf8Info(name); | |||
append(i, o, n, flags); | |||
} | |||
/** | |||
* Appends a new entry. | |||
* | |||
* @param inner <code>inner_class_info_index</code> | |||
* @param outer <code>outer_class_info_index</code> | |||
* @param name <code>inner_name_index</code> | |||
* @param flags <code>inner_class_access_flags</code> | |||
*/ | |||
public void append(int inner, int outer, int name, int flags) { | |||
byte[] data = get(); | |||
int len = data.length; | |||
byte[] newData = new byte[len + 8]; | |||
for (int i = 2; i < len; ++i) | |||
newData[i] = data[i]; | |||
int n = ByteArray.readU16bit(data, 0); | |||
ByteArray.write16bit(n + 1, newData, 0); | |||
ByteArray.write16bit(inner, newData, len); | |||
ByteArray.write16bit(outer, newData, len + 2); | |||
ByteArray.write16bit(name, newData, len + 4); | |||
ByteArray.write16bit(flags, newData, len + 6); | |||
set(newData); | |||
} | |||
/** | |||
* Makes a copy. Class names are replaced according to the | |||
* given <code>Map</code> object. |