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