resolve.java

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

JAVA
1,519
字号
        Symbol bestSoFar = typeNotFound;        for (Scope.Entry e = scope.lookup(name); e.scope != null; e = e.next()) {            Symbol sym = loadClass(env, e.sym.flatName());            if (bestSoFar.kind == TYP && sym.kind == TYP &&                bestSoFar != sym)                return new AmbiguityError(bestSoFar, sym);            else if (sym.kind < bestSoFar.kind)                bestSoFar = sym;        }        return bestSoFar;    }    /** Find an unqualified type symbol.     *  @param env       The current environment.     *  @param name      The type's name.     */    Symbol findType(Env<AttrContext> env, Name name) {        Symbol bestSoFar = typeNotFound;        Symbol sym;        boolean staticOnly = false;        for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {            if (isStatic(env1)) staticOnly = true;            for (Scope.Entry e = env1.info.scope.lookup(name);                 e.scope != null;                 e = e.next()) {                if (e.sym.kind == TYP) {                    if (staticOnly &&                        e.sym.type.tag == TYPEVAR &&                        e.sym.owner.kind == TYP) return new StaticError(e.sym);                    return e.sym;                }            }            sym = findMemberType(env1, env1.enclClass.sym.type, name,                                 env1.enclClass.sym);            if (staticOnly && sym.kind == TYP &&                sym.type.tag == CLASS &&                sym.type.getEnclosingType().tag == CLASS &&                env1.enclClass.sym.type.isParameterized() &&                sym.type.getEnclosingType().isParameterized())                return new StaticError(sym);            else if (sym.exists()) return sym;            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;            JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass;            if ((encl.sym.flags() & STATIC) != 0)                staticOnly = true;        }        if (env.tree.getTag() != JCTree.IMPORT) {            sym = findGlobalType(env, env.toplevel.namedImportScope, name);            if (sym.exists()) return sym;            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;            sym = findGlobalType(env, env.toplevel.packge.members(), name);            if (sym.exists()) return sym;            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;            sym = findGlobalType(env, env.toplevel.starImportScope, name);            if (sym.exists()) return sym;            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;        }        return bestSoFar;    }    /** Find an unqualified identifier which matches a specified kind set.     *  @param env       The current environment.     *  @param name      The indentifier's name.     *  @param kind      Indicates the possible symbol kinds     *                   (a subset of VAL, TYP, PCK).     */    Symbol findIdent(Env<AttrContext> env, Name name, int kind) {        Symbol bestSoFar = typeNotFound;        Symbol sym;        if ((kind & VAR) != 0) {            sym = findVar(env, name);            if (sym.exists()) return sym;            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;        }        if ((kind & TYP) != 0) {            sym = findType(env, name);            if (sym.exists()) return sym;            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;        }        if ((kind & PCK) != 0) return reader.enterPackage(name);        else return bestSoFar;    }    /** Find an identifier in a package which matches a specified kind set.     *  @param env       The current environment.     *  @param name      The identifier's name.     *  @param kind      Indicates the possible symbol kinds     *                   (a nonempty subset of TYP, PCK).     */    Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck,                              Name name, int kind) {        Name fullname = TypeSymbol.formFullName(name, pck);        Symbol bestSoFar = typeNotFound;        PackageSymbol pack = null;        if ((kind & PCK) != 0) {            pack = reader.enterPackage(fullname);            if (pack.exists()) return pack;        }        if ((kind & TYP) != 0) {            Symbol sym = loadClass(env, fullname);            if (sym.exists()) {                // don't allow programs to use flatnames                if (name == sym.name) return sym;            }            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;        }        return (pack != null) ? pack : bestSoFar;    }    /** Find an identifier among the members of a given type `site'.     *  @param env       The current environment.     *  @param site      The type containing the symbol to be found.     *  @param name      The identifier's name.     *  @param kind      Indicates the possible symbol kinds     *                   (a subset of VAL, TYP).     */    Symbol findIdentInType(Env<AttrContext> env, Type site,                           Name name, int kind) {        Symbol bestSoFar = typeNotFound;        Symbol sym;        if ((kind & VAR) != 0) {            sym = findField(env, site, name, site.tsym);            if (sym.exists()) return sym;            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;        }        if ((kind & TYP) != 0) {            sym = findMemberType(env, site, name, site.tsym);            if (sym.exists()) return sym;            else if (sym.kind < bestSoFar.kind) bestSoFar = sym;        }        return bestSoFar;    }/* *************************************************************************** *  Access checking *  The following methods convert ResolveErrors to ErrorSymbols, issuing *  an error message in the process ****************************************************************************/    /** If `sym' is a bad symbol: report error and return errSymbol     *  else pass through unchanged,     *  additional arguments duplicate what has been used in trying to find the     *  symbol (--> flyweight pattern). This improves performance since we     *  expect misses to happen frequently.     *     *  @param sym       The symbol that was found, or a ResolveError.     *  @param pos       The position to use for error reporting.     *  @param site      The original type from where the selection took place.     *  @param name      The symbol's name.     *  @param argtypes  The invocation's value arguments,     *                   if we looked for a method.     *  @param typeargtypes  The invocation's type arguments,     *                   if we looked for a method.     */    Symbol access(Symbol sym,                  DiagnosticPosition pos,                  Type site,                  Name name,                  boolean qualified,                  List<Type> argtypes,                  List<Type> typeargtypes) {        if (sym.kind >= AMBIGUOUS) {//          printscopes(site.tsym.members());//DEBUG            if (!site.isErroneous() &&                !Type.isErroneous(argtypes) &&                (typeargtypes==null || !Type.isErroneous(typeargtypes)))                ((ResolveError)sym).report(log, pos, site, name, argtypes, typeargtypes);            do {                sym = ((ResolveError)sym).sym;            } while (sym.kind >= AMBIGUOUS);            if (sym == syms.errSymbol // preserve the symbol name through errors                || ((sym.kind & ERRONEOUS) == 0 // make sure an error symbol is returned                    && (sym.kind & TYP) != 0))                sym = new ErrorType(name, qualified?site.tsym:syms.noSymbol).tsym;        }        return sym;    }    /** Same as above, but without type arguments and arguments.     */    Symbol access(Symbol sym,                  DiagnosticPosition pos,                  Type site,                  Name name,                  boolean qualified) {        if (sym.kind >= AMBIGUOUS)            return access(sym, pos, site, name, qualified, List.<Type>nil(), null);        else            return sym;    }    /** Check that sym is not an abstract method.     */    void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {        if ((sym.flags() & ABSTRACT) != 0)            log.error(pos, "abstract.cant.be.accessed.directly",                      kindName(sym), sym, sym.location());    }/* *************************************************************************** *  Debugging ****************************************************************************/    /** print all scopes starting with scope s and proceeding outwards.     *  used for debugging.     */    public void printscopes(Scope s) {        while (s != null) {            if (s.owner != null)                System.err.print(s.owner + ": ");            for (Scope.Entry e = s.elems; e != null; e = e.sibling) {                if ((e.sym.flags() & ABSTRACT) != 0)                    System.err.print("abstract ");                System.err.print(e.sym + " ");            }            System.err.println();            s = s.next;        }    }    void printscopes(Env<AttrContext> env) {        while (env.outer != null) {            System.err.println("------------------------------");            printscopes(env.info.scope);            env = env.outer;        }    }    public void printscopes(Type t) {        while (t.tag == CLASS) {            printscopes(t.tsym.members());            t = types.supertype(t);        }    }/* *************************************************************************** *  Name resolution *  Naming conventions are as for symbol lookup *  Unlike the find... methods these methods will report access errors ****************************************************************************/    /** Resolve an unqualified (non-method) identifier.     *  @param pos       The position to use for error reporting.     *  @param env       The environment current at the identifier use.     *  @param name      The identifier's name.     *  @param kind      The set of admissible symbol kinds for the identifier.     */    Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,                        Name name, int kind) {        return access(            findIdent(env, name, kind),            pos, env.enclClass.sym.type, name, false);    }    /** Resolve an unqualified method identifier.     *  @param pos       The position to use for error reporting.     *  @param env       The environment current at the method invocation.     *  @param name      The identifier's name.     *  @param argtypes  The types of the invocation's value arguments.     *  @param typeargtypes  The types of the invocation's type arguments.     */    Symbol resolveMethod(DiagnosticPosition pos,                         Env<AttrContext> env,                         Name name,                         List<Type> argtypes,                         List<Type> typeargtypes) {        Symbol sym = findFun(env, name, argtypes, typeargtypes, false, env.info.varArgs=false);        if (varargsEnabled && sym.kind >= WRONG_MTHS) {            sym = findFun(env, name, argtypes, typeargtypes, true, false);            if (sym.kind >= WRONG_MTHS)                sym = findFun(env, name, argtypes, typeargtypes, true, env.info.varArgs=true);        }        if (sym.kind >= AMBIGUOUS) {            sym = access(                sym, pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes);        }        return sym;    }    /** Resolve a qualified method identifier     *  @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.     *  @param argtypes  The types of the invocation's value arguments.     *  @param typeargtypes  The types of the invocation's type arguments.     */    Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,                                  Type site, Name name, List<Type> argtypes,                                  List<Type> typeargtypes) {        Symbol sym = findMethod(env, site, name, argtypes, typeargtypes, false,                                env.info.varArgs=false, false);        if (varargsEnabled && sym.kind >= WRONG_MTHS) {

⌨️ 快捷键说明

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