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 java.util.List;
1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.Iterator;
2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.*;
2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.*;
2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.compiler.ast.*;
2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/* Code generator methods depending on javassist.* classes.
2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class MemberResolver implements TokenId {
2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private ClassPool classPool;
2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public MemberResolver(ClassPool cp) {
3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        classPool = cp;
3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public ClassPool getClassPool() { return classPool; }
3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static void fatal() throws CompileError {
3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throw new CompileError("fatal");
3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param jvmClassName      a class name.  Not a package name.
4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public void recordPackage(String jvmClassName) {
4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String classname = jvmToJavaName(jvmClassName);
4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        for (;;) {
4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int i = classname.lastIndexOf('.');
4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (i > 0) {
4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                classname = classname.substring(0, i);
4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                classPool.recordInvalidClassName(classname);
4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else
5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static class Method {
5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public CtClass declaring;
5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public MethodInfo info;
5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public int notmatch;
5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public Method(CtClass c, MethodInfo i, int n) {
6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            declaring = c;
6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            info = i;
6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            notmatch = n;
6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        /**
6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         * Returns true if the invoked method is static.
6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         */
6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public boolean isStatic() {
7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int acc = info.getAccessFlags();
7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return (acc & AccessFlag.STATIC) != 0;
7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public Method lookupMethod(CtClass clazz, CtClass currentClass, MethodInfo current,
7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                String methodName,
7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                int[] argTypes, int[] argDims,
7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                String[] argClassNames)
7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws CompileError
8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Method maybe = null;
8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // to enable the creation of a recursively called method
8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (current != null && clazz == currentClass)
8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (current.getName().equals(methodName)) {
8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                int res = compareSignature(current.getDescriptor(),
8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                           argTypes, argDims, argClassNames);
8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (res != NO) {
8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    Method r = new Method(clazz, current, res);
8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    if (res == YES)
9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        return r;
9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    else
9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        maybe = r;
9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Method m = lookupMethod(clazz, methodName, argTypes, argDims,
9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                argClassNames, maybe != null);
9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (m != null)
9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return m;
10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else
10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return maybe;
10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private Method lookupMethod(CtClass clazz, String methodName,
10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                               int[] argTypes, int[] argDims,
10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                               String[] argClassNames, boolean onlyExact)
10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws CompileError
10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Method maybe = null;
11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        ClassFile cf = clazz.getClassFile2();
11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // If the class is an array type, the class file is null.
11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // If so, search the super class java.lang.Object for clone() etc.
11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (cf != null) {
11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            List list = cf.getMethods();
11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int n = list.size();
11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            for (int i = 0; i < n; ++i) {
11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                MethodInfo minfo = (MethodInfo)list.get(i);
11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (minfo.getName().equals(methodName)) {
11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    int res = compareSignature(minfo.getDescriptor(),
12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                           argTypes, argDims, argClassNames);
12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    if (res != NO) {
12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        Method r = new Method(clazz, minfo, res);
12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        if (res == YES)
12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                            return r;
12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        else if (maybe == null || maybe.notmatch > res)
12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                            maybe = r;
12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    }
12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (onlyExact)
13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            maybe = null;
13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else
13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            onlyExact = maybe != null;
13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int mod = clazz.getModifiers();
13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        boolean isIntf = Modifier.isInterface(mod);
13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            // skip searching java.lang.Object if clazz is an interface type.
14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (!isIntf) {
14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                CtClass pclazz = clazz.getSuperclass();
14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (pclazz != null) {
14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    Method r = lookupMethod(pclazz, methodName, argTypes,
14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                            argDims, argClassNames, onlyExact);
14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    if (r != null)
14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        return r;
14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (NotFoundException e) {}
15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (isIntf || Modifier.isAbstract(mod))
15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            try {
15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                CtClass[] ifs = clazz.getInterfaces();
15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                int size = ifs.length;
15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                for (int i = 0; i < size; ++i) {
15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    Method r = lookupMethod(ifs[i], methodName,
15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                            argTypes, argDims, argClassNames,
16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                            onlyExact);
16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    if (r != null)
16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        return r;
16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (isIntf) {
16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    // finally search java.lang.Object.
16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    CtClass pclazz = clazz.getSuperclass();
16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    if (pclazz != null) {
16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        Method r = lookupMethod(pclazz, methodName, argTypes,
17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                                argDims, argClassNames, onlyExact);
17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        if (r != null)
17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                            return r;
17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    }
17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            catch (NotFoundException e) {}
17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return maybe;
17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static final int YES = 0;
18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static final int NO = -1;
18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /*
18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Returns YES if actual parameter types matches the given signature.
18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * argTypes, argDims, and argClassNames represent actual parameters.
18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * This method does not correctly implement the Java method dispatch
19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * algorithm.
19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * If some of the parameter types exactly match but others are subtypes of
19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the corresponding type in the signature, this method returns the number
19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * of parameter types that do not exactly match.
19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int compareSignature(String desc, int[] argTypes,
19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                 int[] argDims, String[] argClassNames)
19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws CompileError
19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int result = YES;
20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int i = 1;
20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int nArgs = argTypes.length;
20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (nArgs != Descriptor.numOfParameters(desc))
20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return NO;
20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int len = desc.length();
20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        for (int n = 0; i < len; ++n) {
20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            char c = desc.charAt(i++);
20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (c == ')')
21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return (n == nArgs ? result : NO);
21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else if (n >= nArgs)
21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return NO;
21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int dim = 0;
21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            while (c == '[') {
21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                ++dim;
21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                c = desc.charAt(i++);
21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (argTypes[n] == NULL) {
22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (dim == 0 && c != 'L')
22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return NO;
22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (c == 'L')
22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    i = desc.indexOf(';', i) + 1;
22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else if (argDims[n] != dim) {
22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (!(dim == 0 && c == 'L'
22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                      && desc.startsWith("java/lang/Object;", i)))
23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return NO;
23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                // if the thread reaches here, c must be 'L'.
23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                i = desc.indexOf(';', i) + 1;
23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                result++;
23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (i <= 0)
23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return NO;  // invalid descriptor?
23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else if (c == 'L') {        // not compare
23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                int j = desc.indexOf(';', i);
24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (j < 0 || argTypes[n] != CLASS)
24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return NO;
24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                String cname = desc.substring(i, j);
24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (!cname.equals(argClassNames[n])) {
24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    CtClass clazz = lookupClassByJvmName(argClassNames[n]);
24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    try {
24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        if (clazz.subtypeOf(lookupClassByJvmName(cname)))
24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                            result++;
24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        else
25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                            return NO;
25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    }
25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    catch (NotFoundException e) {
25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        result++; // should be NO?
25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    }
25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                i = j + 1;
25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else {
26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                int t = descToType(c);
26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                int at = argTypes[n];
26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (t != at)
26369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    if (t == INT
26469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        && (at == SHORT || at == BYTE || at == CHAR))
26569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        result++;
26669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    else
26769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        return NO;
26869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
26969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
27069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
27169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return NO;
27269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
27369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
27469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
27569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Only used by fieldAccess() in MemberCodeGen and TypeChecker.
27669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
27769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param jvmClassName  a JVM class name.  e.g. java/lang/String
27869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
27969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtField lookupFieldByJvmName2(String jvmClassName, Symbol fieldSym,
28069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                         ASTree expr) throws NoFieldException
28169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
28269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String field = fieldSym.get();
28369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass cc = null;
28469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
28569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            cc = lookupClass(jvmToJavaName(jvmClassName), true);
28669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
28769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (CompileError e) {
28869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            // EXPR might be part of a qualified class name.
28969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new NoFieldException(jvmClassName + "/" + field, expr);
29069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
29169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
29269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
29369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return cc.getField(field);
29469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
29569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (NotFoundException e) {
29669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            // maybe an inner class.
29769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            jvmClassName = javaToJvmName(cc.getName());
29869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new NoFieldException(jvmClassName + "$" + field, expr);
29969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
30069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
30169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
30269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
30369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param jvmClassName  a JVM class name.  e.g. java/lang/String
30469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
30569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtField lookupFieldByJvmName(String jvmClassName, Symbol fieldName)
30669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws CompileError
30769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
30869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return lookupField(jvmToJavaName(jvmClassName), fieldName);
30969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
31069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
31169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
31269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param name      a qualified class name. e.g. java.lang.String
31369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
31469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtField lookupField(String className, Symbol fieldName)
31569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws CompileError
31669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
31769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass cc = lookupClass(className, false);
31869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
31969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return cc.getField(fieldName.get());
32069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
32169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (NotFoundException e) {}
32269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throw new CompileError("no such field: " + fieldName.get());
32369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
32469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
32569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtClass lookupClassByName(ASTList name) throws CompileError {
32669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return lookupClass(Declarator.astToClassName(name, '.'), false);
32769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
32869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
32969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtClass lookupClassByJvmName(String jvmName) throws CompileError {
33069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return lookupClass(jvmToJavaName(jvmName), false);
33169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
33269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
33369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtClass lookupClass(Declarator decl) throws CompileError {
33469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return lookupClass(decl.getType(), decl.getArrayDim(),
33569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                           decl.getClassName());
33669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
33769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
33869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
33969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @parma classname         jvm class name.
34069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
34169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtClass lookupClass(int type, int dim, String classname)
34269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws CompileError
34369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
34469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String cname = "";
34569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass clazz;
34669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (type == CLASS) {
34769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            clazz = lookupClassByJvmName(classname);
34869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (dim > 0)
34969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                cname = clazz.getName();
35069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else
35169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return clazz;
35269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
35369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else
35469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            cname = getTypeName(type);
35569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
35669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        while (dim-- > 0)
35769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            cname += "[]";
35869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
35969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return lookupClass(cname, false);
36069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
36169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
36269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /*
36369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * type cannot be CLASS
36469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
36569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    static String getTypeName(int type) throws CompileError {
36669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String cname = "";
36769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (type) {
36869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case BOOLEAN :
36969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            cname = "boolean";
37069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
37169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case CHAR :
37269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            cname = "char";
37369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
37469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case BYTE :
37569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            cname = "byte";
37669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
37769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case SHORT :
37869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            cname = "short";
37969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
38069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case INT :
38169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            cname = "int";
38269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
38369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case LONG :
38469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            cname = "long";
38569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
38669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case FLOAT :
38769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            cname = "float";
38869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
38969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case DOUBLE :
39069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            cname = "double";
39169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
39269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case VOID :
39369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            cname = "void";
39469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
39569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        default :
39669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            fatal();
39769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
39869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
39969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return cname;
40069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
40169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
40269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
40369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param name      a qualified class name. e.g. java.lang.String
40469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
40569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtClass lookupClass(String name, boolean notCheckInner)
40669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws CompileError
40769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
40869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
40969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return lookupClass0(name, notCheckInner);
41069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
41169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (NotFoundException e) {
41269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return searchImports(name);
41369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
41469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
41569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
41669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private CtClass searchImports(String orgName)
41769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws CompileError
41869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
41969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (orgName.indexOf('.') < 0) {
42069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            Iterator it = classPool.getImportedPackages();
42169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            while (it.hasNext()) {
42269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                String pac = (String)it.next();
42369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                String fqName = pac + '.' + orgName;
42469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                try {
42569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    CtClass cc = classPool.get(fqName);
42669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    // if the class is found,
42769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    classPool.recordInvalidClassName(orgName);
42869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return cc;
42969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
43069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                catch (NotFoundException e) {
43169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    classPool.recordInvalidClassName(fqName);
43269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    try {
43369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        if (pac.endsWith("." + orgName)) {
43469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                            CtClass cc = classPool.get(pac);
43569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                            // if the class is found,
43669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                            classPool.recordInvalidClassName(orgName);
43769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                            return cc;
43869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        }
43969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    }
44069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    catch (NotFoundException e2) {
44169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        classPool.recordInvalidClassName(pac);
44269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    }
44369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
44469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
44569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
44669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
44769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throw new CompileError("no such class: " + orgName);
44869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
44969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
45069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private CtClass lookupClass0(String classname, boolean notCheckInner)
45169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws NotFoundException
45269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
45369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass cc = null;
45469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        do {
45569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            try {
45669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                cc = classPool.get(classname);
45769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
45869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            catch (NotFoundException e) {
45969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                int i = classname.lastIndexOf('.');
46069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (notCheckInner || i < 0)
46169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    throw e;
46269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                else {
46369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    StringBuffer sbuf = new StringBuffer(classname);
46469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    sbuf.setCharAt(i, '$');
46569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    classname = sbuf.toString();
46669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
46769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
46869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        } while (cc == null);
46969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return cc;
47069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
47169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
47269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /* Converts a class name into a JVM-internal representation.
47369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
47469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * It may also expand a simple class name to java.lang.*.
47569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * For example, this converts Object into java/lang/Object.
47669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
47769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public String resolveClassName(ASTList name) throws CompileError {
47869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (name == null)
47969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return null;
48069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else
48169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return javaToJvmName(lookupClassByName(name).getName());
48269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
48369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
48469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /* Expands a simple class name to java.lang.*.
48569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * For example, this converts Object into java/lang/Object.
48669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
48769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public String resolveJvmClassName(String jvmName) throws CompileError {
48869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (jvmName == null)
48969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return null;
49069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else
49169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return javaToJvmName(lookupClassByJvmName(jvmName).getName());
49269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
49369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
49469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static CtClass getSuperclass(CtClass c) throws CompileError {
49569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
49669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            CtClass sc = c.getSuperclass();
49769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (sc != null)
49869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return sc;
49969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
50069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (NotFoundException e) {}
50169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throw new CompileError("cannot find the super class of "
50269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                               + c.getName());
50369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
50469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
50569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static String javaToJvmName(String classname) {
50669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return classname.replace('.', '/');
50769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
50869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
50969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static String jvmToJavaName(String classname) {
51069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return classname.replace('/', '.');
51169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
51269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
51369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static int descToType(char c) throws CompileError {
51469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (c) {
51569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case 'Z' :
51669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return BOOLEAN;
51769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case 'C' :
51869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return CHAR;
51969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case 'B' :
52069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return  BYTE;
52169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case 'S' :
52269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return SHORT;
52369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case 'I' :
52469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return INT;
52569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case 'J' :
52669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return LONG;
52769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case 'F' :
52869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return FLOAT;
52969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case 'D' :
53069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return DOUBLE;
53169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case 'V' :
53269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return VOID;
53369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case 'L' :
53469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case '[' :
53569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return CLASS;
53669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        default :
53769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            fatal();
53869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return VOID;    // never reach here
53969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
54069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
54169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
54269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static int getModifiers(ASTList mods) {
54369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int m = 0;
54469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        while (mods != null) {
54569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            Keyword k = (Keyword)mods.head();
54669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            mods = mods.tail();
54769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            switch (k.get()) {
54869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case STATIC :
54969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                m |= Modifier.STATIC;
55069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
55169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FINAL :
55269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                m |= Modifier.FINAL;
55369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
55469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case SYNCHRONIZED :
55569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                m |= Modifier.SYNCHRONIZED;
55669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
55769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ABSTRACT :
55869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                m |= Modifier.ABSTRACT;
55969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
56069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case PUBLIC :
56169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                m |= Modifier.PUBLIC;
56269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
56369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case PROTECTED :
56469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                m |= Modifier.PROTECTED;
56569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
56669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case PRIVATE :
56769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                m |= Modifier.PRIVATE;
56869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
56969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case VOLATILE :
57069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                m |= Modifier.VOLATILE;
57169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
57269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case TRANSIENT :
57369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                m |= Modifier.TRANSIENT;
57469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
57569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case STRICT :
57669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                m |= Modifier.STRICT;
57769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
57869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
57969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
58069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
58169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return m;
58269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
58369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal}
584