169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/* 269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit. 369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved. 469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version 669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with 769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License. Alternatively, the contents of this file may be used under 869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later. 969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis, 1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the 1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License. 1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.compiler; 1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CtClass; 1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CtField; 2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.ClassPool; 2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.Modifier; 2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.NotFoundException; 2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.compiler.ast.*; 2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.*; 2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class TypeChecker extends Visitor implements Opcode, TokenId { 2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static final String javaLangObject = "java.lang.Object"; 2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static final String jvmJavaLangObject = "java/lang/Object"; 2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static final String jvmJavaLangString = "java/lang/String"; 3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static final String jvmJavaLangClass = "java/lang/Class"; 3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* The following fields are used by atXXX() methods 3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for returning the type of the compiled expression. 3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected int exprType; // VOID, NULL, CLASS, BOOLEAN, INT, ... 3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected int arrayDim; 3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected String className; // JVM-internal representation 3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected MemberResolver resolver; 4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected CtClass thisClass; 4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected MethodInfo thisMethod; 4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public TypeChecker(CtClass cc, ClassPool cp) { 4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal resolver = new MemberResolver(cp); 4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal thisClass = cc; 4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal thisMethod = null; 4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* 5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Converts an array of tuples of exprType, arrayDim, and className 5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * into a String object. 5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected static String argTypesToString(int[] types, int[] dims, 5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String[] cnames) { 5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal StringBuffer sbuf = new StringBuffer(); 5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append('('); 5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = types.length; 5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (n > 0) { 5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int i = 0; 6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (true) { 6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal typeToString(sbuf, types[i], dims[i], cnames[i]); 6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (++i < n) 6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(','); 6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(')'); 7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return sbuf.toString(); 7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* 7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Converts a tuple of exprType, arrayDim, and className 7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * into a String object. 7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected static StringBuffer typeToString(StringBuffer sbuf, 7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int type, int dim, String cname) { 7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String s; 8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (type == CLASS) 8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal s = MemberResolver.jvmToJavaName(cname); 8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (type == NULL) 8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal s = "Object"; 8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal s = MemberResolver.getTypeName(type); 8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (CompileError e) { 8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal s = "?"; 9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(s); 9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (dim-- > 0) 9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append("[]"); 9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return sbuf; 9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Records the currently compiled method. 10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setThisMethod(MethodInfo m) { 10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal thisMethod = m; 10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected static void fatal() throws CompileError { 10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new CompileError("fatal"); 10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the JVM-internal representation of this class name. 11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected String getThisName() { 11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return MemberResolver.javaToJvmName(thisClass.getName()); 11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the JVM-internal representation of this super class name. 11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected String getSuperName() throws CompileError { 12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return MemberResolver.javaToJvmName( 12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal MemberResolver.getSuperclass(thisClass).getName()); 12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* Converts a class name into a JVM-internal representation. 12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * It may also expand a simple class name to java.lang.*. 12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * For example, this converts Object into java/lang/Object. 12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected String resolveClassName(ASTList name) throws CompileError { 13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return resolver.resolveClassName(name); 13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* Expands a simple class name to java.lang.*. 13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * For example, this converts Object into java/lang/Object. 13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected String resolveClassName(String jvmName) throws CompileError { 13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return resolver.resolveJvmClassName(jvmName); 13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atNewExpr(NewExpr expr) throws CompileError { 14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (expr.isArray()) 14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atNewArrayExpr(expr); 14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtClass clazz = resolver.lookupClassByName(expr.getClassName()); 14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String cname = clazz.getName(); 14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTList args = expr.getArguments(); 14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atMethodCallCore(clazz, MethodInfo.nameInit, args); 14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = CLASS; 15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = 0; 15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = MemberResolver.javaToJvmName(cname); 15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atNewArrayExpr(NewExpr expr) throws CompileError { 15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int type = expr.getArrayType(); 15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTList size = expr.getArraySize(); 15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTList classname = expr.getClassName(); 15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree init = expr.getInitializer(); 16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (init != null) 16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal init.accept(this); 16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (size.length() > 1) 16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atMultiNewArray(type, classname, size); 16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree sizeExpr = size.head(); 16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (sizeExpr != null) 16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sizeExpr.accept(this); 16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = type; 17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = 1; 17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (type == CLASS) 17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = resolveClassName(classname); 17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = null; 17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atArrayInit(ArrayInit init) throws CompileError { 18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTList list = init; 18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (list != null) { 18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree h = list.head(); 18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal list = list.tail(); 18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (h != null) 18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal h.accept(this); 18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected void atMultiNewArray(int type, ASTList classname, ASTList size) 19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int count, dim; 19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal dim = size.length(); 19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (count = 0; size != null; size = size.tail()) { 19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree s = size.head(); 19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (s == null) 19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; // int[][][] a = new int[3][4][]; 19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ++count; 20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal s.accept(this); 20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = type; 20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = dim; 20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (type == CLASS) 20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = resolveClassName(classname); 20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = null; 20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atAssignExpr(AssignExpr expr) throws CompileError { 21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // =, %=, &=, *=, /=, +=, -=, ^=, |=, <<=, >>=, >>>= 21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int op = expr.getOperator(); 21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree left = expr.oprand1(); 21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree right = expr.oprand2(); 21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (left instanceof Variable) 21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atVariableAssign(expr, op, (Variable)left, 21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ((Variable)left).getDeclarator(), 21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal right); 22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (left instanceof Expr) { 22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Expr e = (Expr)left; 22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (e.getOperator() == ARRAY) { 22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atArrayAssign(expr, op, (Expr)left, right); 22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return; 22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atFieldAssign(expr, op, left, right); 23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* op is either =, %=, &=, *=, /=, +=, -=, ^=, |=, <<=, >>=, or >>>=. 23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * expr and var can be null. 23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void atVariableAssign(Expr expr, int op, Variable var, 23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Declarator d, ASTree right) 23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int varType = d.getType(); 24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int varArray = d.getArrayDim(); 24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String varClass = d.getClassName(); 24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (op != '=') 24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atVariable(var); 24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal right.accept(this); 24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = varType; 25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = varArray; 25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = varClass; 25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void atArrayAssign(Expr expr, int op, Expr array, 25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree right) throws CompileError 25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atArrayRead(array.oprand1(), array.oprand2()); 25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int aType = exprType; 25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int aDim = arrayDim; 26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String cname = className; 26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal right.accept(this); 26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = aType; 26369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = aDim; 26469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = cname; 26569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 26669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 26769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected void atFieldAssign(Expr expr, int op, ASTree left, ASTree right) 26869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 26969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 27069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtField f = fieldAccess(left); 27169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atFieldRead(f); 27269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int fType = exprType; 27369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int fDim = arrayDim; 27469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String cname = className; 27569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal right.accept(this); 27669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = fType; 27769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = fDim; 27869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = cname; 27969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 28069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 28169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atCondExpr(CondExpr expr) throws CompileError { 28269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal booleanExpr(expr.condExpr()); 28369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr.thenExpr().accept(this); 28469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int type1 = exprType; 28569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int dim1 = arrayDim; 28669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String cname1 = className; 28769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr.elseExpr().accept(this); 28869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 28969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (dim1 == 0 && dim1 == arrayDim) 29069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (CodeGen.rightIsStrong(type1, exprType)) 29169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr.setThen(new CastExpr(exprType, 0, expr.thenExpr())); 29269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (CodeGen.rightIsStrong(exprType, type1)) { 29369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr.setElse(new CastExpr(type1, 0, expr.elseExpr())); 29469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = type1; 29569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 29669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 29769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 29869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* 29969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If atBinExpr() substitutes a new expression for the original 30069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * binary-operator expression, it changes the operator name to '+' 30169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * (if the original is not '+') and sets the new expression to the 30269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * left-hand-side expression and null to the right-hand-side expression. 30369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 30469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atBinExpr(BinExpr expr) throws CompileError { 30569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int token = expr.getOperator(); 30669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int k = CodeGen.lookupBinOp(token); 30769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (k >= 0) { 30869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* arithmetic operators: +, -, *, /, %, |, ^, &, <<, >>, >>> 30969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 31069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (token == '+') { 31169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Expr e = atPlusExpr(expr); 31269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (e != null) { 31369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* String concatenation has been translated into 31469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * an expression using StringBuffer. 31569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 31669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal e = CallExpr.makeCall(Expr.make('.', e, 31769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal new Member("toString")), null); 31869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr.setOprand1(e); 31969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr.setOprand2(null); // <---- look at this! 32069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = jvmJavaLangString; 32169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 32269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 32369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 32469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree left = expr.oprand1(); 32569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree right = expr.oprand2(); 32669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal left.accept(this); 32769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int type1 = exprType; 32869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal right.accept(this); 32969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (!isConstant(expr, token, left, right)) 33069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal computeBinExprType(expr, token, type1); 33169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 33269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 33369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 33469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* equation: &&, ||, ==, !=, <=, >=, <, > 33569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 33669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal booleanExpr(expr); 33769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 33869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 33969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 34069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* EXPR must be a + expression. 34169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * atPlusExpr() returns non-null if the given expression is string 34269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * concatenation. The returned value is "new StringBuffer().append..". 34369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 34469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private Expr atPlusExpr(BinExpr expr) throws CompileError { 34569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree left = expr.oprand1(); 34669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree right = expr.oprand2(); 34769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (right == null) { 34869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // this expression has been already type-checked. 34969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // see atBinExpr() above. 35069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal left.accept(this); 35169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return null; 35269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 35369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 35469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (isPlusExpr(left)) { 35569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Expr newExpr = atPlusExpr((BinExpr)left); 35669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (newExpr != null) { 35769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal right.accept(this); 35869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = CLASS; 35969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = 0; 36069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = "java/lang/StringBuffer"; 36169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return makeAppendCall(newExpr, right); 36269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 36369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 36469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 36569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal left.accept(this); 36669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 36769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int type1 = exprType; 36869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int dim1 = arrayDim; 36969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String cname = className; 37069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal right.accept(this); 37169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 37269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (isConstant(expr, '+', left, right)) 37369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return null; 37469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 37569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if ((type1 == CLASS && dim1 == 0 && jvmJavaLangString.equals(cname)) 37669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal || (exprType == CLASS && arrayDim == 0 37769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal && jvmJavaLangString.equals(className))) { 37869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTList sbufClass = ASTList.make(new Symbol("java"), 37969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal new Symbol("lang"), new Symbol("StringBuffer")); 38069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree e = new NewExpr(sbufClass, null); 38169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = CLASS; 38269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = 0; 38369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = "java/lang/StringBuffer"; 38469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return makeAppendCall(makeAppendCall(e, left), right); 38569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 38669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 38769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal computeBinExprType(expr, '+', type1); 38869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return null; 38969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 39069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 39169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 39269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private boolean isConstant(BinExpr expr, int op, ASTree left, 39369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree right) throws CompileError 39469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 39569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal left = stripPlusExpr(left); 39669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal right = stripPlusExpr(right); 39769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree newExpr = null; 39869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (left instanceof StringL && right instanceof StringL && op == '+') 39969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newExpr = new StringL(((StringL)left).get() 40069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal + ((StringL)right).get()); 40169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (left instanceof IntConst) 40269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newExpr = ((IntConst)left).compute(op, right); 40369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (left instanceof DoubleConst) 40469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newExpr = ((DoubleConst)left).compute(op, right); 40569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 40669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (newExpr == null) 40769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return false; // not a constant expression 40869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 40969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr.setOperator('+'); 41069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr.setOprand1(newExpr); 41169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr.setOprand2(null); 41269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newExpr.accept(this); // for setting exprType, arrayDim, ... 41369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return true; 41469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 41569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 41669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 41769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* CodeGen.atSwitchStmnt() also calls stripPlusExpr(). 41869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 41969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static ASTree stripPlusExpr(ASTree expr) { 42069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (expr instanceof BinExpr) { 42169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal BinExpr e = (BinExpr)expr; 42269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (e.getOperator() == '+' && e.oprand2() == null) 42369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return e.getLeft(); 42469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 42569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (expr instanceof Expr) { // note: BinExpr extends Expr. 42669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Expr e = (Expr)expr; 42769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int op = e.getOperator(); 42869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (op == MEMBER) { 42969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree cexpr = getConstantFieldValue((Member)e.oprand2()); 43069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (cexpr != null) 43169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return cexpr; 43269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 43369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (op == '+' && e.getRight() == null) 43469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return e.getLeft(); 43569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 43669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (expr instanceof Member) { 43769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree cexpr = getConstantFieldValue((Member)expr); 43869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (cexpr != null) 43969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return cexpr; 44069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 44169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 44269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return expr; 44369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 44469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 44569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 44669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If MEM is a static final field, this method returns a constant 44769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * expression representing the value of that field. 44869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 44969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static ASTree getConstantFieldValue(Member mem) { 45069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return getConstantFieldValue(mem.getField()); 45169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 45269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 45369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static ASTree getConstantFieldValue(CtField f) { 45469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (f == null) 45569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return null; 45669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 45769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Object value = f.getConstantValue(); 45869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (value == null) 45969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return null; 46069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 46169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (value instanceof String) 46269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return new StringL((String)value); 46369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (value instanceof Double || value instanceof Float) { 46469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int token = (value instanceof Double) 46569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ? DoubleConstant : FloatConstant; 46669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return new DoubleConst(((Number)value).doubleValue(), token); 46769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 46869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (value instanceof Number) { 46969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int token = (value instanceof Long) ? LongConstant : IntConstant; 47069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return new IntConst(((Number)value).longValue(), token); 47169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 47269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (value instanceof Boolean) 47369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return new Keyword(((Boolean)value).booleanValue() 47469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ? TokenId.TRUE : TokenId.FALSE); 47569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 47669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return null; 47769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 47869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 47969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static boolean isPlusExpr(ASTree expr) { 48069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (expr instanceof BinExpr) { 48169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal BinExpr bexpr = (BinExpr)expr; 48269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int token = bexpr.getOperator(); 48369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return token == '+'; 48469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 48569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 48669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return false; 48769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 48869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 48969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static Expr makeAppendCall(ASTree target, ASTree arg) { 49069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return CallExpr.makeCall(Expr.make('.', target, new Member("append")), 49169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal new ASTList(arg)); 49269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 49369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 49469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void computeBinExprType(BinExpr expr, int token, int type1) 49569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 49669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 49769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // arrayDim should be 0. 49869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int type2 = exprType; 49969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (token == LSHIFT || token == RSHIFT || token == ARSHIFT) 50069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = type1; 50169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 50269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal insertCast(expr, type1, type2); 50369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 50469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (CodeGen.isP_INT(exprType)) 50569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = INT; // type1 may be BYTE, ... 50669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 50769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 50869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void booleanExpr(ASTree expr) 50969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 51069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 51169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int op = CodeGen.getCompOperator(expr); 51269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (op == EQ) { // ==, !=, ... 51369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal BinExpr bexpr = (BinExpr)expr; 51469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bexpr.oprand1().accept(this); 51569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int type1 = exprType; 51669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int dim1 = arrayDim; 51769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bexpr.oprand2().accept(this); 51869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (dim1 == 0 && arrayDim == 0) 51969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal insertCast(bexpr, type1, exprType); 52069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 52169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (op == '!') 52269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ((Expr)expr).oprand1().accept(this); 52369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (op == ANDAND || op == OROR) { 52469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal BinExpr bexpr = (BinExpr)expr; 52569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bexpr.oprand1().accept(this); 52669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bexpr.oprand2().accept(this); 52769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 52869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else // others 52969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr.accept(this); 53069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 53169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = BOOLEAN; 53269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = 0; 53369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 53469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 53569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void insertCast(BinExpr expr, int type1, int type2) 53669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 53769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 53869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (CodeGen.rightIsStrong(type1, type2)) 53969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr.setLeft(new CastExpr(type2, 0, expr.oprand1())); 54069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 54169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = type1; 54269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 54369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 54469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atCastExpr(CastExpr expr) throws CompileError { 54569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String cname = resolveClassName(expr.getClassName()); 54669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr.getOprand().accept(this); 54769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = expr.getType(); 54869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = expr.getArrayDim(); 54969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = cname; 55069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 55169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 55269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atInstanceOfExpr(InstanceOfExpr expr) throws CompileError { 55369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr.getOprand().accept(this); 55469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = BOOLEAN; 55569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = 0; 55669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 55769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 55869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atExpr(Expr expr) throws CompileError { 55969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // array access, member access, 56069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // (unary) +, (unary) -, ++, --, !, ~ 56169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 56269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int token = expr.getOperator(); 56369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree oprand = expr.oprand1(); 56469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (token == '.') { 56569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String member = ((Symbol)expr.oprand2()).get(); 56669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (member.equals("length")) 56769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atArrayLength(expr); 56869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (member.equals("class")) 56969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atClassObject(expr); // .class 57069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 57169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atFieldRead(expr); 57269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 57369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (token == MEMBER) { // field read 57469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String member = ((Symbol)expr.oprand2()).get(); 57569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (member.equals("class")) 57669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atClassObject(expr); // .class 57769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 57869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atFieldRead(expr); 57969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 58069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (token == ARRAY) 58169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atArrayRead(oprand, expr.oprand2()); 58269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (token == PLUSPLUS || token == MINUSMINUS) 58369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atPlusPlus(token, oprand, expr); 58469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (token == '!') 58569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal booleanExpr(expr); 58669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (token == CALL) // method call 58769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal fatal(); 58869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 58969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal oprand.accept(this); 59069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (!isConstant(expr, token, oprand)) 59169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (token == '-' || token == '~') 59269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (CodeGen.isP_INT(exprType)) 59369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = INT; // type may be BYTE, ... 59469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 59569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 59669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 59769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private boolean isConstant(Expr expr, int op, ASTree oprand) { 59869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal oprand = stripPlusExpr(oprand); 59969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (oprand instanceof IntConst) { 60069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal IntConst c = (IntConst)oprand; 60169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal long v = c.get(); 60269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (op == '-') 60369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal v = -v; 60469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (op == '~') 60569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal v = ~v; 60669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 60769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return false; 60869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 60969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal c.set(v); 61069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 61169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (oprand instanceof DoubleConst) { 61269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal DoubleConst c = (DoubleConst)oprand; 61369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (op == '-') 61469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal c.set(-c.get()); 61569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 61669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return false; 61769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 61869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 61969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return false; 62069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 62169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr.setOperator('+'); 62269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return true; 62369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 62469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 62569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atCallExpr(CallExpr expr) throws CompileError { 62669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String mname = null; 62769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtClass targetClass = null; 62869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree method = expr.oprand1(); 62969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTList args = (ASTList)expr.oprand2(); 63069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 63169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (method instanceof Member) { 63269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal mname = ((Member)method).get(); 63369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal targetClass = thisClass; 63469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 63569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (method instanceof Keyword) { // constructor 63669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal mname = MethodInfo.nameInit; // <init> 63769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (((Keyword)method).get() == SUPER) 63869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal targetClass = MemberResolver.getSuperclass(thisClass); 63969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 64069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal targetClass = thisClass; 64169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 64269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (method instanceof Expr) { 64369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Expr e = (Expr)method; 64469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal mname = ((Symbol)e.oprand2()).get(); 64569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int op = e.getOperator(); 64669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (op == MEMBER) // static method 64769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal targetClass 64869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal = resolver.lookupClass(((Symbol)e.oprand1()).get(), 64969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal false); 65069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (op == '.') { 65169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree target = e.oprand1(); 65269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 65369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal target.accept(this); 65469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 65569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (NoFieldException nfe) { 65669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (nfe.getExpr() != target) 65769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw nfe; 65869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 65969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // it should be a static method. 66069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = CLASS; 66169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = 0; 66269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = nfe.getField(); // JVM-internal 66369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal e.setOperator(MEMBER); 66469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal e.setOprand1(new Symbol(MemberResolver.jvmToJavaName( 66569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className))); 66669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 66769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 66869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (arrayDim > 0) 66969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal targetClass = resolver.lookupClass(javaLangObject, true); 67069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (exprType == CLASS /* && arrayDim == 0 */) 67169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal targetClass = resolver.lookupClassByJvmName(className); 67269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 67369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal badMethod(); 67469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 67569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 67669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal badMethod(); 67769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 67869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 67969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal fatal(); 68069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 68169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal MemberResolver.Method minfo 68269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal = atMethodCallCore(targetClass, mname, args); 68369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr.setMethod(minfo); 68469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 68569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 68669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static void badMethod() throws CompileError { 68769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new CompileError("bad method"); 68869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 68969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 69069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 69169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return a pair of the class declaring the invoked method 69269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * and the MethodInfo of that method. Never null. 69369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 69469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public MemberResolver.Method atMethodCallCore(CtClass targetClass, 69569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String mname, ASTList args) 69669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 69769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 69869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int nargs = getMethodArgsLength(args); 69969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int[] types = new int[nargs]; 70069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int[] dims = new int[nargs]; 70169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String[] cnames = new String[nargs]; 70269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atMethodArgs(args, types, dims, cnames); 70369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 70469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal MemberResolver.Method found 70569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal = resolver.lookupMethod(targetClass, thisClass, thisMethod, 70669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal mname, types, dims, cnames); 70769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (found == null) { 70869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String clazz = targetClass.getName(); 70969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String signature = argTypesToString(types, dims, cnames); 71069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String msg; 71169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (mname.equals(MethodInfo.nameInit)) 71269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal msg = "cannot find constructor " + clazz + signature; 71369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 71469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal msg = mname + signature + " not found in " + clazz; 71569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 71669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new CompileError(msg); 71769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 71869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 71969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String desc = found.info.getDescriptor(); 72069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal setReturnType(desc); 72169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return found; 72269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 72369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 72469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int getMethodArgsLength(ASTList args) { 72569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return ASTList.length(args); 72669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 72769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 72869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atMethodArgs(ASTList args, int[] types, int[] dims, 72969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String[] cnames) throws CompileError { 73069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int i = 0; 73169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (args != null) { 73269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree a = args.head(); 73369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal a.accept(this); 73469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal types[i] = exprType; 73569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal dims[i] = arrayDim; 73669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal cnames[i] = className; 73769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ++i; 73869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal args = args.tail(); 73969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 74069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 74169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 74269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal void setReturnType(String desc) throws CompileError { 74369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int i = desc.indexOf(')'); 74469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (i < 0) 74569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal badMethod(); 74669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 74769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal char c = desc.charAt(++i); 74869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int dim = 0; 74969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (c == '[') { 75069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ++dim; 75169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal c = desc.charAt(++i); 75269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 75369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 75469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = dim; 75569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (c == 'L') { 75669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int j = desc.indexOf(';', i + 1); 75769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (j < 0) 75869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal badMethod(); 75969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 76069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = CLASS; 76169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = desc.substring(i + 1, j); 76269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 76369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 76469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = MemberResolver.descToType(c); 76569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = null; 76669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 76769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 76869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 76969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void atFieldRead(ASTree expr) throws CompileError { 77069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atFieldRead(fieldAccess(expr)); 77169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 77269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 77369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void atFieldRead(CtField f) throws CompileError { 77469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal FieldInfo finfo = f.getFieldInfo2(); 77569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String type = finfo.getDescriptor(); 77669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 77769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int i = 0; 77869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int dim = 0; 77969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal char c = type.charAt(i); 78069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (c == '[') { 78169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ++dim; 78269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal c = type.charAt(++i); 78369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 78469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 78569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = dim; 78669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = MemberResolver.descToType(c); 78769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 78869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (c == 'L') 78969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = type.substring(i + 1, type.indexOf(';', i + 1)); 79069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 79169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = null; 79269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 79369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 79469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* if EXPR is to access a static field, fieldAccess() translates EXPR 79569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * into an expression using '#' (MEMBER). For example, it translates 79669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * java.lang.Integer.TYPE into java.lang.Integer#TYPE. This translation 79769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * speeds up type resolution by MemberCodeGen. 79869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 79969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected CtField fieldAccess(ASTree expr) throws CompileError { 80069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (expr instanceof Member) { 80169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Member mem = (Member)expr; 80269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String name = mem.get(); 80369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 80469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtField f = thisClass.getField(name); 80569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (Modifier.isStatic(f.getModifiers())) 80669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal mem.setField(f); 80769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 80869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return f; 80969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 81069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (NotFoundException e) { 81169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // EXPR might be part of a static member access? 81269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new NoFieldException(name, expr); 81369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 81469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 81569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (expr instanceof Expr) { 81669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Expr e = (Expr)expr; 81769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int op = e.getOperator(); 81869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (op == MEMBER) { 81969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Member mem = (Member)e.oprand2(); 82069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtField f 82169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal = resolver.lookupField(((Symbol)e.oprand1()).get(), mem); 82269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal mem.setField(f); 82369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return f; 82469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 82569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (op == '.') { 82669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 82769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal e.oprand1().accept(this); 82869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 82969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (NoFieldException nfe) { 83069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (nfe.getExpr() != e.oprand1()) 83169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw nfe; 83269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 83369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* EXPR should be a static field. 83469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If EXPR might be part of a qualified class name, 83569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * lookupFieldByJvmName2() throws NoFieldException. 83669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 83769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return fieldAccess2(e, nfe.getField()); 83869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 83969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 84069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CompileError err = null; 84169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 84269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (exprType == CLASS && arrayDim == 0) 84369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return resolver.lookupFieldByJvmName(className, 84469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal (Symbol)e.oprand2()); 84569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 84669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (CompileError ce) { 84769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal err = ce; 84869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 84969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 85069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* If a filed name is the same name as a package's, 85169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * a static member of a class in that package is not 85269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * visible. For example, 85369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 85469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * class Foo { 85569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * int javassist; 85669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * } 85769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 85869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * It is impossible to add the following method: 85969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 86069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * String m() { return javassist.CtClass.intType.toString(); } 86169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 86269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * because javassist is a field name. However, this is 86369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * often inconvenient, this compiler allows it. The following 86469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * code is for that. 86569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 86669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree oprnd1 = e.oprand1(); 86769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (oprnd1 instanceof Symbol) 86869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return fieldAccess2(e, ((Symbol)oprnd1).get()); 86969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 87069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (err != null) 87169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw err; 87269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 87369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 87469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 87569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new CompileError("bad filed access"); 87669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 87769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 87869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private CtField fieldAccess2(Expr e, String jvmClassName) throws CompileError { 87969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Member fname = (Member)e.oprand2(); 88069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtField f = resolver.lookupFieldByJvmName2(jvmClassName, fname, e); 88169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal e.setOperator(MEMBER); 88269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal e.setOprand1(new Symbol(MemberResolver.jvmToJavaName(jvmClassName))); 88369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal fname.setField(f); 88469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return f; 88569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 88669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 88769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atClassObject(Expr expr) throws CompileError { 88869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = CLASS; 88969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = 0; 89069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className =jvmJavaLangClass; 89169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 89269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 89369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atArrayLength(Expr expr) throws CompileError { 89469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr.oprand1().accept(this); 89569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = INT; 89669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = 0; 89769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 89869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 89969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atArrayRead(ASTree array, ASTree index) 90069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 90169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 90269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal array.accept(this); 90369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int type = exprType; 90469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int dim = arrayDim; 90569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String cname = className; 90669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal index.accept(this); 90769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = type; 90869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = dim - 1; 90969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = cname; 91069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 91169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 91269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void atPlusPlus(int token, ASTree oprand, Expr expr) 91369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 91469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 91569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean isPost = oprand == null; // ++i or i++? 91669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (isPost) 91769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal oprand = expr.oprand2(); 91869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 91969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (oprand instanceof Variable) { 92069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Declarator d = ((Variable)oprand).getDeclarator(); 92169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = d.getType(); 92269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = d.getArrayDim(); 92369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 92469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 92569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (oprand instanceof Expr) { 92669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Expr e = (Expr)oprand; 92769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (e.getOperator() == ARRAY) { 92869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atArrayRead(e.oprand1(), e.oprand2()); 92969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // arrayDim should be 0. 93069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int t = exprType; 93169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (t == INT || t == BYTE || t == CHAR || t == SHORT) 93269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = INT; 93369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 93469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return; 93569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 93669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 93769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 93869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atFieldPlusPlus(oprand); 93969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 94069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 94169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 94269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected void atFieldPlusPlus(ASTree oprand) throws CompileError 94369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 94469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtField f = fieldAccess(oprand); 94569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atFieldRead(f); 94669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int t = exprType; 94769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (t == INT || t == BYTE || t == CHAR || t == SHORT) 94869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = INT; 94969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 95069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 95169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atMember(Member mem) throws CompileError { 95269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal atFieldRead(mem); 95369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 95469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 95569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atVariable(Variable v) throws CompileError { 95669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Declarator d = v.getDeclarator(); 95769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = d.getType(); 95869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = d.getArrayDim(); 95969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = d.getClassName(); 96069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 96169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 96269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atKeyword(Keyword k) throws CompileError { 96369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = 0; 96469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int token = k.get(); 96569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal switch (token) { 96669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case TRUE : 96769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case FALSE : 96869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = BOOLEAN; 96969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 97069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case NULL : 97169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = NULL; 97269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 97369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case THIS : 97469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case SUPER : 97569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = CLASS; 97669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (token == THIS) 97769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = getThisName(); 97869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 97969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = getSuperName(); 98069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 98169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal default : 98269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal fatal(); 98369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 98469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 98569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 98669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atStringL(StringL s) throws CompileError { 98769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = CLASS; 98869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = 0; 98969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal className = jvmJavaLangString; 99069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 99169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 99269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atIntConst(IntConst i) throws CompileError { 99369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = 0; 99469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int type = i.getType(); 99569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (type == IntConstant || type == CharConstant) 99669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = (type == IntConstant ? INT : CHAR); 99769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 99869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = LONG; 99969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 100069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 100169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void atDoubleConst(DoubleConst d) throws CompileError { 100269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arrayDim = 0; 100369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (d.getType() == DoubleConstant) 100469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = DOUBLE; 100569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 100669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exprType = FLOAT; 100769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 100869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal} 1009