K2: don't use dispatch receiver to store imported static qualifiers

Related to KT-53441
This commit is contained in:
Mikhail Glukhikh
2022-11-08 18:07:26 +01:00
committed by Space Team
parent 7205a90d9d
commit 104fd4c14d
11 changed files with 128 additions and 85 deletions
@@ -1,4 +1,4 @@
FILE: main.kt FILE: main.kt
public final fun test(list: R|kotlin/collections/List<kotlin/String>|, string: R|kotlin/String|): R|kotlin/Unit| { public final fun test(list: R|kotlin/collections/List<kotlin/String>|, string: R|kotlin/String|): R|kotlin/Unit| {
Q|Matchers|.R|/Matchers.assertThat|<R|ft<kotlin/collections/List<kotlin/String>, kotlin/collections/List<kotlin/String>?>|>(R|<local>/list|, Q|Matchers|.R|/Matchers.hasItem|<R|kotlin/String!|>(R|<local>/string|)) R|/Matchers.assertThat|<R|ft<kotlin/collections/List<kotlin/String>, kotlin/collections/List<kotlin/String>?>|>(R|<local>/list|, R|/Matchers.hasItem|<R|kotlin/String!|>(R|<local>/string|))
} }
@@ -1,4 +1,4 @@
FILE: FlexiblePrimitiveOverloading.kt FILE: FlexiblePrimitiveOverloading.kt
public final fun foo(): R|kotlin/Unit| { public final fun foo(): R|kotlin/Unit| {
Q|java/lang/Integer|.R|java/lang/Integer.getInteger|(String(text), Int(239)) R|java/lang/Integer.getInteger|(String(text), Int(239))
} }
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectOrStaticData
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
@@ -227,26 +228,24 @@ private fun FirCallableSymbol<*>.toSymbolForCall(
isDelegate: Boolean = false, isDelegate: Boolean = false,
isReference: Boolean = false isReference: Boolean = false
): IrSymbol? { ): IrSymbol? {
val dispatchReceiverType = when (dispatchReceiver) { val fakeOverrideOwnerLookupTag = fir.importedFromObjectOrStaticData.takeIf { isStatic }?.let {
ConeClassLikeLookupTagImpl(it.objectClassId)
} ?: when (dispatchReceiver) {
is FirNoReceiverExpression -> { is FirNoReceiverExpression -> {
val containingClass = containingClassLookupTag() val containingClass = containingClassLookupTag()
if (containingClass != null && containingClass.classId != StandardClassIds.Any) { if (containingClass != null && containingClass.classId != StandardClassIds.Any) {
// Make sure that symbol is not extension and is not from inline class // Make sure that symbol is not extension and is not from inline class
((explicitReceiver as? FirResolvedQualifier)?.symbol as? FirClassSymbol)?.defaultType() ((explicitReceiver as? FirResolvedQualifier)?.symbol as? FirClassSymbol)?.toLookupTag()
} else { } else {
null null
} }
} }
is FirResolvedQualifier -> {
if (isStatic) (dispatchReceiver.symbol as? FirClassSymbol)?.defaultType() else dispatchReceiver.typeRef.coneType
}
else -> { else -> {
dispatchReceiver.typeRef.coneType if (isStatic && dispatchReceiver is FirResolvedQualifier) (dispatchReceiver.symbol as? FirClassSymbol)?.toLookupTag()
else dispatchReceiver.typeRef.coneType.let { it.findClassRepresentation(it, declarationStorage.session) }
} }
} }
val dispatchReceiverLookupTag = dispatchReceiverType?.findClassRepresentation(dispatchReceiverType, declarationStorage.session)
return when (this) { return when (this) {
is FirSimpleSyntheticPropertySymbol -> { is FirSimpleSyntheticPropertySymbol -> {
@@ -255,7 +254,7 @@ private fun FirCallableSymbol<*>.toSymbolForCall(
} else { } else {
(fir as? FirSyntheticProperty)?.let { syntheticProperty -> (fir as? FirSyntheticProperty)?.let { syntheticProperty ->
if (isReference) { if (isReference) {
declarationStorage.getIrPropertySymbol(this, dispatchReceiverLookupTag) declarationStorage.getIrPropertySymbol(this, fakeOverrideOwnerLookupTag)
} else { } else {
val delegateSymbol = if (preferGetter) { val delegateSymbol = if (preferGetter) {
syntheticProperty.getter.delegate.symbol syntheticProperty.getter.delegate.symbol
@@ -270,8 +269,8 @@ private fun FirCallableSymbol<*>.toSymbolForCall(
} }
} }
is FirFunctionSymbol<*> -> declarationStorage.getIrFunctionSymbol(this, dispatchReceiverLookupTag) is FirFunctionSymbol<*> -> declarationStorage.getIrFunctionSymbol(this, fakeOverrideOwnerLookupTag)
is FirPropertySymbol -> declarationStorage.getIrPropertySymbol(this, dispatchReceiverLookupTag) is FirPropertySymbol -> declarationStorage.getIrPropertySymbol(this, fakeOverrideOwnerLookupTag)
is FirFieldSymbol -> declarationStorage.getIrFieldSymbol(this) is FirFieldSymbol -> declarationStorage.getIrFieldSymbol(this)
is FirBackingFieldSymbol -> declarationStorage.getIrBackingFieldSymbol(this) is FirBackingFieldSymbol -> declarationStorage.getIrBackingFieldSymbol(this)
is FirDelegateFieldSymbol -> declarationStorage.getIrDelegateFieldSymbol(this) is FirDelegateFieldSymbol -> declarationStorage.getIrDelegateFieldSymbol(this)
@@ -431,13 +431,13 @@ class Fir2IrDeclarationStorage(
fun getCachedIrFunction( fun getCachedIrFunction(
function: FirSimpleFunction, function: FirSimpleFunction,
dispatchReceiverLookupTag: ConeClassLikeLookupTag?, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?,
signatureCalculator: () -> IdSignature? signatureCalculator: () -> IdSignature?
): IrSimpleFunction? { ): IrSimpleFunction? {
if (function.visibility == Visibilities.Local) { if (function.visibility == Visibilities.Local) {
return localStorage.getLocalFunction(function) return localStorage.getLocalFunction(function)
} }
return getCachedIrCallable(function, dispatchReceiverLookupTag, functionCache, signatureCalculator) { signature -> return getCachedIrCallable(function, fakeOverrideOwnerLookupTag, functionCache, signatureCalculator) { signature ->
symbolTable.referenceSimpleFunctionIfAny(signature)?.owner symbolTable.referenceSimpleFunctionIfAny(signature)?.owner
} }
} }
@@ -470,7 +470,7 @@ class Fir2IrDeclarationStorage(
return createIrFunction( return createIrFunction(
function, function,
irParent, irParent,
containingClass = function.containingClassLookupTag(), fakeOverrideOwnerLookupTag = function.containingClassLookupTag(),
isLocal = isLocal, isLocal = isLocal,
forceTopLevelPrivate = forceTopLevelPrivate forceTopLevelPrivate = forceTopLevelPrivate
) )
@@ -482,7 +482,7 @@ class Fir2IrDeclarationStorage(
thisReceiverOwner: IrClass? = irParent as? IrClass, thisReceiverOwner: IrClass? = irParent as? IrClass,
predefinedOrigin: IrDeclarationOrigin? = null, predefinedOrigin: IrDeclarationOrigin? = null,
isLocal: Boolean = false, isLocal: Boolean = false,
containingClass: ConeClassLikeLookupTag? = null, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null,
forceTopLevelPrivate: Boolean = false, forceTopLevelPrivate: Boolean = false,
): IrSimpleFunction = convertCatching(function) { ): IrSimpleFunction = convertCatching(function) {
val simpleFunction = function as? FirSimpleFunction val simpleFunction = function as? FirSimpleFunction
@@ -513,7 +513,7 @@ class Fir2IrDeclarationStorage(
function.dispatchReceiverType?.isPrimitive != true && function.containerSource == null && function.dispatchReceiverType?.isPrimitive != true && function.containerSource == null &&
updatedOrigin != IrDeclarationOrigin.FAKE_OVERRIDE && !function.isOverride updatedOrigin != IrDeclarationOrigin.FAKE_OVERRIDE && !function.isOverride
) { ) {
signatureComposer.composeSignature(function, containingClass, forceTopLevelPrivate) signatureComposer.composeSignature(function, fakeOverrideOwnerLookupTag, forceTopLevelPrivate)
} }
if (irParent is Fir2IrLazyClass && signature != null) { if (irParent is Fir2IrLazyClass && signature != null) {
// For private functions signature is null, fallback to non-lazy function // For private functions signature is null, fallback to non-lazy function
@@ -670,14 +670,14 @@ class Fir2IrDeclarationStorage(
startOffset: Int, startOffset: Int,
endOffset: Int, endOffset: Int,
dontUseSignature: Boolean = false, dontUseSignature: Boolean = false,
containingClass: ConeClassLikeLookupTag? = null, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null,
propertyAccessorForAnnotations: FirPropertyAccessor? = propertyAccessor, propertyAccessorForAnnotations: FirPropertyAccessor? = propertyAccessor,
forceTopLevelPrivate: Boolean = false, forceTopLevelPrivate: Boolean = false,
): IrSimpleFunction = convertCatching(propertyAccessor ?: property) { ): IrSimpleFunction = convertCatching(propertyAccessor ?: property) {
val prefix = if (isSetter) "set" else "get" val prefix = if (isSetter) "set" else "get"
val signature = val signature =
runUnless(dontUseSignature) { runUnless(dontUseSignature) {
signatureComposer.composeAccessorSignature(property, isSetter, containingClass, forceTopLevelPrivate) signatureComposer.composeAccessorSignature(property, isSetter, fakeOverrideOwnerLookupTag, forceTopLevelPrivate)
} }
val containerSource = (correspondingProperty as? IrProperty)?.containerSource val containerSource = (correspondingProperty as? IrProperty)?.containerSource
return declareIrAccessor( return declareIrAccessor(
@@ -811,7 +811,7 @@ class Fir2IrDeclarationStorage(
createIrProperty( createIrProperty(
field.toStubProperty(), field.toStubProperty(),
irParent, irParent,
containingClass = containingClassId?.let { ConeClassLikeLookupTagImpl(it) } fakeOverrideOwnerLookupTag = containingClassId?.let { ConeClassLikeLookupTagImpl(it) }
) )
} }
} }
@@ -839,7 +839,7 @@ class Fir2IrDeclarationStorage(
thisReceiverOwner: IrClass? = irParent as? IrClass, thisReceiverOwner: IrClass? = irParent as? IrClass,
predefinedOrigin: IrDeclarationOrigin? = null, predefinedOrigin: IrDeclarationOrigin? = null,
isLocal: Boolean = false, isLocal: Boolean = false,
containingClass: ConeClassLikeLookupTag? = (irParent as? IrClass)?.classId?.let { ConeClassLikeLookupTagImpl(it) }, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = (irParent as? IrClass)?.classId?.let { ConeClassLikeLookupTagImpl(it) },
forceTopLevelPrivate: Boolean = false, forceTopLevelPrivate: Boolean = false,
): IrProperty = convertCatching(property) { ): IrProperty = convertCatching(property) {
val origin = val origin =
@@ -853,7 +853,7 @@ class Fir2IrDeclarationStorage(
property.dispatchReceiverType?.isPrimitive != true && property.containerSource == null && property.dispatchReceiverType?.isPrimitive != true && property.containerSource == null &&
origin != IrDeclarationOrigin.FAKE_OVERRIDE && !property.isOverride origin != IrDeclarationOrigin.FAKE_OVERRIDE && !property.isOverride
) { ) {
signatureComposer.composeSignature(property, containingClass, forceTopLevelPrivate) signatureComposer.composeSignature(property, fakeOverrideOwnerLookupTag, forceTopLevelPrivate)
} }
if (irParent is Fir2IrLazyClass && signature != null) { if (irParent is Fir2IrLazyClass && signature != null) {
// For private functions signature is null, fallback to non-lazy property // For private functions signature is null, fallback to non-lazy property
@@ -928,7 +928,7 @@ class Fir2IrDeclarationStorage(
else -> origin else -> origin
}, },
startOffset, endOffset, startOffset, endOffset,
dontUseSignature = signature == null, containingClass, dontUseSignature = signature == null, fakeOverrideOwnerLookupTag,
property.unwrapFakeOverrides().getter, property.unwrapFakeOverrides().getter,
forceTopLevelPrivate = forceTopLevelPrivate, forceTopLevelPrivate = forceTopLevelPrivate,
) )
@@ -941,7 +941,7 @@ class Fir2IrDeclarationStorage(
else -> origin else -> origin
}, },
startOffset, endOffset, startOffset, endOffset,
dontUseSignature = signature == null, containingClass, dontUseSignature = signature == null, fakeOverrideOwnerLookupTag,
property.unwrapFakeOverrides().setter, property.unwrapFakeOverrides().setter,
forceTopLevelPrivate = forceTopLevelPrivate, forceTopLevelPrivate = forceTopLevelPrivate,
) )
@@ -958,22 +958,22 @@ class Fir2IrDeclarationStorage(
fun getCachedIrProperty( fun getCachedIrProperty(
property: FirProperty, property: FirProperty,
dispatchReceiverLookupTag: ConeClassLikeLookupTag?, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?,
signatureCalculator: () -> IdSignature? signatureCalculator: () -> IdSignature?
): IrProperty? { ): IrProperty? {
return getCachedIrCallable(property, dispatchReceiverLookupTag, propertyCache, signatureCalculator) { signature -> return getCachedIrCallable(property, fakeOverrideOwnerLookupTag, propertyCache, signatureCalculator) { signature ->
symbolTable.referencePropertyIfAny(signature)?.owner symbolTable.referencePropertyIfAny(signature)?.owner
} }
} }
private inline fun <reified FC : FirCallableDeclaration, reified IC : IrDeclaration> getCachedIrCallable( private inline fun <reified FC : FirCallableDeclaration, reified IC : IrDeclaration> getCachedIrCallable(
declaration: FC, declaration: FC,
dispatchReceiverLookupTag: ConeClassLikeLookupTag?, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?,
cache: MutableMap<FC, IC>, cache: MutableMap<FC, IC>,
signatureCalculator: () -> IdSignature?, signatureCalculator: () -> IdSignature?,
referenceIfAny: (IdSignature) -> IC? referenceIfAny: (IdSignature) -> IC?
): IC? { ): IC? {
val isFakeOverride = dispatchReceiverLookupTag != null && dispatchReceiverLookupTag != declaration.containingClassLookupTag() val isFakeOverride = fakeOverrideOwnerLookupTag != null && fakeOverrideOwnerLookupTag != declaration.containingClassLookupTag()
if (!isFakeOverride) { if (!isFakeOverride) {
cache[declaration]?.let { return it } cache[declaration]?.let { return it }
} }
@@ -1238,7 +1238,7 @@ class Fir2IrDeclarationStorage(
val fir = firConstructorSymbol.fir val fir = firConstructorSymbol.fir
return getIrCallableSymbol( return getIrCallableSymbol(
firConstructorSymbol, firConstructorSymbol,
dispatchReceiverLookupTag = null, fakeOverrideOwnerLookupTag = null,
getCachedIrDeclaration = { constructor: FirConstructor, _, calculator -> getCachedIrConstructor(constructor, calculator) }, getCachedIrDeclaration = { constructor: FirConstructor, _, calculator -> getCachedIrConstructor(constructor, calculator) },
createIrDeclaration = { parent, origin -> createIrDeclaration = { parent, origin ->
createIrConstructor(fir, parent as IrClass, predefinedOrigin = origin, forceTopLevelPrivate = forceTopLevelPrivate) createIrConstructor(fir, parent as IrClass, predefinedOrigin = origin, forceTopLevelPrivate = forceTopLevelPrivate)
@@ -1265,7 +1265,7 @@ class Fir2IrDeclarationStorage(
fun getIrFunctionSymbol( fun getIrFunctionSymbol(
firFunctionSymbol: FirFunctionSymbol<*>, firFunctionSymbol: FirFunctionSymbol<*>,
dispatchReceiverLookupTag: ConeClassLikeLookupTag? = null, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null,
forceTopLevelPrivate: Boolean = false, forceTopLevelPrivate: Boolean = false,
): IrFunctionSymbol { ): IrFunctionSymbol {
return when (val fir = firFunctionSymbol.fir) { return when (val fir = firFunctionSymbol.fir) {
@@ -1277,20 +1277,20 @@ class Fir2IrDeclarationStorage(
createIrFunction(fir, irParent, predefinedOrigin = declarationOrigin).symbol createIrFunction(fir, irParent, predefinedOrigin = declarationOrigin).symbol
} }
is FirSimpleFunction -> { is FirSimpleFunction -> {
val unmatchedReceiver = dispatchReceiverLookupTag != firFunctionSymbol.containingClassLookupTag() val unmatchedReceiver = fakeOverrideOwnerLookupTag != firFunctionSymbol.containingClassLookupTag()
if (unmatchedReceiver) { if (unmatchedReceiver) {
generateLazyFakeOverrides(fir.name, dispatchReceiverLookupTag) generateLazyFakeOverrides(fir.name, fakeOverrideOwnerLookupTag)
} }
val originalSymbol = getIrCallableSymbol( val originalSymbol = getIrCallableSymbol(
firFunctionSymbol, firFunctionSymbol,
dispatchReceiverLookupTag, fakeOverrideOwnerLookupTag,
getCachedIrDeclaration = ::getCachedIrFunction, getCachedIrDeclaration = ::getCachedIrFunction,
createIrDeclaration = { parent, origin -> createIrDeclaration = { parent, origin ->
createIrFunction( createIrFunction(
fir, parent, fir, parent,
predefinedOrigin = origin, predefinedOrigin = origin,
forceTopLevelPrivate = forceTopLevelPrivate, forceTopLevelPrivate = forceTopLevelPrivate,
containingClass = dispatchReceiverLookupTag, fakeOverrideOwnerLookupTag = fakeOverrideOwnerLookupTag,
) )
}, },
createIrLazyDeclaration = { signature, lazyParent, declarationOrigin -> createIrLazyDeclaration = { signature, lazyParent, declarationOrigin ->
@@ -1298,9 +1298,9 @@ class Fir2IrDeclarationStorage(
}, },
forceTopLevelPrivate = forceTopLevelPrivate forceTopLevelPrivate = forceTopLevelPrivate
) as IrFunctionSymbol ) as IrFunctionSymbol
if (unmatchedReceiver && dispatchReceiverLookupTag is ConeClassLookupTagWithFixedSymbol) { if (unmatchedReceiver && fakeOverrideOwnerLookupTag is ConeClassLookupTagWithFixedSymbol) {
val originalFunction = originalSymbol.owner as IrSimpleFunction val originalFunction = originalSymbol.owner as IrSimpleFunction
dispatchReceiverLookupTag.findIrFakeOverride(fir.name, originalFunction) as IrFunctionSymbol? ?: originalSymbol fakeOverrideOwnerLookupTag.findIrFakeOverride(fir.name, originalFunction) as IrFunctionSymbol? ?: originalSymbol
} else { } else {
originalSymbol originalSymbol
} }
@@ -1338,7 +1338,7 @@ class Fir2IrDeclarationStorage(
fun getIrPropertySymbol( fun getIrPropertySymbol(
firPropertySymbol: FirPropertySymbol, firPropertySymbol: FirPropertySymbol,
dispatchReceiverLookupTag: ConeClassLikeLookupTag? = null, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null,
forceTopLevelPrivate: Boolean = false, forceTopLevelPrivate: Boolean = false,
): IrSymbol { ): IrSymbol {
val fir = firPropertySymbol.fir val fir = firPropertySymbol.fir
@@ -1346,19 +1346,19 @@ class Fir2IrDeclarationStorage(
return localStorage.getDelegatedProperty(fir)?.symbol ?: getIrVariableSymbol(fir) return localStorage.getDelegatedProperty(fir)?.symbol ?: getIrVariableSymbol(fir)
} }
val containingClassLookupTag = firPropertySymbol.containingClassLookupTag() val containingClassLookupTag = firPropertySymbol.containingClassLookupTag()
val unmatchedReceiver = dispatchReceiverLookupTag != containingClassLookupTag val unmatchedReceiver = fakeOverrideOwnerLookupTag != containingClassLookupTag
if (unmatchedReceiver) { if (unmatchedReceiver) {
generateLazyFakeOverrides(fir.name, dispatchReceiverLookupTag) generateLazyFakeOverrides(fir.name, fakeOverrideOwnerLookupTag)
} }
fun ConeClassLikeLookupTag?.getIrCallableSymbol() = getIrCallableSymbol( fun ConeClassLikeLookupTag?.getIrCallableSymbol() = getIrCallableSymbol(
firPropertySymbol, firPropertySymbol,
dispatchReceiverLookupTag = this, fakeOverrideOwnerLookupTag = this,
getCachedIrDeclaration = ::getCachedIrProperty, getCachedIrDeclaration = ::getCachedIrProperty,
createIrDeclaration = { parent, origin -> createIrDeclaration = { parent, origin ->
createIrProperty( createIrProperty(
fir, parent, predefinedOrigin = origin, forceTopLevelPrivate = forceTopLevelPrivate, fir, parent, predefinedOrigin = origin, forceTopLevelPrivate = forceTopLevelPrivate,
containingClass = dispatchReceiverLookupTag, fakeOverrideOwnerLookupTag = fakeOverrideOwnerLookupTag,
) )
}, },
createIrLazyDeclaration = { signature, lazyParent, declarationOrigin -> createIrLazyDeclaration = { signature, lazyParent, declarationOrigin ->
@@ -1367,7 +1367,7 @@ class Fir2IrDeclarationStorage(
forceTopLevelPrivate = forceTopLevelPrivate forceTopLevelPrivate = forceTopLevelPrivate
) )
val originalSymbol = dispatchReceiverLookupTag.getIrCallableSymbol() val originalSymbol = fakeOverrideOwnerLookupTag.getIrCallableSymbol()
val originalProperty = originalSymbol.owner as IrProperty val originalProperty = originalSymbol.owner as IrProperty
fun IrProperty.isIllegalFakeOverride(): Boolean { fun IrProperty.isIllegalFakeOverride(): Boolean {
@@ -1379,7 +1379,7 @@ class Fir2IrDeclarationStorage(
return false return false
} }
if (dispatchReceiverLookupTag != null && if (fakeOverrideOwnerLookupTag != null &&
firPropertySymbol is FirSyntheticPropertySymbol && firPropertySymbol is FirSyntheticPropertySymbol &&
originalProperty.isIllegalFakeOverride() originalProperty.isIllegalFakeOverride()
) { ) {
@@ -1387,8 +1387,8 @@ class Fir2IrDeclarationStorage(
return containingClassLookupTag.getIrCallableSymbol() return containingClassLookupTag.getIrCallableSymbol()
} }
return if (unmatchedReceiver && dispatchReceiverLookupTag is ConeClassLookupTagWithFixedSymbol) { return if (unmatchedReceiver && fakeOverrideOwnerLookupTag is ConeClassLookupTagWithFixedSymbol) {
dispatchReceiverLookupTag.findIrFakeOverride(fir.name, originalProperty) as IrPropertySymbol fakeOverrideOwnerLookupTag.findIrFakeOverride(fir.name, originalProperty) as IrPropertySymbol
} else { } else {
originalSymbol originalSymbol
} }
@@ -1429,8 +1429,8 @@ class Fir2IrDeclarationStorage(
}?.symbol }?.symbol
} }
private fun generateLazyFakeOverrides(name: Name, dispatchReceiverLookupTag: ConeClassLikeLookupTag?) { private fun generateLazyFakeOverrides(name: Name, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?) {
val firClassSymbol = dispatchReceiverLookupTag?.toSymbol(session) as? FirClassSymbol val firClassSymbol = fakeOverrideOwnerLookupTag?.toSymbol(session) as? FirClassSymbol
if (firClassSymbol != null) { if (firClassSymbol != null) {
val irClass = classifierStorage.getIrClassSymbol(firClassSymbol).owner val irClass = classifierStorage.getIrClassSymbol(firClassSymbol).owner
if (irClass is Fir2IrLazyClass) { if (irClass is Fir2IrLazyClass) {
@@ -1445,7 +1445,7 @@ class Fir2IrDeclarationStorage(
I : IrSymbolOwner, I : IrSymbolOwner,
> getIrCallableSymbol( > getIrCallableSymbol(
firSymbol: FS, firSymbol: FS,
dispatchReceiverLookupTag: ConeClassLikeLookupTag?, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?,
getCachedIrDeclaration: (firDeclaration: F, dispatchReceiverLookupTag: ConeClassLikeLookupTag?, () -> IdSignature?) -> I?, getCachedIrDeclaration: (firDeclaration: F, dispatchReceiverLookupTag: ConeClassLikeLookupTag?, () -> IdSignature?) -> I?,
createIrDeclaration: (parent: IrDeclarationParent?, origin: IrDeclarationOrigin) -> I, createIrDeclaration: (parent: IrDeclarationParent?, origin: IrDeclarationOrigin) -> I,
createIrLazyDeclaration: (signature: IdSignature, lazyOwner: IrDeclarationParent, origin: IrDeclarationOrigin) -> I, createIrLazyDeclaration: (signature: IdSignature, lazyOwner: IrDeclarationParent, origin: IrDeclarationOrigin) -> I,
@@ -1453,9 +1453,9 @@ class Fir2IrDeclarationStorage(
): IrSymbol { ): IrSymbol {
val fir = firSymbol.fir as F val fir = firSymbol.fir as F
val irParent by lazy { findIrParent(fir) } val irParent by lazy { findIrParent(fir) }
val signature by lazy { signatureComposer.composeSignature(fir, dispatchReceiverLookupTag, forceTopLevelPrivate) } val signature by lazy { signatureComposer.composeSignature(fir, fakeOverrideOwnerLookupTag, forceTopLevelPrivate) }
synchronized(symbolTable.lock) { synchronized(symbolTable.lock) {
getCachedIrDeclaration(fir, dispatchReceiverLookupTag.takeIf { it !is ConeClassLookupTagWithFixedSymbol }) { getCachedIrDeclaration(fir, fakeOverrideOwnerLookupTag.takeIf { it !is ConeClassLookupTagWithFixedSymbol }) {
// Parent calculation provokes declaration calculation for some members from IrBuiltIns // Parent calculation provokes declaration calculation for some members from IrBuiltIns
@Suppress("UNUSED_EXPRESSION") irParent @Suppress("UNUSED_EXPRESSION") irParent
signature signature
@@ -212,7 +212,7 @@ class DelegatedMemberGenerator(
val delegateFunction = val delegateFunction =
declarationStorage.createIrFunction( declarationStorage.createIrFunction(
delegateOverride, subClass, predefinedOrigin = IrDeclarationOrigin.DELEGATED_MEMBER, delegateOverride, subClass, predefinedOrigin = IrDeclarationOrigin.DELEGATED_MEMBER,
containingClass = firSubClass.symbol.toLookupTag() fakeOverrideOwnerLookupTag = firSubClass.symbol.toLookupTag()
) )
val baseSymbols = mutableListOf<FirNamedFunctionSymbol>() val baseSymbols = mutableListOf<FirNamedFunctionSymbol>()
// the overridden symbols should be collected only after all fake overrides for all superclases are created and bound to their // the overridden symbols should be collected only after all fake overrides for all superclases are created and bound to their
@@ -293,7 +293,7 @@ class DelegatedMemberGenerator(
val delegateProperty = val delegateProperty =
declarationStorage.createIrProperty( declarationStorage.createIrProperty(
firDelegateProperty, subClass, predefinedOrigin = IrDeclarationOrigin.DELEGATED_MEMBER, firDelegateProperty, subClass, predefinedOrigin = IrDeclarationOrigin.DELEGATED_MEMBER,
containingClass = firSubClass.symbol.toLookupTag() fakeOverrideOwnerLookupTag = firSubClass.symbol.toLookupTag()
) )
// the overridden symbols should be collected only after all fake overrides for all superclases are created and bound to their // the overridden symbols should be collected only after all fake overrides for all superclases are created and bound to their
// overridden symbols, otherwise in some cases they will be left in inconsistent state leading to the errors in IR // overridden symbols, otherwise in some cases they will be left in inconsistent state leading to the errors in IR
@@ -36,6 +36,7 @@ class Candidate(
private val baseSystem: ConstraintStorage, private val baseSystem: ConstraintStorage,
override val callInfo: CallInfo, override val callInfo: CallInfo,
val originScope: FirScope?, val originScope: FirScope?,
val importedQualifierForStatic: FirExpression? = null,
val isFromCompanionObjectTypeScope: Boolean = false val isFromCompanionObjectTypeScope: Boolean = false
) : AbstractCandidate() { ) : AbstractCandidate() {
@@ -49,6 +49,7 @@ class CandidateFactory private constructor(
explicitReceiverKind: ExplicitReceiverKind, explicitReceiverKind: ExplicitReceiverKind,
scope: FirScope?, scope: FirScope?,
dispatchReceiverValue: ReceiverValue? = null, dispatchReceiverValue: ReceiverValue? = null,
importedQualifierForStatic: FirExpression? = null,
givenExtensionReceiverOptions: List<ReceiverValue> = emptyList(), givenExtensionReceiverOptions: List<ReceiverValue> = emptyList(),
objectsByName: Boolean = false objectsByName: Boolean = false
): Candidate { ): Candidate {
@@ -56,10 +57,15 @@ class CandidateFactory private constructor(
val symbol = symbol.unwrapIntegerOperatorSymbolIfNeeded(callInfo) val symbol = symbol.unwrapIntegerOperatorSymbolIfNeeded(callInfo)
val result = Candidate( val result = Candidate(
symbol, dispatchReceiverValue, givenExtensionReceiverOptions, symbol,
explicitReceiverKind, context.inferenceComponents.constraintSystemFactory, baseSystem, dispatchReceiverValue,
givenExtensionReceiverOptions,
explicitReceiverKind,
context.inferenceComponents.constraintSystemFactory,
baseSystem,
callInfo, callInfo,
scope, scope,
importedQualifierForStatic,
isFromCompanionObjectTypeScope = when (explicitReceiverKind) { isFromCompanionObjectTypeScope = when (explicitReceiverKind) {
ExplicitReceiverKind.EXTENSION_RECEIVER -> ExplicitReceiverKind.EXTENSION_RECEIVER ->
givenExtensionReceiverOptions.singleOrNull().isCandidateFromCompanionObjectTypeScope() givenExtensionReceiverOptions.singleOrNull().isCandidateFromCompanionObjectTypeScope()
@@ -540,7 +540,10 @@ internal object CheckVisibility : CheckerStage() {
sink.yieldDiagnostic(VisibilityError) sink.yieldDiagnostic(VisibilityError)
} }
if (!visibilityChecker.isVisible(declaration, candidate.callInfo, dispatchReceiverValue = null)) { if (!visibilityChecker.isVisible(
declaration, candidate.callInfo, dispatchReceiverValue = null, importedQualifierForStatic = null
)
) {
sink.yieldDiagnostic(VisibilityError) sink.yieldDiagnostic(VisibilityError)
} }
} }
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.getExplicitBackingField import org.jetbrains.kotlin.fir.declarations.utils.getExplicitBackingField
import org.jetbrains.kotlin.fir.declarations.utils.isStatic import org.jetbrains.kotlin.fir.declarations.utils.isStatic
import org.jetbrains.kotlin.fir.declarations.utils.visibility import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
@@ -27,10 +28,11 @@ import org.jetbrains.kotlin.utils.addToStdlib.runIf
fun FirVisibilityChecker.isVisible( fun FirVisibilityChecker.isVisible(
declaration: FirMemberDeclaration, declaration: FirMemberDeclaration,
callInfo: CallInfo, callInfo: CallInfo,
dispatchReceiverValue: ReceiverValue? dispatchReceiverValue: ReceiverValue?,
importedQualifierForStatic: FirExpression?
): Boolean { ): Boolean {
val staticQualifierForCallable = runIf(declaration is FirCallableDeclaration && declaration.isStatic) { val staticQualifierForCallable = runIf(declaration is FirCallableDeclaration && declaration.isStatic) {
val explicitReceiver = callInfo.explicitReceiver ?: (dispatchReceiverValue as? ExpressionReceiverValue)?.explicitReceiver val explicitReceiver = callInfo.explicitReceiver ?: importedQualifierForStatic
(explicitReceiver as? FirResolvedQualifier)?.symbol?.fir as? FirRegularClass (explicitReceiver as? FirResolvedQualifier)?.symbol?.fir as? FirRegularClass
} }
return isVisible( return isVisible(
@@ -49,19 +51,21 @@ fun FirVisibilityChecker.isVisible(
candidate: Candidate candidate: Candidate
): Boolean { ): Boolean {
val callInfo = candidate.callInfo val callInfo = candidate.callInfo
val dispatchReceiverValue = candidate.dispatchReceiverValue
val importedQualifierForStatic = candidate.importedQualifierForStatic
if (!isVisible(declaration, callInfo, candidate.dispatchReceiverValue)) { if (!isVisible(declaration, callInfo, dispatchReceiverValue, importedQualifierForStatic)) {
val dispatchReceiverWithoutSmartCastType = val dispatchReceiverWithoutSmartCastType =
removeSmartCastTypeForAttemptToFitVisibility(candidate.dispatchReceiverValue, candidate.callInfo.session) ?: return false removeSmartCastTypeForAttemptToFitVisibility(dispatchReceiverValue, candidate.callInfo.session) ?: return false
if (!isVisible(declaration, callInfo, dispatchReceiverWithoutSmartCastType)) return false if (!isVisible(declaration, callInfo, dispatchReceiverWithoutSmartCastType, importedQualifierForStatic)) return false
candidate.dispatchReceiverValue = dispatchReceiverWithoutSmartCastType candidate.dispatchReceiverValue = dispatchReceiverWithoutSmartCastType
} }
val backingField = declaration.getBackingFieldIfApplicable() val backingField = declaration.getBackingFieldIfApplicable()
if (backingField != null) { if (backingField != null) {
candidate.hasVisibleBackingField = isVisible(backingField, callInfo, candidate.dispatchReceiverValue) candidate.hasVisibleBackingField = isVisible(backingField, callInfo, dispatchReceiverValue, importedQualifierForStatic)
} }
return true return true
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.resolve.calls.tower package org.jetbrains.kotlin.fir.resolve.calls.tower
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.resolve.calls.*
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
@@ -74,6 +75,7 @@ private class TowerScopeLevelProcessor(
override fun consumeCandidate( override fun consumeCandidate(
symbol: FirBasedSymbol<*>, symbol: FirBasedSymbol<*>,
dispatchReceiverValue: ReceiverValue?, dispatchReceiverValue: ReceiverValue?,
importedQualifierForStatic: FirExpression?,
givenExtensionReceiverOptions: List<ReceiverValue>, givenExtensionReceiverOptions: List<ReceiverValue>,
scope: FirScope, scope: FirScope,
objectsByName: Boolean objectsByName: Boolean
@@ -85,6 +87,7 @@ private class TowerScopeLevelProcessor(
explicitReceiverKind, explicitReceiverKind,
scope, scope,
dispatchReceiverValue, dispatchReceiverValue,
importedQualifierForStatic,
givenExtensionReceiverOptions, givenExtensionReceiverOptions,
objectsByName objectsByName
), candidateFactory.context ), candidateFactory.context
@@ -7,9 +7,12 @@ package org.jetbrains.kotlin.fir.resolve.calls.tower
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.ContextReceiverGroup import org.jetbrains.kotlin.fir.declarations.ContextReceiverGroup
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId
import org.jetbrains.kotlin.fir.declarations.utils.isInner import org.jetbrains.kotlin.fir.declarations.utils.isInner
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression
import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedQualifier import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedQualifier
import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.*
@@ -25,6 +28,7 @@ import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.HidesMembers import org.jetbrains.kotlin.name.StandardClassIds.Annotations.HidesMembers
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.addToStdlib.runIf
enum class ProcessResult { enum class ProcessResult {
FOUND, SCOPE_EMPTY; FOUND, SCOPE_EMPTY;
@@ -53,6 +57,7 @@ abstract class TowerScopeLevel {
fun consumeCandidate( fun consumeCandidate(
symbol: T, symbol: T,
dispatchReceiverValue: ReceiverValue?, dispatchReceiverValue: ReceiverValue?,
importedQualifierForStatic: FirExpression?,
givenExtensionReceiverOptions: List<ReceiverValue>, givenExtensionReceiverOptions: List<ReceiverValue>,
scope: FirScope, scope: FirScope,
objectsByName: Boolean = false objectsByName: Boolean = false
@@ -132,7 +137,13 @@ class MemberScopeTowerLevel(
) )
withSynthetic?.processScopeMembers { symbol -> withSynthetic?.processScopeMembers { symbol ->
empty = false empty = false
output.consumeCandidate(symbol, dispatchReceiverValue, givenExtensionReceiverOptions = emptyList(), scope) output.consumeCandidate(
symbol,
dispatchReceiverValue,
importedQualifierForStatic = null,
givenExtensionReceiverOptions = emptyList(),
scope
)
} }
} }
return if (empty) ProcessResult.SCOPE_EMPTY else ProcessResult.FOUND return if (empty) ProcessResult.SCOPE_EMPTY else ProcessResult.FOUND
@@ -158,7 +169,7 @@ class MemberScopeTowerLevel(
val candidates = mutableListOf<MemberWithBaseScope<T>>() val candidates = mutableListOf<MemberWithBaseScope<T>>()
for (group in overridableGroups) { for (group in overridableGroups) {
val visibleCandidates = group.filter { val visibleCandidates = group.filter {
visibilityChecker.isVisible(it.member.fir, callInfo, dispatchReceiverValue) visibilityChecker.isVisible(it.member.fir, callInfo, dispatchReceiverValue, importedQualifierForStatic = null)
} }
val visibleCandidatesFromSmartcast = visibleCandidates.filter { candidatesMapping.getValue(it) } val visibleCandidatesFromSmartcast = visibleCandidates.filter { candidatesMapping.getValue(it) }
@@ -192,12 +203,12 @@ class MemberScopeTowerLevel(
for ((candidate, scope) in candidatesWithScope) { for ((candidate, scope) in candidatesWithScope) {
if (candidate.hasConsistentExtensionReceiver(givenExtensionReceiverOptions)) { if (candidate.hasConsistentExtensionReceiver(givenExtensionReceiverOptions)) {
output.consumeCandidate( output.consumeCandidate(
candidate, dispatchReceiverValue, candidate,
dispatchReceiverValue,
importedQualifierForStatic = null,
givenExtensionReceiverOptions, givenExtensionReceiverOptions,
scope scope
) )
} else if (candidate is FirClassLikeSymbol<*>) {
output.consumeCandidate(candidate, null, givenExtensionReceiverOptions, scope)
} }
} }
} }
@@ -215,7 +226,6 @@ class MemberScopeTowerLevel(
processor = { processor = {
lookupCtx.recordCallableMemberLookup(it) lookupCtx.recordCallableMemberLookup(it)
// WARNING, DO NOT CAST FUNCTIONAL TYPE ITSELF // WARNING, DO NOT CAST FUNCTIONAL TYPE ITSELF
@Suppress("UNCHECKED_CAST")
consumer(it as FirFunctionSymbol<*>) consumer(it as FirFunctionSymbol<*>)
} }
) )
@@ -313,21 +323,27 @@ class ScopeTowerLevel(
fun areThereExtensionReceiverOptions(): Boolean = givenExtensionReceiverOptions.isNotEmpty() fun areThereExtensionReceiverOptions(): Boolean = givenExtensionReceiverOptions.isNotEmpty()
private fun dispatchReceiverValue(candidate: FirCallableSymbol<*>): ReceiverValue? { private fun FirCallableDeclaration.importedQualifierForObjectOrStatic(): FirExpression? {
candidate.fir.importedFromObjectOrStaticData?.let { data -> val objectClassId = importedFromObjectOrStaticData?.objectClassId ?: return null
val objectClassId = data.objectClassId val symbol = session.symbolProvider.getClassLikeSymbolByClassId(objectClassId)
val symbol = session.symbolProvider.getClassLikeSymbolByClassId(objectClassId) if (symbol is FirRegularClassSymbol) {
if (symbol is FirRegularClassSymbol) { return buildResolvedQualifier {
val resolvedQualifier = buildResolvedQualifier { packageFqName = objectClassId.packageFqName
packageFqName = objectClassId.packageFqName relativeClassFqName = objectClassId.relativeClassName
relativeClassFqName = objectClassId.relativeClassName this.symbol = symbol
this.symbol = symbol }.apply {
}.apply { resultType = bodyResolveComponents.typeForQualifier(this)
resultType = bodyResolveComponents.typeForQualifier(this)
}
return ExpressionReceiverValue(resolvedQualifier)
} }
} }
return null
}
private fun dispatchReceiverValue(candidate: FirCallableSymbol<*>): ReceiverValue? {
if (candidate.fir.isStatic) return null
val importedQualifierReceiver = candidate.fir.importedQualifierForObjectOrStatic()
if (importedQualifierReceiver != null) {
return ExpressionReceiverValue(importedQualifierReceiver)
}
if (candidate !is FirBackingFieldSymbol) { if (candidate !is FirBackingFieldSymbol) {
return null return null
@@ -381,13 +397,22 @@ class ScopeTowerLevel(
val receiverExpected = withHideMembersOnly || areThereExtensionReceiverOptions() val receiverExpected = withHideMembersOnly || areThereExtensionReceiverOptions()
if (candidateReceiverTypeRef == null == receiverExpected) return if (candidateReceiverTypeRef == null == receiverExpected) return
val dispatchReceiverValue = dispatchReceiverValue(candidate) val dispatchReceiverValue = dispatchReceiverValue(candidate)
if (dispatchReceiverValue == null && shouldSkipCandidateWithInconsistentExtensionReceiver(candidate)) { val isStatic = candidate.fir.isStatic
val importedQualifierForStatic = runIf(isStatic) {
candidate.fir.importedQualifierForObjectOrStatic()
}
if (dispatchReceiverValue == null &&
importedQualifierForStatic == null &&
shouldSkipCandidateWithInconsistentExtensionReceiver(candidate)
) {
return return
} }
val unwrappedCandidate = candidate.fir.importedFromObjectOrStaticData?.original?.symbol ?: candidate val unwrappedCandidate = candidate.fir.importedFromObjectOrStaticData?.original?.symbol.takeIf { !isStatic } ?: candidate
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
processor.consumeCandidate( processor.consumeCandidate(
unwrappedCandidate as T, dispatchReceiverValue, unwrappedCandidate as T,
dispatchReceiverValue,
importedQualifierForStatic,
givenExtensionReceiverOptions, givenExtensionReceiverOptions,
scope scope
) )
@@ -433,7 +458,9 @@ class ScopeTowerLevel(
scope.processClassifiersByName(info.name) { scope.processClassifiersByName(info.name) {
empty = false empty = false
processor.consumeCandidate( processor.consumeCandidate(
it, dispatchReceiverValue = null, it,
dispatchReceiverValue = null,
importedQualifierForStatic = null,
givenExtensionReceiverOptions = emptyList(), givenExtensionReceiverOptions = emptyList(),
scope = scope, scope = scope,
objectsByName = true objectsByName = true