diff --git a/plugins/devkit/devkit-core/resources/inspectionDescriptions/IncorrectServiceRetrieving.html b/plugins/devkit/devkit-core/resources/inspectionDescriptions/IncorrectServiceRetrieving.html
new file mode 100644
index 000000000000..e2ff2712254b
--- /dev/null
+++ b/plugins/devkit/devkit-core/resources/inspectionDescriptions/IncorrectServiceRetrieving.html
@@ -0,0 +1,28 @@
+
+
+Reports the following problems when retrieving services:
+
+ - Attempts to retrieve an unregistered service.
+ - Mismatch when retrieving a service: attempting to get a project-level service as an application-level service, or vice versa.
+
+Example (Kotlin):
+
+@Service
+class MyAppService
+
+@Service(Service.Level.PROJECT)
+class MyProjectService(private val project: Project)
+
+
+// Bad:
+val projectService = service<MyProjectService>() // The project-level service is retrieved as an application-level service
+val applicationService = project.service<MyAppService>() // The application-level service is retrieved as a project-level service
+
+
+// Good:
+val projectService = project.service<MyProjectService>()
+val applicationService = service<MyAppService>();
+
+New in 2023.2
+
+
\ No newline at end of file
diff --git a/plugins/devkit/devkit-core/resources/inspectionDescriptions/RetrievingService.html b/plugins/devkit/devkit-core/resources/inspectionDescriptions/RetrievingService.html
deleted file mode 100644
index 106127071f4f..000000000000
--- a/plugins/devkit/devkit-core/resources/inspectionDescriptions/RetrievingService.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-Reports the following problems when retrieving services:
-
- - Attempts to retrieve an unregistered service
- - Mismatch when retrieving a service: attempting to get a project-level service as an application-level service, or vice versa.
- - Getting service call can be replaced with a call to an existing static
getInstance() or getInstance(Project)
- method.
-
-
-New in 2023.2
-
-
\ No newline at end of file
diff --git a/plugins/devkit/devkit-core/resources/inspectionDescriptions/SimplifiableServiceRetrieving.html b/plugins/devkit/devkit-core/resources/inspectionDescriptions/SimplifiableServiceRetrieving.html
new file mode 100644
index 000000000000..c36a2b49cc2c
--- /dev/null
+++ b/plugins/devkit/devkit-core/resources/inspectionDescriptions/SimplifiableServiceRetrieving.html
@@ -0,0 +1,33 @@
+
+
+Reports service getting calls that can be replaced with a calls to an existing static getInstance()
+or getInstance(Project) methods.
+Example (Java):
+
+@Service
+public class MyAppService {
+ public static MyAppService getInstance() {
+ return ApplicationManager.getApplication().getService(MyAppService.class);
+ }
+}
+
+@Service(Service.Level.PROJECT)
+public class MyProjectService {
+ public static MyProjectService getInstance(Project project) {
+ return project.getService(MyProjectService.class);
+ }
+}
+
+
+// Bad:
+MyAppService applicationService = ApplicationManager.getApplication().getService(MyAppService.class);
+MyProjectService projectService = project.getService(MyProjectService.class);
+
+
+// Good:
+MyAppService applicationService = MyAppService.getInstance();
+MyProjectService projectService = MyProjectService.getInstance(project);
+
+New in 2023.2
+
+
\ No newline at end of file
diff --git a/plugins/devkit/devkit-core/resources/intellij.devkit.core.xml b/plugins/devkit/devkit-core/resources/intellij.devkit.core.xml
index d597af13ab0b..2750ebfdc93c 100644
--- a/plugins/devkit/devkit-core/resources/intellij.devkit.core.xml
+++ b/plugins/devkit/devkit-core/resources/intellij.devkit.core.xml
@@ -285,12 +285,18 @@
enabledByDefault="true" level="WARNING"
implementationClass="org.jetbrains.idea.devkit.inspections.MismatchedLightServiceLevelAndCtorInspection"
key="inspection.mismatched.light.service.level.and.ctor.display.name"/>
-
+ implementationClass="org.jetbrains.idea.devkit.inspections.IncorrectServiceRetrievingInspection"
+ key="inspection.incorrect.service.retrieving.display.name"/>
+
+ val message = DevKitBundle.message("inspection.incorrect.service.retrieving.not.registered", className)
+ holder.registerUProblem(node, message)
+ }
+ }
+ else if (!isServiceRetrievedCorrectly(serviceLevel, howServiceRetrieved)) {
+ val message = when (howServiceRetrieved) {
+ Level.APP -> DevKitBundle.message("inspection.incorrect.service.retrieving.mismatch.for.project.level")
+ Level.PROJECT -> DevKitBundle.message("inspection.incorrect.service.retrieving.mismatch.for.app.level")
+ }
+ holder.registerUProblem(node, message)
+ }
+ return true
+ }
+ }, arrayOf(UCallExpression::class.java))
+ }
+
+ private fun isServiceRetrievedCorrectly(serviceLevel: LevelType, howServiceRetrieved: Level): Boolean {
+ return serviceLevel == LevelType.NOT_SPECIFIED ||
+ when (howServiceRetrieved) {
+ Level.APP -> serviceLevel.isApp()
+ Level.PROJECT -> serviceLevel.isProject()
+ }
+ }
+}
diff --git a/plugins/devkit/devkit-core/src/inspections/RetrievingServiceInspection.kt b/plugins/devkit/devkit-core/src/inspections/RetrievingServiceInspection.kt
deleted file mode 100644
index 57f0b1e51fd2..000000000000
--- a/plugins/devkit/devkit-core/src/inspections/RetrievingServiceInspection.kt
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package org.jetbrains.idea.devkit.inspections
-
-import com.intellij.codeInspection.*
-import com.intellij.openapi.application.Application
-import com.intellij.openapi.components.ComponentManager
-import com.intellij.openapi.components.Service.Level
-import com.intellij.openapi.project.Project
-import com.intellij.openapi.util.text.StringUtil
-import com.intellij.psi.CommonClassNames
-import com.intellij.psi.PsiClassType
-import com.intellij.psi.PsiElementVisitor
-import com.intellij.psi.util.InheritanceUtil
-import com.intellij.uast.UastHintedVisitorAdapter
-import com.siyeh.ig.callMatcher.CallMatcher
-import org.jetbrains.idea.devkit.DevKitBundle
-import org.jetbrains.uast.*
-import org.jetbrains.uast.generate.UastCodeGenerationPlugin
-import org.jetbrains.uast.generate.replace
-import org.jetbrains.uast.visitor.AbstractUastNonRecursiveVisitor
-
-private val SERVICE_KT_METHODS =
- CallMatcher.staticCall("com.intellij.openapi.components.ServiceKt", "service", "serviceOrNull", "serviceIfCreated")
- .parameterCount(0)
-private val SERVICES_KT_METHODS =
- CallMatcher.staticCall("com.intellij.openapi.components.ServicesKt", "service", "serviceOrNull", "serviceIfCreated")
- .parameterTypes(ComponentManager::class.java.canonicalName)
-
-private val COMPONENT_MANAGER_GET_SERVICE = CallMatcher.anyOf(
- CallMatcher.instanceCall(ComponentManager::class.java.canonicalName, "getService").parameterTypes(CommonClassNames.JAVA_LANG_CLASS),
- CallMatcher.instanceCall(ComponentManager::class.java.canonicalName, "getService").parameterTypes(CommonClassNames.JAVA_LANG_CLASS,
- "boolean"),
- SERVICE_KT_METHODS,
- SERVICES_KT_METHODS,
-)
-
-internal class RetrievingServiceInspection : DevKitUastInspectionBase() {
-
- override fun buildInternalVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
- return UastHintedVisitorAdapter.create(holder.file.language, object : AbstractUastNonRecursiveVisitor() {
-
- override fun visitCallExpression(node: UCallExpression): Boolean {
- if (!COMPONENT_MANAGER_GET_SERVICE.uCallMatches(node)) return true
- val howServiceRetrieved = howServiceRetrieved(node) ?: return true
- val serviceType = node.returnType as? PsiClassType ?: return true
- val serviceClass = serviceType.resolve()?.toUElement(UClass::class.java) ?: return true
- val serviceLevel = getLevelType(holder.project, serviceClass)
- if (serviceLevel == LevelType.MODULE) return true
- if (serviceLevel == LevelType.NOT_REGISTERED) {
- val className = serviceClass.qualifiedName
- if (className != null) {
- val message = DevKitBundle.message("inspection.retrieving.service.not.registered", className)
- holder.registerUProblem(node, message)
- }
- }
- else if (!isServiceRetrievedCorrectly(serviceLevel, howServiceRetrieved)) {
- registerProblemMismatchedRetrieving(howServiceRetrieved, holder, node)
- }
- else {
- val retrievingExpression = node.uastParent as? UQualifiedReferenceExpression ?: return true
- val getInstanceMethod = findGetInstanceMethod(retrievingExpression, howServiceRetrieved, serviceClass)
- if (getInstanceMethod != null) {
- registerProblem(getInstanceMethod, howServiceRetrieved, holder, retrievingExpression)
- }
- }
- return true
- }
- }, arrayOf(UCallExpression::class.java))
- }
-
- private fun registerProblemMismatchedRetrieving(howServiceRetrieved: Level,
- holder: ProblemsHolder,
- node: UCallExpression) {
- val message = when (howServiceRetrieved) {
- Level.APP -> DevKitBundle.message("inspection.retrieving.service.mismatch.for.project.level")
- Level.PROJECT -> DevKitBundle.message("inspection.retrieving.service.mismatch.for.app.level")
- }
- holder.registerUProblem(node, message)
- }
-
- private fun isServiceRetrievedCorrectly(serviceLevel: LevelType, howServiceRetrieved: Level): Boolean {
- return serviceLevel == LevelType.NOT_SPECIFIED ||
- when (howServiceRetrieved) {
- Level.APP -> serviceLevel.isApp()
- Level.PROJECT -> serviceLevel.isProject()
- }
- }
-
- private fun howServiceRetrieved(getServiceCandidate: UCallExpression): Level? {
- if (SERVICE_KT_METHODS.uCallMatches(getServiceCandidate)) return Level.APP
- val receiverType = getServiceCandidate.receiver?.getExpressionType() ?: return null
- val aClass = (receiverType as? PsiClassType)?.resolve() ?: return null
- return when {
- InheritanceUtil.isInheritor(aClass, Application::class.java.canonicalName) -> Level.APP
- InheritanceUtil.isInheritor(aClass, Project::class.java.canonicalName) -> Level.PROJECT
- else -> null
- }
- }
-
- private fun findGetInstanceMethod(retrievingExpression: UQualifiedReferenceExpression,
- howServiceRetrieved: Level,
- serviceClass: UClass): UMethod? {
- val returnExpr = retrievingExpression.uastParent as? UReturnExpression
- if (returnExpr != null) {
- val containingMethod = returnExpr.jumpTarget as? UMethod
- if (containingMethod != null) {
- if (howServiceRetrieved == Level.APP && isGetInstanceApplicationLevel(containingMethod)) return null
- if (howServiceRetrieved == Level.PROJECT && isGetInstanceProjectLevel(containingMethod)) return null
- }
- }
- return when (howServiceRetrieved) {
- Level.APP -> findGetInstanceApplicationLevel(serviceClass)
- Level.PROJECT -> findGetInstanceProjectLevel(serviceClass)
- }
- }
-
- private fun registerProblem(replacementMethod: UMethod,
- howServiceRetrieved: Level,
- holder: ProblemsHolder,
- retrievingExpression: UQualifiedReferenceExpression) {
- val qualifiedName = replacementMethod.getContainingUClass()?.qualifiedName ?: return
- val serviceName = StringUtil.getShortName(qualifiedName)
- val message = DevKitBundle.message("inspection.retrieving.service.can.be.replaced.with", serviceName, replacementMethod.name)
- val fix = ReplaceWithGetInstanceCallFix(serviceName, replacementMethod.name, howServiceRetrieved)
- holder.registerUProblem(retrievingExpression, message, fixes = arrayOf(fix), ProblemHighlightType.WEAK_WARNING)
- }
-
- private fun findGetInstanceProjectLevel(uClass: UClass): UMethod? {
- return uClass.methods.find { isGetInstanceProjectLevel(it) }
- }
-
- private fun isGetInstanceProjectLevel(method: UMethod): Boolean {
- if (!(method.isStaticOrJvmStatic &&
- method.visibility == UastVisibility.PUBLIC &&
- method.uastParameters.size == 1)) {
- return false
- }
- val param = method.uastParameters[0]
- if (param.type.canonicalText != Project::class.java.canonicalName) return false
- val qualifiedRef = getReturnExpression(method)?.returnExpression as? UQualifiedReferenceExpression ?: return false
- return COMPONENT_MANAGER_GET_SERVICE.uCallMatches(qualifiedRef.selector as? UCallExpression) &&
- (qualifiedRef.receiver as? USimpleNameReferenceExpression)?.resolveToUElement() == param
- }
-
- private fun findGetInstanceApplicationLevel(uClass: UClass): UMethod? {
- return uClass.methods.find { isGetInstanceApplicationLevel(it) }
- }
-
- private fun isGetInstanceApplicationLevel(method: UMethod): Boolean {
- if (!(method.isStaticOrJvmStatic &&
- method.visibility == UastVisibility.PUBLIC &&
- method.uastParameters.isEmpty())) {
- return false
- }
- val qualifiedRef = getReturnExpression(method)?.returnExpression as? UQualifiedReferenceExpression ?: return false
- return COMPONENT_MANAGER_GET_SERVICE.uCallMatches(qualifiedRef.selector as? UCallExpression) &&
- qualifiedRef.receiver.getExpressionType()?.isInheritorOf(Application::class.java.canonicalName) == true
- }
-
- private val UMethod.isStaticOrJvmStatic: Boolean
- get() = this.isStatic || this.findAnnotation(JvmStatic::class.java.canonicalName) != null
-
- private fun getReturnExpression(method: UMethod): UReturnExpression? {
- return (method.uastBody as? UBlockExpression)?.expressions?.singleOrNull() as? UReturnExpression
- }
-
- private class ReplaceWithGetInstanceCallFix(private val serviceName: String,
- private val methodName: String,
- private val howServiceRetrieved: Level) : LocalQuickFix {
-
- override fun getFamilyName(): String = DevKitBundle.message("inspection.retrieving.service.replace.with", serviceName, methodName)
-
- override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
- val oldCall = descriptor.psiElement.toUElement()?.getParentOfType() ?: return
- val generationPlugin = UastCodeGenerationPlugin.byLanguage(descriptor.psiElement.language) ?: return
- val factory = generationPlugin.getElementFactory(project)
- val serviceName = oldCall.getExpressionType()?.canonicalText ?: return
- val parameters = when (howServiceRetrieved) {
- Level.APP -> emptyList()
- Level.PROJECT -> listOf(oldCall.receiver)
- }
- val context = oldCall.sourcePsi
- val receiver = factory.createQualifiedReference(serviceName, context) ?: factory.createSimpleReference(serviceName, context)
- val newCall = factory.createCallExpression(receiver = receiver,
- methodName = methodName, parameters = parameters,
- expectedReturnType = oldCall.getExpressionType(), kind = UastCallKind.METHOD_CALL,
- context = null) ?: return
- oldCall.replace(newCall)
- }
- }
-}
diff --git a/plugins/devkit/devkit-core/src/inspections/ServiceRetrievingUtil.kt b/plugins/devkit/devkit-core/src/inspections/ServiceRetrievingUtil.kt
new file mode 100644
index 000000000000..d5eda43aa9d7
--- /dev/null
+++ b/plugins/devkit/devkit-core/src/inspections/ServiceRetrievingUtil.kt
@@ -0,0 +1,54 @@
+// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+
+@file:JvmName("ServiceRetrievingUtil")
+
+package org.jetbrains.idea.devkit.inspections
+
+import com.intellij.openapi.application.Application
+import com.intellij.openapi.components.ComponentManager
+import com.intellij.openapi.components.Service
+import com.intellij.openapi.project.Project
+import com.intellij.psi.CommonClassNames
+import com.intellij.psi.PsiClassType
+import com.intellij.psi.util.InheritanceUtil
+import com.siyeh.ig.callMatcher.CallMatcher
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.UClass
+import org.jetbrains.uast.toUElement
+
+private val SERVICE_KT_METHODS =
+ CallMatcher.staticCall("com.intellij.openapi.components.ServiceKt", "service", "serviceOrNull", "serviceIfCreated")
+ .parameterCount(0)
+private val SERVICES_KT_METHODS =
+ CallMatcher.staticCall("com.intellij.openapi.components.ServicesKt", "service", "serviceOrNull", "serviceIfCreated")
+ .parameterTypes(ComponentManager::class.java.canonicalName)
+
+internal val COMPONENT_MANAGER_GET_SERVICE = CallMatcher.anyOf(
+ CallMatcher.instanceCall(ComponentManager::class.java.canonicalName, "getService").parameterTypes(CommonClassNames.JAVA_LANG_CLASS),
+ CallMatcher.instanceCall(ComponentManager::class.java.canonicalName, "getService").parameterTypes(CommonClassNames.JAVA_LANG_CLASS,
+ "boolean"),
+ SERVICE_KT_METHODS,
+ SERVICES_KT_METHODS,
+)
+
+internal data class ServiceRetrievingInfo(val howServiceRetrieved: Service.Level,
+ val serviceClass: UClass)
+
+internal fun getServiceRetrievingInfo(node: UCallExpression): ServiceRetrievingInfo? {
+ if (!COMPONENT_MANAGER_GET_SERVICE.uCallMatches(node)) return null
+ val howServiceRetrieved = howServiceRetrieved(node) ?: return null
+ val serviceType = node.returnType as? PsiClassType ?: return null
+ val serviceClass = serviceType.resolve()?.toUElement(UClass::class.java) ?: return null
+ return ServiceRetrievingInfo(howServiceRetrieved, serviceClass)
+}
+
+internal fun howServiceRetrieved(getServiceCandidate: UCallExpression): Service.Level? {
+ if (SERVICE_KT_METHODS.uCallMatches(getServiceCandidate)) return Service.Level.APP
+ val receiverType = getServiceCandidate.receiver?.getExpressionType() ?: return null
+ val aClass = (receiverType as? PsiClassType)?.resolve() ?: return null
+ return when {
+ InheritanceUtil.isInheritor(aClass, Application::class.java.canonicalName) -> Service.Level.APP
+ InheritanceUtil.isInheritor(aClass, Project::class.java.canonicalName) -> Service.Level.PROJECT
+ else -> null
+ }
+}
diff --git a/plugins/devkit/devkit-core/src/inspections/SimplifiableServiceRetrievingInspection.kt b/plugins/devkit/devkit-core/src/inspections/SimplifiableServiceRetrievingInspection.kt
new file mode 100644
index 000000000000..2e5d2b107516
--- /dev/null
+++ b/plugins/devkit/devkit-core/src/inspections/SimplifiableServiceRetrievingInspection.kt
@@ -0,0 +1,122 @@
+// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package org.jetbrains.idea.devkit.inspections
+
+import com.intellij.codeInspection.*
+import com.intellij.openapi.application.Application
+import com.intellij.openapi.components.Service
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.util.text.StringUtil
+import com.intellij.psi.PsiElementVisitor
+import com.intellij.uast.UastHintedVisitorAdapter
+import org.jetbrains.idea.devkit.DevKitBundle
+import org.jetbrains.uast.*
+import org.jetbrains.uast.generate.UastCodeGenerationPlugin
+import org.jetbrains.uast.generate.replace
+import org.jetbrains.uast.visitor.AbstractUastNonRecursiveVisitor
+
+internal class SimplifiableServiceRetrievingInspection : DevKitUastInspectionBase() {
+
+ override fun buildInternalVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
+ return UastHintedVisitorAdapter.create(holder.file.language, object : AbstractUastNonRecursiveVisitor() {
+
+ override fun visitCallExpression(node: UCallExpression): Boolean {
+ val (howServiceRetrieved, serviceClass) = getServiceRetrievingInfo(node) ?: return true
+ val retrievingExpression = node.uastParent as? UQualifiedReferenceExpression ?: return true
+ val getInstanceMethod = findGetInstanceMethod(retrievingExpression, howServiceRetrieved, serviceClass)
+ if (getInstanceMethod != null) {
+ registerProblem(getInstanceMethod, howServiceRetrieved, holder, retrievingExpression)
+ }
+ return true
+ }
+ }, arrayOf(UCallExpression::class.java))
+ }
+
+ private fun findGetInstanceMethod(retrievingExpression: UQualifiedReferenceExpression,
+ howServiceRetrieved: Service.Level,
+ serviceClass: UClass): UMethod? {
+ val returnExpr = retrievingExpression.uastParent as? UReturnExpression
+ if (returnExpr != null) {
+ val containingMethod = returnExpr.jumpTarget as? UMethod
+ if (containingMethod != null) {
+ if (howServiceRetrieved == Service.Level.APP && isGetInstanceApplicationLevel(containingMethod)) return null
+ if (howServiceRetrieved == Service.Level.PROJECT && isGetInstanceProjectLevel(containingMethod)) return null
+ }
+ }
+ return when (howServiceRetrieved) {
+ Service.Level.APP -> findGetInstanceApplicationLevel(serviceClass)
+ Service.Level.PROJECT -> findGetInstanceProjectLevel(serviceClass)
+ }
+ }
+
+ private fun registerProblem(replacementMethod: UMethod,
+ howServiceRetrieved: Service.Level,
+ holder: ProblemsHolder,
+ retrievingExpression: UQualifiedReferenceExpression) {
+ val qualifiedName = replacementMethod.getContainingUClass()?.qualifiedName ?: return
+ val serviceName = StringUtil.getShortName(qualifiedName)
+ val message = DevKitBundle.message("inspection.simplifiable.service.retrieving.can.be.replaced.with", serviceName,
+ replacementMethod.name)
+ val fix = ReplaceWithGetInstanceCallFix(serviceName, replacementMethod.name, howServiceRetrieved)
+ holder.registerUProblem(retrievingExpression, message, fixes = arrayOf(fix))
+ }
+
+ private fun findGetInstanceProjectLevel(uClass: UClass): UMethod? {
+ return uClass.methods.find { isGetInstanceProjectLevel(it) }
+ }
+
+ private fun isGetInstanceProjectLevel(method: UMethod): Boolean {
+ if (!(method.isStaticOrJvmStatic && method.visibility == UastVisibility.PUBLIC && method.uastParameters.size == 1)) {
+ return false
+ }
+ val param = method.uastParameters[0]
+ if (param.type.canonicalText != Project::class.java.canonicalName) return false
+ val qualifiedRef = getReturnExpression(method)?.returnExpression as? UQualifiedReferenceExpression ?: return false
+ return COMPONENT_MANAGER_GET_SERVICE.uCallMatches(qualifiedRef.selector as? UCallExpression) &&
+ (qualifiedRef.receiver as? USimpleNameReferenceExpression)?.resolveToUElement() == param
+ }
+
+ private fun findGetInstanceApplicationLevel(uClass: UClass): UMethod? {
+ return uClass.methods.find { isGetInstanceApplicationLevel(it) }
+ }
+
+ private fun isGetInstanceApplicationLevel(method: UMethod): Boolean {
+ if (!(method.isStaticOrJvmStatic && method.visibility == UastVisibility.PUBLIC && method.uastParameters.isEmpty())) {
+ return false
+ }
+ val qualifiedRef = getReturnExpression(method)?.returnExpression as? UQualifiedReferenceExpression ?: return false
+ return COMPONENT_MANAGER_GET_SERVICE.uCallMatches(qualifiedRef.selector as? UCallExpression) &&
+ qualifiedRef.receiver.getExpressionType()?.isInheritorOf(Application::class.java.canonicalName) == true
+ }
+
+ private val UMethod.isStaticOrJvmStatic: Boolean
+ get() = this.isStatic || this.findAnnotation(JvmStatic::class.java.canonicalName) != null
+
+ private fun getReturnExpression(method: UMethod): UReturnExpression? {
+ return (method.uastBody as? UBlockExpression)?.expressions?.singleOrNull() as? UReturnExpression
+ }
+
+ private class ReplaceWithGetInstanceCallFix(private val serviceName: String,
+ private val methodName: String,
+ private val howServiceRetrieved: Service.Level) : LocalQuickFix {
+
+ override fun getFamilyName(): String = DevKitBundle.message("inspection.simplifiable.service.retrieving.replace.with", serviceName,
+ methodName)
+
+ override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
+ val oldCall = descriptor.psiElement.toUElement()?.getParentOfType() ?: return
+ val generationPlugin = UastCodeGenerationPlugin.byLanguage(descriptor.psiElement.language) ?: return
+ val factory = generationPlugin.getElementFactory(project)
+ val serviceName = oldCall.getExpressionType()?.canonicalText ?: return
+ val parameters = when (howServiceRetrieved) {
+ Service.Level.APP -> emptyList()
+ Service.Level.PROJECT -> listOf(oldCall.receiver)
+ }
+ val context = oldCall.sourcePsi
+ val receiver = factory.createQualifiedReference(serviceName, context) ?: factory.createSimpleReference(serviceName, context)
+ val newCall = factory.createCallExpression(receiver = receiver, methodName = methodName, parameters = parameters,
+ expectedReturnType = oldCall.getExpressionType(), kind = UastCallKind.METHOD_CALL,
+ context = null) ?: return
+ oldCall.replace(newCall)
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/retrievingService/AppLevelServiceAsProjectLevel.java b/plugins/devkit/devkit-java-tests/testData/inspections/incorrectServiceRetrieving/AppLevelServiceAsProjectLevel.java
similarity index 100%
rename from plugins/devkit/devkit-java-tests/testData/inspections/retrievingService/AppLevelServiceAsProjectLevel.java
rename to plugins/devkit/devkit-java-tests/testData/inspections/incorrectServiceRetrieving/AppLevelServiceAsProjectLevel.java
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/retrievingService/ProjectLevelServiceAsAppLevel.java b/plugins/devkit/devkit-java-tests/testData/inspections/incorrectServiceRetrieving/ProjectLevelServiceAsAppLevel.java
similarity index 100%
rename from plugins/devkit/devkit-java-tests/testData/inspections/retrievingService/ProjectLevelServiceAsAppLevel.java
rename to plugins/devkit/devkit-java-tests/testData/inspections/incorrectServiceRetrieving/ProjectLevelServiceAsAppLevel.java
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/retrievingService/UnregisteredService.java b/plugins/devkit/devkit-java-tests/testData/inspections/incorrectServiceRetrieving/UnregisteredService.java
similarity index 100%
rename from plugins/devkit/devkit-java-tests/testData/inspections/retrievingService/UnregisteredService.java
rename to plugins/devkit/devkit-java-tests/testData/inspections/incorrectServiceRetrieving/UnregisteredService.java
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/retrievingService/ReplaceWithGetInstanceApplicationLevel.java b/plugins/devkit/devkit-java-tests/testData/inspections/simplifiableServiceRetrieving/ReplaceWithGetInstanceApplicationLevel.java
similarity index 100%
rename from plugins/devkit/devkit-java-tests/testData/inspections/retrievingService/ReplaceWithGetInstanceApplicationLevel.java
rename to plugins/devkit/devkit-java-tests/testData/inspections/simplifiableServiceRetrieving/ReplaceWithGetInstanceApplicationLevel.java
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/retrievingService/ReplaceWithGetInstanceApplicationLevel_after.java b/plugins/devkit/devkit-java-tests/testData/inspections/simplifiableServiceRetrieving/ReplaceWithGetInstanceApplicationLevel_after.java
similarity index 100%
rename from plugins/devkit/devkit-java-tests/testData/inspections/retrievingService/ReplaceWithGetInstanceApplicationLevel_after.java
rename to plugins/devkit/devkit-java-tests/testData/inspections/simplifiableServiceRetrieving/ReplaceWithGetInstanceApplicationLevel_after.java
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/retrievingService/ReplaceWithGetInstanceProjectLevel.java b/plugins/devkit/devkit-java-tests/testData/inspections/simplifiableServiceRetrieving/ReplaceWithGetInstanceProjectLevel.java
similarity index 100%
rename from plugins/devkit/devkit-java-tests/testData/inspections/retrievingService/ReplaceWithGetInstanceProjectLevel.java
rename to plugins/devkit/devkit-java-tests/testData/inspections/simplifiableServiceRetrieving/ReplaceWithGetInstanceProjectLevel.java
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/retrievingService/ReplaceWithGetInstanceProjectLevel_after.java b/plugins/devkit/devkit-java-tests/testData/inspections/simplifiableServiceRetrieving/ReplaceWithGetInstanceProjectLevel_after.java
similarity index 100%
rename from plugins/devkit/devkit-java-tests/testData/inspections/retrievingService/ReplaceWithGetInstanceProjectLevel_after.java
rename to plugins/devkit/devkit-java-tests/testData/inspections/simplifiableServiceRetrieving/ReplaceWithGetInstanceProjectLevel_after.java
diff --git a/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/DevkitInspectionsRegistrationCheckTest.java b/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/DevkitInspectionsRegistrationCheckTest.java
index 03bbed774fb8..0ea2be38349b 100644
--- a/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/DevkitInspectionsRegistrationCheckTest.java
+++ b/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/DevkitInspectionsRegistrationCheckTest.java
@@ -44,7 +44,7 @@ public class DevkitInspectionsRegistrationCheckTest extends BasePlatformTestCase
List devkitInspections = ContainerUtil.filter(LocalInspectionEP.LOCAL_INSPECTION.getExtensionList(), ep -> {
return "DevKit".equals(ep.getPluginDescriptor().getPluginId().getIdString());
});
- assertEquals("Mismatch in total inspections, check classpath in test run configuration (intellij.devkit.plugin)", 67,
+ assertEquals("Mismatch in total inspections, check classpath in test run configuration (intellij.devkit.plugin)", 68,
devkitInspections.size());
List disabledInspections = ContainerUtil.filter(devkitInspections, ep -> !ep.enabledByDefault);
diff --git a/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/IncorrectServiceRetrievingInspectionTest.kt b/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/IncorrectServiceRetrievingInspectionTest.kt
new file mode 100644
index 000000000000..9cd0715c8bc7
--- /dev/null
+++ b/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/IncorrectServiceRetrievingInspectionTest.kt
@@ -0,0 +1,25 @@
+// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package org.jetbrains.idea.devkit.inspections
+
+import com.intellij.testFramework.TestDataPath
+import org.jetbrains.idea.devkit.DevkitJavaTestsUtil
+
+@TestDataPath("\$CONTENT_ROOT/testData/inspections/incorrectServiceRetrieving")
+internal class IncorrectServiceRetrievingInspectionTest : IncorrectServiceRetrievingInspectionTestBase() {
+
+ override fun getBasePath() = DevkitJavaTestsUtil.TESTDATA_PATH + "inspections/incorrectServiceRetrieving/"
+
+ override fun getFileExtension() = "java"
+
+ fun testAppLevelServiceAsProjectLevel() {
+ doTest()
+ }
+
+ fun testProjectLevelServiceAsAppLevel() {
+ doTest()
+ }
+
+ fun testUnregisteredService() {
+ doTest()
+ }
+}
diff --git a/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/RetrievingServiceInspectionTest.kt b/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/RetrievingServiceInspectionTest.kt
deleted file mode 100644
index 30b7bed4936e..000000000000
--- a/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/RetrievingServiceInspectionTest.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package org.jetbrains.idea.devkit.inspections
-
-import com.intellij.testFramework.TestDataPath
-import org.jetbrains.idea.devkit.DevKitBundle
-import org.jetbrains.idea.devkit.DevkitJavaTestsUtil
-import org.jetbrains.idea.devkit.inspections.quickfix.RetrievingServiceInspectionTestBase
-
-@TestDataPath("\$CONTENT_ROOT/testData/inspections/retrievingService")
-internal class RetrievingServiceInspectionTest : RetrievingServiceInspectionTestBase() {
-
- override fun getBasePath() = DevkitJavaTestsUtil.TESTDATA_PATH + "inspections/retrievingService/"
-
- override fun getFileExtension() = "java"
-
- fun testAppLevelServiceAsProjectLevel() {
- doTest()
- }
-
- fun testProjectLevelServiceAsAppLevel() {
- doTest()
- }
-
- fun testReplaceWithGetInstanceApplicationLevel() {
- doTest(DevKitBundle.message("inspection.retrieving.service.replace.with", "MyService", "getInstance"))
- }
-
- fun testReplaceWithGetInstanceProjectLevel() {
- doTest(DevKitBundle.message("inspection.retrieving.service.replace.with", "MyService", "getInstance"))
- }
-
- fun testUnregisteredService() {
- doTest()
- }
-}
diff --git a/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/quickfix/SimplifiableServiceRetrievingInspectionTest.kt b/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/quickfix/SimplifiableServiceRetrievingInspectionTest.kt
new file mode 100644
index 000000000000..9795e5c4ea74
--- /dev/null
+++ b/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/quickfix/SimplifiableServiceRetrievingInspectionTest.kt
@@ -0,0 +1,22 @@
+// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package org.jetbrains.idea.devkit.inspections.quickfix
+
+import com.intellij.testFramework.TestDataPath
+import org.jetbrains.idea.devkit.DevKitBundle
+import org.jetbrains.idea.devkit.DevkitJavaTestsUtil
+
+@TestDataPath("\$CONTENT_ROOT/testData/inspections/simplifiableServiceRetrieving")
+internal class SimplifiableServiceRetrievingInspectionTest : SimplifiableServiceRetrievingInspectionTestBase() {
+
+ override fun getBasePath() = DevkitJavaTestsUtil.TESTDATA_PATH + "inspections/simplifiableServiceRetrieving/"
+
+ override fun getFileExtension() = "java"
+
+ fun testReplaceWithGetInstanceApplicationLevel() {
+ doTest(DevKitBundle.message("inspection.simplifiable.service.retrieving.replace.with", "MyService", "getInstance"))
+ }
+
+ fun testReplaceWithGetInstanceProjectLevel() {
+ doTest(DevKitBundle.message("inspection.simplifiable.service.retrieving.replace.with", "MyService", "getInstance"))
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/retrievingService/RetrievingServiceAsAppLevel.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/incorrectServiceRetrieving/RetrievingServiceAsAppLevel.kt
similarity index 100%
rename from plugins/devkit/devkit-kotlin-tests/testData/inspections/retrievingService/RetrievingServiceAsAppLevel.kt
rename to plugins/devkit/devkit-kotlin-tests/testData/inspections/incorrectServiceRetrieving/RetrievingServiceAsAppLevel.kt
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/retrievingService/RetrievingServiceAsProjectLevel.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/incorrectServiceRetrieving/RetrievingServiceAsProjectLevel.kt
similarity index 100%
rename from plugins/devkit/devkit-kotlin-tests/testData/inspections/retrievingService/RetrievingServiceAsProjectLevel.kt
rename to plugins/devkit/devkit-kotlin-tests/testData/inspections/incorrectServiceRetrieving/RetrievingServiceAsProjectLevel.kt
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/retrievingService/UnregisteredServices.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/incorrectServiceRetrieving/UnregisteredServices.kt
similarity index 100%
rename from plugins/devkit/devkit-kotlin-tests/testData/inspections/retrievingService/UnregisteredServices.kt
rename to plugins/devkit/devkit-kotlin-tests/testData/inspections/incorrectServiceRetrieving/UnregisteredServices.kt
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/retrievingService/service.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/incorrectServiceRetrieving/service.kt
similarity index 100%
rename from plugins/devkit/devkit-kotlin-tests/testData/inspections/retrievingService/service.kt
rename to plugins/devkit/devkit-kotlin-tests/testData/inspections/incorrectServiceRetrieving/service.kt
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/retrievingService/services.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/incorrectServiceRetrieving/services.kt
similarity index 100%
rename from plugins/devkit/devkit-kotlin-tests/testData/inspections/retrievingService/services.kt
rename to plugins/devkit/devkit-kotlin-tests/testData/inspections/incorrectServiceRetrieving/services.kt
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/retrievingService/ReplaceWithGetInstanceApplicationLevel.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/simplifiableServiceRetrieving/ReplaceWithGetInstanceApplicationLevel.kt
similarity index 100%
rename from plugins/devkit/devkit-kotlin-tests/testData/inspections/retrievingService/ReplaceWithGetInstanceApplicationLevel.kt
rename to plugins/devkit/devkit-kotlin-tests/testData/inspections/simplifiableServiceRetrieving/ReplaceWithGetInstanceApplicationLevel.kt
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/retrievingService/ReplaceWithGetInstanceApplicationLevel_after.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/simplifiableServiceRetrieving/ReplaceWithGetInstanceApplicationLevel_after.kt
similarity index 100%
rename from plugins/devkit/devkit-kotlin-tests/testData/inspections/retrievingService/ReplaceWithGetInstanceApplicationLevel_after.kt
rename to plugins/devkit/devkit-kotlin-tests/testData/inspections/simplifiableServiceRetrieving/ReplaceWithGetInstanceApplicationLevel_after.kt
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/retrievingService/ReplaceWithGetInstanceProjectLevel.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/simplifiableServiceRetrieving/ReplaceWithGetInstanceProjectLevel.kt
similarity index 100%
rename from plugins/devkit/devkit-kotlin-tests/testData/inspections/retrievingService/ReplaceWithGetInstanceProjectLevel.kt
rename to plugins/devkit/devkit-kotlin-tests/testData/inspections/simplifiableServiceRetrieving/ReplaceWithGetInstanceProjectLevel.kt
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/retrievingService/ReplaceWithGetInstanceProjectLevel_after.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/simplifiableServiceRetrieving/ReplaceWithGetInstanceProjectLevel_after.kt
similarity index 100%
rename from plugins/devkit/devkit-kotlin-tests/testData/inspections/retrievingService/ReplaceWithGetInstanceProjectLevel_after.kt
rename to plugins/devkit/devkit-kotlin-tests/testData/inspections/simplifiableServiceRetrieving/ReplaceWithGetInstanceProjectLevel_after.kt
diff --git a/plugins/devkit/devkit-kotlin-tests/testSrc/org/jetbrains/idea/devkit/kotlin/inspections/KtIncorrectServiceRetrievingInspectionTest.kt b/plugins/devkit/devkit-kotlin-tests/testSrc/org/jetbrains/idea/devkit/kotlin/inspections/KtIncorrectServiceRetrievingInspectionTest.kt
new file mode 100644
index 000000000000..84c06686de3d
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testSrc/org/jetbrains/idea/devkit/kotlin/inspections/KtIncorrectServiceRetrievingInspectionTest.kt
@@ -0,0 +1,32 @@
+// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package org.jetbrains.idea.devkit.kotlin.inspections
+
+import com.intellij.testFramework.TestDataPath
+import org.jetbrains.idea.devkit.inspections.IncorrectServiceRetrievingInspectionTestBase
+import org.jetbrains.idea.devkit.kotlin.DevkitKtTestsUtil
+
+@TestDataPath("\$CONTENT_ROOT/testData/inspections/incorrectServiceRetrieving")
+internal class KtIncorrectServiceRetrievingInspectionTest : IncorrectServiceRetrievingInspectionTestBase() {
+
+ override fun setUp() {
+ super.setUp()
+ myFixture.configureByFile("service.kt")
+ myFixture.configureByFile("services.kt")
+ }
+
+ override fun getBasePath() = DevkitKtTestsUtil.TESTDATA_PATH + "inspections/incorrectServiceRetrieving/"
+
+ override fun getFileExtension() = "kt"
+
+ fun testRetrievingServiceAsProjectLevel() {
+ doTest()
+ }
+
+ fun testRetrievingServiceAsAppLevel() {
+ doTest()
+ }
+
+ fun testUnregisteredServices() {
+ doTest()
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testSrc/org/jetbrains/idea/devkit/kotlin/inspections/KtRetrievingServiceInspectionTest.kt b/plugins/devkit/devkit-kotlin-tests/testSrc/org/jetbrains/idea/devkit/kotlin/inspections/quickfix/KtSimplifiableServiceRetrievingInspectionTest.kt
similarity index 59%
rename from plugins/devkit/devkit-kotlin-tests/testSrc/org/jetbrains/idea/devkit/kotlin/inspections/KtRetrievingServiceInspectionTest.kt
rename to plugins/devkit/devkit-kotlin-tests/testSrc/org/jetbrains/idea/devkit/kotlin/inspections/quickfix/KtSimplifiableServiceRetrievingInspectionTest.kt
index 9029a9b36628..557c2748c47e 100644
--- a/plugins/devkit/devkit-kotlin-tests/testSrc/org/jetbrains/idea/devkit/kotlin/inspections/KtRetrievingServiceInspectionTest.kt
+++ b/plugins/devkit/devkit-kotlin-tests/testSrc/org/jetbrains/idea/devkit/kotlin/inspections/quickfix/KtSimplifiableServiceRetrievingInspectionTest.kt
@@ -1,32 +1,18 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package org.jetbrains.idea.devkit.kotlin.inspections
+package org.jetbrains.idea.devkit.kotlin.inspections.quickfix
import com.intellij.testFramework.TestDataPath
import org.jetbrains.idea.devkit.DevKitBundle
-import org.jetbrains.idea.devkit.inspections.quickfix.RetrievingServiceInspectionTestBase
+import org.jetbrains.idea.devkit.inspections.quickfix.SimplifiableServiceRetrievingInspectionTestBase
import org.jetbrains.idea.devkit.kotlin.DevkitKtTestsUtil
-@TestDataPath("\$CONTENT_ROOT/testData/inspections/retrievingService")
-internal class KtRetrievingServiceInspectionTest : RetrievingServiceInspectionTestBase() {
+@TestDataPath("\$CONTENT_ROOT/testData/inspections/simplifiableServiceRetrieving")
+internal class KtSimplifiableServiceRetrievingInspectionTest : SimplifiableServiceRetrievingInspectionTestBase() {
- override fun setUp() {
- super.setUp()
- myFixture.configureByFile("service.kt")
- myFixture.configureByFile("services.kt")
- }
-
- override fun getBasePath() = DevkitKtTestsUtil.TESTDATA_PATH + "inspections/retrievingService/"
+ override fun getBasePath() = DevkitKtTestsUtil.TESTDATA_PATH + "inspections/simplifiableServiceRetrieving/"
override fun getFileExtension() = "kt"
- fun testRetrievingServiceAsProjectLevel() {
- doTest()
- }
-
- fun testRetrievingServiceAsAppLevel() {
- doTest()
- }
-
fun testReplaceWithGetInstanceApplicationLevel() {
myFixture.addClass(
"""
@@ -40,7 +26,7 @@ internal class KtRetrievingServiceInspectionTest : RetrievingServiceInspectionTe
}
}
""")
- doTest(DevKitBundle.message("inspection.retrieving.service.replace.with", "MyService", "getInstance"))
+ doTest(DevKitBundle.message("inspection.simplifiable.service.retrieving.replace.with", "MyService", "getInstance"))
}
fun testReplaceWithGetInstanceProjectLevel() {
@@ -57,10 +43,6 @@ internal class KtRetrievingServiceInspectionTest : RetrievingServiceInspectionTe
}
}
""")
- doTest(DevKitBundle.message("inspection.retrieving.service.replace.with", "MyService", "getInstance"))
- }
-
- fun testUnregisteredServices() {
- doTest()
+ doTest(DevKitBundle.message("inspection.simplifiable.service.retrieving.replace.with", "MyService", "getInstance"))
}
}
diff --git a/plugins/devkit/devkit-tests/testSrc/org/jetbrains/idea/devkit/inspections/IncorrectServiceRetrievingInspectionTestBase.kt b/plugins/devkit/devkit-tests/testSrc/org/jetbrains/idea/devkit/inspections/IncorrectServiceRetrievingInspectionTestBase.kt
new file mode 100644
index 000000000000..bf6d612065d9
--- /dev/null
+++ b/plugins/devkit/devkit-tests/testSrc/org/jetbrains/idea/devkit/inspections/IncorrectServiceRetrievingInspectionTestBase.kt
@@ -0,0 +1,67 @@
+// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package org.jetbrains.idea.devkit.inspections
+
+import org.jetbrains.idea.devkit.inspections.quickfix.LightDevKitInspectionFixTestBase
+
+abstract class IncorrectServiceRetrievingInspectionTestBase : LightDevKitInspectionFixTestBase() {
+
+ override fun setUp() {
+ super.setUp()
+ myFixture.enableInspections(IncorrectServiceRetrievingInspection())
+ myFixture.addClass(
+ """
+ package com.intellij.openapi.components;
+
+ public @interface Service {
+ Level[] value() default Level.APP;
+
+ enum Level { APP, PROJECT }
+ }
+ """)
+ myFixture.addClass(
+ """
+ package com.intellij.openapi.components;
+
+ public interface ComponentManager {
+ T getService(@NotNull Class serviceClass);
+ T getService(@NotNull Class serviceClass, boolean createIfNeeded);
+ }
+ """)
+ myFixture.addClass(
+ """
+ package com.intellij.openapi.project;
+
+ import com.intellij.openapi.components.ComponentManager;
+
+ public interface Project extends ComponentManager {}
+ """)
+ myFixture.addClass(
+ """
+ package com.intellij.openapi.application;
+
+ public final class ApplicationManager {
+ private static Application ourApplication;
+
+ public static Application getApplication() {
+ return ourApplication;
+ }
+ }
+ """)
+ myFixture.addClass(
+ """
+ package com.intellij.openapi.application;
+
+ import com.intellij.openapi.components.ComponentManager;
+
+ public interface Application extends ComponentManager {}
+ """)
+ myFixture.addClass(
+ """
+ package kotlin.reflect;
+
+ public class KClass {
+ public Class java;
+ }
+ """)
+ }
+}
diff --git a/plugins/devkit/devkit-tests/testSrc/org/jetbrains/idea/devkit/inspections/quickfix/RetrievingServiceInspectionTestBase.kt b/plugins/devkit/devkit-tests/testSrc/org/jetbrains/idea/devkit/inspections/quickfix/SimplifiableServiceRetrievingInspectionTestBase.kt
similarity index 86%
rename from plugins/devkit/devkit-tests/testSrc/org/jetbrains/idea/devkit/inspections/quickfix/RetrievingServiceInspectionTestBase.kt
rename to plugins/devkit/devkit-tests/testSrc/org/jetbrains/idea/devkit/inspections/quickfix/SimplifiableServiceRetrievingInspectionTestBase.kt
index 50a148951b22..a8a161867927 100644
--- a/plugins/devkit/devkit-tests/testSrc/org/jetbrains/idea/devkit/inspections/quickfix/RetrievingServiceInspectionTestBase.kt
+++ b/plugins/devkit/devkit-tests/testSrc/org/jetbrains/idea/devkit/inspections/quickfix/SimplifiableServiceRetrievingInspectionTestBase.kt
@@ -1,13 +1,13 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.idea.devkit.inspections.quickfix
-import org.jetbrains.idea.devkit.inspections.RetrievingServiceInspection
+import org.jetbrains.idea.devkit.inspections.SimplifiableServiceRetrievingInspection
-abstract class RetrievingServiceInspectionTestBase : LightDevKitInspectionFixTestBase() {
+abstract class SimplifiableServiceRetrievingInspectionTestBase : LightDevKitInspectionFixTestBase() {
override fun setUp() {
super.setUp()
- myFixture.enableInspections(RetrievingServiceInspection())
+ myFixture.enableInspections(SimplifiableServiceRetrievingInspection())
myFixture.addClass(
"""
package com.intellij.openapi.components;