214 || |
214 || |
215 env.toplevel.packge == sym.packge()) |
215 env.toplevel.packge == sym.packge()) |
216 && |
216 && |
217 isAccessible(env, site) |
217 isAccessible(env, site) |
218 && |
218 && |
219 sym.isInheritedIn(site.tsym, types); |
219 sym.isInheritedIn(site.tsym, types) |
|
220 && |
|
221 notOverriddenIn(site, sym); |
220 case PROTECTED: |
222 case PROTECTED: |
221 return |
223 return |
222 (env.toplevel.packge == sym.owner.owner // fast special case |
224 (env.toplevel.packge == sym.owner.owner // fast special case |
223 || |
225 || |
224 env.toplevel.packge == sym.packge() |
226 env.toplevel.packge == sym.packge() |
229 // (but type names should be disallowed elsewhere!) |
231 // (but type names should be disallowed elsewhere!) |
230 env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP) |
232 env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP) |
231 && |
233 && |
232 isAccessible(env, site) |
234 isAccessible(env, site) |
233 && |
235 && |
234 // `sym' is accessible only if not overridden by |
236 notOverriddenIn(site, sym); |
235 // another symbol which is a member of `site' |
|
236 // (because, if it is overridden, `sym' is not strictly |
|
237 // speaking a member of `site'.) |
|
238 (sym.kind != MTH || sym.isConstructor() || sym.isStatic() || |
|
239 ((MethodSymbol)sym).implementation(site.tsym, types, true) == sym); |
|
240 default: // this case includes erroneous combinations as well |
237 default: // this case includes erroneous combinations as well |
241 return isAccessible(env, site); |
238 return isAccessible(env, site) && notOverriddenIn(site, sym); |
|
239 } |
|
240 } |
|
241 //where |
|
242 /* `sym' is accessible only if not overridden by |
|
243 * another symbol which is a member of `site' |
|
244 * (because, if it is overridden, `sym' is not strictly |
|
245 * speaking a member of `site'.) |
|
246 */ |
|
247 private boolean notOverriddenIn(Type site, Symbol sym) { |
|
248 if (sym.kind != MTH || sym.isConstructor() || sym.isStatic()) |
|
249 return true; |
|
250 else { |
|
251 Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true); |
|
252 return (s2 == null || s2 == sym); |
242 } |
253 } |
243 } |
254 } |
244 //where |
255 //where |
245 /** Is given protected symbol accessible if it is selected from given site |
256 /** Is given protected symbol accessible if it is selected from given site |
246 * and the selection takes place in given class? |
257 * and the selection takes place in given class? |
603 * @param useVarargs Box trailing arguments into an array for varargs. |
614 * @param useVarargs Box trailing arguments into an array for varargs. |
604 */ |
615 */ |
605 Symbol mostSpecific(Symbol m1, |
616 Symbol mostSpecific(Symbol m1, |
606 Symbol m2, |
617 Symbol m2, |
607 Env<AttrContext> env, |
618 Env<AttrContext> env, |
608 Type site, |
619 final Type site, |
609 boolean allowBoxing, |
620 boolean allowBoxing, |
610 boolean useVarargs) { |
621 boolean useVarargs) { |
611 switch (m2.kind) { |
622 switch (m2.kind) { |
612 case MTH: |
623 case MTH: |
613 if (m1 == m2) return m1; |
624 if (m1 == m2) return m1; |
659 // check that both signatures have the same erasure |
670 // check that both signatures have the same erasure |
660 if (!types.isSameTypes(m1.erasure(types).getParameterTypes(), |
671 if (!types.isSameTypes(m1.erasure(types).getParameterTypes(), |
661 m2.erasure(types).getParameterTypes())) |
672 m2.erasure(types).getParameterTypes())) |
662 return new AmbiguityError(m1, m2); |
673 return new AmbiguityError(m1, m2); |
663 // both abstract, neither overridden; merge throws clause and result type |
674 // both abstract, neither overridden; merge throws clause and result type |
664 Symbol result; |
675 Symbol mostSpecific; |
665 Type result2 = mt2.getReturnType(); |
676 Type result2 = mt2.getReturnType(); |
666 if (mt2.tag == FORALL) |
677 if (mt2.tag == FORALL) |
667 result2 = types.subst(result2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars); |
678 result2 = types.subst(result2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars); |
668 if (types.isSubtype(mt1.getReturnType(), result2)) { |
679 if (types.isSubtype(mt1.getReturnType(), result2)) { |
669 result = m1; |
680 mostSpecific = m1; |
670 } else if (types.isSubtype(result2, mt1.getReturnType())) { |
681 } else if (types.isSubtype(result2, mt1.getReturnType())) { |
671 result = m2; |
682 mostSpecific = m2; |
672 } else { |
683 } else { |
673 // Theoretically, this can't happen, but it is possible |
684 // Theoretically, this can't happen, but it is possible |
674 // due to error recovery or mixing incompatible class files |
685 // due to error recovery or mixing incompatible class files |
675 return new AmbiguityError(m1, m2); |
686 return new AmbiguityError(m1, m2); |
676 } |
687 } |
677 result = result.clone(result.owner); |
688 MethodSymbol result = new MethodSymbol( |
678 result.type = (Type)result.type.clone(); |
689 mostSpecific.flags(), |
|
690 mostSpecific.name, |
|
691 null, |
|
692 mostSpecific.owner) { |
|
693 @Override |
|
694 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) { |
|
695 if (origin == site.tsym) |
|
696 return this; |
|
697 else |
|
698 return super.implementation(origin, types, checkResult); |
|
699 } |
|
700 }; |
|
701 result.type = (Type)mostSpecific.type.clone(); |
679 result.type.setThrown(chk.intersect(mt1.getThrownTypes(), |
702 result.type.setThrown(chk.intersect(mt1.getThrownTypes(), |
680 mt2.getThrownTypes())); |
703 mt2.getThrownTypes())); |
681 return result; |
704 return result; |
682 } |
705 } |
683 if (m1SignatureMoreSpecific) return m1; |
706 if (m1SignatureMoreSpecific) return m1; |