From 91f08b0d1e09d2bf7c790c412d678ede8d46d87b Mon Sep 17 00:00:00 2001 From: "igor.petrenko" Date: Tue, 27 Jan 2026 11:08:26 +0200 Subject: [PATCH 1/2] CE-128 oap-plugin: parameter completion --- build.gradle.kts | 2 +- .../OapParameterCompletionContributor.kt | 45 ++++++++++++++++++ .../plugin/psi/impl/JavaPsiUtils.kt | 47 +++++++++++++++++++ src/main/resources/META-INF/plugin.xml | 1 + .../completion/OapParametersCompletionTest.kt | 37 +++++++++++++++ 5 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/oap/application/plugin/completion/OapParameterCompletionContributor.kt create mode 100644 src/main/kotlin/oap/application/plugin/psi/impl/JavaPsiUtils.kt create mode 100644 src/test/kotlin/oap/application/plugin/completion/OapParametersCompletionTest.kt diff --git a/build.gradle.kts b/build.gradle.kts index ac3e6a0..c8a724b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "oap" -version = "0.0.6" +version = "0.0.7" repositories { mavenCentral() diff --git a/src/main/kotlin/oap/application/plugin/completion/OapParameterCompletionContributor.kt b/src/main/kotlin/oap/application/plugin/completion/OapParameterCompletionContributor.kt new file mode 100644 index 0000000..550d796 --- /dev/null +++ b/src/main/kotlin/oap/application/plugin/completion/OapParameterCompletionContributor.kt @@ -0,0 +1,45 @@ +package oap.application.plugin.completion + +import com.intellij.codeInsight.completion.* +import com.intellij.codeInsight.lookup.LookupElementBuilder +import com.intellij.icons.AllIcons +import com.intellij.patterns.PlatformPatterns +import com.intellij.psi.PsiElement +import com.intellij.util.Icons +import com.intellij.util.ProcessingContext +import oap.application.plugin.gen.psi.OapParameterKeyValueFirstId +import oap.application.plugin.psi.impl.JavaPsiUtils + +class OapParameterCompletionContributor : CompletionContributor() { + init { + extend( + CompletionType.BASIC, + PlatformPatterns.psiElement().withParent(OapParameterKeyValueFirstId::class.java), + object : CompletionProvider() { + override fun addCompletions( + parameters: CompletionParameters, + context: ProcessingContext, + result: CompletionResultSet + ) { + val position: PsiElement = parameters.position + + var prefix: String = position.text.removeSuffix(CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED) + + val parameters: List = JavaPsiUtils.findParameters(position) + + for (parameter: JavaPsiUtils.ServiceParameter in parameters) { + if (parameter.name.startsWith(prefix)) { + result.addElement(LookupElementBuilder.create(parameter.name).withIcon( + when(parameter.type) { + JavaPsiUtils.ServiceParameterType.FIELD -> AllIcons.Nodes.Field + JavaPsiUtils.ServiceParameterType.CONSTRUCTOR_PARAMETER -> AllIcons.Nodes.Constructor + JavaPsiUtils.ServiceParameterType.METHOD -> AllIcons.Nodes.Method + } + )) + } + } + } + } + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/oap/application/plugin/psi/impl/JavaPsiUtils.kt b/src/main/kotlin/oap/application/plugin/psi/impl/JavaPsiUtils.kt new file mode 100644 index 0000000..b7fc2f5 --- /dev/null +++ b/src/main/kotlin/oap/application/plugin/psi/impl/JavaPsiUtils.kt @@ -0,0 +1,47 @@ +package oap.application.plugin.psi.impl + +import com.intellij.lang.jvm.JvmParameter +import com.intellij.openapi.util.Key +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiField +import com.intellij.psi.PsiMethod +import com.intellij.psi.util.CachedValueProvider +import com.intellij.psi.util.CachedValuesManager +import com.intellij.psi.util.PsiTreeUtil +import oap.application.plugin.gen.psi.OapModuleServicesService +import oap.application.plugin.psi.OapClassValueMixin +import oap.application.plugin.psi.impl.JavaPsiUtils.ServiceParameterType.* + +object JavaPsiUtils { + fun findParameters(serviceIn: PsiElement): List { + val service: OapModuleServicesService? = PsiTreeUtil.getParentOfType(serviceIn, OapModuleServicesService::class.java) + val psiClass: PsiClass? = (service?.moduleServicesServiceImplementation?.classNamePsi as? OapClassValueMixin)?.getPsiClass() + if (psiClass != null) { + return CachedValuesManager.getCachedValue(psiClass, Key("Class Parameters")) { + val ret = ArrayList() + + val psiMethods: List = psiClass.methods.filter { m -> m.name.startsWith("set") && m.parameterList.parametersCount == 1 } + + val parameters: List = psiClass.constructors.flatMap { c -> c.parameters.filter { c -> c.name != null } } + + val fields: List = psiClass.allFields.asList() + + psiMethods.forEach { m -> ret.add(ServiceParameter(m.name, METHOD)) } + parameters.forEach { c -> ret.add(ServiceParameter(c.name!!, CONSTRUCTOR_PARAMETER)) } + fields.forEach { f -> ret.add(ServiceParameter(f.name, FIELD)) } + + CachedValueProvider.Result.create(ret) + } + + } + + return listOf() + } + + enum class ServiceParameterType { + METHOD, CONSTRUCTOR_PARAMETER, FIELD + } + + class ServiceParameter(val name: String, val type: ServiceParameterType) +} \ No newline at end of file diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 0a6bc42..51dc65c 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -45,6 +45,7 @@ + + } + } + } + """.trimIndent() + ) + myFixture.complete(CompletionType.BASIC) + + assertSameElements(myFixture.lookupElementStrings!!, "enabled", "dependOn", "services", "configurations") + } +} \ No newline at end of file From c77ad5d7701e70cd7d0fec4319f3faaaac723b0f Mon Sep 17 00:00:00 2001 From: "igor.petrenko" Date: Tue, 27 Jan 2026 11:52:02 +0200 Subject: [PATCH 2/2] CE-128 oap-plugin: parameter completion --- .../application/plugin/psi/impl/JavaPsiUtils.kt | 17 ++++++++++------- .../completion/OapParametersCompletionTest.kt | 5 ++++- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/oap/application/plugin/psi/impl/JavaPsiUtils.kt b/src/main/kotlin/oap/application/plugin/psi/impl/JavaPsiUtils.kt index b7fc2f5..58ab9da 100644 --- a/src/main/kotlin/oap/application/plugin/psi/impl/JavaPsiUtils.kt +++ b/src/main/kotlin/oap/application/plugin/psi/impl/JavaPsiUtils.kt @@ -2,10 +2,7 @@ package oap.application.plugin.psi.impl import com.intellij.lang.jvm.JvmParameter import com.intellij.openapi.util.Key -import com.intellij.psi.PsiClass -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiField -import com.intellij.psi.PsiMethod +import com.intellij.psi.* import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.PsiTreeUtil @@ -25,13 +22,19 @@ object JavaPsiUtils { val parameters: List = psiClass.constructors.flatMap { c -> c.parameters.filter { c -> c.name != null } } - val fields: List = psiClass.allFields.asList() + val fields: List = psiClass.allFields.filter { !it.hasModifierProperty(PsiModifier.FINAL) } - psiMethods.forEach { m -> ret.add(ServiceParameter(m.name, METHOD)) } + psiMethods.forEach { m -> ret.add(ServiceParameter(m.name.substring(3).replaceFirstChar { it.lowercaseChar() }, METHOD)) } parameters.forEach { c -> ret.add(ServiceParameter(c.name!!, CONSTRUCTOR_PARAMETER)) } fields.forEach { f -> ret.add(ServiceParameter(f.name, FIELD)) } - CachedValueProvider.Result.create(ret) + var dependencies: List = emptyList() + + dependencies += psiMethods; + dependencies += parameters.mapNotNull { it.sourceElement }; + dependencies += fields; + + CachedValueProvider.Result.create(ret, dependencies) } } diff --git a/src/test/kotlin/oap/application/plugin/completion/OapParametersCompletionTest.kt b/src/test/kotlin/oap/application/plugin/completion/OapParametersCompletionTest.kt index 20cf780..5db6cf0 100644 --- a/src/test/kotlin/oap/application/plugin/completion/OapParametersCompletionTest.kt +++ b/src/test/kotlin/oap/application/plugin/completion/OapParametersCompletionTest.kt @@ -32,6 +32,9 @@ class OapParametersCompletionTest : OapFixtureTestCase() { ) myFixture.complete(CompletionType.BASIC) - assertSameElements(myFixture.lookupElementStrings!!, "enabled", "dependOn", "services", "configurations") + assertSameElements( + myFixture.lookupElementStrings!!, + "constructor1StringField", "constructor2IntField", "constructor2StringField", "integerField", "intField", "privateStringField", "setterMethodString", "stringField" + ) } } \ No newline at end of file