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
+ 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
+ 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
+ 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
+ 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