mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Java: Mark service implementations as used if the service declaration is used - added test cases, updated test data (IDEA-169204)
This commit is contained in:
+8
@@ -0,0 +1,8 @@
|
||||
package my.ext;
|
||||
import my.api.MyService;
|
||||
|
||||
public class MyServiceExt implements MyService {
|
||||
public MyServiceExt() {}
|
||||
@Override
|
||||
public void foo() {}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
</problems>
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package my.ext;
|
||||
import my.api.MyService;
|
||||
|
||||
public class MyServiceExt implements MyService {
|
||||
public MyServiceExt() {}
|
||||
@Override
|
||||
public void foo() {}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
</problems>
|
||||
+12
@@ -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() {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
</problems>
|
||||
+31
-3
@@ -3,8 +3,36 @@
|
||||
<problem>
|
||||
<file>MyServiceImpl.java</file>
|
||||
<line>5</line>
|
||||
<entry_point TYPE="java.module" FQNAME="M2" />
|
||||
<problem_class severity="WARNING">unused</problem_class>
|
||||
<description>Unused declaration</description>
|
||||
<package>my.impl</package>
|
||||
<entry_point TYPE="method" FQNAME="my.impl.MyServiceImpl MyServiceImpl()" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>Constructor has usage(s) but they all belong to calls chain that has no members reachable from entry points.</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyServiceImpl.java</file>
|
||||
<line>4</line>
|
||||
<package>my.impl</package>
|
||||
<entry_point TYPE="class" FQNAME="my.impl.MyServiceImpl" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>Class has one instantiation but it is not reachable from entry points.</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyService.java</file>
|
||||
<line>1</line>
|
||||
<package>my.api</package>
|
||||
<entry_point TYPE="method" FQNAME="my.api.MyService void foo()" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description><ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul></description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyService.java</file>
|
||||
<line>1</line>
|
||||
<package>my.api</package>
|
||||
<entry_point TYPE="class" FQNAME="my.api.MyService" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>&nbsp;Interface has an implementation but <ul><li>it is never instantiated OR</li><li>no instantiations are reachable from entry points.</li></ul></description>
|
||||
</problem>
|
||||
</problems>
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package my.ext;
|
||||
import my.api.MyService;
|
||||
|
||||
public class MyServiceExt implements MyService {
|
||||
public MyServiceExt() {}
|
||||
@Override
|
||||
public void foo() {}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>MyServiceExt.java</file>
|
||||
<line>5</line>
|
||||
<package>my.ext</package>
|
||||
<entry_point TYPE="method" FQNAME="my.ext.MyServiceExt MyServiceExt()" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>Constructor has usage(s) but they all belong to calls chain that has no members reachable from entry points.</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyServiceExt.java</file>
|
||||
<line>4</line>
|
||||
<package>my.ext</package>
|
||||
<entry_point TYPE="class" FQNAME="my.ext.MyServiceExt" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>Class has one instantiation but it is not reachable from entry points.</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyService.java</file>
|
||||
<line>1</line>
|
||||
<package>my.api</package>
|
||||
<entry_point TYPE="method" FQNAME="my.api.MyService void foo()" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description><ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul></description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyService.java</file>
|
||||
<line>1</line>
|
||||
<package>my.api</package>
|
||||
<entry_point TYPE="class" FQNAME="my.api.MyService" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>&nbsp;Interface has an implementation but <ul><li>it is never instantiated OR</li><li>no instantiations are reachable from entry points.</li></ul></description>
|
||||
</problem>
|
||||
</problems>
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package my.ext;
|
||||
import my.api.MyService;
|
||||
|
||||
public class MyServiceExt implements MyService {
|
||||
@Override
|
||||
public void foo() {}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>MyServiceExt.java</file>
|
||||
<line>4</line>
|
||||
<package>my.ext</package>
|
||||
<entry_point TYPE="class" FQNAME="my.ext.MyServiceExt" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>Class is not instantiated.</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyService.java</file>
|
||||
<line>1</line>
|
||||
<package>my.api</package>
|
||||
<entry_point TYPE="method" FQNAME="my.api.MyService void foo()" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description><ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul></description>
|
||||
</problem>
|
||||
</problems>
|
||||
+12
@@ -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() {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>MyServiceExt.java</file>
|
||||
<line>5</line>
|
||||
<package>my.ext</package>
|
||||
<entry_point TYPE="method" FQNAME="my.ext.MyServiceExt my.api.MyService provider()" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>Method has one usage but it is not reachable from entry points.</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyService.java</file>
|
||||
<line>1</line>
|
||||
<package>my.api</package>
|
||||
<entry_point TYPE="method" FQNAME="my.api.MyService void foo()" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description><ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul></description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyService.java</file>
|
||||
<line>1</line>
|
||||
<package>my.api</package>
|
||||
<entry_point TYPE="class" FQNAME="my.api.MyService" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>&nbsp;Interface has an implementation but <ul><li>it is never instantiated OR</li><li>no instantiations are reachable from entry points.</li></ul></description>
|
||||
</problem>
|
||||
</problems>
|
||||
+13
-3
@@ -3,8 +3,18 @@
|
||||
<problem>
|
||||
<file>MyServiceImpl.java</file>
|
||||
<line>4</line>
|
||||
<entry_point TYPE="java.module" FQNAME="M2" />
|
||||
<problem_class severity="WARNING">unused</problem_class>
|
||||
<description>Unused declaration</description>
|
||||
<package>my.impl</package>
|
||||
<entry_point TYPE="class" FQNAME="my.impl.MyServiceImpl" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>Class is not instantiated.</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyService.java</file>
|
||||
<line>1</line>
|
||||
<package>my.api</package>
|
||||
<entry_point TYPE="method" FQNAME="my.api.MyService void foo()" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description><ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul></description>
|
||||
</problem>
|
||||
</problems>
|
||||
+22
-3
@@ -3,8 +3,27 @@
|
||||
<problem>
|
||||
<file>MyServiceImpl.java</file>
|
||||
<line>5</line>
|
||||
<entry_point TYPE="java.module" FQNAME="M2" />
|
||||
<problem_class severity="WARNING">unused</problem_class>
|
||||
<description>Unused declaration</description>
|
||||
<package>my.impl</package>
|
||||
<entry_point TYPE="method" FQNAME="my.impl.MyServiceImpl my.api.MyService provider()" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>Method has one usage but it is not reachable from entry points.</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyService.java</file>
|
||||
<line>1</line>
|
||||
<package>my.api</package>
|
||||
<entry_point TYPE="method" FQNAME="my.api.MyService void foo()" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description><ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul></description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>MyService.java</file>
|
||||
<line>1</line>
|
||||
<package>my.api</package>
|
||||
<entry_point TYPE="class" FQNAME="my.api.MyService" />
|
||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">unused declaration</problem_class>
|
||||
<description>&nbsp;Interface has an implementation but <ul><li>it is never instantiated OR</li><li>no instantiations are reachable from entry points.</li></ul></description>
|
||||
</problem>
|
||||
</problems>
|
||||
+42
-15
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user