src/share/classes/com/sun/tools/javac/comp/Check.java

changeset 2000
4a6acc42c3a1
parent 1978
7bf6313e1ced
child 2016
f4efd6ef6e80
equal deleted inserted replaced
1999:7993cfab8610 2000:4a6acc42c3a1
2366 void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) { 2366 void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
2367 ClashFilter cf = new ClashFilter(site); 2367 ClashFilter cf = new ClashFilter(site);
2368 //for each method m1 that is overridden (directly or indirectly) 2368 //for each method m1 that is overridden (directly or indirectly)
2369 //by method 'sym' in 'site'... 2369 //by method 'sym' in 'site'...
2370 for (Symbol m1 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) { 2370 for (Symbol m1 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) {
2371 if (!sym.overrides(m1, site.tsym, types, false)) continue; 2371 if (!sym.overrides(m1, site.tsym, types, false)) {
2372 checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)m1);
2373 continue;
2374 }
2372 //...check each method m2 that is a member of 'site' 2375 //...check each method m2 that is a member of 'site'
2373 for (Symbol m2 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) { 2376 for (Symbol m2 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) {
2374 if (m2 == m1) continue; 2377 if (m2 == m1) continue;
2375 //if (i) the signature of 'sym' is not a subsignature of m1 (seen as 2378 //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
2376 //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error 2379 //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
2404 ClashFilter cf = new ClashFilter(site); 2407 ClashFilter cf = new ClashFilter(site);
2405 //for each method m1 that is a member of 'site'... 2408 //for each method m1 that is a member of 'site'...
2406 for (Symbol s : types.membersClosure(site, true).getElementsByName(sym.name, cf)) { 2409 for (Symbol s : types.membersClosure(site, true).getElementsByName(sym.name, cf)) {
2407 //if (i) the signature of 'sym' is not a subsignature of m1 (seen as 2410 //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
2408 //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error 2411 //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
2409 if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck) && 2412 if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck)) {
2410 types.hasSameArgs(s.erasure(types), sym.erasure(types))) { 2413 if (types.hasSameArgs(s.erasure(types), sym.erasure(types))) {
2411 log.error(pos, 2414 log.error(pos,
2412 "name.clash.same.erasure.no.hide", 2415 "name.clash.same.erasure.no.hide",
2413 sym, sym.location(), 2416 sym, sym.location(),
2414 s, s.location()); 2417 s, s.location());
2415 return; 2418 return;
2416 } 2419 } else {
2420 checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)s);
2421 }
2422 }
2417 } 2423 }
2418 } 2424 }
2419 2425
2420 //where 2426 //where
2421 private class ClashFilter implements Filter<Symbol> { 2427 private class ClashFilter implements Filter<Symbol> {
2494 s.isInheritedIn(site.tsym, types) && 2500 s.isInheritedIn(site.tsym, types) &&
2495 !s.isConstructor(); 2501 !s.isConstructor();
2496 } 2502 }
2497 } 2503 }
2498 2504
2505 /**
2506 * Report warnings for potentially ambiguous method declarations. Two declarations
2507 * are potentially ambiguous if they feature two unrelated functional interface
2508 * in same argument position (in which case, a call site passing an implicit
2509 * lambda would be ambiguous).
2510 */
2511 void checkPotentiallyAmbiguousOverloads(DiagnosticPosition pos, Type site,
2512 MethodSymbol msym1, MethodSymbol msym2) {
2513 if (msym1 != msym2 &&
2514 allowDefaultMethods &&
2515 lint.isEnabled(LintCategory.OVERLOADS) &&
2516 (msym1.flags() & POTENTIALLY_AMBIGUOUS) == 0 &&
2517 (msym2.flags() & POTENTIALLY_AMBIGUOUS) == 0) {
2518 Type mt1 = types.memberType(site, msym1);
2519 Type mt2 = types.memberType(site, msym2);
2520 //if both generic methods, adjust type variables
2521 if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL) &&
2522 types.hasSameBounds((ForAll)mt1, (ForAll)mt2)) {
2523 mt2 = types.subst(mt2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars);
2524 }
2525 //expand varargs methods if needed
2526 int maxLength = Math.max(mt1.getParameterTypes().length(), mt2.getParameterTypes().length());
2527 List<Type> args1 = rs.adjustArgs(mt1.getParameterTypes(), msym1, maxLength, true);
2528 List<Type> args2 = rs.adjustArgs(mt2.getParameterTypes(), msym2, maxLength, true);
2529 //if arities don't match, exit
2530 if (args1.length() != args2.length()) return;
2531 boolean potentiallyAmbiguous = false;
2532 while (args1.nonEmpty() && args2.nonEmpty()) {
2533 Type s = args1.head;
2534 Type t = args2.head;
2535 if (!types.isSubtype(t, s) && !types.isSubtype(s, t)) {
2536 if (types.isFunctionalInterface(s) && types.isFunctionalInterface(t) &&
2537 types.findDescriptorType(s).getParameterTypes().length() > 0 &&
2538 types.findDescriptorType(s).getParameterTypes().length() ==
2539 types.findDescriptorType(t).getParameterTypes().length()) {
2540 potentiallyAmbiguous = true;
2541 } else {
2542 break;
2543 }
2544 }
2545 args1 = args1.tail;
2546 args2 = args2.tail;
2547 }
2548 if (potentiallyAmbiguous) {
2549 //we found two incompatible functional interfaces with same arity
2550 //this means a call site passing an implicit lambda would be ambigiuous
2551 msym1.flags_field |= POTENTIALLY_AMBIGUOUS;
2552 msym2.flags_field |= POTENTIALLY_AMBIGUOUS;
2553 log.warning(LintCategory.OVERLOADS, pos, "potentially.ambiguous.overload",
2554 msym1, msym1.location(),
2555 msym2, msym2.location());
2556 return;
2557 }
2558 }
2559 }
2560
2499 /** Report a conflict between a user symbol and a synthetic symbol. 2561 /** Report a conflict between a user symbol and a synthetic symbol.
2500 */ 2562 */
2501 private void syntheticError(DiagnosticPosition pos, Symbol sym) { 2563 private void syntheticError(DiagnosticPosition pos, Symbol sym) {
2502 if (!sym.type.isErroneous()) { 2564 if (!sym.type.isErroneous()) {
2503 if (warnOnSyntheticConflicts) { 2565 if (warnOnSyntheticConflicts) {

mercurial