Base dynamic support in new resolve
This commit is contained in:
+18
-6
@@ -35,10 +35,13 @@ 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.tasks.DynamicCallableDescriptors
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategyForInvoke
|
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategyForInvoke
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||||
|
import org.jetbrains.kotlin.types.isDynamic
|
||||||
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
|
||||||
@@ -46,7 +49,8 @@ import org.jetbrains.kotlin.utils.sure
|
|||||||
class NewResolveOldInference(
|
class NewResolveOldInference(
|
||||||
val candidateResolver: CandidateResolver,
|
val candidateResolver: CandidateResolver,
|
||||||
val towerResolver: TowerResolver,
|
val towerResolver: TowerResolver,
|
||||||
val resolutionResultsHandler: ResolutionResultsHandler
|
val resolutionResultsHandler: ResolutionResultsHandler,
|
||||||
|
val dynamicCallableDescriptors: DynamicCallableDescriptors
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun runResolve(
|
fun runResolve(
|
||||||
@@ -57,7 +61,8 @@ class NewResolveOldInference(
|
|||||||
): OverloadResolutionResultsImpl<*> {
|
): OverloadResolutionResultsImpl<*> {
|
||||||
val explicitReceiver = context.call.explicitReceiver.check { it.exists() }
|
val explicitReceiver = context.call.explicitReceiver.check { it.exists() }
|
||||||
|
|
||||||
val scopeTower = ScopeTowerImpl(context, explicitReceiver, context.call.createLookupLocation())
|
val dynamicScope = dynamicCallableDescriptors.createDynamicDescriptorScope(context.call, context.scope.ownerDescriptor)
|
||||||
|
val scopeTower = ScopeTowerImpl(context, dynamicScope, explicitReceiver, context.call.createLookupLocation())
|
||||||
|
|
||||||
val baseContext = Context(scopeTower, name, context, tracing)
|
val baseContext = Context(scopeTower, name, context, tracing)
|
||||||
|
|
||||||
@@ -74,7 +79,7 @@ class NewResolveOldInference(
|
|||||||
val call = (context.call as? CallTransformer.CallForImplicitInvoke).sure {
|
val call = (context.call as? CallTransformer.CallForImplicitInvoke).sure {
|
||||||
"Call should be CallForImplicitInvoke, but it is: ${context.call}"
|
"Call should be CallForImplicitInvoke, but it is: ${context.call}"
|
||||||
}
|
}
|
||||||
createCollectorWithReceiverValueOrEmpty(explicitReceiver) {
|
createProcessorWithReceiverValueOrEmpty(explicitReceiver) {
|
||||||
createCallTowerProcessorForExplicitInvoke(baseContext, call.dispatchReceiver, it)
|
createCallTowerProcessorForExplicitInvoke(baseContext, call.dispatchReceiver, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,7 +92,7 @@ class NewResolveOldInference(
|
|||||||
return convertToOverloadResults(candidates, tracing, context)
|
return convertToOverloadResults(candidates, tracing, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createCollectorWithReceiverValueOrEmpty(
|
private fun createProcessorWithReceiverValueOrEmpty(
|
||||||
explicitReceiver: Receiver?,
|
explicitReceiver: Receiver?,
|
||||||
create: (ReceiverValue?) -> ScopeTowerProcessor<Candidate>
|
create: (ReceiverValue?) -> ScopeTowerProcessor<Candidate>
|
||||||
): ScopeTowerProcessor<Candidate> {
|
): ScopeTowerProcessor<Candidate> {
|
||||||
@@ -100,7 +105,6 @@ class NewResolveOldInference(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun createFunctionTowerProcessor(baseContext: Context, explicitReceiver: Receiver?): CompositeScopeTowerProcessor<Candidate> {
|
private fun createFunctionTowerProcessor(baseContext: Context, explicitReceiver: Receiver?): CompositeScopeTowerProcessor<Candidate> {
|
||||||
// a.foo() -- simple function call
|
// a.foo() -- simple function call
|
||||||
val simpleFunction = createFunctionProcessor(baseContext, explicitReceiver)
|
val simpleFunction = createFunctionProcessor(baseContext, explicitReceiver)
|
||||||
@@ -109,7 +113,7 @@ class NewResolveOldInference(
|
|||||||
val invokeProcessor = InvokeTowerProcessor(baseContext, explicitReceiver)
|
val invokeProcessor = InvokeTowerProcessor(baseContext, explicitReceiver)
|
||||||
|
|
||||||
// a.foo() -- property foo is extension function with receiver a -- a.invoke()
|
// a.foo() -- property foo is extension function with receiver a -- a.invoke()
|
||||||
val invokeExtensionProcessor = createCollectorWithReceiverValueOrEmpty(explicitReceiver) { InvokeExtensionTowerProcessor(baseContext, it) }
|
val invokeExtensionProcessor = createProcessorWithReceiverValueOrEmpty(explicitReceiver) { InvokeExtensionTowerProcessor(baseContext, it) }
|
||||||
|
|
||||||
return CompositeScopeTowerProcessor(simpleFunction, invokeProcessor, invokeExtensionProcessor)
|
return CompositeScopeTowerProcessor(simpleFunction, invokeProcessor, invokeExtensionProcessor)
|
||||||
}
|
}
|
||||||
@@ -178,6 +182,14 @@ class NewResolveOldInference(
|
|||||||
explicitReceiverKind, null, candidateTrace, tracing,
|
explicitReceiverKind, null, candidateTrace, tracing,
|
||||||
basicCallContext.dataFlowInfoForArguments // todo may be we should create new mutable info for arguments
|
basicCallContext.dataFlowInfoForArguments // todo may be we should create new mutable info for arguments
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// see spec-docs/dynamic-types.md
|
||||||
|
if (extensionReceiver != null && extensionReceiver.type.isDynamic()
|
||||||
|
&& !towerCandidate.descriptor.extensionReceiverParameter!!.value.type.isDynamic()) {
|
||||||
|
candidateCall.addStatus(ResolutionStatus.RECEIVER_PRESENCE_ERROR)
|
||||||
|
return Candidate(ResolutionCandidateStatus(listOf(ExtensionWithStaticTypeWithDynamicReceiver)), candidateCall)
|
||||||
|
}
|
||||||
|
|
||||||
val callCandidateResolutionContext = CallCandidateResolutionContext.create(
|
val callCandidateResolutionContext = CallCandidateResolutionContext.create(
|
||||||
candidateCall, basicCallContext, candidateTrace, tracing, basicCallContext.call,
|
candidateCall, basicCallContext, candidateTrace, tracing, basicCallContext.call,
|
||||||
ReceiverValue.NO_RECEIVER, CandidateResolveMode.FULLY // todo
|
ReceiverValue.NO_RECEIVER, CandidateResolveMode.FULLY // todo
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ 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.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.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
@@ -33,6 +34,8 @@ interface ScopeTower {
|
|||||||
|
|
||||||
val lexicalScope: LexicalScope
|
val lexicalScope: LexicalScope
|
||||||
|
|
||||||
|
val dynamicScope: MemberScope
|
||||||
|
|
||||||
val location: LookupLocation
|
val location: LookupLocation
|
||||||
|
|
||||||
val dataFlowInfo: DataFlowDecorator
|
val dataFlowInfo: DataFlowDecorator
|
||||||
@@ -91,6 +94,8 @@ class UsedSmartCastForDispatchReceiver(val smartCastType: KotlinType): Resolutio
|
|||||||
|
|
||||||
object ErrorDescriptorDiagnostic : ResolutionDiagnostic(ResolutionCandidateApplicability.INAPPLICABLE)
|
object ErrorDescriptorDiagnostic : ResolutionDiagnostic(ResolutionCandidateApplicability.INAPPLICABLE)
|
||||||
object SynthesizedDescriptorDiagnostic: ResolutionDiagnostic(ResolutionCandidateApplicability.RESOLVED_SYNTHESIZED)
|
object SynthesizedDescriptorDiagnostic: ResolutionDiagnostic(ResolutionCandidateApplicability.RESOLVED_SYNTHESIZED)
|
||||||
|
object DynamicDescriptorDiagnostic: ResolutionDiagnostic(ResolutionCandidateApplicability.RESOLVED_SYNTHESIZED)
|
||||||
object UnstableSmartCastDiagnostic: ResolutionDiagnostic(ResolutionCandidateApplicability.MAY_THROW_RUNTIME_ERROR)
|
object UnstableSmartCastDiagnostic: ResolutionDiagnostic(ResolutionCandidateApplicability.MAY_THROW_RUNTIME_ERROR)
|
||||||
|
object ExtensionWithStaticTypeWithDynamicReceiver: ResolutionDiagnostic(ResolutionCandidateApplicability.INAPPLICABLE)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue
|
|||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||||
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
|
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
|
||||||
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.receivers.ClassQualifier
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
@@ -43,6 +44,7 @@ internal class CandidateWithBoundDispatchReceiverImpl<D : CallableDescriptor>(
|
|||||||
|
|
||||||
internal class ScopeTowerImpl(
|
internal class ScopeTowerImpl(
|
||||||
resolutionContext: ResolutionContext<*>,
|
resolutionContext: ResolutionContext<*>,
|
||||||
|
override val dynamicScope: MemberScope,
|
||||||
private val explicitReceiver: Receiver?,
|
private val explicitReceiver: Receiver?,
|
||||||
override val location: LookupLocation
|
override val location: LookupLocation
|
||||||
): ScopeTower {
|
): ScopeTower {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.QualifierReceiver
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
import org.jetbrains.kotlin.types.ErrorUtils
|
import org.jetbrains.kotlin.types.ErrorUtils
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.isDynamic
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -147,6 +148,12 @@ internal class ReceiverScopeTowerLevel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dispatchReceiver.type.isDynamic()) {
|
||||||
|
scopeTower.dynamicScope.members().mapTo(result) {
|
||||||
|
createCandidateDescriptor(it, dispatchReceiver, DynamicDescriptorDiagnostic)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user