resolve.java

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

JAVA
1,519
字号
                        return null;                formals = formals.tail;                actuals = actuals.tail;            }            mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes);        } else if (mt.tag == FORALL) {            ForAll pmt = (ForAll) mt;            List<Type> tvars1 = types.newInstances(pmt.tvars);            tvars = tvars.appendList(tvars1);            mt = types.subst(pmt.qtype, pmt.tvars, tvars1);        }        // find out whether we need to go the slow route via infer        boolean instNeeded = tvars.tail != null/*inlined: tvars.nonEmpty()*/;        for (List<Type> l = argtypes;             l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;             l = l.tail) {            if (l.head.tag == FORALL) instNeeded = true;        }        if (instNeeded)            return            infer.instantiateMethod(tvars,                                    (MethodType)mt,                                    argtypes,                                    allowBoxing,                                    useVarargs,                                    warn);        return            argumentsAcceptable(argtypes, mt.getParameterTypes(),                                allowBoxing, useVarargs, warn)            ? mt            : null;    }    /** Same but returns null instead throwing a NoInstanceException     */    Type instantiate(Env<AttrContext> env,                     Type site,                     Symbol m,                     List<Type> argtypes,                     List<Type> typeargtypes,                     boolean allowBoxing,                     boolean useVarargs,                     Warner warn) {        try {            return rawInstantiate(env, site, m, argtypes, typeargtypes,                                  allowBoxing, useVarargs, warn);        } catch (Infer.NoInstanceException ex) {            return null;        }    }    /** Check if a parameter list accepts a list of args.     */    boolean argumentsAcceptable(List<Type> argtypes,                                List<Type> formals,                                boolean allowBoxing,                                boolean useVarargs,                                Warner warn) {        Type varargsFormal = useVarargs ? formals.last() : null;        while (argtypes.nonEmpty() && formals.head != varargsFormal) {            boolean works = allowBoxing                ? types.isConvertible(argtypes.head, formals.head, warn)                : types.isSubtypeUnchecked(argtypes.head, formals.head, warn);            if (!works) return false;            argtypes = argtypes.tail;            formals = formals.tail;        }        if (formals.head != varargsFormal) return false; // not enough args        if (!useVarargs)            return argtypes.isEmpty();        Type elt = types.elemtype(varargsFormal);        while (argtypes.nonEmpty()) {            if (!types.isConvertible(argtypes.head, elt, warn))                return false;            argtypes = argtypes.tail;        }        return true;    }/* *************************************************************************** *  Symbol lookup *  the following naming conventions for arguments are used * *       env      is the environment where the symbol was mentioned *       site     is the type of which the symbol is a member *       name     is the symbol's name *                if no arguments are given *       argtypes are the value arguments, if we search for a method * *  If no symbol was found, a ResolveError detailing the problem is returned. ****************************************************************************/    /** Find field. Synthetic fields are always skipped.     *  @param env     The current environment.     *  @param site    The original type from where the selection takes place.     *  @param name    The name of the field.     *  @param c       The class to search for the field. This is always     *                 a superclass or implemented interface of site's class.     */    Symbol findField(Env<AttrContext> env,                     Type site,                     Name name,                     TypeSymbol c) {        Symbol bestSoFar = varNotFound;        Symbol sym;        Scope.Entry e = c.members().lookup(name);        while (e.scope != null) {            if (e.sym.kind == VAR && (e.sym.flags_field & SYNTHETIC) == 0) {                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 = findField(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 = findField(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;    }    /** Resolve a field identifier, throw a fatal error if not found.     *  @param pos       The position to use for error reporting.     *  @param env       The environment current at the method invocation.     *  @param site      The type of the qualifying expression, in which     *                   identifier is searched.     *  @param name      The identifier's name.     */    public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env,                                          Type site, Name name) {        Symbol sym = findField(env, site, name, site.tsym);        if (sym.kind == VAR) return (VarSymbol)sym;        else throw new FatalError(                 JCDiagnostic.fragment("fatal.err.cant.locate.field",                                name));    }    /** Find unqualified variable or field with given name.     *  Synthetic fields always skipped.     *  @param env     The current environment.     *  @param name    The name of the variable or field.     */    Symbol findVar(Env<AttrContext> env, Name name) {        Symbol bestSoFar = varNotFound;        Symbol sym;        Env<AttrContext> env1 = env;        boolean staticOnly = false;        while (env1.outer != null) {            if (isStatic(env1)) staticOnly = true;            Scope.Entry e = env1.info.scope.lookup(name);            while (e.scope != null &&                   (e.sym.kind != VAR ||                    (e.sym.flags_field & SYNTHETIC) != 0))                e = e.next();            sym = (e.scope != null)                ? e.sym                : findField(                    env1, env1.enclClass.sym.type, name, env1.enclClass.sym);            if (sym.exists()) {                if (staticOnly &&                    sym.kind == VAR &&                    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 = findField(env, syms.predefClass.type, name, syms.predefClass);        if (sym.exists())            return sym;        if (bestSoFar.exists())            return bestSoFar;        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 == VAR) {                if (e.sym.owner.type != origin)                    sym = sym.clone(e.getOrigin().owner);                return isAccessible(env, origin, sym)                    ? sym : new AccessError(env, origin, sym);            }        }        Symbol origin = null;        e = env.toplevel.starImportScope.lookup(name);        for (; e.scope != null; e = e.next()) {            sym = e.sym;            if (sym.kind != VAR)                continue;            // invariant: sym.kind == VAR            if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner)                return new AmbiguityError(bestSoFar, sym);            else if (bestSoFar.kind >= VAR) {                origin = e.getOrigin().owner;                bestSoFar = isAccessible(env, origin.type, sym)                    ? sym : new AccessError(env, origin.type, sym);            }        }        if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type)            return bestSoFar.clone(origin);        else            return bestSoFar;    }    Warner noteWarner = new Warner();    /** Select the best method for a call site among two choices.     *  @param env              The current environment.     *  @param site             The original type from where the     *                          selection takes place.     *  @param argtypes         The invocation's value arguments,     *  @param typeargtypes     The invocation's type arguments,     *  @param sym              Proposed new best match.     *  @param bestSoFar        Previously found best match.     *  @param allowBoxing Allow boxing conversions of arguments.     *  @param useVarargs Box trailing arguments into an array for varargs.     */    Symbol selectBest(Env<AttrContext> env,                      Type site,                      List<Type> argtypes,                      List<Type> typeargtypes,                      Symbol sym,                      Symbol bestSoFar,                      boolean allowBoxing,                      boolean useVarargs,                      boolean operator) {        if (sym.kind == ERR) return bestSoFar;        if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;        assert sym.kind < AMBIGUOUS;        try {            if (rawInstantiate(env, site, sym, argtypes, typeargtypes,                               allowBoxing, useVarargs, Warner.noWarnings) == null) {                // inapplicable                switch (bestSoFar.kind) {                case ABSENT_MTH: return wrongMethod.setWrongSym(sym);                case WRONG_MTH: return wrongMethods;                default: return bestSoFar;                }            }        } catch (Infer.NoInstanceException ex) {            switch (bestSoFar.kind) {            case ABSENT_MTH:                return wrongMethod.setWrongSym(sym, ex.getDiagnostic());            case WRONG_MTH:                return wrongMethods;            default:                return bestSoFar;            }        }        if (!isAccessible(env, site, sym)) {            return (bestSoFar.kind == ABSENT_MTH)                ? new AccessError(env, site, sym)                : bestSoFar;        }        return (bestSoFar.kind > AMBIGUOUS)            ? sym            : mostSpecific(sym, bestSoFar, env, site,                           allowBoxing && operator, useVarargs);    }    /* Return the most specific of the two methods for a call,     *  given that both are accessible and applicable.     *  @param m1               A new candidate for most specific.     *  @param m2               The previous most specific candidate.     *  @param env              The current environment.     *  @param site             The original type from where the selection     *                          takes place.     *  @param allowBoxing Allow boxing conversions of arguments.     *  @param useVarargs Box trailing arguments into an array for varargs.     */    Symbol mostSpecific(Symbol m1,                        Symbol m2,                        Env<AttrContext> env,                        Type site,                        boolean allowBoxing,                        boolean useVarargs) {        switch (m2.kind) {        case MTH:            if (m1 == m2) return m1;            Type mt1 = types.memberType(site, m1);            noteWarner.unchecked = false;            boolean m1SignatureMoreSpecific =                (instantiate(env, site, m2, types.lowerBoundArgtypes(mt1), null,

⌨️ 快捷键说明

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