KotlinLanguageInjector: cleanup code

This commit is contained in:
Dmitry Gridin
2019-08-01 13:45:24 +03:00
parent 49aa4aba71
commit 9ea2446ec0
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.injection package org.jetbrains.kotlin.idea.injection
@@ -29,7 +18,6 @@ import com.intellij.patterns.PatternConditionPlus
import com.intellij.patterns.PsiClassNamePatternCondition import com.intellij.patterns.PsiClassNamePatternCondition
import com.intellij.patterns.ValuePatternCondition import com.intellij.patterns.ValuePatternCondition
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil
import com.intellij.psi.search.LocalSearchScope import com.intellij.psi.search.LocalSearchScope
import com.intellij.psi.search.searches.ReferencesSearch import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValueProvider
@@ -65,9 +53,9 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class KotlinLanguageInjector( class KotlinLanguageInjector(
private val configuration: Configuration, private val configuration: Configuration,
private val project: Project, private val project: Project,
private val temporaryPlacesRegistry: TemporaryPlacesRegistry private val temporaryPlacesRegistry: TemporaryPlacesRegistry
) : MultiHostInjector { ) : MultiHostInjector {
companion object { companion object {
private val STRING_LITERALS_REGEXP = "\"([^\"]*)\"".toRegex() private val STRING_LITERALS_REGEXP = "\"([^\"]*)\"".toRegex()
@@ -81,7 +69,8 @@ class KotlinLanguageInjector(
private data class KotlinCachedInjection(val modificationCount: Long, val baseInjection: BaseInjection) private data class KotlinCachedInjection(val modificationCount: Long, val baseInjection: BaseInjection)
private var KtStringTemplateExpression.cachedInjectionWithModification: KotlinCachedInjection? by UserDataProperty( private var KtStringTemplateExpression.cachedInjectionWithModification: KotlinCachedInjection? by UserDataProperty(
Key.create<KotlinCachedInjection>("CACHED_INJECTION_WITH_MODIFICATION")) Key.create<KotlinCachedInjection>("CACHED_INJECTION_WITH_MODIFICATION")
)
override fun getLanguagesToInject(registrar: MultiHostRegistrar, context: PsiElement) { override fun getLanguagesToInject(registrar: MultiHostRegistrar, context: PsiElement) {
val ktHost: KtStringTemplateExpression = context as? KtStringTemplateExpression ?: return val ktHost: KtStringTemplateExpression = context as? KtStringTemplateExpression ?: return
@@ -113,9 +102,9 @@ class KotlinLanguageInjector(
if (ApplicationManager.getApplication().isReadAccessAllowed && ProgressManager.getInstance().progressIndicator == null) { if (ApplicationManager.getApplication().isReadAccessAllowed && ProgressManager.getInstance().progressIndicator == null) {
// The action cannot be canceled by caller and by internal checkCanceled() calls. // The action cannot be canceled by caller and by internal checkCanceled() calls.
// Force creating new indicator that is canceled on write action start, otherwise there might be lags in typing. // Force creating new indicator that is canceled on write action start, otherwise there might be lags in typing.
runInReadActionWithWriteActionPriority(::computeAndCache) ?: kotlinCachedInjection?.baseInjection ?: ABSENT_KOTLIN_INJECTION runInReadActionWithWriteActionPriority(::computeAndCache) ?: kotlinCachedInjection?.baseInjection
} ?: ABSENT_KOTLIN_INJECTION
else { } else {
computeAndCache() computeAndCache()
} }
} }
@@ -138,20 +127,20 @@ class KotlinLanguageInjector(
InjectorUtils.putInjectedFileUserData( InjectorUtils.putInjectedFileUserData(
ktHost, ktHost,
language, language,
InjectedLanguageUtil.FRANKENSTEIN_INJECTION, com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil.FRANKENSTEIN_INJECTION,
if (parts.isUnparsable) java.lang.Boolean.TRUE else null if (parts.isUnparsable) java.lang.Boolean.TRUE else null
) )
} } else {
else {
InjectorUtils.registerInjectionSimple(ktHost, baseInjection, support, registrar) InjectorUtils.registerInjectionSimple(ktHost, baseInjection, support, registrar)
} }
} }
@Suppress("FoldInitializerAndIfToElvis") @Suppress("FoldInitializerAndIfToElvis")
private fun computeBaseInjection( private fun computeBaseInjection(
ktHost: KtStringTemplateExpression, ktHost: KtStringTemplateExpression,
support: KotlinLanguageInjectionSupport, support: KotlinLanguageInjectionSupport,
registrar: MultiHostRegistrar): BaseInjection? { registrar: MultiHostRegistrar
): BaseInjection? {
val containingFile = ktHost.containingFile val containingFile = ktHost.containingFile
val tempInjectedLanguage = temporaryPlacesRegistry.getLanguageFor(ktHost, containingFile) val tempInjectedLanguage = temporaryPlacesRegistry.getLanguageFor(ktHost, containingFile)
@@ -173,11 +162,11 @@ class KotlinLanguageInjector(
private fun findInjectionInfo(place: KtElement, originalHost: Boolean = true): InjectionInfo? { private fun findInjectionInfo(place: KtElement, originalHost: Boolean = true): InjectionInfo? {
return injectWithExplicitCodeInstruction(place) return injectWithExplicitCodeInstruction(place)
?: injectWithCall(place) ?: injectWithCall(place)
?: injectReturnValue(place) ?: injectReturnValue(place)
?: injectInAnnotationCall(place) ?: injectInAnnotationCall(place)
?: injectWithReceiver(place) ?: injectWithReceiver(place)
?: injectWithVariableUsage(place, originalHost) ?: injectWithVariableUsage(place, originalHost)
} }
private fun injectReturnValue(place: KtElement): InjectionInfo? { private fun injectReturnValue(place: KtElement): InjectionInfo? {
@@ -288,8 +277,7 @@ class KotlinLanguageInjector(
if (injectionForJavaMethod != null) { if (injectionForJavaMethod != null) {
return injectionForJavaMethod return injectionForJavaMethod
} }
} } else if (resolvedTo is KtFunction) {
else if (resolvedTo is KtFunction) {
val injectionForJavaMethod = injectionForKotlinCall(argument, resolvedTo, reference) val injectionForJavaMethod = injectionForKotlinCall(argument, resolvedTo, reference)
if (injectionForJavaMethod != null) { if (injectionForJavaMethod != null) {
return injectionForJavaMethod return injectionForJavaMethod
@@ -336,9 +324,10 @@ class KotlinLanguageInjector(
} }
val annotations = AnnotationUtilEx.getAnnotationFrom( val annotations = AnnotationUtilEx.getAnnotationFrom(
psiParameter, psiParameter,
configuration.advancedConfiguration.languageAnnotationPair, configuration.advancedConfiguration.languageAnnotationPair,
true) true
)
if (annotations.isNotEmpty()) { if (annotations.isNotEmpty()) {
return processAnnotationInjectionInner(annotations) return processAnnotationInjectionInner(annotations)
@@ -401,24 +390,24 @@ class KotlinLanguageInjector(
} }
private val injectableTargetClassShortNames = CachedValuesManager.getManager(project) private val injectableTargetClassShortNames = CachedValuesManager.getManager(project)
.createCachedValue({ .createCachedValue({
CachedValueProvider.Result.create(HashSet<String>().apply { CachedValueProvider.Result.create(HashSet<String>().apply {
for (injection in configuration.getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID)) { for (injection in configuration.getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID)) {
for (injectionPlace in injection.injectionPlaces) { for (injectionPlace in injection.injectionPlaces) {
for (targetClassFQN in retrieveJavaPlaceTargetClassesFQNs(injectionPlace)) { for (targetClassFQN in retrieveJavaPlaceTargetClassesFQNs(injectionPlace)) {
add(StringUtilRt.getShortName(targetClassFQN)) add(StringUtilRt.getShortName(targetClassFQN))
}
} }
} }
for (injection in configuration.getInjections(KOTLIN_SUPPORT_ID)) { }
for (injectionPlace in injection.injectionPlaces) { for (injection in configuration.getInjections(KOTLIN_SUPPORT_ID)) {
for (targetClassFQN in retrieveKotlinPlaceTargetClassesFQNs(injectionPlace)) { for (injectionPlace in injection.injectionPlaces) {
add(StringUtilRt.getShortName(targetClassFQN)) for (targetClassFQN in retrieveKotlinPlaceTargetClassesFQNs(injectionPlace)) {
} add(StringUtilRt.getShortName(targetClassFQN))
} }
} }
}, configuration) }
}, false) }, configuration)
}, false)
private fun fastCheckInjectionsExists(annotationEntry: KtCallElement): Boolean { private fun fastCheckInjectionsExists(annotationEntry: KtCallElement): Boolean {
val referencedName = getNameReference(annotationEntry.calleeExpression)?.getReferencedName() ?: return false val referencedName = getNameReference(annotationEntry.calleeExpression)?.getReferencedName() ?: return false
@@ -428,10 +417,12 @@ class KotlinLanguageInjector(
private fun retrieveJavaPlaceTargetClassesFQNs(place: InjectionPlace): Collection<String> { private fun retrieveJavaPlaceTargetClassesFQNs(place: InjectionPlace): Collection<String> {
val classCondition = place.elementPattern.condition.conditions.firstOrNull { it.debugMethodName == "definedInClass" } val classCondition = place.elementPattern.condition.conditions.firstOrNull { it.debugMethodName == "definedInClass" }
as? PatternConditionPlus<*, *> ?: return emptyList() as? PatternConditionPlus<*, *> ?: return emptyList()
val psiClassNamePatternCondition = classCondition.valuePattern.condition.conditions. val psiClassNamePatternCondition =
firstIsInstanceOrNull<PsiClassNamePatternCondition>() ?: return emptyList() classCondition.valuePattern.condition.conditions.firstIsInstanceOrNull<PsiClassNamePatternCondition>() ?: return emptyList()
val valuePatternCondition = psiClassNamePatternCondition.namePattern.condition.conditions.firstIsInstanceOrNull<ValuePatternCondition<String>>() ?: return emptyList() val valuePatternCondition =
psiClassNamePatternCondition.namePattern.condition.conditions.firstIsInstanceOrNull<ValuePatternCondition<String>>()
?: return emptyList()
return valuePatternCondition.values return valuePatternCondition.values
} }