"kotlinVariable()" macro to filter by expected type, dropped IterableVariableMacro
This commit is contained in:
@@ -139,10 +139,10 @@ class WhenEntryAdditionalData(val whenWithSubject: Boolean) : ExpectedInfo.Addit
|
||||
object IfConditionAdditionalData : ExpectedInfo.AdditionalData
|
||||
|
||||
class ExpectedInfos(
|
||||
val bindingContext: BindingContext,
|
||||
val resolutionFacade: ResolutionFacade,
|
||||
val useHeuristicSignatures: Boolean = true,
|
||||
val useOuterCallsExpectedTypeCount: Int = 0
|
||||
private val bindingContext: BindingContext,
|
||||
private val resolutionFacade: ResolutionFacade,
|
||||
private val useHeuristicSignatures: Boolean = true,
|
||||
private val useOuterCallsExpectedTypeCount: Int = 0
|
||||
) {
|
||||
public fun calculate(expressionWithType: KtExpression): Collection<ExpectedInfo> {
|
||||
val expectedInfos = calculateForArgument(expressionWithType)
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<template resource-bundle="org.jetbrains.kotlin.idea.KotlinBundle" key="livetemplate.description.iter"
|
||||
name="iter" toReformat="true" toShortenFQNames="true"
|
||||
value="for ($VAR$ in $ITERABLE$) { $END$ }">
|
||||
<variable alwaysStopAt="true" defaultValue=""iterable"" expression="kotlinIterableVariable()" name="ITERABLE" />
|
||||
<variable alwaysStopAt="true" defaultValue=""iterable"" expression="kotlinVariable()" name="ITERABLE" />
|
||||
<variable alwaysStopAt="true" defaultValue=""i"" expression="kotlinSuggestVariableName()" name="VAR" />
|
||||
<context>
|
||||
<option name="KOTLIN_STATEMENT" value="true" />
|
||||
|
||||
@@ -426,9 +426,9 @@
|
||||
<liveTemplateContext implementation="org.jetbrains.kotlin.idea.liveTemplates.KotlinTemplateContextType$Comment"/>
|
||||
<defaultLiveTemplatesProvider implementation="org.jetbrains.kotlin.idea.liveTemplates.KotlinLiveTemplatesProvider"/>
|
||||
<liveTemplateMacro implementation="org.jetbrains.kotlin.idea.liveTemplates.macro.AnyVariableMacro"/>
|
||||
<liveTemplateMacro implementation="org.jetbrains.kotlin.idea.liveTemplates.macro.SuitableVariableMacro"/>
|
||||
<liveTemplateMacro implementation="org.jetbrains.kotlin.idea.liveTemplates.macro.FunctionParametersMacro"/>
|
||||
<liveTemplateMacro implementation="org.jetbrains.kotlin.idea.liveTemplates.macro.AnonymousSuperMacro"/>
|
||||
<liveTemplateMacro implementation="org.jetbrains.kotlin.idea.liveTemplates.macro.IterableVariableMacro"/>
|
||||
<liveTemplateMacro implementation="org.jetbrains.kotlin.idea.liveTemplates.macro.SuggestVariableNameMacro"/>
|
||||
<liveTemplateOptionalProcessor implementation="org.jetbrains.kotlin.idea.liveTemplates.KotlinShortenFQNamesProcessor"/>
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@ import com.intellij.openapi.util.UserDataHolder
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
|
||||
class AnyVariableMacro : BaseKotlinVariableMacro() {
|
||||
override fun getName() = "kotlinVariable"
|
||||
override fun getPresentableName() = "kotlinVariable()"
|
||||
override fun getName() = "kotlinAnyVariable"
|
||||
override fun getPresentableName() = "kotlinAnyVariable()"
|
||||
|
||||
override fun isSuitable(variableDescriptor: VariableDescriptor, project: Project, userData: UserDataHolder) = true
|
||||
}
|
||||
|
||||
+24
-13
@@ -21,35 +21,46 @@ import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.util.UserDataHolder
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.core.IterableTypesDetection
|
||||
import org.jetbrains.kotlin.idea.core.IterableTypesDetector
|
||||
import org.jetbrains.kotlin.idea.core.ExpectedInfo
|
||||
import org.jetbrains.kotlin.idea.core.ExpectedInfos
|
||||
import org.jetbrains.kotlin.idea.core.SmartCastCalculator
|
||||
import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
|
||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
||||
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
class IterableVariableMacro : BaseKotlinVariableMacro() {
|
||||
class SuitableVariableMacro : BaseKotlinVariableMacro() {
|
||||
private companion object {
|
||||
val ITERABLE_TYPES_DETECTOR_KEY = Key<IterableTypesDetector>("ITERABLE_TYPES_DETECTOR_KEY")
|
||||
val EXPECTED_INFOS_KEY = Key<Collection<ExpectedInfo>>("EXPECTED_INFOS_KEY")
|
||||
val SMART_CAST_CALCULATOR_KEY = Key<SmartCastCalculator>("SMART_CAST_CALCULATOR_KEY")
|
||||
}
|
||||
|
||||
override fun getName() = "kotlinIterableVariable"
|
||||
override fun getPresentableName() = "kotlinIterableVariable()"
|
||||
override fun getName() = "kotlinVariable"
|
||||
override fun getPresentableName() = "kotlinVariable()"
|
||||
|
||||
override fun initUserData(userData: UserDataHolder, contextElement: KtElement, bindingContext: BindingContext) {
|
||||
val resolutionFacade = contextElement.getResolutionFacade()
|
||||
val scope = contextElement.getResolutionScope(bindingContext, resolutionFacade)
|
||||
val detector = resolutionFacade.getIdeService(IterableTypesDetection::class.java).createDetector(scope)
|
||||
val smartCastCalculator = SmartCastCalculator(bindingContext, scope.ownerDescriptor, contextElement, null, resolutionFacade)
|
||||
userData.putUserData(ITERABLE_TYPES_DETECTOR_KEY, detector)
|
||||
userData.putUserData(SMART_CAST_CALCULATOR_KEY, smartCastCalculator)
|
||||
if (contextElement is KtNameReferenceExpression) {
|
||||
val callTypeAndReceiver = CallTypeAndReceiver.detect(contextElement)
|
||||
if (callTypeAndReceiver is CallTypeAndReceiver.DEFAULT) {
|
||||
val expectedInfos = ExpectedInfos(bindingContext, resolutionFacade).calculate(contextElement)
|
||||
if (expectedInfos.isNotEmpty()) {
|
||||
userData.putUserData(EXPECTED_INFOS_KEY, expectedInfos)
|
||||
|
||||
val scope = contextElement.getResolutionScope(bindingContext, resolutionFacade)
|
||||
val smartCastCalculator = SmartCastCalculator(bindingContext, scope.ownerDescriptor, contextElement, null, resolutionFacade)
|
||||
userData.putUserData(SMART_CAST_CALCULATOR_KEY, smartCastCalculator)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun isSuitable(variableDescriptor: VariableDescriptor, project: Project, userData: UserDataHolder): Boolean {
|
||||
val detector = userData.getUserData(ITERABLE_TYPES_DETECTOR_KEY)!!
|
||||
val expectedInfos = userData.getUserData(EXPECTED_INFOS_KEY) ?: return true
|
||||
val smartCastCalculator = userData.getUserData(SMART_CAST_CALCULATOR_KEY)!!
|
||||
val types = smartCastCalculator.types(variableDescriptor)
|
||||
return types.any { detector.isIterable(it, null) }
|
||||
return expectedInfos.any { expectedInfo -> types.any { expectedInfo.filter.matchingSubstitutor(FuzzyType(it, emptyList())) != null } }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user