From 0eda1f3969c4e7e801892ea512202c7969850021 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 14 Mar 2016 17:54:10 +0300 Subject: [PATCH] Spring Support: SpEL injections #KT-11406 Fixed --- Changelog.md | 1 + .../src/META-INF/kotlin-spring.xml | 2 + .../idea/spring/el/KotlinSpringELInjector.kt | 82 +++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 idea/idea-ultimate/src/org/jetbrains/kotlin/idea/spring/el/KotlinSpringELInjector.kt diff --git a/Changelog.md b/Changelog.md index 4876619712d..b0cafb02769 100644 --- a/Changelog.md +++ b/Changelog.md @@ -99,6 +99,7 @@ New features: - [KT-11098](https://youtrack.jetbrains.com/issue/KT-11098) Inspection on final classes/functions annotated with Spring @Configuration/@Component/@Bean - [KT-11405](https://youtrack.jetbrains.com/issue/KT-11405) Navigation and Find Usages for Spring beans referenced in annotation arguments and BeanFactory method calls - [KT-3741](https://youtrack.jetbrains.com/issue/KT-3741) Show Spring-specific line markers on Kotlin classes +- [KT-11406](https://youtrack.jetbrains.com/issue/KT-11406) Support Spring EL injections inside of Kotlin string literals General issues fixed: diff --git a/idea/idea-ultimate/src/META-INF/kotlin-spring.xml b/idea/idea-ultimate/src/META-INF/kotlin-spring.xml index 347c6c334ca..12b5f6831cf 100644 --- a/idea/idea-ultimate/src/META-INF/kotlin-spring.xml +++ b/idea/idea-ultimate/src/META-INF/kotlin-spring.xml @@ -2,6 +2,8 @@ + + host.putUserData(ELContextProvider.ourContextProviderKey, SpringElContextProvider(host)) } + } + } + + override fun getLanguagesToInject(registrar: MultiHostRegistrar, host: PsiElement) { + if (host is KtStringTemplateExpression) { + if (!host.isPlain()) return + + val argument = host.parent as? KtValueArgument ?: return + val argumentName = argument.getArgumentName() + if (argumentName != null && argumentName.asName.asString() != "value") return + + val entry = argument.getStrictParentOfType() ?: return + val context = entry.analyze(BodyResolveMode.PARTIAL) + val resolvedCall = entry.getResolvedCall(context) ?: return + val annotation = (resolvedCall.resultingDescriptor as? ConstructorDescriptor)?.containingDeclaration ?: return + if (annotation.importableFqName?.asString() !in RELEVANT_ANNOTATIONS) return + + val text = host.getText() + val ranges = SpringElTemplateParser.parse(text).ifEmpty { return } + for (range in ranges) { + registrar + .startInjecting(SpringELLanguage.INSTANCE) + .addPlace(null, null, host as PsiLanguageInjectionHost, range) + .doneInjecting() + } + + contextRecorder!!(host) + } + } + + override fun elementsToInjectIn() = contextRecorder?.let { listOf(KtStringTemplateExpression::class.java) } ?: emptyList() +} +