diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/externalConstructor/MyServiceExt.java b/java/java-tests/testData/inspection/unusedServiceImplementations/externalConstructor/MyServiceExt.java new file mode 100644 index 000000000000..411a9b013a77 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/externalConstructor/MyServiceExt.java @@ -0,0 +1,8 @@ +package my.ext; +import my.api.MyService; + +public class MyServiceExt implements MyService { + public MyServiceExt() {} + @Override + public void foo() {} +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/externalConstructor/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/externalConstructor/expected.xml new file mode 100644 index 000000000000..5e933496b9cf --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/externalConstructor/expected.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/externalImplementation/MyServiceExt.java b/java/java-tests/testData/inspection/unusedServiceImplementations/externalImplementation/MyServiceExt.java new file mode 100644 index 000000000000..411a9b013a77 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/externalImplementation/MyServiceExt.java @@ -0,0 +1,8 @@ +package my.ext; +import my.api.MyService; + +public class MyServiceExt implements MyService { + public MyServiceExt() {} + @Override + public void foo() {} +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/externalImplementation/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/externalImplementation/expected.xml new file mode 100644 index 000000000000..5e933496b9cf --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/externalImplementation/expected.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/externalProvider/MyServiceExt.java b/java/java-tests/testData/inspection/unusedServiceImplementations/externalProvider/MyServiceExt.java new file mode 100644 index 000000000000..9f707509eee3 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/externalProvider/MyServiceExt.java @@ -0,0 +1,12 @@ +package my.ext; +import my.api.MyService; + +public class MyServiceExt { + public static MyService provider() { + return new MyService() { + @Override + public void foo() { + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/externalProvider/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/externalProvider/expected.xml new file mode 100644 index 000000000000..5e933496b9cf --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/externalProvider/expected.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedConstructor/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedConstructor/expected.xml index ae969d8f95d0..ebefeeadcca9 100644 --- a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedConstructor/expected.xml +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedConstructor/expected.xml @@ -3,8 +3,36 @@ MyServiceImpl.java 5 - - unused - Unused declaration + my.impl + + unused declaration + Constructor has usage(s) but they all belong to calls chain that has no members reachable from entry points. + + + + MyServiceImpl.java + 4 + my.impl + + unused declaration + Class has one instantiation but it is not reachable from entry points. + + + + MyService.java + 1 + my.api + + unused declaration + <ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul> + + + + MyService.java + 1 + my.api + + unused declaration + &nbsp;Interface has an implementation but <ul><li>it is never instantiated OR</li><li>no instantiations are reachable from entry points.</li></ul> \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalConstructor/MyServiceExt.java b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalConstructor/MyServiceExt.java new file mode 100644 index 000000000000..411a9b013a77 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalConstructor/MyServiceExt.java @@ -0,0 +1,8 @@ +package my.ext; +import my.api.MyService; + +public class MyServiceExt implements MyService { + public MyServiceExt() {} + @Override + public void foo() {} +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalConstructor/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalConstructor/expected.xml new file mode 100644 index 000000000000..decf67e8deb8 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalConstructor/expected.xml @@ -0,0 +1,38 @@ + + + + MyServiceExt.java + 5 + my.ext + + unused declaration + Constructor has usage(s) but they all belong to calls chain that has no members reachable from entry points. + + + + MyServiceExt.java + 4 + my.ext + + unused declaration + Class has one instantiation but it is not reachable from entry points. + + + + MyService.java + 1 + my.api + + unused declaration + <ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul> + + + + MyService.java + 1 + my.api + + unused declaration + &nbsp;Interface has an implementation but <ul><li>it is never instantiated OR</li><li>no instantiations are reachable from entry points.</li></ul> + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalImplementation/MyServiceExt.java b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalImplementation/MyServiceExt.java new file mode 100644 index 000000000000..443a299451f9 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalImplementation/MyServiceExt.java @@ -0,0 +1,7 @@ +package my.ext; +import my.api.MyService; + +public class MyServiceExt implements MyService { + @Override + public void foo() {} +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalImplementation/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalImplementation/expected.xml new file mode 100644 index 000000000000..4057c0b897a1 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalImplementation/expected.xml @@ -0,0 +1,20 @@ + + + + MyServiceExt.java + 4 + my.ext + + unused declaration + Class is not instantiated. + + + + MyService.java + 1 + my.api + + unused declaration + <ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul> + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalProvider/MyServiceExt.java b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalProvider/MyServiceExt.java new file mode 100644 index 000000000000..9f707509eee3 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalProvider/MyServiceExt.java @@ -0,0 +1,12 @@ +package my.ext; +import my.api.MyService; + +public class MyServiceExt { + public static MyService provider() { + return new MyService() { + @Override + public void foo() { + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalProvider/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalProvider/expected.xml new file mode 100644 index 000000000000..c62bfe4b7c88 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalProvider/expected.xml @@ -0,0 +1,29 @@ + + + + MyServiceExt.java + 5 + my.ext + + unused declaration + Method has one usage but it is not reachable from entry points. + + + + MyService.java + 1 + my.api + + unused declaration + <ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul> + + + + MyService.java + 1 + my.api + + unused declaration + &nbsp;Interface has an implementation but <ul><li>it is never instantiated OR</li><li>no instantiations are reachable from entry points.</li></ul> + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedImplementation/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedImplementation/expected.xml index 6a061d5f437d..0d81e05ee29e 100644 --- a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedImplementation/expected.xml +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedImplementation/expected.xml @@ -3,8 +3,18 @@ MyServiceImpl.java 4 - - unused - Unused declaration + my.impl + + unused declaration + Class is not instantiated. + + + + MyService.java + 1 + my.api + + unused declaration + <ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul> \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedProvider/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedProvider/expected.xml index ae969d8f95d0..a30bfd93dcce 100644 --- a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedProvider/expected.xml +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedProvider/expected.xml @@ -3,8 +3,27 @@ MyServiceImpl.java 5 - - unused - Unused declaration + my.impl + + unused declaration + Method has one usage but it is not reachable from entry points. + + + + MyService.java + 1 + my.api + + unused declaration + <ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul> + + + + MyService.java + 1 + my.api + + unused declaration + &nbsp;Interface has an implementation but <ul><li>it is never instantiated OR</li><li>no instantiations are reachable from entry points.</li></ul> \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/Java9UnusedServiceImplementationsTest.kt b/java/java-tests/testSrc/com/intellij/codeInspection/Java9UnusedServiceImplementationsTest.kt index c423f01fdb51..8a8be31ff7ef 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/Java9UnusedServiceImplementationsTest.kt +++ b/java/java-tests/testSrc/com/intellij/codeInspection/Java9UnusedServiceImplementationsTest.kt @@ -16,18 +16,17 @@ package com.intellij.codeInspection import com.intellij.analysis.AnalysisScope -import com.intellij.idea.Bombed import com.intellij.openapi.application.ex.PathManagerEx +import com.intellij.openapi.module.ModuleManager +import com.intellij.openapi.roots.ModuleRootModificationUtil import com.intellij.openapi.util.io.FileUtil -import com.intellij.openapi.util.io.FileUtil.loadFileText import com.intellij.testFramework.InspectionTestCase import com.intellij.testFramework.InspectionTestUtil import com.intellij.testFramework.createGlobalContextForTool import com.intellij.testFramework.fixtures.LightJava9ModulesCodeInsightFixtureTestCase -import com.intellij.testFramework.fixtures.MultiModuleJava9ProjectDescriptor.ModuleDescriptor.M2 -import com.intellij.testFramework.fixtures.MultiModuleJava9ProjectDescriptor.ModuleDescriptor.MAIN +import com.intellij.testFramework.fixtures.MultiModuleJava9ProjectDescriptor.ModuleDescriptor +import com.intellij.testFramework.fixtures.MultiModuleJava9ProjectDescriptor.ModuleDescriptor.* import org.intellij.lang.annotations.Language -import org.jetbrains.annotations.NonNls /** * @author Pavel.Dolgov @@ -38,8 +37,7 @@ class Java9UnusedServiceImplementationsTest : LightJava9ModulesCodeInsightFixtur override fun setUp() { super.setUp() - addFile("module-info.java", "module MAIN { requires M2; }", MAIN) - addFile("module-info.java", "module M2 { exports my.api; provides my.api.MyService with my.impl.MyServiceImpl; }", M2) + moduleInfo("module MAIN { requires API; }", MAIN) addFile("my/api/MyService.java", "package my.api; public interface MyService { void foo(); }", M2) } @@ -50,17 +48,27 @@ class Java9UnusedServiceImplementationsTest : LightJava9ModulesCodeInsightFixtur fun testProvider() = doTest() - @Bombed(user ="Pavel Dolgov", year = 2017, month = 8, day = 1, description = "Disabled, until the test infrastructure supports it") fun testUnusedImplementation() = doTest(false) - @Bombed(user ="Pavel Dolgov", year = 2017, month = 8, day = 1, description = "Disabled, until the test infrastructure supports it") fun testUnusedConstructor() = doTest(false) - @Bombed(user ="Pavel Dolgov", year = 2017, month = 8, day = 1, description = "Disabled, until the test infrastructure supports it") fun testUnusedProvider() = doTest(false) - private fun doTest(withUsage: Boolean = true) { - @Language("JAVA") @NonNls + fun testExternalImplementation() = doTest(sameModule = false) + + fun testExternalConstructor() = doTest(sameModule = false) + + fun testExternalProvider() = doTest(sameModule = false) + + fun testUnusedExternalImplementation() = doTest(false, sameModule = false) + + fun testUnusedExternalConstructor() = doTest(false, sameModule = false) + + fun testUnusedExternalProvider() = doTest(false, sameModule = false) + + + private fun doTest(withUsage: Boolean = true, sameModule: Boolean = true) { + @Language("JAVA") val usageText = """ import my.api.MyService; public class MyApp { @@ -72,11 +80,26 @@ class Java9UnusedServiceImplementationsTest : LightJava9ModulesCodeInsightFixtur }""" if (withUsage) addFile("my/app/MyApp.java", usageText, MAIN) + if (sameModule) { + moduleInfo("module API { exports my.api; provides my.api.MyService with my.impl.MyServiceImpl; }", M2) + } + else { + val moduleManager = ModuleManager.getInstance(project) + val m2 = moduleManager.findModuleByName(M2.moduleName)!! + val m4 = moduleManager.findModuleByName(M4.moduleName)!! + ModuleRootModificationUtil.addDependency(m4, m2) + moduleInfo("module API { exports my.api; }", M2) + moduleInfo("module EXT { requires API; provides my.api.MyService with my.ext.MyServiceExt; }", M4) + } + val testPath = testDataPath + "/" + getTestName(true) - val sourceFile = FileUtil.findFirstThatExist(testPath + "/MyServiceImpl.java") + val sourceFile = FileUtil.findFirstThatExist("$testPath/MyService${if (sameModule) "Impl" else "Ext"}.java") assertNotNull("Test data: $testPath", sourceFile) - val implText = String(loadFileText(sourceFile!!)) - addFile("my/impl/MyServiceImpl.java", implText, M2) + val implText = String(FileUtil.loadFileText(sourceFile!!)) + if (sameModule) + addFile("my/impl/MyServiceImpl.java", implText, M2) + else + addFile("my/ext/MyServiceExt.java", implText, M4) val toolWrapper = InspectionTestCase.getUnusedDeclarationWrapper() val scope = AnalysisScope(project) @@ -84,4 +107,8 @@ class Java9UnusedServiceImplementationsTest : LightJava9ModulesCodeInsightFixtur InspectionTestUtil.runTool(toolWrapper, scope, globalContext) InspectionTestUtil.compareToolResults(globalContext, toolWrapper, true, testPath) } + + private fun moduleInfo(@Language("JAVA") moduleInfoText: String, descriptor: ModuleDescriptor) { + addFile("module-info.java", moduleInfoText, descriptor) + } } \ No newline at end of file