[java, jigsaw] Support JDK-8197532: add tests (IDEA-367339) IJ-CR-154794

(cherry picked from commit e3acb5c8848ae13da6f28c1593b432e27c81cd14)

IJ-CR-154794

GitOrigin-RevId: 881dcb8023063fcdd7116191c662b180986d4f93
This commit is contained in:
Aleksey Dobrynin
2025-02-18 15:41:46 +01:00
committed by intellij-monorepo-bot
parent 0f074beae7
commit 25a39de77f
12 changed files with 93 additions and 17 deletions

View File

@@ -1121,9 +1121,14 @@ public final class JavaErrorKinds {
.withHighlightType(JavaErrorHighlightType.WRONG_REF)
.withAnchor(ref -> requireNonNullElse(ref.getReferenceNameElement(), ref))
.<List<JavaResolveResult>>parameterized()
.withRawDescription((ref, results) -> message("reference.ambiguous", ref.getReferenceName(),
format(requireNonNull(results.get(0).getElement())),
format(requireNonNull(results.get(1).getElement()))));
.withRawDescription((ref, results) -> {
String element1 = format(requireNonNull(results.get(0).getElement()));
String element2 = format(requireNonNull(results.get(1).getElement()));
boolean comparison = element1.compareTo(element2) < 0;
return message("reference.ambiguous", ref.getReferenceName(),
comparison ? element1 : element2,
comparison ? element2 : element1);
});
public static final Parameterized<PsiJavaCodeReferenceElement, PsiElement> REFERENCE_NON_STATIC_FROM_STATIC_CONTEXT =
parameterized(PsiJavaCodeReferenceElement.class, PsiElement.class, "reference.non.static.from.static.context")
.withHighlightType(JavaErrorHighlightType.WRONG_REF)

View File

@@ -46,20 +46,20 @@ class MultipleInheritance2 {
static class Z1 extends Y implements I1 {
{
System.out.println(<error descr="Reference to 'X' is ambiguous, both 'Y.X' and 'I1.X' match">X</error>);
System.out.println(<error descr="Reference to 'X' is ambiguous, both 'I1.X' and 'Y.X' match">X</error>);
}
}
interface I2 extends I1 {}
static class Z2 extends Y implements I2 {
{
System.out.println(<error descr="Reference to 'X' is ambiguous, both 'Y.X' and 'I1.X' match">X</error>);
System.out.println(<error descr="Reference to 'X' is ambiguous, both 'I1.X' and 'Y.X' match">X</error>);
}
}
static class Z3 extends Y implements Runnable, I2 {
{
System.out.println(<error descr="Reference to 'X' is ambiguous, both 'Y.X' and 'I1.X' match">X</error>);
System.out.println(<error descr="Reference to 'X' is ambiguous, both 'I1.X' and 'Y.X' match">X</error>);
}
public void run() {}

View File

@@ -44,7 +44,7 @@ class Main1 {
static class C extends D implements A
{
interface E extends <error descr="Reference to 'B' is ambiguous, both 'Main1.D.B' and 'Main1.A.B' match">B</error> { }
interface E extends <error descr="Reference to 'B' is ambiguous, both 'Main1.A.B' and 'Main1.D.B' match">B</error> { }
interface E1 extends D.B {
}
interface E2 extends A.B { }
@@ -72,7 +72,7 @@ class C extends D implements A
interface E1 extends D.<error descr="'D.B' has private access in 'D'">B</error> { }
interface E2 extends A.B { }
interface F extends <error descr="Reference to 'B1' is ambiguous, both 'D.B1' and 'A.B1' match">B1</error> { }
interface F extends <error descr="Reference to 'B1' is ambiguous, both 'A.B1' and 'D.B1' match">B1</error> { }
interface F1 extends D.B1 { }
interface F2 extends A.B1 { }

View File

@@ -22,7 +22,7 @@ class MyTest {
{
Bar1 b1 = MyTest :: foo;
bar(MyTest :: <error descr="Reference to 'foo' is ambiguous, both 'foo(int)' and 'foo(String)' match">foo</error>);
bar(MyTest :: <error descr="Reference to 'foo' is ambiguous, both 'foo(String)' and 'foo(int)' match">foo</error>);
}
}

View File

@@ -6,7 +6,7 @@ interface Func<TIn, TOut>{
class Main {
public static void main(final String[] args) {
Func<Integer, String> func = Integer::<error descr="Reference to 'toString' is ambiguous, both 'toString(int)' and 'toString()' match">toString</error>;
Func<Integer, String> func = Integer::<error descr="Reference to 'toString' is ambiguous, both 'toString()' and 'toString(int)' match">toString</error>;
System.out.println(func.run(6));
}
}

View File

@@ -16,7 +16,7 @@ class DemoApplicationTests {
Stream.of("")
.map(l -> a.get(l.length()))
.map(s -> new DemoApplicationTests()).findAny()
.map(d -> d.foo(this::<error descr="Reference to 'bar' is ambiguous, both 'bar(long)' and 'bar(int)' match">bar</error>));
.map(d -> d.foo(this::<error descr="Reference to 'bar' is ambiguous, both 'bar(int)' and 'bar(long)' match">bar</error>));
}
<T> void foo(Consumer<T> c) {}

View File

@@ -10,6 +10,6 @@ class Test {
static void m(Test t, Object s) {}
static void test() {
I i = Test::<error descr="Reference to 'm' is ambiguous, both 'm(Test, String)' and 'm(String)' match">m</error>;
I i = Test::<error descr="Reference to 'm' is ambiguous, both 'm(String)' and 'm(Test, String)' match">m</error>;
}
}

View File

@@ -10,6 +10,6 @@ class Test {
}
static void test() {
I i = A::<error descr="Reference to 'foo' is ambiguous, both 'foo(A, A...)' and 'foo()' match">foo</error>;
I i = A::<error descr="Reference to 'foo' is ambiguous, both 'foo()' and 'foo(A, A...)' match">foo</error>;
}
}

View File

@@ -1,5 +1,5 @@
import module my.source.moduleB;
import module my.source.moduleA;
class AmbiguousModuleImport {
<error descr="Reference to 'Imported' is ambiguous, both 'my.source.moduleB.Imported' and 'my.source.moduleA.Imported' match">Imported</error> <caret>module;
<error descr="Reference to 'Imported' is ambiguous, both 'my.source.moduleA.Imported' and 'my.source.moduleB.Imported' match">Imported</error> <caret>module;
}

View File

@@ -14,10 +14,15 @@ import com.intellij.java.testFramework.fixtures.MultiModuleJava9ProjectDescripto
import com.intellij.java.workspace.entities.JavaModuleSettingsEntity
import com.intellij.java.workspace.entities.javaSettings
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.WriteAction
import com.intellij.openapi.application.runWriteActionAndWait
import com.intellij.openapi.diagnostic.ReportingClassSubstitutor
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.module.ModuleManager.Companion.getInstance
import com.intellij.openapi.projectRoots.JavaSdk
import com.intellij.openapi.projectRoots.ProjectJdkTable
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.ModuleRootModificationUtil
import com.intellij.openapi.roots.ProjectRootManager
@@ -42,6 +47,7 @@ import com.intellij.testFramework.DumbModeTestUtils
import com.intellij.testFramework.IdeaTestUtil
import com.intellij.testFramework.VfsTestUtil
import com.intellij.testFramework.workspaceModel.updateProjectModel
import com.intellij.util.ThrowableRunnable
import junit.framework.AssertionFailedError
import junit.framework.TestCase
import org.assertj.core.api.Assertions.assertThat
@@ -964,6 +970,39 @@ class ModuleHighlightingTest : LightJava9ModulesCodeInsightFixtureTestCase() {
}""".trimIndent(), MR_JAVA9)
}
fun testImportJavaSe() {
withInternalJdk(INTERNAL_MAIN, LanguageLevel.JDK_23_PREVIEW) {
highlight("Main.java", """
<error descr="Module 'java.se' is missing from the module graph">import module java.se;</error>
import module jdk.httpserver;
import module java.smartcardio;
public class Main {
private <error descr="Reference to 'Date' is ambiguous, both 'java.sql.Date' and 'java.util.Date' match">Date</error> date;
private HttpsServer http;
private ATR attr;
}""".trimIndent(), INTERNAL_MAIN)
}
}
fun testSmartCardio9() {
withInternalJdk(INTERNAL_MAIN, LanguageLevel.JDK_1_9) {
highlight("Main.java", """
public class Main {
private <error descr="Package 'javax.smartcardio' is declared in module 'java.smartcardio', which is not in the module graph">javax.smartcardio</error>.ATR attr;
}""".trimIndent(), INTERNAL_MAIN)
}
}
fun testSmartCardio11() {
withInternalJdk(INTERNAL_MAIN, LanguageLevel.JDK_11) {
highlight("Main.java", """
public class Main {
private javax.smartcardio.ATR attr;
}""".trimIndent(), INTERNAL_MAIN)
}
}
//<editor-fold desc="Helpers.">
private fun highlight(text: String) = highlight("module-info.java", text)
@@ -987,6 +1026,35 @@ class ModuleHighlightingTest : LightJava9ModulesCodeInsightFixtureTestCase() {
assertThat(available).describedAs(availableIntentions.toString()).containsExactlyInAnyOrder(*fixes)
}
private fun withInternalJdk(moduleDescriptor: ModuleDescriptor, level: LanguageLevel, block: () -> Unit) {
val name = "INTERNAL_JDK_TEST"
val module = getInstance(project).findModuleByName(moduleDescriptor.moduleName)!!
try {
WriteAction.runAndWait<RuntimeException?>(ThrowableRunnable {
val jdk = ProjectJdkTable.getInstance().findJdk(name)
?: JavaSdk.getInstance().createJdk(name, JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk().getHomePath()!!, false)
ProjectJdkTable.getInstance().addJdk(jdk, project)
ModuleRootModificationUtil.setModuleSdk(module, jdk)
})
IdeaTestUtil.withLevel(module, level) {
block()
}
}
finally {
WriteAction.runAndWait<RuntimeException?>(ThrowableRunnable {
ModuleRootModificationUtil.setModuleSdk(module, projectDescriptor.sdk)
ProjectJdkTable.getInstance().findJdk(name)?.also { jdk ->
ProjectJdkTable.getInstance().removeJdk(jdk)
}
})
}
}
private fun ModuleDescriptor.createSourceRoot(srcPathPrefix: String): VirtualFile? {
val module = ModuleManager.getInstance(project).findModuleByName(moduleName) ?: return null
val dummyRoot = VirtualFileManager.getInstance().findFileByUrl("temp:///") ?: return null

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.codeInsight.daemon.lambda;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
@@ -66,7 +66,7 @@ class NewMethodRefHighlightingTest extends LightJavaCodeInsightFixtureTestCase5
getFixture().doHighlighting()
.stream()
.filter(info -> info.type == HighlightInfoType.ERROR)
.forEach(info -> assertEquals("<html>Reference to 'm' is ambiguous, both 'm(Test, String)' and 'm(String)' match</html>",
.forEach(info -> assertEquals("<html>Reference to 'm' is ambiguous, both 'm(String)' and 'm(Test, String)' match</html>",
info.getToolTip()));
}
@Test void testStaticWithVarargsNonStaticReferenceTypeAmbiguity() { doTest(); }

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.testFramework.fixtures
import com.intellij.openapi.application.ex.PathManagerEx
@@ -38,6 +38,7 @@ object MultiModuleJava9ProjectDescriptor : DefaultLightProjectDescriptor() {
M6("light_idea_test_m6", sourceRootName = "src_m6", resourceRootName = "res_m6"),
M7("light_idea_test_m7", sourceRootName = "src_m7"),
M8("light_idea_test_m8", sourceRootName = "src_m8"),
INTERNAL_MAIN("llight_idea_test_internal_main", sourceRootName = "src_internal_main", resourceRootName = "res_internal_main"),
MR_MAIN("light.idea.test.mr.main", sourceRootName = "src_mr_main"),
MR_JAVA9("light.idea.test.mr.java9", sourceRootName = "src_mr_java9"),
M_TEST("light_idea_test_m_test", sourceRootName = "m_src_src", testRootName = "m_test_src");
@@ -83,6 +84,8 @@ object MultiModuleJava9ProjectDescriptor : DefaultLightProjectDescriptor() {
val mrAdd = makeModule(project, ModuleDescriptor.MR_JAVA9)
ModuleRootModificationUtil.addDependency(mrAdd, mrMain, DependencyScope.COMPILE, false)
makeModule(project, ModuleDescriptor.INTERNAL_MAIN)
val m_test = makeModule(project, ModuleDescriptor.M_TEST)
ModuleRootModificationUtil.addDependency(m_test, m2, DependencyScope.TEST, false)