Get nested builder inference sessions properly, across delegated inference sessions too

^KT-48445 Fixed
This commit is contained in:
Victor Petukhov
2021-09-06 18:30:41 +03:00
parent 1d9ffebad6
commit 810aee60db
4 changed files with 67 additions and 40 deletions
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
import org.jetbrains.kotlin.resolve.calls.components.* import org.jetbrains.kotlin.resolve.calls.components.*
import org.jetbrains.kotlin.resolve.calls.inference.BuilderInferenceSession
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode
@@ -37,6 +38,18 @@ class DelegatedPropertyInferenceSession(
) : ManyCandidatesResolver<FunctionDescriptor>( ) : ManyCandidatesResolver<FunctionDescriptor>(
psiCallResolver, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter, callComponents, builtIns psiCallResolver, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter, callComponents, builtIns
) { ) {
init {
if (parentSession is ManyCandidatesResolver<*>) {
parentSession.addNestedInferenceSession(this)
}
}
fun getNestedBuilderInferenceSessions(): List<BuilderInferenceSession> {
val builderInferenceSessions = nestedInferenceSessions.filterIsInstance<BuilderInferenceSession>()
val delegatedPropertyInferenceSessions = nestedInferenceSessions.filterIsInstance<DelegatedPropertyInferenceSession>()
return builderInferenceSessions + delegatedPropertyInferenceSessions.map { it.getNestedBuilderInferenceSessions() }.flatten()
}
override fun prepareForCompletion(commonSystem: NewConstraintSystem, resolvedCallsInfo: List<PSIPartialCallInfo>) { override fun prepareForCompletion(commonSystem: NewConstraintSystem, resolvedCallsInfo: List<PSIPartialCallInfo>) {
val csBuilder = commonSystem.getBuilder() val csBuilder = commonSystem.getBuilder()
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.resolve.calls.inference package org.jetbrains.kotlin.resolve.calls.inference
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.* import org.jetbrains.kotlin.descriptors.impl.*
@@ -60,14 +59,12 @@ class BuilderInferenceSession(
) : ManyCandidatesResolver<CallableDescriptor>( ) : ManyCandidatesResolver<CallableDescriptor>(
psiCallResolver, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter, callComponents, builtIns psiCallResolver, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter, callComponents, builtIns
) { ) {
private var nestedBuilderInferenceSessions: MutableSet<BuilderInferenceSession> = mutableSetOf()
private lateinit var lambda: ResolvedLambdaAtom private lateinit var lambda: ResolvedLambdaAtom
private val commonSystem = NewConstraintSystemImpl(callComponents.constraintInjector, builtIns, callComponents.kotlinTypeRefiner) private val commonSystem = NewConstraintSystemImpl(callComponents.constraintInjector, builtIns, callComponents.kotlinTypeRefiner)
init { init {
if (topLevelCallContext.inferenceSession is BuilderInferenceSession) { if (topLevelCallContext.inferenceSession is ManyCandidatesResolver<*>) {
topLevelCallContext.inferenceSession.nestedBuilderInferenceSessions.add(this) topLevelCallContext.inferenceSession.addNestedInferenceSession(this)
} }
stubsForPostponedVariables.keys.forEach(commonSystem::registerVariable) stubsForPostponedVariables.keys.forEach(commonSystem::registerVariable)
} }
@@ -266,6 +263,16 @@ class BuilderInferenceSession(
return commonSystem.fixedTypeVariables.cast() // TODO: SUB return commonSystem.fixedTypeVariables.cast() // TODO: SUB
} }
@OptIn(ExperimentalStdlibApi::class)
private fun getNestedBuilderInferenceSessions() = buildList {
for (nestedSession in nestedInferenceSessions) {
when (nestedSession) {
is BuilderInferenceSession -> add(nestedSession)
is DelegatedPropertyInferenceSession -> addAll(nestedSession.getNestedBuilderInferenceSessions())
}
}
}
/* /*
* We update calls in top-down way: * We update calls in top-down way:
* - updating calls within top-level builder inference call * - updating calls within top-level builder inference call
@@ -279,6 +286,8 @@ class BuilderInferenceSession(
commonSystem.errors commonSystem.errors
) )
val nestedBuilderInferenceSessions = getNestedBuilderInferenceSessions()
for (nestedSession in nestedBuilderInferenceSessions) { for (nestedSession in nestedBuilderInferenceSessions) {
// TODO: exclude injected variables // TODO: exclude injected variables
nestedSession.updateAllCalls( nestedSession.updateAllCalls(
@@ -30,6 +30,11 @@ abstract class ManyCandidatesResolver<D : CallableDescriptor>(
protected val partiallyResolvedCallsInfo = arrayListOf<PSIPartialCallInfo>() protected val partiallyResolvedCallsInfo = arrayListOf<PSIPartialCallInfo>()
private val errorCallsInfo = arrayListOf<PSIErrorCallInfo<D>>() private val errorCallsInfo = arrayListOf<PSIErrorCallInfo<D>>()
private val completedCalls = hashSetOf<ResolvedAtom>() private val completedCalls = hashSetOf<ResolvedAtom>()
protected val nestedInferenceSessions = hashSetOf<ManyCandidatesResolver<*>>()
fun addNestedInferenceSession(inferenceSession: ManyCandidatesResolver<*>) {
nestedInferenceSessions.add(inferenceSession)
}
open fun prepareForCompletion(commonSystem: NewConstraintSystem, resolvedCallsInfo: List<PSIPartialCallInfo>) { open fun prepareForCompletion(commonSystem: NewConstraintSystem, resolvedCallsInfo: List<PSIPartialCallInfo>) {
// do nothing // do nothing
@@ -14,39 +14,39 @@ internal class TowerDataElementsForName() {
} }
} }
//internal class TowerDataElementsForName2() { internal class TowerDataElementsForName2() {
// @OptIn(ExperimentalStdlibApi::class) @OptIn(ExperimentalStdlibApi::class)
// val reversedFilteredLocalScopes = buildList { val reversedFilteredLocalScopes = buildList {
// val reversedFilteredLocalScopes by lazy(LazyThreadSafetyMode.NONE) { val reversedFilteredLocalScopes by lazy(LazyThreadSafetyMode.NONE) {
// @OptIn(ExperimentalStdlibApi::class) @OptIn(ExperimentalStdlibApi::class)
// buildList { buildList {
// for (i in lastIndex downTo 0) { for (i in lastIndex downTo 0) {
// add("") add("")
// } }
// } }
// } }
// add(reversedFilteredLocalScopes) add(reversedFilteredLocalScopes)
// } }
//} }
//
//internal class TowerDataElementsForName3() { internal class TowerDataElementsForName3() {
// val reversedFilteredLocalScopes by lazy(LazyThreadSafetyMode.NONE) { val reversedFilteredLocalScopes by lazy(LazyThreadSafetyMode.NONE) {
// @OptIn(ExperimentalStdlibApi::class) @OptIn(ExperimentalStdlibApi::class)
// buildList l1@ { buildList l1@ {
// for (i in lastIndex downTo 0) { for (i in lastIndex downTo 0) {
// val reversedFilteredLocalScopes by lazy(LazyThreadSafetyMode.NONE) { val reversedFilteredLocalScopes by lazy(LazyThreadSafetyMode.NONE) {
// @OptIn(ExperimentalStdlibApi::class) @OptIn(ExperimentalStdlibApi::class)
// buildList { buildList {
// for (i in lastIndex downTo 0) { for (i in lastIndex downTo 0) {
// add("") add("")
// this@l1.add("") this@l1.add("")
// } }
// } }
// } }
// } }
// } }
// } }
//} }
// mute due to KT-48633 // mute due to KT-48633
//internal class TowerDataElementsForName4() { //internal class TowerDataElementsForName4() {
@@ -68,8 +68,8 @@ internal class TowerDataElementsForName() {
fun box(): String { fun box(): String {
val x1 = TowerDataElementsForName().reversedFilteredLocalScopes val x1 = TowerDataElementsForName().reversedFilteredLocalScopes
// val x2 = TowerDataElementsForName2().reversedFilteredLocalScopes val x2 = TowerDataElementsForName2().reversedFilteredLocalScopes
// val x3 = TowerDataElementsForName3().reversedFilteredLocalScopes val x3 = TowerDataElementsForName3().reversedFilteredLocalScopes
// val x4 = TowerDataElementsForName4().reversedFilteredLocalScopes // val x4 = TowerDataElementsForName4().reversedFilteredLocalScopes
return "OK" return "OK"
} }