/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