Skip to content

Commit 3a87bcb

Browse files
ecj doesn't properly apply the comb rule from 15.12.1 (eclipse-jdt#4087)
+ don't find private methods from super types + unless there is only one private method, to be reported as invisible + support running with run.javac on JDK 24.0.1 Fixes eclipse-jdt#4081
1 parent 0dead21 commit 3a87bcb

File tree

4 files changed

+122
-16
lines changed

4 files changed

+122
-16
lines changed

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/Scope.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1684,6 +1684,9 @@ public MethodBinding findMethod0(ReferenceBinding receiverType, char[] selector,
16841684
// superclass lookup
16851685
ReferenceBinding classHierarchyStart = currentType;
16861686
MethodVerifier verifier = environment().methodVerifier();
1687+
boolean currentIsSuper = false;
1688+
MethodBinding singlePrivateMethod = null;
1689+
boolean multiplePrivateMethods = false;
16871690
while (currentType != null) {
16881691
unitScope.recordTypeReference(currentType);
16891692
currentType = (ReferenceBinding) currentType.capture(this, invocationSite == null ? 0 : invocationSite.sourceStart(), invocationSite == null ? 0 : invocationSite.sourceEnd());
@@ -1721,18 +1724,29 @@ public MethodBinding findMethod0(ReferenceBinding receiverType, char[] selector,
17211724
}
17221725

17231726
if (currentLength > 0) {
1724-
// append currentMethods, filtering out null entries
1725-
if (currentMethods.length == currentLength) {
1727+
// append currentMethods, filtering out null entries and private super methods
1728+
if (currentMethods.length == currentLength && !currentIsSuper) {
17261729
found.addAll(currentMethods);
17271730
} else {
17281731
for (MethodBinding currentMethod : currentMethods) {
1729-
if (currentMethod != null)
1730-
found.add(currentMethod);
1732+
if (currentMethod != null) {
1733+
if (currentIsSuper && currentMethod.isPrivate()) {
1734+
if (singlePrivateMethod == null && !multiplePrivateMethods) {
1735+
singlePrivateMethod = currentMethod;
1736+
} else {
1737+
singlePrivateMethod = null;
1738+
multiplePrivateMethods = true;
1739+
}
1740+
} else {
1741+
found.add(currentMethod);
1742+
}
1743+
}
17311744
}
17321745
}
17331746
}
17341747
}
17351748
currentType = currentType.superclass();
1749+
currentIsSuper = true;
17361750
}
17371751

17381752
// if found several candidates, then eliminate those not matching argument types
@@ -1772,6 +1786,9 @@ public MethodBinding findMethod0(ReferenceBinding receiverType, char[] selector,
17721786
case ProblemReasons.TypeParameterArityMismatch :
17731787
return problemMethod;
17741788
}
1789+
} else if (foundSize == 0 && singlePrivateMethod != null) {
1790+
// if there is only one private method, we want to report that it is not visible.
1791+
return new ProblemMethodBinding(singlePrivateMethod, selector, singlePrivateMethod.parameters, ProblemReasons.NotVisible);
17751792
}
17761793
// abstract classes may get a match in interfaces; for non abstract
17771794
// classes, reduces secondary errors since missing interface method

org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,8 @@ static int minorFromRawVersion (String version, String rawVersion) {
575575
switch(rawVersion) {
576576
case "24-ea", "24-beta", "24":
577577
return 0000;
578+
case "24.0.1":
579+
return 0100;
578580
}
579581
}
580582
throw new RuntimeException("unknown raw javac version: " + rawVersion);

org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InnerEmulationTest.java

Lines changed: 98 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5994,31 +5994,118 @@ public void test172() throws Exception {
59945994
this.runNegativeTest(
59955995
files,
59965996
"----------\n" +
5997-
"1. WARNING in X.java (at line 8)\n" +
5997+
"1. ERROR in X.java (at line 8)\n" +
59985998
" a(null);\n" +
5999-
" ^^^^^^^\n" +
6000-
"Access to enclosing method a(String) from the type X is emulated by a synthetic accessor method\n" +
6001-
"----------\n" +
6002-
"2. WARNING in X.java (at line 9)\n" +
6003-
" c(null);\n" +
6004-
" ^^^^^^^\n" +
6005-
"Access to enclosing method c(String) from the type X is emulated by a synthetic accessor method\n" +
5999+
" ^\n" +
6000+
"The method a() in the type X is not applicable for the arguments (null)\n" +
60066001
"----------\n" +
6007-
"3. WARNING in X.java (at line 14)\n" +
6002+
"2. WARNING in X.java (at line 14)\n" +
60086003
" a(null);\n" +
60096004
" ^^^^^^^\n" +
60106005
"Access to enclosing method a(String) from the type X is emulated by a synthetic accessor method\n" +
60116006
"----------\n" +
6012-
"4. WARNING in X.java (at line 15)\n" +
6007+
"3. WARNING in X.java (at line 15)\n" +
60136008
" c(null);\n" +
60146009
" ^^^^^^^\n" +
60156010
"Access to enclosing method c(String) from the type X is emulated by a synthetic accessor method\n" +
60166011
"----------\n"
60176012
);
60186013
} else {
6019-
this.runConformTest(files, "");
6014+
this.runNegativeTest(files,
6015+
"----------\n" +
6016+
"1. ERROR in X.java (at line 8)\n" +
6017+
" a(null);\n" +
6018+
" ^\n" +
6019+
"The method a() in the type X is not applicable for the arguments (null)\n" +
6020+
"----------\n");
60206021
}
60216022
}
6023+
public void test172b() throws Exception {
6024+
runNegativeTest(new String[] {
6025+
"X.java",
6026+
"""
6027+
class Y {
6028+
void a() { }
6029+
private static void a(String s) { }
6030+
6031+
public static class X extends Y {
6032+
6033+
void a(int x, int y) { }
6034+
private void c() { }
6035+
private static void c(String s) { }
6036+
6037+
static class M1 extends X {
6038+
public void x() {
6039+
a(null);
6040+
c(null);
6041+
}
6042+
}
6043+
6044+
static class M2 {
6045+
public void x() {
6046+
a(null);
6047+
c(null);
6048+
}
6049+
}
6050+
}
6051+
}
6052+
"""
6053+
},
6054+
"""
6055+
----------
6056+
1. ERROR in X.java (at line 13)
6057+
a(null);
6058+
^
6059+
The method a(int, int) in the type Y.X is not applicable for the arguments (null)
6060+
----------
6061+
2. ERROR in X.java (at line 20)
6062+
a(null);
6063+
^
6064+
The method a(int, int) in the type Y.X is not applicable for the arguments (null)
6065+
----------
6066+
""");
6067+
}
6068+
public void test172c() throws Exception {
6069+
runNegativeTest(new String[] {
6070+
"Test.java",
6071+
"""
6072+
class Super {
6073+
void f2(String s) {}
6074+
void f3(String s) {}
6075+
void f3(int i1, int i2) {}
6076+
}
6077+
6078+
class Test {
6079+
void f1(int i) {}
6080+
void f2(int i) {}
6081+
void f3(int i) {}
6082+
6083+
void m() {
6084+
new Super() {
6085+
{
6086+
f1(0); // OK, resolves to Test.f1(int)
6087+
f2(0); // compile-time error
6088+
f3(0); // compile-time error
6089+
}
6090+
};
6091+
}
6092+
}
6093+
"""
6094+
},
6095+
"""
6096+
----------
6097+
1. ERROR in Test.java (at line 16)
6098+
f2(0); // compile-time error
6099+
^^
6100+
The method f2(String) in the type Super is not applicable for the arguments (int)
6101+
----------
6102+
2. ERROR in Test.java (at line 17)
6103+
f3(0); // compile-time error
6104+
^^
6105+
The method f3(int, int) in the type Super is not applicable for the arguments (int)
6106+
----------
6107+
""");
6108+
}
60226109
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=308245
60236110
public void test173() throws Exception {
60246111
this.runConformTest(

org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTestForMethod.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4130,7 +4130,7 @@ public void test147() {
41304130
+ "1. ERROR in test\\X.java (at line 6)\n"
41314131
+ " * @see Visibility#avm_private(int) Invalid ref: non-applicable inherited method\n"
41324132
+ " ^^^^^^^^^^^\n"
4133-
+ "Javadoc: The method avm_private() in the type AbstractVisibility is not applicable for the arguments (int)\n"
4133+
+ "Javadoc: The method avm_private() from the type AbstractVisibility is not visible\n"
41344134
+ "----------\n"
41354135
+ "2. ERROR in test\\X.java (at line 7)\n"
41364136
+ " * @see Visibility#avm_public(String) Invalid ref: non-applicable inherited method\n"

0 commit comments

Comments
 (0)