1 15 16 package javassist.compiler; 17 18 import javassist.*; 19 import javassist.compiler.ast.*; 20 21 23 24 public class JvstTypeChecker extends TypeChecker { 25 private JvstCodeGen codeGen; 26 27 public JvstTypeChecker(CtClass cc, ClassPool cp, JvstCodeGen gen) { 28 super(cc, cp); 29 codeGen = gen; 30 } 31 32 35 public void addNullIfVoid() { 36 if (exprType == VOID) { 37 exprType = CLASS; 38 arrayDim = 0; 39 className = jvmJavaLangObject; 40 } 41 } 42 43 46 public void atMember(Member mem) throws CompileError { 47 String name = mem.get(); 48 if (name.equals(codeGen.paramArrayName)) { 49 exprType = CLASS; 50 arrayDim = 1; 51 className = jvmJavaLangObject; 52 } 53 else if (name.equals(JvstCodeGen.sigName)) { 54 exprType = CLASS; 55 arrayDim = 1; 56 className = "java/lang/Class"; 57 } 58 else if (name.equals(JvstCodeGen.dollarTypeName) 59 || name.equals(JvstCodeGen.clazzName)) { 60 exprType = CLASS; 61 arrayDim = 0; 62 className = "java/lang/Class"; 63 } 64 else 65 super.atMember(mem); 66 } 67 68 protected void atFieldAssign(Expr expr, int op, ASTree left, ASTree right) 69 throws CompileError 70 { 71 if (left instanceof Member 72 && ((Member)left).get().equals(codeGen.paramArrayName)) { 73 right.accept(this); 74 CtClass[] params = codeGen.paramTypeList; 75 if (params == null) 76 return; 77 78 int n = params.length; 79 for (int i = 0; i < n; ++i) 80 compileUnwrapValue(params[i]); 81 } 82 else 83 super.atFieldAssign(expr, op, left, right); 84 } 85 86 public void atCastExpr(CastExpr expr) throws CompileError { 87 ASTList classname = expr.getClassName(); 88 if (classname != null && expr.getArrayDim() == 0) { 89 ASTree p = classname.head(); 90 if (p instanceof Symbol && classname.tail() == null) { 91 String typename = ((Symbol)p).get(); 92 if (typename.equals(codeGen.returnCastName)) { 93 atCastToRtype(expr); 94 return; 95 } 96 else if (typename.equals(JvstCodeGen.wrapperCastName)) { 97 atCastToWrapper(expr); 98 return; 99 } 100 } 101 } 102 103 super.atCastExpr(expr); 104 } 105 106 110 protected void atCastToRtype(CastExpr expr) throws CompileError { 111 CtClass returnType = codeGen.returnType; 112 expr.getOprand().accept(this); 113 if (exprType == VOID || CodeGen.isRefType(exprType) || arrayDim > 0) 114 compileUnwrapValue(returnType); 115 else if (returnType instanceof CtPrimitiveType) { 116 CtPrimitiveType pt = (CtPrimitiveType)returnType; 117 int destType = MemberResolver.descToType(pt.getDescriptor()); 118 exprType = destType; 119 arrayDim = 0; 120 className = null; 121 } 122 } 123 124 protected void atCastToWrapper(CastExpr expr) throws CompileError { 125 expr.getOprand().accept(this); 126 if (CodeGen.isRefType(exprType) || arrayDim > 0) 127 return; 129 CtClass clazz = resolver.lookupClass(exprType, arrayDim, className); 130 if (clazz instanceof CtPrimitiveType) { 131 exprType = CLASS; 132 arrayDim = 0; 133 className = jvmJavaLangObject; 134 } 135 } 136 137 140 public void atCallExpr(CallExpr expr) throws CompileError { 141 ASTree method = expr.oprand1(); 142 if (method instanceof Member) { 143 String name = ((Member)method).get(); 144 if (codeGen.procHandler != null 145 && name.equals(codeGen.proceedName)) { 146 codeGen.procHandler.setReturnType(this, 147 (ASTList)expr.oprand2()); 148 return; 149 } 150 else if (name.equals(JvstCodeGen.cflowName)) { 151 atCflow((ASTList)expr.oprand2()); 152 return; 153 } 154 } 155 156 super.atCallExpr(expr); 157 } 158 159 161 protected void atCflow(ASTList cname) throws CompileError { 162 exprType = INT; 163 arrayDim = 0; 164 className = null; 165 } 166 167 170 public boolean isParamListName(ASTList args) { 171 if (codeGen.paramTypeList != null 172 && args != null && args.tail() == null) { 173 ASTree left = args.head(); 174 return (left instanceof Member 175 && ((Member)left).get().equals(codeGen.paramListName)); 176 } 177 else 178 return false; 179 } 180 181 public int getMethodArgsLength(ASTList args) { 182 String pname = codeGen.paramListName; 183 int n = 0; 184 while (args != null) { 185 ASTree a = args.head(); 186 if (a instanceof Member && ((Member)a).get().equals(pname)) { 187 if (codeGen.paramTypeList != null) 188 n += codeGen.paramTypeList.length; 189 } 190 else 191 ++n; 192 193 args = args.tail(); 194 } 195 196 return n; 197 } 198 199 public void atMethodArgs(ASTList args, int[] types, int[] dims, 200 String [] cnames) throws CompileError { 201 CtClass[] params = codeGen.paramTypeList; 202 String pname = codeGen.paramListName; 203 int i = 0; 204 while (args != null) { 205 ASTree a = args.head(); 206 if (a instanceof Member && ((Member)a).get().equals(pname)) { 207 if (params != null) { 208 int n = params.length; 209 for (int k = 0; k < n; ++k) { 210 CtClass p = params[k]; 211 setType(p); 212 types[i] = exprType; 213 dims[i] = arrayDim; 214 cnames[i] = className; 215 ++i; 216 } 217 } 218 } 219 else { 220 a.accept(this); 221 types[i] = exprType; 222 dims[i] = arrayDim; 223 cnames[i] = className; 224 ++i; 225 } 226 227 args = args.tail(); 228 } 229 } 230 231 233 void compileInvokeSpecial(ASTree target, String classname, 234 String methodname, String descriptor, 235 ASTList args) 236 throws CompileError 237 { 238 target.accept(this); 239 int nargs = getMethodArgsLength(args); 240 atMethodArgs(args, new int[nargs], new int[nargs], 241 new String [nargs]); 242 setReturnType(descriptor); 243 addNullIfVoid(); 244 } 245 246 protected void compileUnwrapValue(CtClass type) throws CompileError 247 { 248 if (type == CtClass.voidType) 249 addNullIfVoid(); 250 else 251 setType(type); 252 } 253 254 257 public void setType(CtClass type) throws CompileError { 258 setType(type, 0); 259 } 260 261 private void setType(CtClass type, int dim) throws CompileError { 262 if (type.isPrimitive()) { 263 CtPrimitiveType pt = (CtPrimitiveType)type; 264 exprType = MemberResolver.descToType(pt.getDescriptor()); 265 arrayDim = dim; 266 className = null; 267 } 268 else if (type.isArray()) 269 try { 270 setType(type.getComponentType(), dim + 1); 271 } 272 catch (NotFoundException e) { 273 throw new CompileError("undefined type: " + type.getName()); 274 } 275 else { 276 exprType = CLASS; 277 arrayDim = dim; 278 className = MemberResolver.javaToJvmName(type.getName()); 279 } 280 } 281 } 282 | Popular Tags |