Refactor DataFlowDecorator.
This commit is contained in:
+28
-4
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
|
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.Call
|
import org.jetbrains.kotlin.psi.Call
|
||||||
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
|
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
|
||||||
@@ -28,23 +29,25 @@ import org.jetbrains.kotlin.resolve.calls.CandidateResolver
|
|||||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall
|
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInfixCall
|
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInfixCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.createLookupLocation
|
import org.jetbrains.kotlin.resolve.calls.callUtil.createLookupLocation
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
import org.jetbrains.kotlin.resolve.calls.context.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.CallCandidateResolutionContext
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.CandidateResolveMode
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCallImpl
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCallImpl
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCallImpl
|
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCallImpl
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl
|
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionResultsHandler
|
import org.jetbrains.kotlin.resolve.calls.results.ResolutionResultsHandler
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.*
|
import org.jetbrains.kotlin.resolve.calls.tasks.*
|
||||||
import org.jetbrains.kotlin.resolve.isHiddenInResolution
|
import org.jetbrains.kotlin.resolve.isHiddenInResolution
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
|
||||||
import org.jetbrains.kotlin.types.DeferredType
|
import org.jetbrains.kotlin.types.DeferredType
|
||||||
import org.jetbrains.kotlin.types.ErrorUtils
|
import org.jetbrains.kotlin.types.ErrorUtils
|
||||||
import org.jetbrains.kotlin.types.isDynamic
|
import org.jetbrains.kotlin.types.isDynamic
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.containsError
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||||
import org.jetbrains.kotlin.utils.sure
|
import org.jetbrains.kotlin.utils.sure
|
||||||
@@ -231,6 +234,27 @@ class NewResolutionOldInference(
|
|||||||
return resolutionResultsHandler.computeResultAndReportErrors(basicCallContext, tracing, resolvedCalls)
|
return resolutionResultsHandler.computeResultAndReportErrors(basicCallContext, tracing, resolvedCalls)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ScopeTowerImpl(
|
||||||
|
val resolutionContext: ResolutionContext<*>,
|
||||||
|
override val dynamicScope: MemberScope,
|
||||||
|
override val syntheticScopes: SyntheticScopes,
|
||||||
|
override val location: LookupLocation
|
||||||
|
): ScopeTower {
|
||||||
|
override val dataFlowInfo: DataFlowDecorator = object : DataFlowDecorator() {
|
||||||
|
override fun calculateSmartCastInfo(receiver: ReceiverValue): SmartCastInfo {
|
||||||
|
val dataFlowValue = DataFlowValueFactory.createDataFlowValue(receiver, resolutionContext)
|
||||||
|
return SmartCastInfo(dataFlowValue.isStable, resolutionContext.dataFlowInfo.getCollectedTypes(dataFlowValue))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val lexicalScope: LexicalScope get() = resolutionContext.scope
|
||||||
|
|
||||||
|
override val implicitReceivers = resolutionContext.scope.getImplicitReceiversHierarchy().
|
||||||
|
mapNotNull { it.value.check { !it.type.containsError() } }
|
||||||
|
|
||||||
|
override val isDebuggerContext: Boolean get() = resolutionContext.isDebuggerContext
|
||||||
|
}
|
||||||
|
|
||||||
internal data class MyCandidate<out D: CallableDescriptor>(
|
internal data class MyCandidate<out D: CallableDescriptor>(
|
||||||
val candidateStatus: ResolutionCandidateStatus,
|
val candidateStatus: ResolutionCandidateStatus,
|
||||||
val resolvedCall: MutableResolvedCall<@UnsafeVariance D>
|
val resolvedCall: MutableResolvedCall<@UnsafeVariance D>
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* 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.resolve.calls.tower
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import org.jetbrains.kotlin.types.typeUtil.containsError
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
|
|
||||||
internal class ScopeTowerImpl(
|
|
||||||
resolutionContext: ResolutionContext<*>,
|
|
||||||
override val dynamicScope: MemberScope,
|
|
||||||
override val syntheticScopes: SyntheticScopes,
|
|
||||||
override val location: LookupLocation
|
|
||||||
): ScopeTower {
|
|
||||||
override val dataFlowInfo: DataFlowDecorator = DataFlowDecoratorImpl(resolutionContext)
|
|
||||||
override val lexicalScope: LexicalScope = resolutionContext.scope
|
|
||||||
|
|
||||||
override val implicitReceivers = resolutionContext.scope.getImplicitReceiversHierarchy().
|
|
||||||
mapNotNull { it.value.check { !it.type.containsError() } }
|
|
||||||
|
|
||||||
override val isDebuggerContext = resolutionContext.isDebuggerContext
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DataFlowDecoratorImpl(private val resolutionContext: ResolutionContext<*>): DataFlowDecorator {
|
|
||||||
private val dataFlowInfo = resolutionContext.dataFlowInfo
|
|
||||||
private val cache = HashMap<ReceiverValue, SmartCastInfo>()
|
|
||||||
|
|
||||||
private fun getSmartCastInfo(receiver: ReceiverValue): SmartCastInfo
|
|
||||||
= cache.getOrPut(receiver) {
|
|
||||||
val dataFlowValue = DataFlowValueFactory.createDataFlowValue(receiver, resolutionContext)
|
|
||||||
SmartCastInfo(dataFlowValue, dataFlowInfo.getCollectedTypes(dataFlowValue))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getDataFlowValue(receiver: ReceiverValue): DataFlowValue = getSmartCastInfo(receiver).dataFlowValue
|
|
||||||
|
|
||||||
override fun isStableReceiver(receiver: ReceiverValue): Boolean = getSmartCastInfo(receiver).dataFlowValue.isStable
|
|
||||||
|
|
||||||
override fun getSmartCastTypes(receiver: ReceiverValue): Set<KotlinType> = getSmartCastInfo(receiver).possibleTypes
|
|
||||||
|
|
||||||
private data class SmartCastInfo(val dataFlowValue: DataFlowValue, val possibleTypes: Set<KotlinType>)
|
|
||||||
}
|
|
||||||
@@ -19,12 +19,12 @@ package org.jetbrains.kotlin.resolve.calls.tower
|
|||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
interface ScopeTower {
|
interface ScopeTower {
|
||||||
/**
|
/**
|
||||||
@@ -46,13 +46,20 @@ interface ScopeTower {
|
|||||||
val isDebuggerContext: Boolean
|
val isDebuggerContext: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DataFlowDecorator {
|
abstract class DataFlowDecorator() {
|
||||||
fun getDataFlowValue(receiver: ReceiverValue): DataFlowValue
|
private val cache = HashMap<ReceiverValue, SmartCastInfo>()
|
||||||
|
|
||||||
fun isStableReceiver(receiver: ReceiverValue): Boolean
|
|
||||||
|
|
||||||
|
fun isStableReceiver(receiver: ReceiverValue): Boolean = getSmartCastInfo(receiver).isStable
|
||||||
// doesn't include receiver.type
|
// doesn't include receiver.type
|
||||||
fun getSmartCastTypes(receiver: ReceiverValue): Set<KotlinType>
|
fun getSmartCastTypes(receiver: ReceiverValue): Set<KotlinType> = getSmartCastInfo(receiver).possibleTypes
|
||||||
|
|
||||||
|
|
||||||
|
private fun getSmartCastInfo(receiver: ReceiverValue): SmartCastInfo
|
||||||
|
= cache.getOrPut(receiver) { calculateSmartCastInfo(receiver) }
|
||||||
|
|
||||||
|
protected data class SmartCastInfo(val isStable: Boolean, val possibleTypes: Set<KotlinType>)
|
||||||
|
|
||||||
|
protected abstract fun calculateSmartCastInfo(receiver: ReceiverValue): SmartCastInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ScopeTowerLevel {
|
interface ScopeTowerLevel {
|
||||||
|
|||||||
Reference in New Issue
Block a user