/Users/lyon/j4p/src/javassist/expr/Cast.java
|
1 /*
2 * Javassist, a Java-bytecode translator toolkit.
3 * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved.
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. Alternatively, the contents of this file may be used under
8 * the terms of the GNU Lesser General Public License Version 2.1 or later.
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 */
15
16 package javassist.expr;
17
18 import javassist.*;
19 import javassist.bytecode.*;
20 import javassist.compiler.*;
21 import javassist.compiler.ast.ASTList;
22
23 /**
24 * Explicit type cast.
25 */
26 public class Cast extends Expr {
27 /**
28 * Undocumented constructor. Do not use; internal-use only.
29 */
30 Cast(int pos, CodeIterator i, CtClass declaring, MethodInfo m) {
31 super(pos, i, declaring, m);
32 }
33
34 /**
35 * Returns the method or constructor containing the type cast
36 * expression represented by this object.
37 */
38 public CtBehavior where() {
39 return super.where();
40 }
41
42 /**
43 * Returns the line number of the source line containing the
44 * type-cast expression.
45 *
46 * @return -1 if this information is not available.
47 */
48 public int getLineNumber() {
49 return super.getLineNumber();
50 }
51
52 /**
53 * Returns the source file containing the type-cast expression.
54 *
55 * @return null if this information is not available.
56 */
57 public String getFileName() {
58 return super.getFileName();
59 }
60
61 /**
62 * Returns the <code>CtClass</code> object representing
63 * the type specified by the cast.
64 */
65 public CtClass getType() throws NotFoundException {
66 ConstPool cp = getConstPool();
67 int pos = currentPos;
68 int index = iterator.u16bitAt(pos + 1);
69 String name = cp.getClassInfo(index);
70 return Descriptor.toCtClass(name, thisClass.getClassPool());
71 }
72
73 /**
74 * Returns the list of exceptions that the expression may throw.
75 * This list includes both the exceptions that the try-catch statements
76 * including the expression can catch and the exceptions that
77 * the throws declaration allows the method to throw.
78 */
79 public CtClass[] mayThrow() {
80 return super.mayThrow();
81 }
82
83 /**
84 * Replaces the explicit cast operator with the bytecode derived from
85 * the given source text.
86 *
87 * <p>$0 is available but the value is <code>null</code>.
88 *
89 * @param statement a Java statement.
90 */
91 public void replace(String statement) throws CannotCompileException {
92 ConstPool constPool = getConstPool();
93 int pos = currentPos;
94 int index = iterator.u16bitAt(pos + 1);
95
96 Javac jc = new Javac(thisClass);
97 ClassPool cp = thisClass.getClassPool();
98 CodeAttribute ca = iterator.get();
99
100 try {
101 CtClass[] params
102 = new CtClass[]{cp.get(javaLangObject)};
103 CtClass retType = getType();
104
105 int paramVar = ca.getMaxLocals();
106 jc.recordParams(javaLangObject, params, true, paramVar,
107 withinStatic());
108 int retVar = jc.recordReturnType(retType, true);
109 jc.recordProceed(new ProceedForCast(index, retType));
110
111 /* Is $_ included in the source code?
112 */
113 checkResultValue(retType, statement);
114
115 Bytecode bytecode = jc.getBytecode();
116 storeStack(params, true, paramVar, bytecode);
117 jc.compileStmnt(statement);
118 bytecode.addLoad(retVar, retType);
119
120 replace0(pos, bytecode, 3);
121 } catch (CompileError e) {
122 throw new CannotCompileException(e);
123 } catch (NotFoundException e) {
124 throw new CannotCompileException(e);
125 } catch (BadBytecode e) {
126 throw new CannotCompileException("broken method");
127 }
128 }
129
130 /* <type> $proceed(Object obj)
131 */
132 static class ProceedForCast implements ProceedHandler {
133 int index;
134 CtClass retType;
135
136 ProceedForCast(int i, CtClass t) {
137 index = i;
138 retType = t;
139 }
140
141 public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
142 throws CompileError {
143 if (gen.atMethodArgsLength(args) != 1)
144 throw new CompileError(Javac.proceedName
145 + "() cannot take more than one parameter "
146 + "for cast");
147
148 gen.atMethodArgs(args, new int[1], new int[1], new String[1]);
149 bytecode.addOpcode(Opcode.CHECKCAST);
150 bytecode.addIndex(index);
151 gen.setType(retType);
152 }
153 }
154 }
155