Refactor DataFlowValueFactory into proper component

This commit is contained in:
Dmitry Savvinov
2018-02-13 13:48:08 +03:00
parent 03567a1c01
commit 0929673576
62 changed files with 397 additions and 242 deletions
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.resolve.BindingTraceContext
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.utils.collectFunctions
@@ -40,7 +41,8 @@ import java.util.*
class IterableTypesDetection(
private val project: Project,
private val forLoopConventionsChecker: ForLoopConventionsChecker,
private val languageVersionSettings: LanguageVersionSettings
private val languageVersionSettings: LanguageVersionSettings,
private val dataFlowValueFactory: DataFlowValueFactory
) {
companion object {
private val iteratorName = Name.identifier("iterator")
@@ -78,7 +80,7 @@ class IterableTypesDetection(
val expression = KtPsiFactory(project).createExpression("fake")
val context = ExpressionTypingContext.newContext(
BindingTraceContext(), scope, DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE, languageVersionSettings)
BindingTraceContext(), scope, DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE, languageVersionSettings, dataFlowValueFactory)
val expressionReceiver = ExpressionReceiver.create(expression, type.type, context.trace.bindingContext)
val elementType = forLoopConventionsChecker.checkIterableConvention(expressionReceiver, context)
return elementType?.let { it.toFuzzyType(type.freeParameters) }
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.resolve.frontendService
import org.jetbrains.kotlin.idea.util.getImplicitReceiversWithInstance
import org.jetbrains.kotlin.idea.util.getResolutionScope
import org.jetbrains.kotlin.psi.KtExpression
@@ -43,6 +44,8 @@ class SmartCastCalculator(
receiver: KtExpression?,
resolutionFacade: ResolutionFacade
) {
private val dataFlowValueFactory = resolutionFacade.frontendService<DataFlowValueFactory>()
// keys are VariableDescriptor's and ThisReceiver's
private val entityToSmartCastInfo: Map<Any, SmartCastInfo> = processDataFlowInfo(
bindingContext.getDataFlowInfoBefore(contextElement),
@@ -82,7 +85,7 @@ class SmartCastCalculator(
val dataFlowValueToEntity: (DataFlowValue) -> Any?
if (receiver != null) {
val receiverType = bindingContext.getType(receiver) ?: return emptyMap()
val receiverIdentifierInfo = DataFlowValueFactory.createDataFlowValue(
val receiverIdentifierInfo = dataFlowValueFactory.createDataFlowValue(
receiver, receiverType, bindingContext, containingDeclarationOrModule
).identifierInfo
dataFlowValueToEntity = { value ->
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getDispatchReceiverWithSmartCast
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
import org.jetbrains.kotlin.types.KotlinType
@@ -120,7 +121,8 @@ fun Call.resolveCandidates(
val callResolutionContext = BasicCallResolutionContext.create(
bindingTrace, resolutionScope, this, expectedType, dataFlowInfo,
ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
false, resolutionFacade.frontendService<LanguageVersionSettings>()
false, resolutionFacade.frontendService<LanguageVersionSettings>(),
resolutionFacade.frontendService<DataFlowValueFactory>()
).replaceCollectAllCandidates(true)
val callResolver = resolutionFacade.frontendService<CallResolver>()