1508 |
1508 |
1509 public boolean checkCompatibleAbstracts(DiagnosticPosition pos, |
1509 public boolean checkCompatibleAbstracts(DiagnosticPosition pos, |
1510 Type t1, |
1510 Type t1, |
1511 Type t2, |
1511 Type t2, |
1512 Type site) { |
1512 Type site) { |
1513 Symbol sym = firstIncompatibility(t1, t2, site); |
1513 return firstIncompatibility(pos, t1, t2, site) == null; |
1514 if (sym != null) { |
|
1515 log.error(pos, "types.incompatible.diff.ret", |
|
1516 t1, t2, sym.name + |
|
1517 "(" + types.memberType(t2, sym).getParameterTypes() + ")"); |
|
1518 return false; |
|
1519 } |
|
1520 return true; |
|
1521 } |
1514 } |
1522 |
1515 |
1523 /** Return the first method which is defined with same args |
1516 /** Return the first method which is defined with same args |
1524 * but different return types in two given interfaces, or null if none |
1517 * but different return types in two given interfaces, or null if none |
1525 * exists. |
1518 * exists. |
1526 * @param t1 The first type. |
1519 * @param t1 The first type. |
1527 * @param t2 The second type. |
1520 * @param t2 The second type. |
1528 * @param site The most derived type. |
1521 * @param site The most derived type. |
1529 * @returns symbol from t2 that conflicts with one in t1. |
1522 * @returns symbol from t2 that conflicts with one in t1. |
1530 */ |
1523 */ |
1531 private Symbol firstIncompatibility(Type t1, Type t2, Type site) { |
1524 private Symbol firstIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) { |
1532 Map<TypeSymbol,Type> interfaces1 = new HashMap<TypeSymbol,Type>(); |
1525 Map<TypeSymbol,Type> interfaces1 = new HashMap<TypeSymbol,Type>(); |
1533 closure(t1, interfaces1); |
1526 closure(t1, interfaces1); |
1534 Map<TypeSymbol,Type> interfaces2; |
1527 Map<TypeSymbol,Type> interfaces2; |
1535 if (t1 == t2) |
1528 if (t1 == t2) |
1536 interfaces2 = interfaces1; |
1529 interfaces2 = interfaces1; |
1537 else |
1530 else |
1538 closure(t2, interfaces1, interfaces2 = new HashMap<TypeSymbol,Type>()); |
1531 closure(t2, interfaces1, interfaces2 = new HashMap<TypeSymbol,Type>()); |
1539 |
1532 |
1540 for (Type t3 : interfaces1.values()) { |
1533 for (Type t3 : interfaces1.values()) { |
1541 for (Type t4 : interfaces2.values()) { |
1534 for (Type t4 : interfaces2.values()) { |
1542 Symbol s = firstDirectIncompatibility(t3, t4, site); |
1535 Symbol s = firstDirectIncompatibility(pos, t3, t4, site); |
1543 if (s != null) return s; |
1536 if (s != null) return s; |
1544 } |
1537 } |
1545 } |
1538 } |
1546 return null; |
1539 return null; |
1547 } |
1540 } |
1566 closure(i, typesSkip, typeMap); |
1559 closure(i, typesSkip, typeMap); |
1567 } |
1560 } |
1568 } |
1561 } |
1569 |
1562 |
1570 /** Return the first method in t2 that conflicts with a method from t1. */ |
1563 /** Return the first method in t2 that conflicts with a method from t1. */ |
1571 private Symbol firstDirectIncompatibility(Type t1, Type t2, Type site) { |
1564 private Symbol firstDirectIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) { |
1572 for (Scope.Entry e1 = t1.tsym.members().elems; e1 != null; e1 = e1.sibling) { |
1565 for (Scope.Entry e1 = t1.tsym.members().elems; e1 != null; e1 = e1.sibling) { |
1573 Symbol s1 = e1.sym; |
1566 Symbol s1 = e1.sym; |
1574 Type st1 = null; |
1567 Type st1 = null; |
1575 if (s1.kind != MTH || !s1.isInheritedIn(site.tsym, types)) continue; |
1568 if (s1.kind != MTH || !s1.isInheritedIn(site.tsym, types)) continue; |
1576 Symbol impl = ((MethodSymbol)s1).implementation(site.tsym, types, false); |
1569 Symbol impl = ((MethodSymbol)s1).implementation(site.tsym, types, false); |
1590 types.isSameType(rt1, rt2) || |
1583 types.isSameType(rt1, rt2) || |
1591 rt1.tag >= CLASS && rt2.tag >= CLASS && |
1584 rt1.tag >= CLASS && rt2.tag >= CLASS && |
1592 (types.covariantReturnType(rt1, rt2, Warner.noWarnings) || |
1585 (types.covariantReturnType(rt1, rt2, Warner.noWarnings) || |
1593 types.covariantReturnType(rt2, rt1, Warner.noWarnings)) || |
1586 types.covariantReturnType(rt2, rt1, Warner.noWarnings)) || |
1594 checkCommonOverriderIn(s1,s2,site); |
1587 checkCommonOverriderIn(s1,s2,site); |
1595 if (!compat) return s2; |
1588 if (!compat) { |
|
1589 log.error(pos, "types.incompatible.diff.ret", |
|
1590 t1, t2, s2.name + |
|
1591 "(" + types.memberType(t2, s2).getParameterTypes() + ")"); |
|
1592 return s2; |
|
1593 } |
|
1594 } else if (!checkNameClash((ClassSymbol)site.tsym, s1, s2)) { |
|
1595 log.error(pos, |
|
1596 "name.clash.same.erasure.no.override", |
|
1597 s1, s1.location(), |
|
1598 s2, s2.location()); |
|
1599 return s2; |
1596 } |
1600 } |
1597 } |
1601 } |
1598 } |
1602 } |
1599 return null; |
1603 return null; |
1600 } |
1604 } |
1642 if ((origin.flags() & ENUM) != 0 && names.finalize.equals(m.name)) |
1646 if ((origin.flags() & ENUM) != 0 && names.finalize.equals(m.name)) |
1643 if (m.overrides(syms.enumFinalFinalize, origin, types, false)) { |
1647 if (m.overrides(syms.enumFinalFinalize, origin, types, false)) { |
1644 log.error(tree.pos(), "enum.no.finalize"); |
1648 log.error(tree.pos(), "enum.no.finalize"); |
1645 return; |
1649 return; |
1646 } |
1650 } |
1647 for (Type t = types.supertype(origin.type); t.tag == CLASS; |
1651 for (Type t = origin.type; t.tag == CLASS; |
1648 t = types.supertype(t)) { |
1652 t = types.supertype(t)) { |
1649 TypeSymbol c = t.tsym; |
1653 if (t != origin.type) { |
1650 Scope.Entry e = c.members().lookup(m.name); |
1654 checkOverride(tree, t, origin, m); |
1651 while (e.scope != null) { |
1655 } |
1652 if (m.overrides(e.sym, origin, types, false)) |
1656 for (Type t2 : types.interfaces(t)) { |
|
1657 checkOverride(tree, t2, origin, m); |
|
1658 } |
|
1659 } |
|
1660 } |
|
1661 |
|
1662 void checkOverride(JCTree tree, Type site, ClassSymbol origin, MethodSymbol m) { |
|
1663 TypeSymbol c = site.tsym; |
|
1664 Scope.Entry e = c.members().lookup(m.name); |
|
1665 while (e.scope != null) { |
|
1666 if (m.overrides(e.sym, origin, types, false)) { |
|
1667 if ((e.sym.flags() & ABSTRACT) == 0) { |
1653 checkOverride(tree, m, (MethodSymbol)e.sym, origin); |
1668 checkOverride(tree, m, (MethodSymbol)e.sym, origin); |
1654 else if (e.sym.kind == MTH && |
1669 } |
1655 e.sym.isInheritedIn(origin, types) && |
1670 } |
1656 (e.sym.flags() & SYNTHETIC) == 0 && |
1671 else if (!checkNameClash(origin, e.sym, m)) { |
1657 !m.isConstructor()) { |
1672 log.error(tree, |
1658 Type er1 = m.erasure(types); |
1673 "name.clash.same.erasure.no.override", |
1659 Type er2 = e.sym.erasure(types); |
1674 m, m.location(), |
1660 if (types.isSameTypes(er1.getParameterTypes(), |
1675 e.sym, e.sym.location()); |
1661 er2.getParameterTypes())) { |
1676 } |
1662 log.error(TreeInfo.diagnosticPositionFor(m, tree), |
1677 e = e.next(); |
1663 "name.clash.same.erasure.no.override", |
1678 } |
1664 m, m.location(), |
1679 } |
1665 e.sym, e.sym.location()); |
1680 |
1666 } |
1681 private boolean checkNameClash(ClassSymbol origin, Symbol s1, Symbol s2) { |
1667 } |
1682 if (s1.kind == MTH && |
1668 e = e.next(); |
1683 s1.isInheritedIn(origin, types) && |
1669 } |
1684 (s1.flags() & SYNTHETIC) == 0 && |
1670 } |
1685 !s2.isConstructor()) { |
1671 } |
1686 Type er1 = s2.erasure(types); |
|
1687 Type er2 = s1.erasure(types); |
|
1688 if (types.isSameTypes(er1.getParameterTypes(), |
|
1689 er2.getParameterTypes())) { |
|
1690 return false; |
|
1691 } |
|
1692 } |
|
1693 return true; |
|
1694 } |
|
1695 |
1672 |
1696 |
1673 /** Check that all abstract members of given class have definitions. |
1697 /** Check that all abstract members of given class have definitions. |
1674 * @param pos Position to be used for error reporting. |
1698 * @param pos Position to be used for error reporting. |
1675 * @param c The class. |
1699 * @param c The class. |
1676 */ |
1700 */ |