FIR: Get rid of usages of FirCallableSymbol::overriddenSymbol

This commit is contained in:
Denis Zharkov
2020-10-30 12:36:06 +03:00
parent 728c2a808f
commit 4282e27d73
25 changed files with 114 additions and 123 deletions
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.originalForSubstitutionOverride
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
@@ -113,8 +114,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
// substitution here // substitution here
val protoConstructor = functionCall.calleeReference.safeAs<FirResolvedNamedReference>() val protoConstructor = functionCall.calleeReference.safeAs<FirResolvedNamedReference>()
?.resolvedSymbol.safeAs<FirConstructorSymbol>() ?.resolvedSymbol.safeAs<FirConstructorSymbol>()
?.overriddenSymbol ?.fir?.originalForSubstitutionOverride
?.fir.safeAs<FirConstructor>()
?: return ?: return
// holds Collection<G> bound. // holds Collection<G> bound.
@@ -9,11 +9,8 @@ import org.jetbrains.kotlin.backend.common.serialization.mangle.KotlinMangleComp
import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleConstant import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleConstant
import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleMode import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleMode
import org.jetbrains.kotlin.backend.common.serialization.mangle.collectForMangler import org.jetbrains.kotlin.backend.common.serialization.mangle.collectForMangler
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
@@ -160,12 +157,9 @@ open class FirJvmMangleComputer(
return parent return parent
} }
if (parent is FirCallableDeclaration<*>) { if (parent is FirCallableDeclaration<*>) {
val overriddenSymbol = parent.symbol.overriddenSymbol val overriddenFir = parent.originalForSubstitutionOverride
if (overriddenSymbol != null) { if (overriddenFir is FirTypeParametersOwner && this in overriddenFir.typeParameters) {
val fir = overriddenSymbol.fir return parent
if (fir is FirTypeParametersOwner && this in fir.typeParameters) {
return parent
}
} }
} }
} }
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.references.FirThisReference
import org.jetbrains.kotlin.fir.references.impl.FirPropertyFromParameterResolvedNamedReference import org.jetbrains.kotlin.fir.references.impl.FirPropertyFromParameterResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.calls.SyntheticPropertySymbol import org.jetbrains.kotlin.fir.resolve.calls.SyntheticPropertySymbol
import org.jetbrains.kotlin.fir.resolve.calls.originalConstructorIfTypeAlias
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.processDirectlyOverriddenFunctions import org.jetbrains.kotlin.fir.scopes.processDirectlyOverriddenFunctions
@@ -102,7 +103,7 @@ fun FirClassifierSymbol<*>.toSymbol(
} }
} }
fun FirReference.toSymbol( fun FirReference.toSymbolForCall(
session: FirSession, session: FirSession,
classifierStorage: Fir2IrClassifierStorage, classifierStorage: Fir2IrClassifierStorage,
declarationStorage: Fir2IrDeclarationStorage, declarationStorage: Fir2IrDeclarationStorage,
@@ -113,7 +114,7 @@ fun FirReference.toSymbol(
is FirResolvedNamedReference -> { is FirResolvedNamedReference -> {
when (val resolvedSymbol = resolvedSymbol) { when (val resolvedSymbol = resolvedSymbol) {
is FirCallableSymbol<*> -> { is FirCallableSymbol<*> -> {
resolvedSymbol.deepestMatchingOverriddenSymbol().toSymbol(declarationStorage, preferGetter) resolvedSymbol.unwrapCallRepresentative().toSymbolForCall(declarationStorage, preferGetter)
} }
is FirClassifierSymbol<*> -> { is FirClassifierSymbol<*> -> {
resolvedSymbol.toSymbol(session, classifierStorage) resolvedSymbol.toSymbol(session, classifierStorage)
@@ -138,7 +139,7 @@ fun FirReference.toSymbol(
} }
} }
private fun FirCallableSymbol<*>.toSymbol(declarationStorage: Fir2IrDeclarationStorage, preferGetter: Boolean): IrSymbol? = when (this) { private fun FirCallableSymbol<*>.toSymbolForCall(declarationStorage: Fir2IrDeclarationStorage, preferGetter: Boolean): IrSymbol? = when (this) {
is FirFunctionSymbol<*> -> declarationStorage.getIrFunctionSymbol(this) is FirFunctionSymbol<*> -> declarationStorage.getIrFunctionSymbol(this)
is SyntheticPropertySymbol -> { is SyntheticPropertySymbol -> {
(fir as? FirSyntheticProperty)?.let { syntheticProperty -> (fir as? FirSyntheticProperty)?.let { syntheticProperty ->
@@ -148,7 +149,7 @@ private fun FirCallableSymbol<*>.toSymbol(declarationStorage: Fir2IrDeclarationS
syntheticProperty.setter?.delegate?.symbol syntheticProperty.setter?.delegate?.symbol
?: throw AssertionError("Written synthetic property must have a setter") ?: throw AssertionError("Written synthetic property must have a setter")
} }
delegateSymbol.deepestMatchingOverriddenSymbol().toSymbol(declarationStorage, preferGetter) delegateSymbol.unwrapCallRepresentative().toSymbolForCall(declarationStorage, preferGetter)
} ?: declarationStorage.getIrPropertySymbol(this) } ?: declarationStorage.getIrPropertySymbol(this)
} }
is FirPropertySymbol -> declarationStorage.getIrPropertySymbol(this) is FirPropertySymbol -> declarationStorage.getIrPropertySymbol(this)
@@ -212,17 +213,25 @@ private fun FirConstKind<*>.toIrConstKind(): IrConstKind<*> = when (this) {
FirConstKind.IntegerLiteral, FirConstKind.UnsignedIntegerLiteral -> throw IllegalArgumentException() FirConstKind.IntegerLiteral, FirConstKind.UnsignedIntegerLiteral -> throw IllegalArgumentException()
} }
internal tailrec fun FirCallableSymbol<*>.deepestOverriddenSymbol(): FirCallableSymbol<*> {
val overriddenSymbol = overriddenSymbol ?: return this internal tailrec fun FirCallableSymbol<*>.unwrapSubstitutionAndIntersectionOverrides(): FirCallableSymbol<*> {
return overriddenSymbol.deepestOverriddenSymbol() val originalForSubstitutionOverride = originalForSubstitutionOverride
if (originalForSubstitutionOverride != null) return originalForSubstitutionOverride.unwrapSubstitutionAndIntersectionOverrides()
val baseForIntersectionOverride = baseForIntersectionOverride
if (baseForIntersectionOverride != null) return baseForIntersectionOverride.unwrapSubstitutionAndIntersectionOverrides()
return this
} }
internal tailrec fun FirCallableSymbol<*>.deepestMatchingOverriddenSymbol(root: FirCallableSymbol<*> = this): FirCallableSymbol<*> { internal tailrec fun FirCallableSymbol<*>.unwrapCallRepresentative(root: FirCallableSymbol<*> = this): FirCallableSymbol<*> {
if (fir.isIntersectionOverride) return this if (fir.isIntersectionOverride) return this
val overriddenSymbol = overriddenSymbol?.takeIf {
val overriddenSymbol = fir.originalForSubstitutionOverride?.takeIf {
it.containingClass() == root.containingClass() it.containingClass() == root.containingClass()
} ?: return this }?.symbol ?: return this
return overriddenSymbol.deepestMatchingOverriddenSymbol(this)
return overriddenSymbol.unwrapCallRepresentative(this)
} }
internal fun FirSimpleFunction.generateOverriddenFunctionSymbols( internal fun FirSimpleFunction.generateOverriddenFunctionSymbols(
@@ -239,7 +248,7 @@ internal fun FirSimpleFunction.generateOverriddenFunctionSymbols(
return@processDirectlyOverriddenFunctions ProcessorAction.NEXT return@processDirectlyOverriddenFunctions ProcessorAction.NEXT
} }
val overridden = declarationStorage.getIrFunctionSymbol(it.unwrapSubstitutionOverrides()) val overridden = declarationStorage.getIrFunctionSymbol(it.unwrapFakeOverrides())
overriddenSet += overridden as IrSimpleFunctionSymbol overriddenSet += overridden as IrSimpleFunctionSymbol
ProcessorAction.NEXT ProcessorAction.NEXT
} }
@@ -260,7 +269,7 @@ internal fun FirProperty.generateOverriddenAccessorSymbols(
if (it is FirAccessorSymbol || it.fir.visibility == Visibilities.Private) { if (it is FirAccessorSymbol || it.fir.visibility == Visibilities.Private) {
return@processDirectlyOverriddenProperties ProcessorAction.NEXT return@processDirectlyOverriddenProperties ProcessorAction.NEXT
} }
val overriddenProperty = declarationStorage.getIrPropertySymbol(it.unwrapSubstitutionOverrides()) as IrPropertySymbol val overriddenProperty = declarationStorage.getIrPropertySymbol(it.unwrapFakeOverrides()) as IrPropertySymbol
val overriddenAccessor = if (isGetter) overriddenProperty.owner.getter?.symbol else overriddenProperty.owner.setter?.symbol val overriddenAccessor = if (isGetter) overriddenProperty.owner.getter?.symbol else overriddenProperty.owner.setter?.symbol
if (overriddenAccessor != null) { if (overriddenAccessor != null) {
overriddenSet += overriddenAccessor overriddenSet += overriddenAccessor
@@ -461,7 +461,7 @@ class Fir2IrDeclarationStorage(
return created return created
} }
if (function.symbol.callableId.isKFunctionInvoke()) { if (function.symbol.callableId.isKFunctionInvoke()) {
(function.symbol.overriddenSymbol as? FirNamedFunctionSymbol)?.let { (function.symbol.originalForSubstitutionOverride as? FirNamedFunctionSymbol)?.let {
created.overriddenSymbols += getIrFunctionSymbol(it) as IrSimpleFunctionSymbol created.overriddenSymbols += getIrFunctionSymbol(it) as IrSimpleFunctionSymbol
} }
} }
@@ -1034,7 +1034,7 @@ class Fir2IrDeclarationStorage(
symbolTable.declareSimpleFunction(signature, { symbol }) { symbolTable.declareSimpleFunction(signature, { symbol }) {
val isFakeOverride = val isFakeOverride =
firFunctionSymbol is FirNamedFunctionSymbol && firFunctionSymbol.fir.isSubstitutionOverride && firFunctionSymbol is FirNamedFunctionSymbol && firFunctionSymbol.fir.isSubstitutionOverride &&
firFunctionSymbol.dispatchReceiverClassOrNull() != firFunctionSymbol.overriddenSymbol?.dispatchReceiverClassOrNull() firFunctionSymbol.dispatchReceiverClassOrNull() != firFunctionSymbol.originalForSubstitutionOverride?.dispatchReceiverClassOrNull()
Fir2IrLazySimpleFunction( Fir2IrLazySimpleFunction(
components, startOffset, endOffset, parentOrigin, firDeclaration, irParent.fir, symbol, isFakeOverride components, startOffset, endOffset, parentOrigin, firDeclaration, irParent.fir, symbol, isFakeOverride
).apply { ).apply {
@@ -1101,7 +1101,7 @@ class Fir2IrDeclarationStorage(
symbolTable.declareProperty(signature, { symbol }) { symbolTable.declareProperty(signature, { symbol }) {
val isFakeOverride = val isFakeOverride =
firPropertySymbol.fir.isSubstitutionOverride && firPropertySymbol.fir.isSubstitutionOverride &&
firPropertySymbol.dispatchReceiverClassOrNull() != firPropertySymbol.overriddenSymbol?.dispatchReceiverClassOrNull() firPropertySymbol.dispatchReceiverClassOrNull() != firPropertySymbol.originalForSubstitutionOverride?.dispatchReceiverClassOrNull()
Fir2IrLazyProperty( Fir2IrLazyProperty(
components, startOffset, endOffset, declarationOrigin, fir, irParent.fir, symbol, isFakeOverride components, startOffset, endOffset, declarationOrigin, fir, irParent.fir, symbol, isFakeOverride
).apply { ).apply {
@@ -6,15 +6,23 @@
package org.jetbrains.kotlin.fir.backend package org.jetbrains.kotlin.fir.backend
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.baseForIntersectionOverride
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.* import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement
import org.jetbrains.kotlin.fir.references.* import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
import org.jetbrains.kotlin.fir.references.FirReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.scope import org.jetbrains.kotlin.fir.resolve.scope
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
@@ -273,7 +281,7 @@ class Fir2IrImplicitCastInserter(
if (castTypeRef is FirResolvedTypeRef && originalTypeRef is FirResolvedTypeRef) { if (castTypeRef is FirResolvedTypeRef && originalTypeRef is FirResolvedTypeRef) {
val castType = castTypeRef.type val castType = castTypeRef.type
if (castType is ConeIntersectionType) { if (castType is ConeIntersectionType) {
val unwrappedSymbol = (referencedSymbol as? FirCallableSymbol)?.overriddenSymbol ?: referencedSymbol val unwrappedSymbol = (referencedSymbol as? FirCallableSymbol)?.baseForIntersectionOverride ?: referencedSymbol
castType.intersectedTypes.forEach { castType.intersectedTypes.forEach {
if (it.doesContainReferencedSymbolInScope(unwrappedSymbol, calleeReference.name)) { if (it.doesContainReferencedSymbolInScope(unwrappedSymbol, calleeReference.name)) {
return implicitCastOrExpression(value, it) return implicitCastOrExpression(value, it)
@@ -401,7 +401,7 @@ class Fir2IrVisitor(
} }
} }
} else if (boundSymbol is FirCallableSymbol) { } else if (boundSymbol is FirCallableSymbol) {
val receiverSymbol = calleeReference.toSymbol(session, classifierStorage, declarationStorage, conversionScope) val receiverSymbol = calleeReference.toSymbolForCall(session, classifierStorage, declarationStorage, conversionScope)
val receiver = (receiverSymbol?.owner as? IrSimpleFunction)?.extensionReceiverParameter val receiver = (receiverSymbol?.owner as? IrSimpleFunction)?.extensionReceiverParameter
if (receiver != null) { if (receiver != null) {
return thisReceiverExpression.convertWithOffsets { startOffset, endOffset -> return thisReceiverExpression.convertWithOffsets { startOffset, endOffset ->
@@ -55,7 +55,7 @@ class CallAndReferenceGenerator(
callableReferenceAccess: FirCallableReferenceAccess, callableReferenceAccess: FirCallableReferenceAccess,
explicitReceiverExpression: IrExpression? explicitReceiverExpression: IrExpression?
): IrExpression { ): IrExpression {
val symbol = callableReferenceAccess.calleeReference.toSymbol(session, classifierStorage, declarationStorage, conversionScope) val symbol = callableReferenceAccess.calleeReference.toSymbolForCall(session, classifierStorage, declarationStorage, conversionScope)
val type = callableReferenceAccess.typeRef.toIrType() val type = callableReferenceAccess.typeRef.toIrType()
fun propertyOrigin(): IrStatementOrigin? = fun propertyOrigin(): IrStatementOrigin? =
when (callableReferenceAccess.source?.psi?.parent) { when (callableReferenceAccess.source?.psi?.parent) {
@@ -197,7 +197,7 @@ class CallAndReferenceGenerator(
val samConstructorCall = qualifiedAccess.tryConvertToSamConstructorCall(type) val samConstructorCall = qualifiedAccess.tryConvertToSamConstructorCall(type)
if (samConstructorCall != null) return samConstructorCall if (samConstructorCall != null) return samConstructorCall
val symbol = qualifiedAccess.calleeReference.toSymbol( val symbol = qualifiedAccess.calleeReference.toSymbolForCall(
session, session,
classifierStorage, classifierStorage,
declarationStorage, declarationStorage,
@@ -277,7 +277,7 @@ class CallAndReferenceGenerator(
fun convertToIrSetCall(variableAssignment: FirVariableAssignment, explicitReceiverExpression: IrExpression?): IrExpression { fun convertToIrSetCall(variableAssignment: FirVariableAssignment, explicitReceiverExpression: IrExpression?): IrExpression {
val type = irBuiltIns.unitType val type = irBuiltIns.unitType
val calleeReference = variableAssignment.calleeReference val calleeReference = variableAssignment.calleeReference
val symbol = calleeReference.toSymbol(session, classifierStorage, declarationStorage, conversionScope, preferGetter = false) val symbol = calleeReference.toSymbolForCall(session, classifierStorage, declarationStorage, conversionScope, preferGetter = false)
val origin = IrStatementOrigin.EQ val origin = IrStatementOrigin.EQ
return variableAssignment.convertWithOffsets { startOffset, endOffset -> return variableAssignment.convertWithOffsets { startOffset, endOffset ->
val assignedValue = visitor.convertToIrExpression(variableAssignment.rValue) val assignedValue = visitor.convertToIrExpression(variableAssignment.rValue)
@@ -272,7 +272,7 @@ internal class ClassMemberGenerator(
startOffset, endOffset, constructedIrType, "Cannot find delegated constructor call" startOffset, endOffset, constructedIrType, "Cannot find delegated constructor call"
) )
} }
val constructorSymbol = referencedSymbol.deepestMatchingOverriddenSymbol() as FirConstructorSymbol val constructorSymbol = referencedSymbol.unwrapCallRepresentative() as FirConstructorSymbol
val firDispatchReceiver = dispatchReceiver val firDispatchReceiver = dispatchReceiver
return convertWithOffsets { startOffset, endOffset -> return convertWithOffsets { startOffset, endOffset ->
val irConstructorSymbol = declarationStorage.getIrFunctionSymbol(constructorSymbol) as IrConstructorSymbol val irConstructorSymbol = declarationStorage.getIrFunctionSymbol(constructorSymbol) as IrConstructorSymbol
@@ -7,9 +7,11 @@ package org.jetbrains.kotlin.fir.backend.generators
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.backend.*
import org.jetbrains.kotlin.fir.baseForIntersectionOverride
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.isIntersectionOverride import org.jetbrains.kotlin.fir.isIntersectionOverride
import org.jetbrains.kotlin.fir.isSubstitutionOverride import org.jetbrains.kotlin.fir.isSubstitutionOverride
import org.jetbrains.kotlin.fir.originalForSubstitutionOverride
import org.jetbrains.kotlin.fir.scopes.* import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.scopes.impl.delegatedWrapperData import org.jetbrains.kotlin.fir.scopes.impl.delegatedWrapperData
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
@@ -104,13 +106,13 @@ internal class DelegatedMemberGenerator(
return when { return when {
wrappedSymbol.fir.isSubstitutionOverride && wrappedSymbol.fir.isSubstitutionOverride &&
(wrappedSymbol.fir.dispatchReceiverType as? ConeClassLikeType)?.lookupTag == firSubClass.symbol.toLookupTag() -> (wrappedSymbol.fir.dispatchReceiverType as? ConeClassLikeType)?.lookupTag == firSubClass.symbol.toLookupTag() ->
wrapped.symbol.overriddenSymbol!!.fir wrapped.originalForSubstitutionOverride
else -> wrapped else -> wrapped
} }
} }
private fun isJavaDefault(function: FirSimpleFunction): Boolean { private fun isJavaDefault(function: FirSimpleFunction): Boolean {
if (function.isIntersectionOverride) return isJavaDefault(function.symbol.overriddenSymbol!!.fir) if (function.isIntersectionOverride) return isJavaDefault(function.baseForIntersectionOverride!!)
return function.origin == FirDeclarationOrigin.Enhancement && function.modality == Modality.OPEN return function.origin == FirDeclarationOrigin.Enhancement && function.modality == Modality.OPEN
} }
@@ -6,12 +6,9 @@
package org.jetbrains.kotlin.fir.backend.generators package org.jetbrains.kotlin.fir.backend.generators
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.FirSymbolOwner
import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.backend.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.dispatchReceiverClassOrNull
import org.jetbrains.kotlin.fir.isSubstitutionOverride
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.FirTypeScope
@@ -25,7 +22,6 @@ import org.jetbrains.kotlin.fir.symbols.PossiblyFirFakeOverrideSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.unwrapSubstitutionOverrides
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
@@ -156,7 +152,7 @@ class FakeOverrideGenerator(
if (originalDeclaration.visibility == Visibilities.Private) return if (originalDeclaration.visibility == Visibilities.Private) return
val origin = IrDeclarationOrigin.FAKE_OVERRIDE val origin = IrDeclarationOrigin.FAKE_OVERRIDE
val baseSymbol = originalSymbol.deepestOverriddenSymbol() as S val baseSymbol = originalSymbol.unwrapSubstitutionAndIntersectionOverrides() as S
if (originalSymbol.fir.origin.fromSupertypes && originalSymbol.dispatchReceiverClassOrNull() == classLookupTag) { if (originalSymbol.fir.origin.fromSupertypes && originalSymbol.dispatchReceiverClassOrNull() == classLookupTag) {
// Substitution case // Substitution case
@@ -204,7 +200,7 @@ class FakeOverrideGenerator(
return scope.directOverridden(symbol).map { return scope.directOverridden(symbol).map {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
if (it is PossiblyFirFakeOverrideSymbol<*, *> && it.fir.isSubstitutionOverride && it.dispatchReceiverClassOrNull() == containingClass) if (it is PossiblyFirFakeOverrideSymbol<*, *> && it.fir.isSubstitutionOverride && it.dispatchReceiverClassOrNull() == containingClass)
it.overriddenSymbol!! as S it.originalForSubstitutionOverride!!
else else
it it
} }
@@ -234,7 +230,7 @@ class FakeOverrideGenerator(
private fun IrProperty.discardAccessorsAccordingToBaseVisibility(baseSymbols: List<FirPropertySymbol>) { private fun IrProperty.discardAccessorsAccordingToBaseVisibility(baseSymbols: List<FirPropertySymbol>) {
for (baseSymbol in baseSymbols) { for (baseSymbol in baseSymbols) {
val unwrapped = baseSymbol.unwrapSubstitutionOverrides() val unwrapped = baseSymbol.unwrapFakeOverrides()
// Do not create fake overrides for accessors if not allowed to do so, e.g., private lateinit var. // Do not create fake overrides for accessors if not allowed to do so, e.g., private lateinit var.
if (unwrapped.fir.getter?.allowsToHaveFakeOverride != true) { if (unwrapped.fir.getter?.allowsToHaveFakeOverride != true) {
getter = null getter = null
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.PossiblyFirFakeOverrideSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
@@ -44,9 +43,9 @@ abstract class FirVisibilityChecker : FirSessionComponent {
): Boolean where T : FirMemberDeclaration, T : FirSymbolOwner<*> { ): Boolean where T : FirMemberDeclaration, T : FirSymbolOwner<*> {
val symbol = declaration.symbol val symbol = declaration.symbol
if (symbol is PossiblyFirFakeOverrideSymbol<*, *> && symbol.overriddenSymbol != null) { if (declaration is FirCallableDeclaration<*> && (declaration.isIntersectionOverride || declaration.isSubstitutionOverride)) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return isVisible(symbol.overriddenSymbol!!.fir as T, candidate) return isVisible(declaration.originalIfFakeOverride() as T, candidate)
} }
val callInfo = candidate.callInfo val callInfo = candidate.callInfo
@@ -21,12 +21,12 @@ import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.unwrapSubstitutionOverrides
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.unwrapFakeOverrides
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.SmartList
@@ -147,5 +147,5 @@ private fun BodyResolveComponents.isConcreteMember(supertype: ConeKotlinType, me
val classSymbol = val classSymbol =
(supertype as? ConeClassLikeType)?.lookupTag?.toSymbol(session) as? FirRegularClassSymbol ?: return true (supertype as? ConeClassLikeType)?.lookupTag?.toSymbol(session) as? FirRegularClassSymbol ?: return true
if (classSymbol.fir.classKind != ClassKind.INTERFACE) return true if (classSymbol.fir.classKind != ClassKind.INTERFACE) return true
return member.symbol.unwrapSubstitutionOverrides().dispatchReceiverClassOrNull()?.classId != StandardClassIds.Any return member.symbol.unwrapFakeOverrides().dispatchReceiverClassOrNull()?.classId != StandardClassIds.Any
} }
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.ConeNullability.NOT_NULL import org.jetbrains.kotlin.fir.types.ConeNullability.NOT_NULL
import org.jetbrains.kotlin.fir.unwrapFakeOverrides
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
@@ -123,7 +124,7 @@ class FirSyntheticPropertiesScope(
private fun FirFunctionSymbol<*>.hasJavaOverridden(): Boolean { private fun FirFunctionSymbol<*>.hasJavaOverridden(): Boolean {
var result = false var result = false
baseScope.processOverriddenFunctionsAndSelf(this) { baseScope.processOverriddenFunctionsAndSelf(this) {
if (it.unwrapSubstitutionOverrides().fir.origin == FirDeclarationOrigin.Enhancement) { if (it.unwrapFakeOverrides().fir.origin == FirDeclarationOrigin.Enhancement) {
result = true result = true
ProcessorAction.STOP ProcessorAction.STOP
} else { } else {
@@ -9,17 +9,17 @@ import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.originalForSubstitutionOverride
import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.calls.Candidate import org.jetbrains.kotlin.fir.resolve.calls.Candidate
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
@@ -122,7 +122,7 @@ fun ConeKotlinType.findContributedInvokeSymbol(
if (declaredInvoke != null) { if (declaredInvoke != null) {
// Make sure the user-contributed or type-substituted invoke we just found above is an override of base invoke. // Make sure the user-contributed or type-substituted invoke we just found above is an override of base invoke.
scope.processOverriddenFunctions(declaredInvoke!!) { functionSymbol -> scope.processOverriddenFunctions(declaredInvoke!!) { functionSymbol ->
if (functionSymbol == baseInvokeSymbol || functionSymbol.overriddenSymbol == baseInvokeSymbol) { if (functionSymbol == baseInvokeSymbol || functionSymbol.originalForSubstitutionOverride == baseInvokeSymbol) {
overriddenInvoke = functionSymbol overriddenInvoke = functionSymbol
ProcessorAction.STOP ProcessorAction.STOP
} else { } else {
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.ThreadSafeMutableState import org.jetbrains.kotlin.fir.ThreadSafeMutableState
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.originalIfFakeOverride
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirProviderInternals import org.jetbrains.kotlin.fir.resolve.providers.FirProviderInternals
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
@@ -30,7 +31,7 @@ class FirProviderImpl(val session: FirSession, val kotlinScopeProvider: KotlinSc
override val symbolProvider: FirSymbolProvider = SymbolProvider() override val symbolProvider: FirSymbolProvider = SymbolProvider()
override fun getFirCallableContainerFile(symbol: FirCallableSymbol<*>): FirFile? { override fun getFirCallableContainerFile(symbol: FirCallableSymbol<*>): FirFile? {
symbol.overriddenSymbol?.let { symbol.originalIfFakeOverride()?.let {
return getFirCallableContainerFile(it) return getFirCallableContainerFile(it)
} }
if (symbol is FirAccessorSymbol) { if (symbol is FirAccessorSymbol) {
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.transformers.* import org.jetbrains.kotlin.fir.resolve.transformers.*
import org.jetbrains.kotlin.fir.resolve.transformers.contracts.runContractResolveForLocalClass import org.jetbrains.kotlin.fir.resolve.transformers.contracts.runContractResolveForLocalClass
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
import org.jetbrains.kotlin.fir.symbols.PossiblyFirFakeOverrideSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirAccessorSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirAccessorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
@@ -212,14 +211,13 @@ private class ReturnTypeCalculatorWithJump(
} }
if (declaration.isIntersectionOverride) { if (declaration.isIntersectionOverride) {
val result = tryCalculateReturnType(declaration.symbol.overriddenSymbol!!.fir) val result = tryCalculateReturnType(declaration.symbol.baseForIntersectionOverride!!.fir)
declaration.replaceReturnTypeRef(result) declaration.replaceReturnTypeRef(result)
return result return result
} }
runIf(declaration.isSubstitutionOverride) { runIf(declaration.isSubstitutionOverride) {
val possiblyFirFakeOverrideSymbol = declaration.symbol as PossiblyFirFakeOverrideSymbol<*, *> val overriddenDeclaration = declaration.originalForSubstitutionOverride ?: return@runIf
val overriddenDeclaration = possiblyFirFakeOverrideSymbol.overriddenSymbol?.fir as FirTypedDeclaration? ?: return@runIf
tryCalculateReturnType(overriddenDeclaration) tryCalculateReturnType(overriddenDeclaration)
return FakeOverrideTypeCalculator.Forced.computeReturnType(declaration) return FakeOverrideTypeCalculator.Forced.computeReturnType(declaration)
} }
@@ -58,7 +58,7 @@ class FirClassSubstitutionScope(
processDirectOverriddenCallablesWithBaseScope: FirTypeScope.(D, ((D, FirTypeScope) -> ProcessorAction)) -> ProcessorAction, processDirectOverriddenCallablesWithBaseScope: FirTypeScope.(D, ((D, FirTypeScope) -> ProcessorAction)) -> ProcessorAction,
fakeOverridesMap: Map<out FirCallableSymbol<*>, FirCallableSymbol<*>> fakeOverridesMap: Map<out FirCallableSymbol<*>, FirCallableSymbol<*>>
): ProcessorAction { ): ProcessorAction {
val original = (callableSymbol.overriddenSymbol as? D)?.takeIf { it in fakeOverridesMap } val original = callableSymbol.originalForSubstitutionOverride?.takeIf { it in fakeOverridesMap }
?: return useSiteMemberScope.processDirectOverriddenCallablesWithBaseScope(callableSymbol, processor) ?: return useSiteMemberScope.processDirectOverriddenCallablesWithBaseScope(callableSymbol, processor)
if (!processor(original, useSiteMemberScope)) return ProcessorAction.STOP if (!processor(original, useSiteMemberScope)) return ProcessorAction.STOP
@@ -16,7 +16,7 @@ fun FirCallableSymbol<*>.dispatchReceiverClassOrNull(): ConeClassLikeLookupTag?
fun FirCallableDeclaration<*>.dispatchReceiverClassOrNull(): ConeClassLikeLookupTag? { fun FirCallableDeclaration<*>.dispatchReceiverClassOrNull(): ConeClassLikeLookupTag? {
if (this !is FirCallableMemberDeclaration<*>) return null if (this !is FirCallableMemberDeclaration<*>) return null
if (dispatchReceiverType is ConeIntersectionType && isIntersectionOverride) return symbol.overriddenSymbol!!.fir.dispatchReceiverClassOrNull() if (dispatchReceiverType is ConeIntersectionType && isIntersectionOverride) return symbol.baseForIntersectionOverride!!.fir.dispatchReceiverClassOrNull()
return (dispatchReceiverType as? ConeClassLikeType)?.lookupTag return (dispatchReceiverType as? ConeClassLikeType)?.lookupTag
} }
@@ -32,3 +32,32 @@ var FirCallableDeclaration<*>.containingClassAttr: ConeClassLikeLookupTag? by Fi
val FirCallableDeclaration<*>.isIntersectionOverride get() = origin == FirDeclarationOrigin.IntersectionOverride val FirCallableDeclaration<*>.isIntersectionOverride get() = origin == FirDeclarationOrigin.IntersectionOverride
val FirCallableDeclaration<*>.isSubstitutionOverride get() = origin == FirDeclarationOrigin.SubstitutionOverride val FirCallableDeclaration<*>.isSubstitutionOverride get() = origin == FirDeclarationOrigin.SubstitutionOverride
inline val <reified D : FirCallableDeclaration<*>> D.originalForSubstitutionOverride: D?
get() = if (isSubstitutionOverride) symbol.overriddenSymbol?.fir as D? else null
inline val <reified S : FirCallableSymbol<*>> S.originalForSubstitutionOverride: S?
get() = fir.originalForSubstitutionOverride?.symbol as S?
inline val <reified D : FirCallableDeclaration<*>> D.baseForIntersectionOverride: D?
get() = if (isIntersectionOverride) symbol.overriddenSymbol?.fir as D? else null
inline val <reified S : FirCallableSymbol<*>> S.baseForIntersectionOverride: S?
get() = fir.baseForIntersectionOverride?.symbol as S?
inline fun <reified D : FirCallableDeclaration<*>> D.originalIfFakeOverride(): D? =
originalForSubstitutionOverride ?: baseForIntersectionOverride
inline fun <reified S : FirCallableSymbol<*>> S.originalIfFakeOverride(): S? =
fir.originalIfFakeOverride()?.symbol as S?
inline fun <reified D : FirCallableDeclaration<*>> D.unwrapFakeOverrides(): D {
var current = this
do {
val next = current.originalIfFakeOverride() ?: return current
current = next
} while (true)
}
inline fun <reified S : FirCallableSymbol<*>> S.unwrapFakeOverrides(): S = fir.unwrapFakeOverrides().symbol as S
@@ -1008,7 +1008,7 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM
} }
private fun AbstractFirBasedSymbol<*>.unwrapIntersectionOverrides(): AbstractFirBasedSymbol<*> { private fun AbstractFirBasedSymbol<*>.unwrapIntersectionOverrides(): AbstractFirBasedSymbol<*> {
if (this is FirCallableSymbol<*> && fir.isIntersectionOverride) return overriddenSymbol!!.unwrapIntersectionOverrides() (this as? FirCallableSymbol<*>)?.baseForIntersectionOverride?.let { return it.unwrapIntersectionOverrides() }
return this return this
} }
@@ -27,12 +27,3 @@ val FirCallableSymbol<*>.isExtension: Boolean
is FirProperty -> fir.receiverTypeRef != null is FirProperty -> fir.receiverTypeRef != null
else -> false else -> false
} }
inline fun <reified E : FirCallableSymbol<*>> E.unwrapSubstitutionOverrides(): E {
var current = this
while (current.overriddenSymbol != null) {
current = current.overriddenSymbol as E
}
return current
}
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.ThreadSafeMutableState
import org.jetbrains.kotlin.fir.builder.RawFirBuilder import org.jetbrains.kotlin.fir.builder.RawFirBuilder
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.originalForSubstitutionOverride
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirProviderInternals import org.jetbrains.kotlin.fir.resolve.providers.FirProviderInternals
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
@@ -79,7 +80,7 @@ internal class FirIdeProvider(
override fun getFirCallableContainerFile(symbol: FirCallableSymbol<*>): FirFile? { override fun getFirCallableContainerFile(symbol: FirCallableSymbol<*>): FirFile? {
symbol.overriddenSymbol?.let { symbol.fir.originalForSubstitutionOverride?.symbol?.let {
return getFirCallableContainerFile(it) return getFirCallableContainerFile(it)
} }
if (symbol is FirAccessorSymbol) { if (symbol is FirAccessorSymbol) {
@@ -8,11 +8,8 @@ package org.jetbrains.kotlin.idea.fir
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSession import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSession
import org.jetbrains.kotlin.idea.stubindex.KotlinFullClassNameIndex import org.jetbrains.kotlin.idea.stubindex.KotlinFullClassNameIndex
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelFunctionFqnNameIndex import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelFunctionFqnNameIndex
@@ -53,7 +50,7 @@ object FirIdeDeserializedDeclarationSourceProvider {
.orEmpty() .orEmpty()
} }
return function.unrollFakeOverrides().chooseCorrespondingPsi(candidates) return function.unwrapFakeOverrides().chooseCorrespondingPsi(candidates)
} }
private fun provideSourceForProperty(property: FirProperty, project: Project): PsiElement? { private fun provideSourceForProperty(property: FirProperty, project: Project): PsiElement? {
@@ -91,7 +88,7 @@ object FirIdeDeserializedDeclarationSourceProvider {
val containingKtClass = constructor.containingKtClass(project) ?: return null val containingKtClass = constructor.containingKtClass(project) ?: return null
if (constructor.isPrimary) return containingKtClass.primaryConstructor if (constructor.isPrimary) return containingKtClass.primaryConstructor
return constructor.unrollFakeOverrides().chooseCorrespondingPsi(containingKtClass.secondaryConstructors) return constructor.unwrapFakeOverrides().chooseCorrespondingPsi(containingKtClass.secondaryConstructors)
} }
private fun FirFunction<*>.chooseCorrespondingPsi( private fun FirFunction<*>.chooseCorrespondingPsi(
@@ -117,7 +114,7 @@ object FirIdeDeserializedDeclarationSourceProvider {
} }
private fun FirCallableDeclaration<*>.containingKtClass(project: Project): KtClassOrObject? = private fun FirCallableDeclaration<*>.containingKtClass(project: Project): KtClassOrObject? =
unrollFakeOverrides().containingClass()?.classId?.let { classByClassId(it, scope(project), project) } unwrapFakeOverrides().containingClass()?.classId?.let { classByClassId(it, scope(project), project) }
private fun classByClassId(classId: ClassId, scope: GlobalSearchScope, project: Project): KtClassOrObject? { private fun classByClassId(classId: ClassId, scope: GlobalSearchScope, project: Project): KtClassOrObject? {
val fqName = classId.asStringForUsingInIndexes().let { classIdMapping[it] ?: it } val fqName = classId.asStringForUsingInIndexes().let { classIdMapping[it] ?: it }
@@ -5,17 +5,12 @@
package org.jetbrains.kotlin.idea.fir package org.jetbrains.kotlin.idea.fir
import org.jetbrains.kotlin.fir.FirSymbolOwner
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.isIntersectionOverride
import org.jetbrains.kotlin.fir.isSubstitutionOverride
import org.jetbrains.kotlin.fir.references.FirReference import org.jetbrains.kotlin.fir.references.FirReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.PossiblyFirFakeOverrideSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
@@ -38,20 +33,3 @@ internal fun FirReference.getResolvedKtSymbolOfNameReference(builder: KtSymbolBy
(getResolvedSymbolOfNameReference()?.fir as? FirDeclaration)?.let { firDeclaration -> (getResolvedSymbolOfNameReference()?.fir as? FirDeclaration)?.let { firDeclaration ->
builder.buildSymbol(firDeclaration) builder.buildSymbol(firDeclaration)
} }
internal inline fun <reified D> D.unrollFakeOverrides(): D where D : FirDeclaration, D : FirSymbolOwner<*> {
val symbol = symbol
if (symbol !is PossiblyFirFakeOverrideSymbol<*, *>) return this
if (!symbol.isFakeOrIntersectionOverride) return this
var current: FirBasedSymbol<*>? = symbol.overriddenSymbol
while (current is PossiblyFirFakeOverrideSymbol<*, *> && current.isFakeOrIntersectionOverride) {
current = current.overriddenSymbol
}
return current?.fir as D
}
private inline val FirBasedSymbol<*>.isFakeOrIntersectionOverride: Boolean
get() {
val declaration = fir as? FirCallableDeclaration<*> ?: return false
return declaration.isSubstitutionOverride || declaration.isIntersectionOverride
}
@@ -5,11 +5,12 @@
package org.jetbrains.kotlin.idea.frontend.api.fir.symbols package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.originalIfFakeOverride
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.FirRefWithValidityCheck import org.jetbrains.kotlin.idea.frontend.api.fir.utils.FirRefWithValidityCheck
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.overriddenDeclaration
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolOrigin import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolOrigin
@@ -27,10 +28,11 @@ private tailrec fun FirDeclaration.ktSymbolOrigin(): KtSymbolOrigin = when (orig
FirDeclarationOrigin.SamConstructor -> KtSymbolOrigin.SAM_CONSTRUCTOR FirDeclarationOrigin.SamConstructor -> KtSymbolOrigin.SAM_CONSTRUCTOR
FirDeclarationOrigin.Enhancement -> KtSymbolOrigin.JAVA FirDeclarationOrigin.Enhancement -> KtSymbolOrigin.JAVA
else -> { else -> {
val overridden = overriddenDeclaration ?: throw InvalidFirDeclarationOriginForSymbol(origin) val overridden =
(this as? FirCallableDeclaration<*>)?.originalIfFakeOverride() ?: throw InvalidFirDeclarationOriginForSymbol(origin)
overridden.ktSymbolOrigin() overridden.ktSymbolOrigin()
} }
} }
class InvalidFirDeclarationOriginForSymbol(origin: FirDeclarationOrigin) : class InvalidFirDeclarationOriginForSymbol(origin: FirDeclarationOrigin) :
IllegalStateException("Invalid FirDeclarationOrigin $origin") IllegalStateException("Invalid FirDeclarationOrigin $origin")
@@ -1,15 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.frontend.api.fir.utils
import org.jetbrains.kotlin.fir.FirSymbolOwner
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
internal inline val FirDeclaration.overriddenDeclaration: FirDeclaration?
get() {
val symbol = (this as? FirSymbolOwner<*>)?.symbol ?: return null
return (symbol as? FirCallableSymbol)?.overriddenSymbol?.fir as? FirDeclaration
}