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