Refactor DataFlowDecorator.

This commit is contained in:
Stanislav Erokhin
2016-08-24 15:24:22 +03:00
parent 8d2d5ea211
commit 58fd24943d
3 changed files with 41 additions and 76 deletions
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.Call
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.isInfixCall
import org.jetbrains.kotlin.resolve.calls.callUtil.createLookupLocation
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
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.context.*
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCallImpl
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCallImpl
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl
import org.jetbrains.kotlin.resolve.calls.results.ResolutionResultsHandler
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.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.receivers.*
import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
import org.jetbrains.kotlin.types.DeferredType
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.isDynamic
import org.jetbrains.kotlin.types.typeUtil.containsError
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addToStdlib.check
import org.jetbrains.kotlin.utils.sure
@@ -231,6 +234,27 @@ class NewResolutionOldInference(
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>(
val candidateStatus: ResolutionCandidateStatus,
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.incremental.components.LookupLocation
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.MemberScope
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.types.KotlinType
import java.util.*
interface ScopeTower {
/**
@@ -46,13 +46,20 @@ interface ScopeTower {
val isDebuggerContext: Boolean
}
interface DataFlowDecorator {
fun getDataFlowValue(receiver: ReceiverValue): DataFlowValue
fun isStableReceiver(receiver: ReceiverValue): Boolean
abstract class DataFlowDecorator() {
private val cache = HashMap<ReceiverValue, SmartCastInfo>()
fun isStableReceiver(receiver: ReceiverValue): Boolean = getSmartCastInfo(receiver).isStable
// 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 {