FIR: prioritize visible imported classes during type resolution

and produce an error on ambiguity.
This commit is contained in:
pyos
2021-02-10 16:45:35 +01:00
committed by Mikhail Glukhikh
parent 291ed4a38a
commit 2dc0404751
25 changed files with 160 additions and 198 deletions
@@ -13,9 +13,11 @@ import org.jetbrains.kotlin.fir.scopes.impl.*
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.name.FqName
private object FirDefaultStarImportingScopeKey : ScopeSessionKey<DefaultImportPriority, FirScope>()
private object FirDefaultSimpleImportingScopeKey : ScopeSessionKey<DefaultImportPriority, FirScope>()
private object FileImportingScopeKey : ScopeSessionKey<FirFile, ListStorageFirScope>()
private val INVISIBLE_DEFAULT_STAR_IMPORT = scopeSessionKey<DefaultImportPriority, FirDefaultStarImportingScope>()
private val VISIBLE_DEFAULT_STAR_IMPORT = scopeSessionKey<DefaultImportPriority, FirDefaultStarImportingScope>()
private val DEFAULT_SIMPLE_IMPORT = scopeSessionKey<DefaultImportPriority, FirDefaultSimpleImportingScope>()
private val PACKAGE_MEMBER = scopeSessionKey<FqName, FirPackageMemberScope>()
private val ALL_IMPORTS = scopeSessionKey<FirFile, ListStorageFirScope>()
private class ListStorageFirScope(val result: List<FirScope>) : FirScope()
@@ -25,7 +27,7 @@ fun createImportingScopes(
scopeSession: ScopeSession,
useCaching: Boolean = true
): List<FirScope> = if (useCaching) {
scopeSession.getOrBuild(file, FileImportingScopeKey) {
scopeSession.getOrBuild(file, ALL_IMPORTS) {
ListStorageFirScope(doCreateImportingScopes(file, session, scopeSession))
}.result
} else {
@@ -39,17 +41,26 @@ private fun doCreateImportingScopes(
): List<FirScope> {
return listOf(
// from low priority to high priority
scopeSession.getOrBuild(DefaultImportPriority.LOW, FirDefaultStarImportingScopeKey) {
FirDefaultStarImportingScope(session, scopeSession, priority = DefaultImportPriority.LOW)
scopeSession.getOrBuild(DefaultImportPriority.LOW, INVISIBLE_DEFAULT_STAR_IMPORT) {
FirDefaultStarImportingScope(session, scopeSession, FirImportingScopeFilter.INVISIBLE_CLASSES, DefaultImportPriority.LOW)
},
scopeSession.getOrBuild(DefaultImportPriority.HIGH, FirDefaultStarImportingScopeKey) {
FirDefaultStarImportingScope(session, scopeSession, priority = DefaultImportPriority.HIGH)
scopeSession.getOrBuild(DefaultImportPriority.HIGH, INVISIBLE_DEFAULT_STAR_IMPORT) {
FirDefaultStarImportingScope(session, scopeSession, FirImportingScopeFilter.INVISIBLE_CLASSES, DefaultImportPriority.HIGH)
},
FirExplicitStarImportingScope(file.imports, session, scopeSession),
scopeSession.getOrBuild(DefaultImportPriority.LOW, FirDefaultSimpleImportingScopeKey) {
FirExplicitStarImportingScope(file.imports, session, scopeSession, FirImportingScopeFilter.INVISIBLE_CLASSES),
// TODO: invisible classes from current package should go before this point
scopeSession.getOrBuild(DefaultImportPriority.LOW, VISIBLE_DEFAULT_STAR_IMPORT) {
FirDefaultStarImportingScope(session, scopeSession, FirImportingScopeFilter.MEMBERS_AND_VISIBLE_CLASSES, DefaultImportPriority.LOW)
},
scopeSession.getOrBuild(DefaultImportPriority.HIGH, VISIBLE_DEFAULT_STAR_IMPORT) {
FirDefaultStarImportingScope(session, scopeSession, FirImportingScopeFilter.MEMBERS_AND_VISIBLE_CLASSES, DefaultImportPriority.HIGH)
},
FirExplicitStarImportingScope(file.imports, session, scopeSession, FirImportingScopeFilter.MEMBERS_AND_VISIBLE_CLASSES),
scopeSession.getOrBuild(DefaultImportPriority.LOW, DEFAULT_SIMPLE_IMPORT) {
FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.LOW)
},
scopeSession.getOrBuild(DefaultImportPriority.HIGH, FirDefaultSimpleImportingScopeKey) {
scopeSession.getOrBuild(DefaultImportPriority.HIGH, DEFAULT_SIMPLE_IMPORT) {
FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.HIGH)
},
scopeSession.getOrBuild(file.packageFqName, PACKAGE_MEMBER) {
@@ -60,8 +71,6 @@ private fun doCreateImportingScopes(
)
}
private val PACKAGE_MEMBER = scopeSessionKey<FqName, FirPackageMemberScope>()
fun ConeClassLikeLookupTag.getNestedClassifierScope(session: FirSession, scopeSession: ScopeSession): FirScope? {
val klass = toSymbol(session)?.fir as? FirRegularClass ?: return null
return klass.scopeProvider.getNestedClassifierScope(klass, session, scopeSession)
@@ -6,9 +6,12 @@
package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
import org.jetbrains.kotlin.fir.declarations.expandedConeType
import org.jetbrains.kotlin.fir.moduleVisibilityChecker
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedForCalls
@@ -16,53 +19,89 @@ import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
enum class FirImportingScopeFilter {
ALL, INVISIBLE_CLASSES, MEMBERS_AND_VISIBLE_CLASSES;
fun check(symbol: FirClassLikeSymbol<*>, session: FirSession): Boolean {
if (this == ALL) return true
// TODO: also check DeprecationLevel.HIDDEN and required Kotlin version
val fir = symbol.fir as? FirMemberDeclaration ?: return false
val isVisible = when (fir.status.visibility) {
// When importing from the same module, status may be unknown because the status resolver depends on super types
// to determine visibility for functions, so it may not have finished yet. Since we only care about classes,
// though, "unknown" will always become public anyway.
Visibilities.Unknown -> true
Visibilities.Internal ->
symbol.fir.session == session || session.moduleVisibilityChecker?.isInFriendModule(fir) == true
// All non-`internal` visibilities are either even more restrictive (e.g. `private`) or must not
// be checked in imports (e.g. `protected` may be valid in some use sites).
else -> !fir.status.visibility.mustCheckInImports()
}
return isVisible == (this == MEMBERS_AND_VISIBLE_CLASSES)
}
}
abstract class FirAbstractImportingScope(
session: FirSession,
protected val scopeSession: ScopeSession,
protected val filter: FirImportingScopeFilter,
lookupInFir: Boolean
) : FirAbstractProviderBasedScope(session, lookupInFir) {
private fun getStaticsScope(symbol: FirClassLikeSymbol<*>): FirScope? {
if (symbol is FirTypeAliasSymbol) {
val expansionSymbol = symbol.fir.expandedConeType?.lookupTag?.toSymbol(session)
if (expansionSymbol != null) {
return getStaticsScope(expansionSymbol)
}
} else {
val firClass = (symbol as FirClassSymbol<*>).fir
return if (firClass.classKind == ClassKind.OBJECT) {
FirObjectImportedCallableScope(
symbol.classId,
firClass.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = false)
)
} else {
firClass.scopeProvider.getStaticScope(firClass, session, scopeSession)
}
private val FirClassLikeSymbol<*>.fullyExpandedSymbol: FirClassSymbol<*>?
get() = when (this) {
is FirTypeAliasSymbol -> fir.expandedConeType?.lookupTag?.toSymbol(session)?.fullyExpandedSymbol
is FirClassSymbol<*> -> this
}
return null
private fun FirClassSymbol<*>.getStaticsScope(): FirScope? =
if (fir.classKind == ClassKind.OBJECT) {
FirObjectImportedCallableScope(
classId, fir.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = false)
)
} else {
fir.scopeProvider.getStaticScope(fir, session, scopeSession)
}
fun getStaticsScope(classId: ClassId): FirScope? =
provider.getClassLikeSymbolByFqName(classId)?.fullyExpandedSymbol?.getStaticsScope()
protected fun findSingleClassifierSymbolByName(name: Name?, imports: List<FirResolvedImport>): FirClassLikeSymbol<*>? {
var result: FirClassLikeSymbol<*>? = null
for (import in imports) {
val importedName = name ?: import.importedName ?: continue
val classId = import.resolvedClassId?.createNestedClassId(importedName)
?: ClassId.topLevel(import.packageFqName.child(importedName))
val symbol = provider.getClassLikeSymbolByFqName(classId) ?: continue
if (!filter.check(symbol, session)) continue
result = when {
result == null || result == symbol -> symbol
// Importing multiple versions of the same type is normally an ambiguity, but in the case of `kotlin.Throws`,
// it should take precedence over platform-specific variants. This is lifted directly from `LazyImportScope`
// from the old backend; most likely `Throws` predates expect-actual, and this is a backwards compatibility hack.
// TODO: remove redundant versions of `Throws` from the standard library
result.classId.isJvmOrNativeThrows && symbol.classId.isCommonThrows -> symbol
result.classId.isCommonThrows && symbol.classId.isJvmOrNativeThrows -> result
// TODO: if there is an ambiguity at this scope, further scopes should not be checked.
// Doing otherwise causes KT-39073. Also, returning null here instead of an error symbol
// or something produces poor quality diagnostics ("unresolved name" rather than "ambiguity").
else -> return null
}
}
return result
}
fun getStaticsScope(classId: ClassId): FirScope? {
val symbol = provider.getClassLikeSymbolByFqName(classId) ?: return null
return getStaticsScope(symbol)
}
protected inline fun processFunctionsByNameWithImport(
name: Name,
import: FirResolvedImport,
crossinline processor: (FirNamedFunctionSymbol) -> Unit
) {
import.resolvedClassId?.let { classId ->
getStaticsScope(classId)?.processFunctionsByName(name) { processor(it) }
} ?: run {
if (name.isSpecial || name.identifier.isNotEmpty()) {
val symbols = provider.getTopLevelFunctionSymbols(import.packageFqName, name)
for (symbol in symbols) {
protected fun processFunctionsByName(name: Name?, imports: List<FirResolvedImport>, processor: (FirNamedFunctionSymbol) -> Unit) {
if (filter == FirImportingScopeFilter.INVISIBLE_CLASSES) return
for (import in imports) {
val importedName = name ?: import.importedName ?: continue
val staticsScope = import.resolvedClassId?.let(::getStaticsScope)
if (staticsScope != null) {
staticsScope.processFunctionsByName(importedName, processor)
} else if (importedName.isSpecial || importedName.identifier.isNotEmpty()) {
for (symbol in provider.getTopLevelFunctionSymbols(import.packageFqName, importedName)) {
symbol.ensureResolvedForCalls(session)
processor(symbol)
}
@@ -70,17 +109,15 @@ abstract class FirAbstractImportingScope(
}
}
protected inline fun processPropertiesByNameWithImport(
name: Name,
import: FirResolvedImport,
crossinline processor: (FirVariableSymbol<*>) -> Unit
) {
import.resolvedClassId?.let { classId ->
getStaticsScope(classId)?.processPropertiesByName(name) { processor(it) }
} ?: run {
if (name.isSpecial || name.identifier.isNotEmpty()) {
val symbols = provider.getTopLevelPropertySymbols(import.packageFqName, name)
for (symbol in symbols) {
protected fun processPropertiesByName(name: Name?, imports: List<FirResolvedImport>, processor: (FirVariableSymbol<*>) -> Unit) {
if (filter == FirImportingScopeFilter.INVISIBLE_CLASSES) return
for (import in imports) {
val importedName = name ?: import.importedName ?: continue
val staticsScope = import.resolvedClassId?.let(::getStaticsScope)
if (staticsScope != null) {
staticsScope.processPropertiesByName(importedName, processor)
} else if (importedName.isSpecial || importedName.identifier.isNotEmpty()) {
for (symbol in provider.getTopLevelPropertySymbols(import.packageFqName, importedName)) {
symbol.ensureResolvedForCalls(session)
processor(symbol)
}
@@ -88,3 +125,9 @@ abstract class FirAbstractImportingScope(
}
}
}
private val ClassId.isJvmOrNativeThrows: Boolean
get() = asSingleFqName() == FqName("kotlin.jvm.Throws") || asSingleFqName() == FqName("kotlin.native.Throws")
private val ClassId.isCommonThrows: Boolean
get() = asSingleFqName() == FqName("kotlin.Throws")
@@ -8,47 +8,33 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.symbolProvider
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
abstract class FirAbstractSimpleImportingScope(
session: FirSession,
scopeSession: ScopeSession
) : FirAbstractImportingScope(session, scopeSession, lookupInFir = true) {
) : FirAbstractImportingScope(session, scopeSession, FirImportingScopeFilter.ALL, lookupInFir = true) {
// TODO try to hide this
abstract val simpleImports: Map<Name, List<FirResolvedImport>>
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
val imports = simpleImports[name] ?: return
if (imports.isEmpty()) return
val provider = session.symbolProvider
for (import in imports) {
val importedName = import.importedName ?: continue
val classId =
import.resolvedClassId?.createNestedClassId(importedName)
?: ClassId.topLevel(import.packageFqName.child(importedName))
val symbol = provider.getClassLikeSymbolByFqName(classId) ?: continue
processor(symbol, ConeSubstitutor.Empty)
}
val symbol = findSingleClassifierSymbolByName(null, imports) ?: return
processor(symbol, ConeSubstitutor.Empty)
}
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
val imports = simpleImports[name] ?: return
for (import in imports) {
processFunctionsByNameWithImport(import.importedName!!, import, processor)
}
processFunctionsByName(null, imports, processor)
}
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
val imports = simpleImports[name] ?: return
for (import in imports) {
processPropertiesByNameWithImport(import.importedName!!, import, processor)
}
processPropertiesByName(null, imports, processor)
}
}
@@ -12,14 +12,14 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
abstract class FirAbstractStarImportingScope(
session: FirSession,
scopeSession: ScopeSession,
lookupInFir: Boolean = true
) : FirAbstractImportingScope(session, scopeSession, lookupInFir) {
filter: FirImportingScopeFilter,
lookupInFir: Boolean
) : FirAbstractImportingScope(session, scopeSession, filter, lookupInFir) {
// TODO try to hide this
abstract val starImports: List<FirResolvedImport>
@@ -27,35 +27,20 @@ abstract class FirAbstractStarImportingScope(
private val absentClassifierNames = mutableSetOf<Name>()
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
if (starImports.isEmpty() || name in absentClassifierNames) {
if ((!name.isSpecial && name.identifier.isEmpty()) || starImports.isEmpty() || name in absentClassifierNames) {
return
}
var empty = true
for (import in starImports) {
val relativeClassName = import.relativeClassName
val classId = when {
!name.isSpecial && name.identifier.isEmpty() -> return
relativeClassName == null -> ClassId(import.packageFqName, name)
else -> ClassId(import.packageFqName, relativeClassName.child(name), false)
}
val symbol = provider.getClassLikeSymbolByFqName(classId) ?: continue
empty = false
val symbol = findSingleClassifierSymbolByName(name, starImports)
if (symbol != null) {
processor(symbol, ConeSubstitutor.Empty)
}
if (empty) {
} else {
absentClassifierNames += name
}
}
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
for (import in starImports) {
processFunctionsByNameWithImport(name, import, processor)
}
}
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) =
processFunctionsByName(name, starImports, processor)
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
for (import in starImports) {
processPropertiesByNameWithImport(name, import, processor)
}
}
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) =
processPropertiesByName(name, starImports, processor)
}
@@ -17,8 +17,9 @@ import org.jetbrains.kotlin.name.Name
class FirDefaultStarImportingScope(
session: FirSession,
scopeSession: ScopeSession,
filter: FirImportingScopeFilter,
priority: DefaultImportPriority
) : FirAbstractStarImportingScope(session, scopeSession, lookupInFir = false) {
) : FirAbstractStarImportingScope(session, scopeSession, filter, lookupInFir = false) {
// TODO: put languageVersionSettings into FirSession?
override val starImports = run {
@@ -13,7 +13,8 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession
class FirExplicitStarImportingScope(
imports: List<FirImport>,
session: FirSession,
scopeSession: ScopeSession
) : FirAbstractStarImportingScope(session, scopeSession) {
scopeSession: ScopeSession,
filter: FirImportingScopeFilter
) : FirAbstractStarImportingScope(session, scopeSession, filter, lookupInFir = true) {
override val starImports = imports.filterIsInstance<FirResolvedImport>().filter { it.isAllUnder }
}
@@ -1,17 +0,0 @@
// FILE: a.kt
package a
class X
// FILE: b.kt
package b
class X
// FILE: c.kt
package c
import a.*
import b.*
class Y : X
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// FILE: a.kt
package a
@@ -14,4 +14,4 @@ package c
import a.X
import b.X
class Y : X
class Y : <!UNRESOLVED_REFERENCE!>X<!>
@@ -1,12 +0,0 @@
// FILE: File.kt
package pack
public open class InetAddressImpl
// FILE: Main.kt
package a
import java.net.* // should not import java.net.InetAddressImpl because it's package local
import pack.*
class X : <!UNRESOLVED_REFERENCE!>InetAddressImpl<!>() // should resolve to our pack.InetAddressImpl
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// FILE: File.kt
package pack
@@ -17,8 +17,8 @@ class D {
import a.A.B
import a.D.B
fun test(b: B) {
B()
fun test(b: <!UNRESOLVED_REFERENCE!>B<!>) {
<!UNRESOLVED_REFERENCE!>B<!>()
}
// FILE: d.kt
@@ -26,6 +26,6 @@ import a.A.*
import a.D.*
// todo ambiguvity here
fun test2(b: B) {
B()
fun test2(b: <!UNRESOLVED_REFERENCE!>B<!>) {
<!UNRESOLVED_REFERENCE!>B<!>()
}
@@ -1,17 +0,0 @@
// FILE: File1.kt
package pack1
private class SomeClass
// FILE: File2.kt
package pack2
public open class SomeClass
// FILE: Main.kt
package a
import pack1.*
import pack2.*
class X : <!EXPOSED_SUPER_CLASS, HIDDEN!>SomeClass<!>()
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// FILE: File1.kt
package pack1
@@ -1,21 +0,0 @@
// FILE: File1.kt
package pack1
public class SomeClass {
private class N
public open class PublicNested
}
// FILE: File2.kt
package pack2
public open class N
// FILE: Main.kt
package a
import pack1.SomeClass.*
import pack2.*
class X : <!EXPOSED_SUPER_CLASS, HIDDEN!>N<!>()
class Y : PublicNested()
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// FILE: File1.kt
package pack1
@@ -24,4 +24,4 @@ package c
import a.*
import b.*
fun test(): x = d().x()
fun test(): <!UNRESOLVED_REFERENCE!>x<!> = d().x()
@@ -22,8 +22,8 @@ class A {
import p1.*
import p2.*
fun test(a: A) {
a.m1()
fun test(a: <!UNRESOLVED_REFERENCE!>A<!>) {
a.<!UNRESOLVED_REFERENCE!>m1<!>()
a.<!UNRESOLVED_REFERENCE!>m2<!>()
}
@@ -39,8 +39,8 @@ import p1.*
import p2.*
import p3.*
fun test(a: A) {
a.v1
fun test(a: <!UNRESOLVED_REFERENCE!>A<!>) {
a.<!UNRESOLVED_REFERENCE!>v1<!>
a.<!UNRESOLVED_REFERENCE!>v2<!>
a.<!UNRESOLVED_REFERENCE!>v3<!>
}
@@ -23,8 +23,8 @@ class A {
import p1.*
import p2.*
fun test(a: A) {
a.m1()
fun test(a: <!UNRESOLVED_REFERENCE!>A<!>) {
a.<!UNRESOLVED_REFERENCE!>m1<!>()
a.<!UNRESOLVED_REFERENCE!>m2<!>()
}
@@ -40,8 +40,8 @@ import p1.*
import p2.*
import p3.*
fun test(a: A) {
a.v1
fun test(a: <!UNRESOLVED_REFERENCE!>A<!>) {
a.<!UNRESOLVED_REFERENCE!>v1<!>
a.<!UNRESOLVED_REFERENCE!>v2<!>
a.<!UNRESOLVED_REFERENCE!>v3<!>
}
@@ -29,6 +29,6 @@ fun test() {
<!AMBIGUITY!>Cls<!>()
take(<!AMBIGUITY!>Cls<!>())
Cls2()
take(Cls2())
<!UNRESOLVED_REFERENCE!>Cls2<!>()
take(<!UNRESOLVED_REFERENCE!>Cls2<!>())
}
@@ -57,7 +57,7 @@ import libCase4.b.*
import kotlin.text.*
fun case4() {
<!DEBUG_INFO_CALL("fqName: fqName is unknown; typeCall: unresolved")!><!AMBIGUITY!>Regex<!>("")<!>
<!DEBUG_INFO_CALL("fqName: libCase4.a.Regex; typeCall: function")!>Regex("")<!>
}
// FILE: Lib4.kt
@@ -221,8 +221,8 @@ import libCase8.b.*
import libCase8.c.*
fun case8(){
<!DEBUG_INFO_CALL("fqName: fqName is unknown; typeCall: unresolved")!><!AMBIGUITY!>A<!>()<!>
<!AMBIGUITY!>A<!>()
<!DEBUG_INFO_CALL("fqName: libCase8.a.A; typeCall: function")!>A()<!>
A()
}
// FILE: Lib11.kt
@@ -278,7 +278,7 @@ import libCase10.b.*
import libCase10.c.*
fun case10(){
<!DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: Ambiguity: A, [libCase10/b/A.A, libCase10/a/A]")!><!AMBIGUITY!>A<!>()<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>A()<!>
}
// FILE: Liba.kt
@@ -15,7 +15,7 @@ import libCase1.*
import kotlin.text.*
fun case1() {
<!DEBUG_INFO_CALL("fqName: libCase1.Regex.Regex; typeCall: function")!>Regex("")<!>
<!DEBUG_INFO_CALL("fqName: kotlin.text.Regex.Regex; typeCall: function")!>Regex("")<!>
}
// FILE: Lib1.kt
@@ -35,7 +35,7 @@ import lib1Case2.*
import kotlin.text.*
fun case2() {
<!DEBUG_INFO_CALL("fqName: fqName is unknown; typeCall: unresolved")!><!AMBIGUITY!>Regex<!>("")<!>
<!DEBUG_INFO_CALL("fqName: kotlin.text.Regex.Regex; typeCall: function")!>Regex("")<!>
}
// FILE: Lib2.kt
@@ -68,7 +68,7 @@ import libCase3.*
import kotlin.text.*
fun case3() {
<!DEBUG_INFO_CALL("fqName: libCase3.Regex.Companion.invoke; typeCall: variable&invoke")!>Regex("")<!>
<!DEBUG_INFO_CALL("fqName: kotlin.text.Regex.Regex; typeCall: function")!>Regex("")<!>
}
// FILE: Lib3.kt
@@ -95,7 +95,7 @@ import lib1Case4.*
import kotlin.text.*
fun case4() {
<!DEBUG_INFO_CALL("fqName: libCase4.Regex.Regex; typeCall: function")!>Regex("")<!>
<!DEBUG_INFO_CALL("fqName: kotlin.text.Regex.Regex; typeCall: function")!>Regex("")<!>
}
// FILE: Lib4.kt