K2: don't use dispatch receiver to store imported static qualifiers
Related to KT-53441
This commit is contained in:
committed by
Space Team
parent
7205a90d9d
commit
104fd4c14d
@@ -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|))
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -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)
|
||||||
|
|||||||
+38
-38
@@ -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
|
||||||
|
|||||||
+2
-2
@@ -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
|
||||||
|
|||||||
+3
@@ -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
|
||||||
|
|||||||
+50
-23
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user