calledClass.getName(), calledMethod);
}
+ /**
+ * Modify a method body so that instantiation of the class
+ * specified by <code>oldClass</code>
+ * is replaced with instantiation of another class <code>newClass</code>.
+ * For example,
+ * <code>replaceNew(ctPoint, ctPoint2)</code>
+ * (where <code>ctPoint</code> and <code>ctPoint2</code> are
+ * compile-time classes for class <code>Point</code> and class
+ * <code>Point2</code>, respectively)
+ * replaces all occurrences of:
+ *
+ * <ul><code>new Point(x, y)</code></ul>
+ *
+ * in the method body with:
+ *
+ * <ul><code>new Point2(x, y)</code></ul>
+ *
+ * <p>Note that <code>Point2</code> must be type-compatible with <code>Point</code>.
+ * It must have the same set of methods, fields, and constructors as the
+ * replaced class.
+ */
+ public void replaceNew(CtClass oldClass, CtClass newClass) {
+ transformers = new TransformNewClass(transformers, oldClass.getName(),
+ newClass.getName());
+ }
+
/**
* Modify a method body so that field read/write expressions access
* a different field from the original one.
* as array access replacements.
*
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
- * @version $Revision: 1.14 $
+ * @version $Revision: 1.15 $
*/
public interface ArrayAccessReplacementMethodNames
{
* accesses to array elements.
*
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
- * @version $Revision: 1.14 $
+ * @version $Revision: 1.15 $
*/
public static class DefaultArrayAccessReplacementMethodNames
implements ArrayAccessReplacementMethodNames
--- /dev/null
+/*
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999-2007 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.convert;
+
+import javassist.bytecode.*;
+import javassist.CtClass;
+import javassist.CannotCompileException;
+
+final public class TransformNewClass extends Transformer {
+ private int nested;
+ private String classname, newClassName;
+ private int newClassIndex, newMethodNTIndex, newMethodIndex;
+
+ public TransformNewClass(Transformer next,
+ String classname, String newClassName) {
+ super(next);
+ this.classname = classname;
+ this.newClassName = newClassName;
+ }
+
+ public void initialize(ConstPool cp, CodeAttribute attr) {
+ nested = 0;
+ newClassIndex = newMethodNTIndex = newMethodIndex = 0;
+ }
+
+ /**
+ * Modifies a sequence of
+ * NEW classname
+ * DUP
+ * ...
+ * INVOKESPECIAL classname:method
+ */
+ public int transform(CtClass clazz, int pos, CodeIterator iterator,
+ ConstPool cp) throws CannotCompileException
+ {
+ int index;
+ int c = iterator.byteAt(pos);
+ if (c == NEW) {
+ index = iterator.u16bitAt(pos + 1);
+ if (cp.getClassInfo(index).equals(classname)) {
+ if (iterator.byteAt(pos + 3) != DUP)
+ throw new CannotCompileException(
+ "NEW followed by no DUP was found");
+
+ if (newClassIndex == 0)
+ newClassIndex = cp.addClassInfo(newClassName);
+
+ iterator.write16bit(newClassIndex, pos + 1);
+ ++nested;
+ }
+ }
+ else if (c == INVOKESPECIAL) {
+ index = iterator.u16bitAt(pos + 1);
+ int typedesc = cp.isConstructor(classname, index);
+ if (typedesc != 0 && nested > 0) {
+ int nt = cp.getMethodrefNameAndType(index);
+ if (newMethodNTIndex != nt) {
+ newMethodNTIndex = nt;
+ newMethodIndex = cp.addMethodrefInfo(newClassIndex, nt);
+ }
+
+ iterator.write16bit(newMethodIndex, pos + 1);
+ --nested;
+ }
+ }
+
+ return pos;
+ }
+}