mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-06 03:21:12 +07:00
[devkit] IDEA-294395 filter out services mentioned in extensions' attributes
GitOrigin-RevId: 5f55e2176907143ae07bb828ac11222ab5f1b3ba
This commit is contained in:
committed by
intellij-monorepo-bot
parent
271c7f2045
commit
8a21dc30d6
@@ -5,6 +5,6 @@ Reports extension implementation being additionally registered as a service/comp
|
||||
While there can be multiple extension instances, the IntelliJ Platform ensures that only one instance of a service/component is loaded,
|
||||
thus registering the same class as both an extension and a service/component may cause issues.
|
||||
</p>
|
||||
<p><small>New in 2023.1</small>
|
||||
<p><small>New in 2023.2</small>
|
||||
</body>
|
||||
</html>
|
||||
@@ -8,6 +8,7 @@ import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.ServiceDescriptor
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.util.InheritanceUtil
|
||||
import com.intellij.psi.xml.XmlTag
|
||||
import com.intellij.util.xml.DomManager
|
||||
import org.jetbrains.idea.devkit.DevKitBundle
|
||||
import org.jetbrains.idea.devkit.dom.Extension
|
||||
@@ -17,6 +18,8 @@ import org.jetbrains.uast.UClass
|
||||
|
||||
class ExtensionRegisteredAsServiceOrComponentInspection : DevKitUastInspectionBase(UClass::class.java) {
|
||||
|
||||
private val serviceAttributeNames = setOf("service")
|
||||
|
||||
override fun checkClass(uClass: UClass, manager: InspectionManager, isOnTheFly: Boolean): Array<ProblemDescriptor?>? {
|
||||
val psiClass = uClass.javaPsi
|
||||
if (!PsiUtil.isExtensionPointImplementationCandidate(psiClass)) {
|
||||
@@ -36,7 +39,7 @@ class ExtensionRegisteredAsServiceOrComponentInspection : DevKitUastInspectionBa
|
||||
if (element is Extension) {
|
||||
if (hasServiceBeanFqn(element)) {
|
||||
isService = true
|
||||
} else {
|
||||
} else if (!isValueOfServiceAttribute(tag, psiClass.qualifiedName)) {
|
||||
isExtension = true
|
||||
}
|
||||
}
|
||||
@@ -61,6 +64,14 @@ class ExtensionRegisteredAsServiceOrComponentInspection : DevKitUastInspectionBa
|
||||
return extension.extensionPoint?.beanClass?.stringValue == ServiceDescriptor::class.java.canonicalName
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all attribute names with a given value and checks they all are among [serviceAttributeNames].
|
||||
*/
|
||||
private fun isValueOfServiceAttribute(tag: XmlTag, value: String?): Boolean {
|
||||
val attributeNames = tag.attributes.filter { it.value == value }.map { it.name }.toSet()
|
||||
return serviceAttributeNames.containsAll(attributeNames)
|
||||
}
|
||||
|
||||
private fun isLightService(uClass: UClass): Boolean {
|
||||
return uClass.findAnnotation(Service::class.java.canonicalName) != null
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import com.intellij.util.xmlb.annotations.Attribute
|
||||
|
||||
class ServiceAttributeBean {
|
||||
@Attribute("id")
|
||||
String id = ""
|
||||
|
||||
@Attribute("service")
|
||||
String service = ""
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
// registered as a service + mentioned in extension registration as a service
|
||||
class ServiceWithServiceAttribute { }
|
||||
@@ -0,0 +1,14 @@
|
||||
<idea-plugin>
|
||||
<id>com.intellij.example</id>
|
||||
|
||||
<extensionPoints>
|
||||
<extensionPoint name="myExtensionWithServiceAttribute" beanClass="ServiceAttributeBean" dynamic="true"/>
|
||||
<extensionPoint name="projectService" beanClass="com.intellij.openapi.components.ServiceDescriptor" dynamic="true"/>
|
||||
</extensionPoints>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij.example">
|
||||
<projectService serviceImplementation="ServiceWithServiceAttribute"/>
|
||||
<myExtensionWithServiceAttribute id="my.extension.with.service.attribute.id" service="ServiceWithServiceAttribute"/>
|
||||
</extensions>
|
||||
|
||||
</idea-plugin>
|
||||
@@ -39,4 +39,9 @@ class ExtensionRegisteredAsServiceOrComponentInspectionTest : ExtensionRegistere
|
||||
setPluginXml("extension-component-plugin.xml")
|
||||
doTest()
|
||||
}
|
||||
|
||||
fun testServiceWithServiceAttribute() {
|
||||
setPluginXml("service-attribute-plugin.xml")
|
||||
myFixture.testHighlighting("ServiceWithServiceAttribute.java", "ServiceAttributeBean.java")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import com.intellij.util.xmlb.annotations.Attribute
|
||||
|
||||
class ServiceAttributeBean {
|
||||
@Attribute("id")
|
||||
val id: String = ""
|
||||
|
||||
@Attribute("service")
|
||||
val service: String = ""
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
// registered as a service + mentioned in extension registration as a service
|
||||
class ServiceWithServiceAttribute { }
|
||||
@@ -0,0 +1,14 @@
|
||||
<idea-plugin>
|
||||
<id>com.intellij.example</id>
|
||||
|
||||
<extensionPoints>
|
||||
<extensionPoint name="myExtensionWithServiceAttribute" beanClass="ServiceAttributeBean" dynamic="true"/>
|
||||
<extensionPoint name="projectService" beanClass="com.intellij.openapi.components.ServiceDescriptor" dynamic="true"/>
|
||||
</extensionPoints>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij.example">
|
||||
<projectService serviceImplementation="ServiceWithServiceAttribute"/>
|
||||
<myExtensionWithServiceAttribute id="my.extension.with.service.attribute.id" service="ServiceWithServiceAttribute"/>
|
||||
</extensions>
|
||||
|
||||
</idea-plugin>
|
||||
@@ -41,4 +41,9 @@ class KtExtensionRegisteredAsServiceOrComponentInspectionTest : ExtensionRegiste
|
||||
setPluginXml("extension-component-plugin.xml")
|
||||
doTest()
|
||||
}
|
||||
|
||||
fun testServiceWithServiceAttribute() {
|
||||
setPluginXml("service-attribute-plugin.xml")
|
||||
myFixture.testHighlighting("ServiceWithServiceAttribute.kt", "ServiceAttributeBean.kt")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,15 @@ abstract class ExtensionRegisteredAsServiceOrComponentInspectionTestBase : Plugi
|
||||
public interface BaseComponent { }
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
myFixture.addClass(
|
||||
//language=java
|
||||
"""
|
||||
package com.intellij.util.xmlb.annotations;
|
||||
|
||||
public @interface Attribute { }
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
protected open fun doTest() {
|
||||
|
||||
Reference in New Issue
Block a user