⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memberresolver.java

📁 Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京技术学院的数学和计算机科学系的 Shigeru Chiba 所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * Javassist, a Java-bytecode translator toolkit. * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License.  Alternatively, the contents of this file may be used under * the terms of the GNU Lesser General Public License Version 2.1 or later. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. */package javassist.compiler;import java.util.List;import java.util.Iterator;import javassist.*;import javassist.bytecode.*;import javassist.compiler.ast.*;/* Code generator methods depending on javassist.* classes. */public class MemberResolver implements TokenId {    private ClassPool classPool;    public MemberResolver(ClassPool cp) {        classPool = cp;    }    public ClassPool getClassPool() { return classPool; }    private static void fatal() throws CompileError {        throw new CompileError("fatal");    }    /**     * @param jvmClassName      a class name.  Not a package name.     */    public void recordPackage(String jvmClassName) {        String classname = jvmToJavaName(jvmClassName);        for (;;) {            int i = classname.lastIndexOf('.');            if (i > 0) {                classname = classname.substring(0, i);                classPool.recordInvalidClassName(classname);            }            else                break;        }    }    public static class Method {        public CtClass declaring;        public MethodInfo info;        public int notmatch;        public Method(CtClass c, MethodInfo i, int n) {            declaring = c;            info = i;            notmatch = n;        }        /**         * Returns true if the invoked method is static.         */        public boolean isStatic() {            int acc = info.getAccessFlags();            return (acc & AccessFlag.STATIC) != 0;        }    }    public Method lookupMethod(CtClass clazz, CtClass currentClass, MethodInfo current,                                String methodName,                                int[] argTypes, int[] argDims,                                String[] argClassNames)        throws CompileError    {        Method maybe = null;        // to enable the creation of a recursively called method        if (current != null && clazz == currentClass)            if (current.getName().equals(methodName)) {                int res = compareSignature(current.getDescriptor(),                                           argTypes, argDims, argClassNames);                if (res != NO) {                    Method r = new Method(clazz, current, res);                    if (res == YES)                        return r;                    else                        maybe = r;                }            }        Method m = lookupMethod(clazz, methodName, argTypes, argDims,                                argClassNames, maybe != null);        if (m != null)            return m;        else            return maybe;    }    private Method lookupMethod(CtClass clazz, String methodName,                               int[] argTypes, int[] argDims,                               String[] argClassNames, boolean onlyExact)        throws CompileError    {        Method maybe = null;        List list = clazz.getClassFile2().getMethods();        int n = list.size();        for (int i = 0; i < n; ++i) {            MethodInfo minfo = (MethodInfo)list.get(i);            if (minfo.getName().equals(methodName)) {                int res = compareSignature(minfo.getDescriptor(),                                           argTypes, argDims, argClassNames);                if (res != NO) {                    Method r = new Method(clazz, minfo, res);                    if (res == YES)                        return r;                    else if (maybe == null || maybe.notmatch > res)                        maybe = r;                }            }        }        if (onlyExact)            maybe = null;        else            onlyExact = maybe != null;        try {            CtClass pclazz = clazz.getSuperclass();            if (pclazz != null) {                Method r = lookupMethod(pclazz, methodName, argTypes,                                        argDims, argClassNames, onlyExact);                if (r != null)                    return r;            }        }        catch (NotFoundException e) {}        int mod = clazz.getModifiers();        if (Modifier.isAbstract(mod) || Modifier.isInterface(mod))            try {                CtClass[] ifs = clazz.getInterfaces();                int size = ifs.length;                for (int i = 0; i < size; ++i) {                    Method r = lookupMethod(ifs[i], methodName,                                            argTypes, argDims, argClassNames,                                            onlyExact);                    if (r != null)                        return r;                }            }            catch (NotFoundException e) {}        return maybe;    }    private static final int YES = 0;    private static final int NO = -1;    /*     * Returns YES if actual parameter types matches the given signature.     *     * argTypes, argDims, and argClassNames represent actual parameters.     *     * This method does not correctly implement the Java method dispatch     * algorithm.     *     * If some of the parameter types exactly match but others are subtypes of     * the corresponding type in the signature, this method returns the number     * of parameter types that do not exactly match.     */    private int compareSignature(String desc, int[] argTypes,                                 int[] argDims, String[] argClassNames)        throws CompileError    {        int result = YES;        int i = 1;        int nArgs = argTypes.length;        if (nArgs != Descriptor.numOfParameters(desc))            return NO;        int len = desc.length();        for (int n = 0; i < len; ++n) {            char c = desc.charAt(i++);            if (c == ')')                return (n == nArgs ? result : NO);            else if (n >= nArgs)                return NO;            int dim = 0;            while (c == '[') {                ++dim;                c = desc.charAt(i++);            }            if (argTypes[n] == NULL) {                if (dim == 0 && c != 'L')                    return NO;                if (c == 'L')                    i = desc.indexOf(';', i) + 1;            }            else if (argDims[n] != dim) {                if (!(dim == 0 && c == 'L'                      && desc.startsWith("java/lang/Object;", i)))                    return NO;                // if the thread reaches here, c must be 'L'.                i = desc.indexOf(';', i) + 1;                result++;                if (i <= 0)                    return NO;  // invalid descriptor?            }            else if (c == 'L') {        // not compare                int j = desc.indexOf(';', i);                if (j < 0 || argTypes[n] != CLASS)                    return NO;                String cname = desc.substring(i, j);                if (!cname.equals(argClassNames[n])) {                    CtClass clazz = lookupClassByJvmName(argClassNames[n]);                    try {                        if (clazz.subtypeOf(lookupClassByJvmName(cname)))                            result++;                        else                            return NO;                    }                    catch (NotFoundException e) {                        result++; // should be NO?                    }                }                i = j + 1;            }            else {                int t = descToType(c);                int at = argTypes[n];                if (t != at)                    if (t == INT                        && (at == SHORT || at == BYTE || at == CHAR))                        result++;                    else                        return NO;            }        }        return NO;    }    /**     * Only used by fieldAccess() in MemberCodeGen and TypeChecker.     *     * @param jvmClassName  a JVM class name.  e.g. java/lang/String     */    public CtField lookupFieldByJvmName2(String jvmClassName, Symbol fieldSym,                                         ASTree expr) throws NoFieldException    {        String field = fieldSym.get();        CtClass cc = null;        try {            cc = lookupClass(jvmToJavaName(jvmClassName), true);        }        catch (CompileError e) {            // EXPR might be part of a qualified class name.            throw new NoFieldException(jvmClassName + "/" + field, expr);        }        try {            return cc.getField(field);        }        catch (NotFoundException e) {            // maybe an inner class.            jvmClassName = javaToJvmName(cc.getName());

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -