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.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
private object FirDefaultStarImportingScopeKey : ScopeSessionKey<DefaultImportPriority, FirScope>() private val INVISIBLE_DEFAULT_STAR_IMPORT = scopeSessionKey<DefaultImportPriority, FirDefaultStarImportingScope>()
private object FirDefaultSimpleImportingScopeKey : ScopeSessionKey<DefaultImportPriority, FirScope>() private val VISIBLE_DEFAULT_STAR_IMPORT = scopeSessionKey<DefaultImportPriority, FirDefaultStarImportingScope>()
private object FileImportingScopeKey : ScopeSessionKey<FirFile, ListStorageFirScope>() 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() private class ListStorageFirScope(val result: List<FirScope>) : FirScope()
@@ -25,7 +27,7 @@ fun createImportingScopes(
scopeSession: ScopeSession, scopeSession: ScopeSession,
useCaching: Boolean = true useCaching: Boolean = true
): List<FirScope> = if (useCaching) { ): List<FirScope> = if (useCaching) {
scopeSession.getOrBuild(file, FileImportingScopeKey) { scopeSession.getOrBuild(file, ALL_IMPORTS) {
ListStorageFirScope(doCreateImportingScopes(file, session, scopeSession)) ListStorageFirScope(doCreateImportingScopes(file, session, scopeSession))
}.result }.result
} else { } else {
@@ -39,17 +41,26 @@ private fun doCreateImportingScopes(
): List<FirScope> { ): List<FirScope> {
return listOf( return listOf(
// from low priority to high priority // from low priority to high priority
scopeSession.getOrBuild(DefaultImportPriority.LOW, FirDefaultStarImportingScopeKey) { scopeSession.getOrBuild(DefaultImportPriority.LOW, INVISIBLE_DEFAULT_STAR_IMPORT) {
FirDefaultStarImportingScope(session, scopeSession, priority = DefaultImportPriority.LOW) FirDefaultStarImportingScope(session, scopeSession, FirImportingScopeFilter.INVISIBLE_CLASSES, DefaultImportPriority.LOW)
}, },
scopeSession.getOrBuild(DefaultImportPriority.HIGH, FirDefaultStarImportingScopeKey) { scopeSession.getOrBuild(DefaultImportPriority.HIGH, INVISIBLE_DEFAULT_STAR_IMPORT) {
FirDefaultStarImportingScope(session, scopeSession, priority = DefaultImportPriority.HIGH) FirDefaultStarImportingScope(session, scopeSession, FirImportingScopeFilter.INVISIBLE_CLASSES, DefaultImportPriority.HIGH)
}, },
FirExplicitStarImportingScope(file.imports, session, scopeSession), FirExplicitStarImportingScope(file.imports, session, scopeSession, FirImportingScopeFilter.INVISIBLE_CLASSES),
scopeSession.getOrBuild(DefaultImportPriority.LOW, FirDefaultSimpleImportingScopeKey) { // 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) FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.LOW)
}, },
scopeSession.getOrBuild(DefaultImportPriority.HIGH, FirDefaultSimpleImportingScopeKey) { scopeSession.getOrBuild(DefaultImportPriority.HIGH, DEFAULT_SIMPLE_IMPORT) {
FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.HIGH) FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.HIGH)
}, },
scopeSession.getOrBuild(file.packageFqName, PACKAGE_MEMBER) { 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? { fun ConeClassLikeLookupTag.getNestedClassifierScope(session: FirSession, scopeSession: ScopeSession): FirScope? {
val klass = toSymbol(session)?.fir as? FirRegularClass ?: return null val klass = toSymbol(session)?.fir as? FirRegularClass ?: return null
return klass.scopeProvider.getNestedClassifierScope(klass, session, scopeSession) return klass.scopeProvider.getNestedClassifierScope(klass, session, scopeSession)
@@ -6,9 +6,12 @@
package org.jetbrains.kotlin.fir.scopes.impl package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirSession 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.FirResolvedImport
import org.jetbrains.kotlin.fir.declarations.expandedConeType 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.ScopeSession
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedForCalls 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.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name 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( abstract class FirAbstractImportingScope(
session: FirSession, session: FirSession,
protected val scopeSession: ScopeSession, protected val scopeSession: ScopeSession,
protected val filter: FirImportingScopeFilter,
lookupInFir: Boolean lookupInFir: Boolean
) : FirAbstractProviderBasedScope(session, lookupInFir) { ) : FirAbstractProviderBasedScope(session, lookupInFir) {
private val FirClassLikeSymbol<*>.fullyExpandedSymbol: FirClassSymbol<*>?
private fun getStaticsScope(symbol: FirClassLikeSymbol<*>): FirScope? { get() = when (this) {
if (symbol is FirTypeAliasSymbol) { is FirTypeAliasSymbol -> fir.expandedConeType?.lookupTag?.toSymbol(session)?.fullyExpandedSymbol
val expansionSymbol = symbol.fir.expandedConeType?.lookupTag?.toSymbol(session) is FirClassSymbol<*> -> this
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)
}
} }
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? { protected fun processFunctionsByName(name: Name?, imports: List<FirResolvedImport>, processor: (FirNamedFunctionSymbol) -> Unit) {
val symbol = provider.getClassLikeSymbolByFqName(classId) ?: return null if (filter == FirImportingScopeFilter.INVISIBLE_CLASSES) return
return getStaticsScope(symbol) for (import in imports) {
} val importedName = name ?: import.importedName ?: continue
val staticsScope = import.resolvedClassId?.let(::getStaticsScope)
protected inline fun processFunctionsByNameWithImport( if (staticsScope != null) {
name: Name, staticsScope.processFunctionsByName(importedName, processor)
import: FirResolvedImport, } else if (importedName.isSpecial || importedName.identifier.isNotEmpty()) {
crossinline processor: (FirNamedFunctionSymbol) -> Unit for (symbol in provider.getTopLevelFunctionSymbols(import.packageFqName, importedName)) {
) {
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) {
symbol.ensureResolvedForCalls(session) symbol.ensureResolvedForCalls(session)
processor(symbol) processor(symbol)
} }
@@ -70,17 +109,15 @@ abstract class FirAbstractImportingScope(
} }
} }
protected inline fun processPropertiesByNameWithImport( protected fun processPropertiesByName(name: Name?, imports: List<FirResolvedImport>, processor: (FirVariableSymbol<*>) -> Unit) {
name: Name, if (filter == FirImportingScopeFilter.INVISIBLE_CLASSES) return
import: FirResolvedImport, for (import in imports) {
crossinline processor: (FirVariableSymbol<*>) -> Unit val importedName = name ?: import.importedName ?: continue
) { val staticsScope = import.resolvedClassId?.let(::getStaticsScope)
import.resolvedClassId?.let { classId -> if (staticsScope != null) {
getStaticsScope(classId)?.processPropertiesByName(name) { processor(it) } staticsScope.processPropertiesByName(importedName, processor)
} ?: run { } else if (importedName.isSpecial || importedName.identifier.isNotEmpty()) {
if (name.isSpecial || name.identifier.isNotEmpty()) { for (symbol in provider.getTopLevelPropertySymbols(import.packageFqName, importedName)) {
val symbols = provider.getTopLevelPropertySymbols(import.packageFqName, name)
for (symbol in symbols) {
symbol.ensureResolvedForCalls(session) symbol.ensureResolvedForCalls(session)
processor(symbol) 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.FirSession
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
import org.jetbrains.kotlin.fir.resolve.ScopeSession 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.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
abstract class FirAbstractSimpleImportingScope( abstract class FirAbstractSimpleImportingScope(
session: FirSession, session: FirSession,
scopeSession: ScopeSession scopeSession: ScopeSession
) : FirAbstractImportingScope(session, scopeSession, lookupInFir = true) { ) : FirAbstractImportingScope(session, scopeSession, FirImportingScopeFilter.ALL, lookupInFir = true) {
// TODO try to hide this // TODO try to hide this
abstract val simpleImports: Map<Name, List<FirResolvedImport>> abstract val simpleImports: Map<Name, List<FirResolvedImport>>
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
val imports = simpleImports[name] ?: return val imports = simpleImports[name] ?: return
if (imports.isEmpty()) return val symbol = findSingleClassifierSymbolByName(null, imports) ?: return
val provider = session.symbolProvider processor(symbol, ConeSubstitutor.Empty)
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)
}
} }
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
val imports = simpleImports[name] ?: return val imports = simpleImports[name] ?: return
for (import in imports) { processFunctionsByName(null, imports, processor)
processFunctionsByNameWithImport(import.importedName!!, import, processor)
}
} }
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
val imports = simpleImports[name] ?: return val imports = simpleImports[name] ?: return
for (import in imports) { processPropertiesByName(null, imports, processor)
processPropertiesByNameWithImport(import.importedName!!, import, 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.FirClassifierSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
abstract class FirAbstractStarImportingScope( abstract class FirAbstractStarImportingScope(
session: FirSession, session: FirSession,
scopeSession: ScopeSession, scopeSession: ScopeSession,
lookupInFir: Boolean = true filter: FirImportingScopeFilter,
) : FirAbstractImportingScope(session, scopeSession, lookupInFir) { lookupInFir: Boolean
) : FirAbstractImportingScope(session, scopeSession, filter, lookupInFir) {
// TODO try to hide this // TODO try to hide this
abstract val starImports: List<FirResolvedImport> abstract val starImports: List<FirResolvedImport>
@@ -27,35 +27,20 @@ abstract class FirAbstractStarImportingScope(
private val absentClassifierNames = mutableSetOf<Name>() private val absentClassifierNames = mutableSetOf<Name>()
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { 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 return
} }
var empty = true val symbol = findSingleClassifierSymbolByName(name, starImports)
for (import in starImports) { if (symbol != null) {
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
processor(symbol, ConeSubstitutor.Empty) processor(symbol, ConeSubstitutor.Empty)
} } else {
if (empty) {
absentClassifierNames += name absentClassifierNames += name
} }
} }
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) =
for (import in starImports) { processFunctionsByName(name, starImports, processor)
processFunctionsByNameWithImport(name, import, processor)
}
}
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) =
for (import in starImports) { processPropertiesByName(name, starImports, processor)
processPropertiesByNameWithImport(name, import, processor)
}
}
} }
@@ -17,8 +17,9 @@ import org.jetbrains.kotlin.name.Name
class FirDefaultStarImportingScope( class FirDefaultStarImportingScope(
session: FirSession, session: FirSession,
scopeSession: ScopeSession, scopeSession: ScopeSession,
filter: FirImportingScopeFilter,
priority: DefaultImportPriority priority: DefaultImportPriority
) : FirAbstractStarImportingScope(session, scopeSession, lookupInFir = false) { ) : FirAbstractStarImportingScope(session, scopeSession, filter, lookupInFir = false) {
// TODO: put languageVersionSettings into FirSession? // TODO: put languageVersionSettings into FirSession?
override val starImports = run { override val starImports = run {
@@ -13,7 +13,8 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession
class FirExplicitStarImportingScope( class FirExplicitStarImportingScope(
imports: List<FirImport>, imports: List<FirImport>,
session: FirSession, session: FirSession,
scopeSession: ScopeSession scopeSession: ScopeSession,
) : FirAbstractStarImportingScope(session, scopeSession) { filter: FirImportingScopeFilter
) : FirAbstractStarImportingScope(session, scopeSession, filter, lookupInFir = true) {
override val starImports = imports.filterIsInstance<FirResolvedImport>().filter { it.isAllUnder } 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 // FILE: a.kt
package a package a
@@ -14,4 +14,4 @@ package c
import a.X import a.X
import b.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 // FILE: File.kt
package pack package pack
@@ -17,8 +17,8 @@ class D {
import a.A.B import a.A.B
import a.D.B import a.D.B
fun test(b: B) { fun test(b: <!UNRESOLVED_REFERENCE!>B<!>) {
B() <!UNRESOLVED_REFERENCE!>B<!>()
} }
// FILE: d.kt // FILE: d.kt
@@ -26,6 +26,6 @@ import a.A.*
import a.D.* import a.D.*
// todo ambiguvity here // todo ambiguvity here
fun test2(b: B) { fun test2(b: <!UNRESOLVED_REFERENCE!>B<!>) {
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 // FILE: File1.kt
package pack1 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 // FILE: File1.kt
package pack1 package pack1
@@ -24,4 +24,4 @@ package c
import a.* import a.*
import b.* import b.*
fun test(): x = d().x() fun test(): <!UNRESOLVED_REFERENCE!>x<!> = d().x()
@@ -22,8 +22,8 @@ class A {
import p1.* import p1.*
import p2.* import p2.*
fun test(a: A) { fun test(a: <!UNRESOLVED_REFERENCE!>A<!>) {
a.m1() a.<!UNRESOLVED_REFERENCE!>m1<!>()
a.<!UNRESOLVED_REFERENCE!>m2<!>() a.<!UNRESOLVED_REFERENCE!>m2<!>()
} }
@@ -39,8 +39,8 @@ import p1.*
import p2.* import p2.*
import p3.* import p3.*
fun test(a: A) { fun test(a: <!UNRESOLVED_REFERENCE!>A<!>) {
a.v1 a.<!UNRESOLVED_REFERENCE!>v1<!>
a.<!UNRESOLVED_REFERENCE!>v2<!> a.<!UNRESOLVED_REFERENCE!>v2<!>
a.<!UNRESOLVED_REFERENCE!>v3<!> a.<!UNRESOLVED_REFERENCE!>v3<!>
} }
@@ -23,8 +23,8 @@ class A {
import p1.* import p1.*
import p2.* import p2.*
fun test(a: A) { fun test(a: <!UNRESOLVED_REFERENCE!>A<!>) {
a.m1() a.<!UNRESOLVED_REFERENCE!>m1<!>()
a.<!UNRESOLVED_REFERENCE!>m2<!>() a.<!UNRESOLVED_REFERENCE!>m2<!>()
} }
@@ -40,8 +40,8 @@ import p1.*
import p2.* import p2.*
import p3.* import p3.*
fun test(a: A) { fun test(a: <!UNRESOLVED_REFERENCE!>A<!>) {
a.v1 a.<!UNRESOLVED_REFERENCE!>v1<!>
a.<!UNRESOLVED_REFERENCE!>v2<!> a.<!UNRESOLVED_REFERENCE!>v2<!>
a.<!UNRESOLVED_REFERENCE!>v3<!> a.<!UNRESOLVED_REFERENCE!>v3<!>
} }
@@ -29,6 +29,6 @@ fun test() {
<!AMBIGUITY!>Cls<!>() <!AMBIGUITY!>Cls<!>()
take(<!AMBIGUITY!>Cls<!>()) take(<!AMBIGUITY!>Cls<!>())
Cls2() <!UNRESOLVED_REFERENCE!>Cls2<!>()
take(Cls2()) take(<!UNRESOLVED_REFERENCE!>Cls2<!>())
} }
@@ -57,7 +57,7 @@ import libCase4.b.*
import kotlin.text.* import kotlin.text.*
fun case4() { 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 // FILE: Lib4.kt
@@ -221,8 +221,8 @@ import libCase8.b.*
import libCase8.c.* import libCase8.c.*
fun case8(){ fun case8(){
<!DEBUG_INFO_CALL("fqName: fqName is unknown; typeCall: unresolved")!><!AMBIGUITY!>A<!>()<!> <!DEBUG_INFO_CALL("fqName: libCase8.a.A; typeCall: function")!>A()<!>
<!AMBIGUITY!>A<!>() A()
} }
// FILE: Lib11.kt // FILE: Lib11.kt
@@ -278,7 +278,7 @@ import libCase10.b.*
import libCase10.c.* import libCase10.c.*
fun case10(){ 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 // FILE: Liba.kt
@@ -15,7 +15,7 @@ import libCase1.*
import kotlin.text.* import kotlin.text.*
fun case1() { 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 // FILE: Lib1.kt
@@ -35,7 +35,7 @@ import lib1Case2.*
import kotlin.text.* import kotlin.text.*
fun case2() { 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 // FILE: Lib2.kt
@@ -68,7 +68,7 @@ import libCase3.*
import kotlin.text.* import kotlin.text.*
fun case3() { 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 // FILE: Lib3.kt
@@ -95,7 +95,7 @@ import lib1Case4.*
import kotlin.text.* import kotlin.text.*
fun case4() { 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 // FILE: Lib4.kt