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 + -
显示快捷键?