aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/javassist/expr/NewExpr.java
diff options
context:
space:
mode:
authorpatriot1burke <patriot1burke@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2003-04-22 13:47:06 +0000
committerpatriot1burke <patriot1burke@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2003-04-22 13:47:06 +0000
commit069bceaf72fd0d6ffad14ce4e3e00ca91a280bde (patch)
treeb8230a15d3061c64d5a64bf9efa654d0d6311ff2 /src/main/javassist/expr/NewExpr.java
parentf610083ba0adbcb3fe92a504015fb26fb5a42530 (diff)
downloadjavassist-069bceaf72fd0d6ffad14ce4e3e00ca91a280bde.tar.gz
javassist-069bceaf72fd0d6ffad14ce4e3e00ca91a280bde.zip
This commit was generated by cvs2svn to compensate for changes in r2, which
included commits to RCS files with non-trunk default branches. git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@6 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
Diffstat (limited to 'src/main/javassist/expr/NewExpr.java')
-rw-r--r--src/main/javassist/expr/NewExpr.java224
1 files changed, 224 insertions, 0 deletions
diff --git a/src/main/javassist/expr/NewExpr.java b/src/main/javassist/expr/NewExpr.java
new file mode 100644
index 00000000..73546238
--- /dev/null
+++ b/src/main/javassist/expr/NewExpr.java
@@ -0,0 +1,224 @@
+/*
+ * This file is part of the Javassist toolkit.
+ *
+ * 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. You may obtain a copy of the License at
+ * either http://www.mozilla.org/MPL/.
+ *
+ * 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.
+ *
+ * The Original Code is Javassist.
+ *
+ * The Initial Developer of the Original Code is Shigeru Chiba. Portions
+ * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba.
+ * All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * The development of this software is supported in part by the PRESTO
+ * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation.
+ */
+
+package javassist.expr;
+
+import javassist.*;
+import javassist.bytecode.*;
+import javassist.compiler.*;
+import javassist.compiler.ast.ASTree;
+import javassist.compiler.ast.ASTList;
+
+/**
+ * Object creation (<tt>new</tt> expression).
+ */
+public class NewExpr extends Expr {
+ String newTypeName;
+ int newPos;
+
+ /**
+ * Undocumented constructor. Do not use; internal-use only.
+ */
+ NewExpr(int pos, CodeIterator i, CtClass declaring, MethodInfo m,
+ String type, int np)
+ {
+ super(pos, i, declaring, m);
+ newTypeName = type;
+ newPos = np;
+ }
+
+ private int getNameAndType(ConstPool cp) {
+ String cname;
+ int pos = currentPos;
+ int c = iterator.byteAt(pos);
+ int index = iterator.u16bitAt(pos + 1);
+
+ if (c == INVOKEINTERFACE)
+ return cp.getInterfaceMethodrefNameAndType(index);
+ else
+ return cp.getMethodrefNameAndType(index);
+ }
+
+ /**
+ * Returns the method or constructor containing the <tt>new</tt>
+ * expression represented by this object.
+ */
+ public CtBehavior where() { return super.where(); }
+
+ /**
+ * Returns the line number of the source line containing the
+ * <tt>new</tt> expression.
+ *
+ * @return -1 if this information is not available.
+ */
+ public int getLineNumber() {
+ return super.getLineNumber();
+ }
+
+ /**
+ * Returns the source file containing the <tt>new</tt> expression.
+ *
+ * @return null if this information is not available.
+ */
+ public String getFileName() {
+ return super.getFileName();
+ }
+
+ /**
+ * Returns the class of the created object.
+ */
+ private CtClass getCtClass() throws NotFoundException {
+ return thisClass.getClassPool().get(newTypeName);
+ }
+
+ /**
+ * Returns the class name of the created object.
+ */
+ public String getClassName() {
+ return newTypeName;
+ }
+
+ /**
+ * Returns the constructor called for creating the object.
+ */
+ public CtConstructor getConstructor() throws NotFoundException {
+ ConstPool cp = getConstPool();
+ int index = iterator.u16bitAt(currentPos + 1);
+ String desc = cp.getMethodrefType(index);
+ return getCtClass().getConstructor(desc);
+ }
+
+ /**
+ * Returns the list of exceptions that the expression may throw.
+ * This list includes both the exceptions that the try-catch statements
+ * including the expression can catch and the exceptions that
+ * the throws declaration allows the method to throw.
+ */
+ public CtClass[] mayThrow() {
+ return super.mayThrow();
+ }
+
+ /*
+ * Returns the parameter types of the constructor.
+
+ public CtClass[] getParameterTypes() throws NotFoundException {
+ ConstPool cp = getConstPool();
+ int index = iterator.u16bitAt(currentPos + 1);
+ String desc = cp.getMethodrefType(index);
+ return Descriptor.getParameterTypes(desc, thisClass.getClassPool());
+ }
+ */
+
+ private int canReplace() throws CannotCompileException {
+ int op = iterator.byteAt(newPos + 3);
+ if (op == Opcode.DUP)
+ return 4;
+ else if (op == Opcode.DUP_X1
+ && iterator.byteAt(newPos + 4) == Opcode.SWAP)
+ return 5;
+ else
+ throw new CannotCompileException(
+ "sorry, cannot edit NEW followed by no DUP");
+ }
+
+ /**
+ * Replaces the <tt>new</tt> expression with the bytecode derived from
+ * the given source text.
+ *
+ * <p>$0 is available but the value is null.
+ *
+ * @param statement a Java statement.
+ */
+ public void replace(String statement) throws CannotCompileException {
+ final int bytecodeSize = 3;
+ int pos = newPos;
+
+ int newIndex = iterator.u16bitAt(pos + 1);
+
+ /* delete the preceding NEW and DUP (or DUP_X1, SWAP) instructions.
+ */
+ int end = pos + canReplace();
+ for (int i = pos; i < end; ++i)
+ iterator.writeByte(NOP, i);
+
+ ConstPool constPool = getConstPool();
+ pos = currentPos;
+ int methodIndex = iterator.u16bitAt(pos + 1); // constructor
+
+ String signature = constPool.getMethodrefType(methodIndex);
+
+ Javac jc = new Javac(thisClass);
+ ClassPool cp = thisClass.getClassPool();
+ CodeAttribute ca = iterator.get();
+ try {
+ CtClass[] params = Descriptor.getParameterTypes(signature, cp);
+ CtClass newType = cp.get(newTypeName);
+ int paramVar = ca.getMaxLocals();
+ jc.recordParams(newTypeName, params,
+ true, paramVar, withinStatic());
+ int retVar = jc.recordReturnType(newType, true);
+ jc.recordProceed(new ProceedForNew(newType, newIndex,
+ methodIndex));
+
+ /* Is $_ included in the source code?
+ */
+ checkResultValue(newType, statement);
+
+ Bytecode bytecode = jc.getBytecode();
+ storeStack(params, true, paramVar, bytecode);
+ jc.compileStmnt(statement);
+ bytecode.addAload(retVar);
+
+ replace0(pos, bytecode, bytecodeSize);
+ }
+ catch (CompileError e) { throw new CannotCompileException(e); }
+ catch (NotFoundException e) { throw new CannotCompileException(e); }
+ catch (BadBytecode e) {
+ throw new CannotCompileException("broken method");
+ }
+ }
+
+ static class ProceedForNew implements ProceedHandler {
+ CtClass newType;
+ int newIndex, methodIndex;
+
+ ProceedForNew(CtClass nt, int ni, int mi) {
+ newType = nt;
+ newIndex = ni;
+ methodIndex = mi;
+ }
+
+ public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
+ throws CompileError
+ {
+ bytecode.addOpcode(NEW);
+ bytecode.addIndex(newIndex);
+ bytecode.addOpcode(DUP);
+ gen.atMethodCall2(newType, MethodInfo.nameInit,
+ args, false, true);
+ gen.setType(newType);
+ }
+ }
+}