resolve.java

来自「是一款用JAVA 编写的编译器 具有很强的编译功能」· Java 代码 · 共 1,519 行 · 第 1/5 页

JAVA
1,519
字号
                             allowBoxing, false, noteWarner) != null ||                 useVarargs && instantiate(env, site, m2, types.lowerBoundArgtypes(mt1), null,                                           allowBoxing, true, noteWarner) != null) &&                !noteWarner.unchecked;            Type mt2 = types.memberType(site, m2);            noteWarner.unchecked = false;            boolean m2SignatureMoreSpecific =                (instantiate(env, site, m1, types.lowerBoundArgtypes(mt2), null,                             allowBoxing, false, noteWarner) != null ||                 useVarargs && instantiate(env, site, m1, types.lowerBoundArgtypes(mt2), null,                                           allowBoxing, true, noteWarner) != null) &&                !noteWarner.unchecked;            if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {                if (!types.overrideEquivalent(mt1, mt2))                    return new AmbiguityError(m1, m2);                // same signature; select (a) the non-bridge method, or                // (b) the one that overrides the other, or (c) the concrete                // one, or (d) merge both abstract signatures                if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE)) {                    return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;                }                // if one overrides or hides the other, use it                TypeSymbol m1Owner = (TypeSymbol)m1.owner;                TypeSymbol m2Owner = (TypeSymbol)m2.owner;                if (types.asSuper(m1Owner.type, m2Owner) != null &&                    ((m1.owner.flags_field & INTERFACE) == 0 ||                     (m2.owner.flags_field & INTERFACE) != 0) &&                    m1.overrides(m2, m1Owner, types, false))                    return m1;                if (types.asSuper(m2Owner.type, m1Owner) != null &&                    ((m2.owner.flags_field & INTERFACE) == 0 ||                     (m1.owner.flags_field & INTERFACE) != 0) &&                    m2.overrides(m1, m2Owner, types, false))                    return m2;                boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;                boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;                if (m1Abstract && !m2Abstract) return m2;                if (m2Abstract && !m1Abstract) return m1;                // both abstract or both concrete                if (!m1Abstract && !m2Abstract)                    return new AmbiguityError(m1, m2);                // check for same erasure                if (!types.isSameType(m1.erasure(types), m2.erasure(types)))                    return new AmbiguityError(m1, m2);                // both abstract, neither overridden; merge throws clause and result type                Symbol result;                Type result2 = mt2.getReturnType();;                if (mt2.tag == FORALL)                    result2 = types.subst(result2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars);                if (types.isSubtype(mt1.getReturnType(), result2)) {                    result = m1;                } else if (types.isSubtype(result2, mt1.getReturnType())) {                    result = m2;                } else {                    // Theoretically, this can't happen, but it is possible                    // due to error recovery or mixing incompatible class files                    return new AmbiguityError(m1, m2);                }                result = result.clone(result.owner);                result.type = (Type)result.type.clone();                result.type.setThrown(chk.intersect(mt1.getThrownTypes(),                                                    mt2.getThrownTypes()));                return result;            }            if (m1SignatureMoreSpecific) return m1;            if (m2SignatureMoreSpecific) return m2;            return new AmbiguityError(m1, m2);        case AMBIGUOUS:            AmbiguityError e = (AmbiguityError)m2;            Symbol err1 = mostSpecific(m1, e.sym1, env, site, allowBoxing, useVarargs);            Symbol err2 = mostSpecific(m1, e.sym2, env, site, allowBoxing, useVarargs);            if (err1 == err2) return err1;            if (err1 == e.sym1 && err2 == e.sym2) return m2;            if (err1 instanceof AmbiguityError &&                err2 instanceof AmbiguityError &&                ((AmbiguityError)err1).sym1 == ((AmbiguityError)err2).sym1)                return new AmbiguityError(m1, m2);            else                return new AmbiguityError(err1, err2);        default:            throw new AssertionError();        }    }    /** Find best qualified method matching given name, type and value     *  arguments.     *  @param env       The current environment.     *  @param site      The original type from where the selection     *                   takes place.     *  @param name      The method's name.     *  @param argtypes  The method's value arguments.     *  @param typeargtypes The method's type arguments     *  @param allowBoxing Allow boxing conversions of arguments.     *  @param useVarargs Box trailing arguments into an array for varargs.     */    Symbol findMethod(Env<AttrContext> env,                      Type site,                      Name name,                      List<Type> argtypes,                      List<Type> typeargtypes,                      boolean allowBoxing,                      boolean useVarargs,                      boolean operator) {        return findMethod(env,                          site,                          name,                          argtypes,                          typeargtypes,                          site.tsym.type,                          true,                          methodNotFound,                          allowBoxing,                          useVarargs,                          operator);    }    // where    private Symbol findMethod(Env<AttrContext> env,                              Type site,                              Name name,                              List<Type> argtypes,                              List<Type> typeargtypes,                              Type intype,                              boolean abstractok,                              Symbol bestSoFar,                              boolean allowBoxing,                              boolean useVarargs,                              boolean operator) {        for (Type ct = intype; ct.tag == CLASS; ct = types.supertype(ct)) {            ClassSymbol c = (ClassSymbol)ct.tsym;            if ((c.flags() & (ABSTRACT | INTERFACE)) == 0)                abstractok = false;            for (Scope.Entry e = c.members().lookup(name);                 e.scope != null;                 e = e.next()) {                //- System.out.println(" e " + e.sym);                if (e.sym.kind == MTH &&                    (e.sym.flags_field & SYNTHETIC) == 0) {                    bestSoFar = selectBest(env, site, argtypes, typeargtypes,                                           e.sym, bestSoFar,                                           allowBoxing,                                           useVarargs,                                           operator);                }            }            //- System.out.println(" - " + bestSoFar);            if (abstractok) {                Symbol concrete = methodNotFound;                if ((bestSoFar.flags() & ABSTRACT) == 0)                    concrete = bestSoFar;                for (List<Type> l = types.interfaces(c.type);                     l.nonEmpty();                     l = l.tail) {                    bestSoFar = findMethod(env, site, name, argtypes,                                           typeargtypes,                                           l.head, abstractok, bestSoFar,                                           allowBoxing, useVarargs, operator);                }                if (concrete != bestSoFar &&                    concrete.kind < ERR  && bestSoFar.kind < ERR &&                    types.isSubSignature(concrete.type, bestSoFar.type))                    bestSoFar = concrete;            }        }        return bestSoFar;    }    /** Find unqualified method matching given name, type and value arguments.     *  @param env       The current environment.     *  @param name      The method's name.     *  @param argtypes  The method's value arguments.     *  @param typeargtypes  The method's type arguments.     *  @param allowBoxing Allow boxing conversions of arguments.     *  @param useVarargs Box trailing arguments into an array for varargs.     */    Symbol findFun(Env<AttrContext> env, Name name,                   List<Type> argtypes, List<Type> typeargtypes,                   boolean allowBoxing, boolean useVarargs) {        Symbol bestSoFar = methodNotFound;        Symbol sym;        Env<AttrContext> env1 = env;        boolean staticOnly = false;        while (env1.outer != null) {            if (isStatic(env1)) staticOnly = true;            sym = findMethod(                env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,                allowBoxing, useVarargs, false);            if (sym.exists()) {                if (staticOnly &&                    sym.kind == MTH &&                    sym.owner.kind == TYP &&                    (sym.flags() & STATIC) == 0) return new StaticError(sym);                else return sym;            } else if (sym.kind < bestSoFar.kind) {                bestSoFar = sym;            }            if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;            env1 = env1.outer;        }        sym = findMethod(env, syms.predefClass.type, name, argtypes,                         typeargtypes, allowBoxing, useVarargs, false);        if (sym.exists())            return sym;        Scope.Entry e = env.toplevel.namedImportScope.lookup(name);        for (; e.scope != null; e = e.next()) {            sym = e.sym;            Type origin = e.getOrigin().owner.type;            if (sym.kind == MTH) {                if (e.sym.owner.type != origin)                    sym = sym.clone(e.getOrigin().owner);                if (!isAccessible(env, origin, sym))                    sym = new AccessError(env, origin, sym);                bestSoFar = selectBest(env, origin,                                       argtypes, typeargtypes,                                       sym, bestSoFar,                                       allowBoxing, useVarargs, false);            }        }        if (bestSoFar.exists())            return bestSoFar;        e = env.toplevel.starImportScope.lookup(name);        for (; e.scope != null; e = e.next()) {            sym = e.sym;            Type origin = e.getOrigin().owner.type;            if (sym.kind == MTH) {                if (e.sym.owner.type != origin)                    sym = sym.clone(e.getOrigin().owner);                if (!isAccessible(env, origin, sym))                    sym = new AccessError(env, origin, sym);                bestSoFar = selectBest(env, origin,                                       argtypes, typeargtypes,                                       sym, bestSoFar,                                       allowBoxing, useVarargs, false);            }        }        return bestSoFar;    }    /** Load toplevel or member class with given fully qualified name and     *  verify that it is accessible.     *  @param env       The current environment.     *  @param name      The fully qualified name of the class to be loaded.     */    Symbol loadClass(Env<AttrContext> env, Name name) {        try {            ClassSymbol c = reader.loadClass(name);            return isAccessible(env, c) ? c : new AccessError(c);        } catch (ClassReader.BadClassFile err) {            throw err;        } catch (CompletionFailure ex) {            return typeNotFound;        }    }    /** Find qualified member type.     *  @param env       The current environment.     *  @param site      The original type from where the selection takes     *                   place.     *  @param name      The type's name.     *  @param c         The class to search for the member type. This is     *                   always a superclass or implemented interface of     *                   site's class.     */    Symbol findMemberType(Env<AttrContext> env,                          Type site,                          Name name,                          TypeSymbol c) {        Symbol bestSoFar = typeNotFound;        Symbol sym;        Scope.Entry e = c.members().lookup(name);        while (e.scope != null) {            if (e.sym.kind == TYP) {                return isAccessible(env, site, e.sym)                    ? e.sym                    : new AccessError(env, site, e.sym);            }            e = e.next();        }        Type st = types.supertype(c.type);        if (st != null && st.tag == CLASS) {            sym = findMemberType(env, site, name, st.tsym);            if (sym.kind < bestSoFar.kind) bestSoFar = sym;        }        for (List<Type> l = types.interfaces(c.type);             bestSoFar.kind != AMBIGUOUS && l.nonEmpty();             l = l.tail) {            sym = findMemberType(env, site, name, l.head.tsym);            if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&                sym.owner != bestSoFar.owner)                bestSoFar = new AmbiguityError(bestSoFar, sym);            else if (sym.kind < bestSoFar.kind)                bestSoFar = sym;        }        return bestSoFar;    }    /** Find a global type in given scope and load corresponding class.     *  @param env       The current environment.     *  @param scope     The scope in which to look for the type.     *  @param name      The type's name.     */    Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {

⌨️ 快捷键说明

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