FIR: handle double-imported constructors properly

This commit is contained in:
Mikhail Glukhikh
2022-03-14 14:32:02 +03:00
committed by Space
parent bd790b792c
commit b038ae8b0c
3 changed files with 25 additions and 49 deletions
@@ -73,15 +73,17 @@ internal fun FirScope.processFunctionsAndConstructorsByName(
processFunctionsByName(callInfo.name, processor) processFunctionsByName(callInfo.name, processor)
} }
private data class SymbolWithSubstitutor(val symbol: FirClassifierSymbol<*>, val substitutor: ConeSubstitutor)
private fun FirScope.getFirstClassifierOrNull( private fun FirScope.getFirstClassifierOrNull(
callInfo: CallInfo, callInfo: CallInfo,
session: FirSession, session: FirSession,
bodyResolveComponents: BodyResolveComponents bodyResolveComponents: BodyResolveComponents
): Pair<FirClassifierSymbol<*>, ConeSubstitutor>? { ): SymbolWithSubstitutor? {
var isSuccessResult = false var isSuccessResult = false
var isAmbiguousResult = false var isAmbiguousResult = false
var result: Pair<FirClassifierSymbol<*>, ConeSubstitutor>? = null var result: SymbolWithSubstitutor? = null
processClassifiersByNameWithSubstitution(callInfo.name) { symbol, substitution -> processClassifiersByNameWithSubstitution(callInfo.name) { symbol, substitutor ->
val classifierDeclaration = symbol.fir val classifierDeclaration = symbol.fir
var isSuccessCandidate = true var isSuccessCandidate = true
if (classifierDeclaration is FirMemberDeclaration) { if (classifierDeclaration is FirMemberDeclaration) {
@@ -103,11 +105,25 @@ private fun FirScope.getFirstClassifierOrNull(
isSuccessCandidate = false isSuccessCandidate = false
} }
if (result == null || (!isSuccessResult && isSuccessCandidate)) { when {
isSuccessResult = isSuccessCandidate isSuccessCandidate && !isSuccessResult -> {
result = symbol to substitution // any result is better than no result
} else { isSuccessResult = true
isAmbiguousResult = true result = SymbolWithSubstitutor(symbol, substitutor)
}
result?.symbol === symbol -> {
// miss identical results
return@processClassifiersByNameWithSubstitution
}
result != null -> {
// results are similar => ambiguity
isAmbiguousResult = true
}
else -> {
// result == null: any result is better than no result
isSuccessResult = isSuccessCandidate
result = SymbolWithSubstitutor(symbol, substitutor)
}
} }
} }
@@ -1,41 +0,0 @@
// FILE: StarImported.kt
package star
class SomeClass
fun foo() {}
val bar = 1
// FILE: ExplicitImported.kt
package explicit
class AnotherClass
fun baz() {}
val gau = 2
// FILE: Test.kt
import star.*
import star.*
import explicit.<!CONFLICTING_IMPORT!>AnotherClass<!>
import explicit.<!CONFLICTING_IMPORT!>AnotherClass<!>
import explicit.baz
import explicit.baz
import explicit.gau
import explicit.gau
fun useSomeClass(): SomeClass = <!RESOLUTION_TO_CLASSIFIER!>SomeClass<!>()
fun useAnotherClass(): AnotherClass = <!RESOLUTION_TO_CLASSIFIER!>AnotherClass<!>()
fun test() {
foo()
baz()
val x = bar
val y = gau
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// FILE: StarImported.kt // FILE: StarImported.kt
package star package star