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..58ab9da --- /dev/null +++ b/src/main/kotlin/oap/application/plugin/psi/impl/JavaPsiUtils.kt @@ -0,0 +1,50 @@ +package oap.application.plugin.psi.impl + +import com.intellij.lang.jvm.JvmParameter +import com.intellij.openapi.util.Key +import com.intellij.psi.* +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.filter { !it.hasModifierProperty(PsiModifier.FINAL) } + + 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)) } + + var dependencies: List = emptyList() + + dependencies += psiMethods; + dependencies += parameters.mapNotNull { it.sourceElement }; + dependencies += fields; + + CachedValueProvider.Result.create(ret, dependencies) + } + + } + + 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!!, + "constructor1StringField", "constructor2IntField", "constructor2StringField", "integerField", "intField", "privateStringField", "setterMethodString", "stringField" + ) + } +} \ No newline at end of file