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

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

-

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;