[FIR] Fix all illegal usages of declarationSiteSession in compiler

There are still some usages in IDE which should be investigated
This commit is contained in:
Dmitriy Novozhilov
2021-04-21 13:26:40 +03:00
committed by TeamCityServer
parent f98f41bbc3
commit 234ab3b35d
53 changed files with 191 additions and 204 deletions
@@ -44,6 +44,7 @@ import kotlin.contracts.contract
object FirCallsEffectAnalyzer : FirControlFlowChecker() { object FirCallsEffectAnalyzer : FirControlFlowChecker() {
override fun analyze(graph: ControlFlowGraph, reporter: DiagnosticReporter, context: CheckerContext) { override fun analyze(graph: ControlFlowGraph, reporter: DiagnosticReporter, context: CheckerContext) {
val session = context.session
val function = (graph.declaration as? FirFunction<*>) ?: return val function = (graph.declaration as? FirFunction<*>) ?: return
if (function !is FirContractDescriptionOwner) return if (function !is FirContractDescriptionOwner) return
if (function.contractDescription.coneEffects?.any { it is ConeCallsEffectDeclaration } != true) return if (function.contractDescription.coneEffects?.any { it is ConeCallsEffectDeclaration } != true) return
@@ -51,13 +52,13 @@ object FirCallsEffectAnalyzer : FirControlFlowChecker() {
val functionalTypeEffects = mutableMapOf<AbstractFirBasedSymbol<*>, ConeCallsEffectDeclaration>() val functionalTypeEffects = mutableMapOf<AbstractFirBasedSymbol<*>, ConeCallsEffectDeclaration>()
function.valueParameters.forEachIndexed { index, parameter -> function.valueParameters.forEachIndexed { index, parameter ->
if (parameter.returnTypeRef.isFunctionalTypeRef(function.declarationSiteSession)) { if (parameter.returnTypeRef.isFunctionalTypeRef(session)) {
val effectDeclaration = function.contractDescription.getParameterCallsEffectDeclaration(index) val effectDeclaration = function.contractDescription.getParameterCallsEffectDeclaration(index)
if (effectDeclaration != null) functionalTypeEffects[parameter.symbol] = effectDeclaration if (effectDeclaration != null) functionalTypeEffects[parameter.symbol] = effectDeclaration
} }
} }
if (function.receiverTypeRef.isFunctionalTypeRef(function.declarationSiteSession)) { if (function.receiverTypeRef.isFunctionalTypeRef(session)) {
val effectDeclaration = function.contractDescription.getParameterCallsEffectDeclaration(-1) val effectDeclaration = function.contractDescription.getParameterCallsEffectDeclaration(-1)
if (effectDeclaration != null) functionalTypeEffects[function.symbol] = effectDeclaration if (effectDeclaration != null) functionalTypeEffects[function.symbol] = effectDeclaration
} }
@@ -33,8 +33,6 @@ import org.jetbrains.kotlin.fir.types.intersectTypesOrNull
import org.jetbrains.kotlin.fir.types.isNullable import org.jetbrains.kotlin.fir.types.isNullable
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.ConstantValueKind import org.jetbrains.kotlin.types.ConstantValueKind
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.TypeCheckerProviderContext
import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addIfNotNull
object FirReturnsImpliesAnalyzer : FirControlFlowChecker() { object FirReturnsImpliesAnalyzer : FirControlFlowChecker() {
@@ -50,7 +48,7 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() {
if (effects.isNullOrEmpty()) return if (effects.isNullOrEmpty()) return
val logicSystem = object : PersistentLogicSystem(function.declarationSiteSession.typeContext) { val logicSystem = object : PersistentLogicSystem(context.session.typeContext) {
override fun processUpdatedReceiverVariable(flow: PersistentFlow, variable: RealVariable) = override fun processUpdatedReceiverVariable(flow: PersistentFlow, variable: RealVariable) =
throw IllegalStateException("Receiver variable update is not possible for this logic system") throw IllegalStateException("Receiver variable update is not possible for this logic system")
@@ -84,8 +82,8 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() {
context: CheckerContext context: CheckerContext
): Boolean { ): Boolean {
val effect = effectDeclaration.effect as ConeReturnsEffectDeclaration val effect = effectDeclaration.effect as ConeReturnsEffectDeclaration
val builtinTypes = function.declarationSiteSession.builtinTypes val builtinTypes = context.session.builtinTypes
val typeContext = function.declarationSiteSession.typeContext val typeContext = context.session.typeContext
val flow = dataFlowInfo.flowOnNodes.getValue(node) as PersistentFlow val flow = dataFlowInfo.flowOnNodes.getValue(node) as PersistentFlow
val isReturn = node is JumpNode && node.fir is FirReturnExpression val isReturn = node is JumpNode && node.fir is FirReturnExpression
@@ -104,7 +102,7 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() {
if (effect.value != ConeConstantReference.WILDCARD) { if (effect.value != ConeConstantReference.WILDCARD) {
val operation = effect.value.toOperation() val operation = effect.value.toOperation()
if (expressionType != null && expressionType.isInapplicableWith(operation, function.declarationSiteSession)) return false if (expressionType != null && expressionType.isInapplicableWith(operation, context.session)) return false
if (resultExpression is FirConstExpression<*>) { if (resultExpression is FirConstExpression<*>) {
if (!resultExpression.isApplicableWith(operation)) return false if (!resultExpression.isApplicableWith(operation)) return false
@@ -179,7 +177,7 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() {
is ConeIsNullPredicate -> { is ConeIsNullPredicate -> {
val fir = function.getParameterSymbol(arg.parameterIndex, context).fir val fir = function.getParameterSymbol(arg.parameterIndex, context).fir
val realVar = variableStorage.getOrCreateRealVariable(flow, fir.symbol, fir) val realVar = variableStorage.getOrCreateRealVariable(flow, fir.symbol, fir)
realVar?.to(simpleTypeStatement(realVar, isNegated, function.declarationSiteSession.builtinTypes.anyType.type))?.let { mutableMapOf(it) } realVar?.to(simpleTypeStatement(realVar, isNegated, context.session.builtinTypes.anyType.type))?.let { mutableMapOf(it) }
} }
is ConeLogicalNot -> arg.buildTypeStatements(function, logicSystem, variableStorage, flow, context) is ConeLogicalNot -> arg.buildTypeStatements(function, logicSystem, variableStorage, flow, context)
?.mapValuesTo(mutableMapOf()) { (_, value) -> value.invert() } ?.mapValuesTo(mutableMapOf()) { (_, value) -> value.invert() }
@@ -53,51 +53,17 @@ private val INLINE_ONLY_ANNOTATION_CLASS_ID = ClassId.topLevel(FqName("kotlin.in
internal fun FirClass<*>.unsubstitutedScope(context: CheckerContext) = internal fun FirClass<*>.unsubstitutedScope(context: CheckerContext) =
this.unsubstitutedScope(context.sessionHolder.session, context.sessionHolder.scopeSession, withForcedTypeCalculator = false) this.unsubstitutedScope(context.sessionHolder.session, context.sessionHolder.scopeSession, withForcedTypeCalculator = false)
/**
* Returns true if this is a superclass of other.
*/
fun FirClass<*>.isSuperclassOf(other: FirClass<*>): Boolean {
/**
* Hides additional parameters.
*/
fun FirClass<*>.isSuperclassOf(other: FirClass<*>, exclude: MutableSet<FirClass<*>>): Boolean {
for (it in other.superTypeRefs) {
val that = it.firClassLike(declarationSiteSession)
?.followAllAlias(declarationSiteSession)
?.safeAs<FirClass<*>>()
?: continue
if (that in exclude) {
continue
}
if (that.classKind == ClassKind.CLASS) {
if (that == this) {
return true
}
exclude.add(that)
return this.isSuperclassOf(that, exclude)
}
}
return false
}
return isSuperclassOf(other, mutableSetOf())
}
/** /**
* Returns true if this is a supertype of other. * Returns true if this is a supertype of other.
*/ */
fun FirClass<*>.isSupertypeOf(other: FirClass<*>): Boolean { fun FirClass<*>.isSupertypeOf(other: FirClass<*>, session: FirSession): Boolean {
/** /**
* Hides additional parameters. * Hides additional parameters.
*/ */
fun FirClass<*>.isSupertypeOf(other: FirClass<*>, exclude: MutableSet<FirClass<*>>): Boolean { fun FirClass<*>.isSupertypeOf(other: FirClass<*>, exclude: MutableSet<FirClass<*>>): Boolean {
for (it in other.superTypeRefs) { for (it in other.superTypeRefs) {
val candidate = it.firClassLike(declarationSiteSession) val candidate = it.firClassLike(session)
?.followAllAlias(declarationSiteSession) ?.followAllAlias(session)
?.safeAs<FirClass<*>>() ?.safeAs<FirClass<*>>()
?: continue ?: continue
@@ -44,7 +44,7 @@ object FirExposedVisibilityDeclarationChecker : FirMemberDeclarationChecker() {
val isInterface = declaration.classKind == ClassKind.INTERFACE val isInterface = declaration.classKind == ClassKind.INTERFACE
for (supertypeRef in supertypes) { for (supertypeRef in supertypes) {
val supertype = supertypeRef.coneTypeSafe<ConeClassLikeType>() ?: continue val supertype = supertypeRef.coneTypeSafe<ConeClassLikeType>() ?: continue
val clazz = supertype.toRegularClass(declaration.declarationSiteSession) ?: continue val clazz = supertype.toRegularClass(context.session) ?: continue
val superIsInterface = clazz.classKind == ClassKind.INTERFACE val superIsInterface = clazz.classKind == ClassKind.INTERFACE
if (superIsInterface != isInterface) { if (superIsInterface != isInterface) {
continue continue
@@ -50,7 +50,7 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
} }
} }
if (declaration.isSubtypeOfCloneable()) { if (declaration.isSubtypeOfCloneable(context.session)) {
reporter.reportOn(declaration.source, FirErrors.VALUE_CLASS_CANNOT_BE_CLONEABLE, context) reporter.reportOn(declaration.source, FirErrors.VALUE_CLASS_CANNOT_BE_CLONEABLE, context)
} }
@@ -210,7 +210,7 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
?.isRecursiveInlineClassType(visited, session) == true ?.isRecursiveInlineClassType(visited, session) == true
} }
private fun FirRegularClass.isSubtypeOfCloneable(): Boolean { private fun FirRegularClass.isSubtypeOfCloneable(session: FirSession): Boolean {
if (classId.isCloneableId()) return true if (classId.isCloneableId()) return true
return lookupSuperTypes(this, lookupInterfaces = true, deep = true, session).any { superType -> return lookupSuperTypes(this, lookupInterfaces = true, deep = true, session).any { superType ->
@@ -59,6 +59,7 @@ object FirOverrideChecker : FirClassChecker() {
private fun ConeKotlinType.substituteAllTypeParameters( private fun ConeKotlinType.substituteAllTypeParameters(
overrideDeclaration: FirCallableMemberDeclaration<*>, overrideDeclaration: FirCallableMemberDeclaration<*>,
baseDeclaration: FirCallableDeclaration<*>, baseDeclaration: FirCallableDeclaration<*>,
context: CheckerContext
): ConeKotlinType { ): ConeKotlinType {
if (overrideDeclaration.typeParameters.isEmpty()) { if (overrideDeclaration.typeParameters.isEmpty()) {
return this return this
@@ -77,7 +78,7 @@ object FirOverrideChecker : FirClassChecker() {
map[from.symbol] = to.toConeType() map[from.symbol] = to.toConeType()
} }
return substitutorByMap(map).substituteOrSelf(this) return substitutorByMap(map, context.session).substituteOrSelf(this)
} }
private fun checkModality( private fun checkModality(
@@ -144,7 +145,7 @@ object FirOverrideChecker : FirClassChecker() {
for (it in bounds.indices) { for (it in bounds.indices) {
val overriddenDeclaration = overriddenSymbols[it].fir val overriddenDeclaration = overriddenSymbols[it].fir
val overriddenReturnType = bounds[it].substituteAllTypeParameters(this, overriddenDeclaration) val overriddenReturnType = bounds[it].substituteAllTypeParameters(this, overriddenDeclaration, context)
val isReturnTypeOkForOverride = val isReturnTypeOkForOverride =
if (overriddenDeclaration is FirProperty && overriddenDeclaration.isVar) if (overriddenDeclaration is FirProperty && overriddenDeclaration.isVar)
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
import org.jetbrains.kotlin.fir.expressions.FirGetClassCall import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.containingClass import org.jetbrains.kotlin.fir.resolve.getContainingClass
import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol
object FirCallableReferenceChecker : FirQualifiedAccessChecker() { object FirCallableReferenceChecker : FirQualifiedAccessChecker() {
@@ -43,7 +43,7 @@ object FirCallableReferenceChecker : FirQualifiedAccessChecker() {
if (source.kind is FirFakeSourceElementKind) return if (source.kind is FirFakeSourceElementKind) return
val referredDeclaration = reference.resolvedSymbol.fir val referredDeclaration = reference.resolvedSymbol.fir
if (referredDeclaration is FirConstructor && referredDeclaration.containingClass?.classKind == ClassKind.ANNOTATION_CLASS) { if (referredDeclaration is FirConstructor && referredDeclaration.getContainingClass(context.session)?.classKind == ClassKind.ANNOTATION_CLASS) {
reporter.reportOn(source, FirErrors.CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR, context) reporter.reportOn(source, FirErrors.CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR, context)
} }
if ((referredDeclaration as? FirCallableMemberDeclaration<*>)?.isExtensionMember == true && if ((referredDeclaration as? FirCallableMemberDeclaration<*>)?.isExtensionMember == true &&
@@ -28,7 +28,7 @@ object FirNotASupertypeChecker : FirQualifiedAccessChecker() {
?: return ?: return
val surrounding = context.findClosestClass(superReference.labelName) ?: return val surrounding = context.findClosestClass(superReference.labelName) ?: return
if (!targetClass.isSupertypeOf(surrounding)) { if (!targetClass.isSupertypeOf(surrounding, context.session)) {
reporter.reportOn(expression.source, FirErrors.NOT_A_SUPERTYPE, context) reporter.reportOn(expression.source, FirErrors.NOT_A_SUPERTYPE, context)
} }
} }
@@ -44,7 +44,7 @@ object FirQualifiedSupertypeExtendedByOtherSupertypeChecker : FirQualifiedAccess
?.followAllAlias(context.session).safeAs<FirClass<*>>() ?.followAllAlias(context.session).safeAs<FirClass<*>>()
?: continue ?: continue
val isSupertype = explicitType.isSupertypeOf(that) val isSupertype = explicitType.isSupertypeOf(that, context.session)
if (explicitType == that || isSupertype) { if (explicitType == that || isSupertype) {
if (isSupertype) { if (isSupertype) {
@@ -59,7 +59,8 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
// we substitute actual values to the // we substitute actual values to the
// type parameters from the declaration // type parameters from the declaration
val substitutor = substitutorByMap( val substitutor = substitutorByMap(
parameterPairs.mapValues { it.value.coneType } parameterPairs.mapValues { it.value.coneType },
context.session
) )
parameterPairs.forEach { (proto, actual) -> parameterPairs.forEach { (proto, actual) ->
@@ -147,7 +148,8 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
// parameters to the ones used in the // parameters to the ones used in the
// typealias target // typealias target
val declarationSiteSubstitutor = substitutorByMap( val declarationSiteSubstitutor = substitutorByMap(
constructorsParameterPairs.toMap().mapValues { it.value.type } constructorsParameterPairs.toMap().mapValues { it.value.type },
context.session
) )
constructorsParameterPairs.forEach { (proto, actual) -> constructorsParameterPairs.forEach { (proto, actual) ->
@@ -209,7 +211,8 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
} }
val substitutor = substitutorByMap( val substitutor = substitutorByMap(
parameterPairs.toMap().mapValues { it.value.type } parameterPairs.toMap().mapValues { it.value.type },
context.session
) )
parameterPairs.forEach { (proto, actual) -> parameterPairs.forEach { (proto, actual) ->
@@ -40,7 +40,7 @@ fun FirSession.registerCommonComponents(languageVersionSettings: LanguageVersion
register(FirLanguageSettingsComponent::class, FirLanguageSettingsComponent(languageVersionSettings)) register(FirLanguageSettingsComponent::class, FirLanguageSettingsComponent(languageVersionSettings))
register(InferenceComponents::class, InferenceComponents(this)) register(InferenceComponents::class, InferenceComponents(this))
register(FirDeclaredMemberScopeProvider::class, FirDeclaredMemberScopeProvider()) register(FirDeclaredMemberScopeProvider::class, FirDeclaredMemberScopeProvider(this))
register(FirCorrespondingSupertypesCache::class, FirCorrespondingSupertypesCache(this)) register(FirCorrespondingSupertypesCache::class, FirCorrespondingSupertypesCache(this))
register(FirDefaultParametersResolver::class, FirDefaultParametersResolver()) register(FirDefaultParametersResolver::class, FirDefaultParametersResolver())
@@ -200,7 +200,7 @@ class FirElementSerializer private constructor(
@OptIn(ExperimentalStdlibApi::class) @OptIn(ExperimentalStdlibApi::class)
private fun FirClass<*>.declarations(): List<FirCallableMemberDeclaration<*>> = buildList { private fun FirClass<*>.declarations(): List<FirCallableMemberDeclaration<*>> = buildList {
val memberScope = val memberScope =
defaultType().scope(declarationSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing) defaultType().scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing)
?: error("Null scope for $this") ?: error("Null scope for $this")
fun addDeclarationIfNeeded(symbol: FirCallableSymbol<*>) { fun addDeclarationIfNeeded(symbol: FirCallableSymbol<*>) {
@@ -938,6 +938,7 @@ class FirElementSerializer private constructor(
@JvmStatic @JvmStatic
fun create( fun create(
session: FirSession,
scopeSession: ScopeSession, scopeSession: ScopeSession,
klass: FirClass<*>, klass: FirClass<*>,
extension: FirSerializerExtension, extension: FirSerializerExtension,
@@ -946,17 +947,17 @@ class FirElementSerializer private constructor(
): FirElementSerializer { ): FirElementSerializer {
val parentClassId = klass.symbol.classId.outerClassId val parentClassId = klass.symbol.classId.outerClassId
val parent = if (parentClassId != null && !parentClassId.isLocal) { val parent = if (parentClassId != null && !parentClassId.isLocal) {
val parentClass = klass.declarationSiteSession.symbolProvider.getClassLikeSymbolByFqName(parentClassId)!!.fir as FirRegularClass val parentClass = session.symbolProvider.getClassLikeSymbolByFqName(parentClassId)!!.fir as FirRegularClass
parentSerializer ?: create(scopeSession, parentClass, extension, null, typeApproximator) parentSerializer ?: create(session, scopeSession, parentClass, extension, null, typeApproximator)
} else { } else {
createTopLevel(klass.declarationSiteSession, scopeSession, extension, typeApproximator) createTopLevel(session, scopeSession, extension, typeApproximator)
} }
// Calculate type parameter ids for the outer class beforehand, as it would've had happened if we were always // Calculate type parameter ids for the outer class beforehand, as it would've had happened if we were always
// serializing outer classes before nested classes. // serializing outer classes before nested classes.
// Otherwise our interner can get wrong ids because we may serialize classes in any order. // Otherwise our interner can get wrong ids because we may serialize classes in any order.
val serializer = FirElementSerializer( val serializer = FirElementSerializer(
klass.declarationSiteSession, session,
scopeSession, scopeSession,
klass, klass,
Interner(parent.typeParameters), Interner(parent.typeParameters),
@@ -210,8 +210,8 @@ class FirJvmSerializerExtension(
private fun FirFunction<*>.needsInlineParameterNullCheckRequirement(): Boolean = private fun FirFunction<*>.needsInlineParameterNullCheckRequirement(): Boolean =
this is FirSimpleFunction && isInline && !isSuspend && !isParamAssertionsDisabled && this is FirSimpleFunction && isInline && !isSuspend && !isParamAssertionsDisabled &&
!Visibilities.isPrivate(visibility) && !Visibilities.isPrivate(visibility) &&
(valueParameters.any { it.returnTypeRef.coneType.isBuiltinFunctionalType(declarationSiteSession) } || (valueParameters.any { it.returnTypeRef.coneType.isBuiltinFunctionalType(session) } ||
receiverTypeRef?.coneType?.isBuiltinFunctionalType(declarationSiteSession) == true) receiverTypeRef?.coneType?.isBuiltinFunctionalType(session) == true)
override fun serializeProperty( override fun serializeProperty(
property: FirProperty, property: FirProperty,
@@ -256,7 +256,7 @@ class FirJvmSerializerExtension(
val container = val container =
dispatchReceiverType?.classId?.let { dispatchReceiverType?.classId?.let {
declarationSiteSession.firProvider.getFirClassifierByFqName(it) as? FirRegularClass session.firProvider.getFirClassifierByFqName(it) as? FirRegularClass
} }
if (container == null || !container.isCompanion) { if (container == null || !container.isCompanion) {
return false return false
@@ -264,7 +264,7 @@ class FirJvmSerializerExtension(
val grandParent = val grandParent =
container.classId.outerClassId?.let { container.classId.outerClassId?.let {
declarationSiteSession.firProvider.getFirClassifierByFqName(it) as? FirRegularClass session.firProvider.getFirClassifierByFqName(it) as? FirRegularClass
} }
return grandParent != null && return grandParent != null &&
(grandParent.classKind == ClassKind.INTERFACE || grandParent.classKind == ClassKind.ANNOTATION_CLASS) (grandParent.classKind == ClassKind.INTERFACE || grandParent.classKind == ClassKind.ANNOTATION_CLASS)
@@ -155,17 +155,18 @@ class FirMetadataSerializer(
private val serializer: FirElementSerializer? = private val serializer: FirElementSerializer? =
when (val metadata = irClass.metadata) { when (val metadata = irClass.metadata) {
is FirMetadataSource.Class -> FirElementSerializer.create( is FirMetadataSource.Class -> FirElementSerializer.create(
components.session,
components.scopeSession, components.scopeSession,
metadata.fir, serializerExtension, (parent as? FirMetadataSerializer)?.serializer, approximator metadata.fir, serializerExtension, (parent as? FirMetadataSerializer)?.serializer, approximator
) )
is FirMetadataSource.File -> FirElementSerializer.createTopLevel( is FirMetadataSource.File -> FirElementSerializer.createTopLevel(
metadata.session, components.session,
components.scopeSession, components.scopeSession,
serializerExtension, serializerExtension,
approximator approximator
) )
is FirMetadataSource.Function -> FirElementSerializer.createForLambda( is FirMetadataSource.Function -> FirElementSerializer.createForLambda(
metadata.session, components.session,
components.scopeSession, components.scopeSession,
serializerExtension, serializerExtension,
approximator approximator
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.name.Name
sealed class FirMetadataSource : MetadataSource { sealed class FirMetadataSource : MetadataSource {
abstract val fir: FirDeclaration abstract val fir: FirDeclaration
val session: FirSession val declarationSiteSession: FirSession
get() = fir.declarationSiteSession get() = fir.declarationSiteSession
override val name: Name? override val name: Name?
@@ -470,7 +470,7 @@ class CallAndReferenceGenerator(
val type = typeProjection.typeRef.coneTypeSafe<ConeKotlinType>() ?: continue val type = typeProjection.typeRef.coneTypeSafe<ConeKotlinType>() ?: continue
map[typeParameter.symbol] = type map[typeParameter.symbol] = type
} }
return ConeSubstitutorByMap(map) return ConeSubstitutorByMap(map, session)
} }
internal fun IrExpression.applyCallArguments(call: FirCall?, annotationMode: Boolean): IrExpression { internal fun IrExpression.applyCallArguments(call: FirCall?, annotationMode: Boolean): IrExpression {
@@ -63,12 +63,12 @@ class JavaScopeProvider(
} }
} }
private fun buildDeclaredMemberScope(regularClass: FirRegularClass): FirScope { private fun buildDeclaredMemberScope(useSiteSession: FirSession, regularClass: FirRegularClass): FirScope {
return if (regularClass is FirJavaClass) declaredMemberScopeWithLazyNestedScope( return if (regularClass is FirJavaClass) useSiteSession.declaredMemberScopeWithLazyNestedScope(
regularClass, regularClass,
existingNames = regularClass.existingNestedClassifierNames, existingNames = regularClass.existingNestedClassifierNames,
symbolProvider = symbolProvider symbolProvider = symbolProvider
) else declaredMemberScope(regularClass) ) else useSiteSession.declaredMemberScope(regularClass)
} }
private fun buildUseSiteMemberScopeWithJavaTypes( private fun buildUseSiteMemberScopeWithJavaTypes(
@@ -77,7 +77,7 @@ class JavaScopeProvider(
scopeSession: ScopeSession, scopeSession: ScopeSession,
): JavaClassUseSiteMemberScope { ): JavaClassUseSiteMemberScope {
return scopeSession.getOrBuild(regularClass.symbol, JAVA_USE_SITE) { return scopeSession.getOrBuild(regularClass.symbol, JAVA_USE_SITE) {
val declaredScope = buildDeclaredMemberScope(regularClass) val declaredScope = buildDeclaredMemberScope(useSiteSession, regularClass)
val superTypes = val superTypes =
if (regularClass.isThereLoopInSupertypes(useSiteSession)) if (regularClass.isThereLoopInSupertypes(useSiteSession))
listOf(StandardClassIds.Any.toConeKotlinType(emptyArray(), isNullable = false)) listOf(StandardClassIds.Any.toConeKotlinType(emptyArray(), isNullable = false))
@@ -122,14 +122,14 @@ class JavaScopeProvider(
if (!visitedClasses.add(klass)) return null if (!visitedClasses.add(klass)) return null
return scopeSession.getOrBuild(klass.symbol, JAVA_ENHANCEMENT_FOR_STATIC) { return scopeSession.getOrBuild(klass.symbol, JAVA_ENHANCEMENT_FOR_STATIC) {
val declaredScope = buildDeclaredMemberScope(klass) val declaredScope = buildDeclaredMemberScope(useSiteSession, klass)
val superClassScope = klass.findJavaSuperClass()?.let { val superClassScope = klass.findJavaSuperClass(useSiteSession)?.let {
(it.scopeProvider as? JavaScopeProvider) (it.scopeProvider as? JavaScopeProvider)
?.getStaticMemberScopeForCallables(it, useSiteSession, scopeSession, visitedClasses) ?.getStaticMemberScopeForCallables(it, useSiteSession, scopeSession, visitedClasses)
} ?: FirTypeScope.Empty } ?: FirTypeScope.Empty
val superTypesScopes = klass.findClosestJavaSuperTypes().mapNotNull { val superTypesScopes = klass.findClosestJavaSuperTypes(useSiteSession).mapNotNull {
(it.scopeProvider as? JavaScopeProvider) (it.scopeProvider as? JavaScopeProvider)
?.getStaticMemberScopeForCallables(it, useSiteSession, scopeSession, visitedClasses) ?.getStaticMemberScopeForCallables(it, useSiteSession, scopeSession, visitedClasses)
} }
@@ -149,24 +149,24 @@ class JavaScopeProvider(
} }
} }
private tailrec fun FirRegularClass.findJavaSuperClass(): FirRegularClass? { private tailrec fun FirRegularClass.findJavaSuperClass(useSiteSession: FirSession): FirRegularClass? {
val superClass = superConeTypes.firstNotNullResult { val superClass = superConeTypes.firstNotNullResult {
(it.lookupTag.toSymbol(declarationSiteSession)?.fir as? FirRegularClass)?.takeIf { superClass -> (it.lookupTag.toSymbol(useSiteSession)?.fir as? FirRegularClass)?.takeIf { superClass ->
superClass.classKind == ClassKind.CLASS superClass.classKind == ClassKind.CLASS
} }
} ?: return null } ?: return null
if (superClass.origin is FirDeclarationOrigin.Java) return superClass if (superClass.origin is FirDeclarationOrigin.Java) return superClass
return superClass.findJavaSuperClass() return superClass.findJavaSuperClass(useSiteSession)
} }
private fun FirRegularClass.findClosestJavaSuperTypes(): Collection<FirRegularClass> { private fun FirRegularClass.findClosestJavaSuperTypes(useSiteSession: FirSession): Collection<FirRegularClass> {
val result = mutableListOf<FirRegularClass>() val result = mutableListOf<FirRegularClass>()
DFS.dfs(listOf(this), DFS.dfs(listOf(this),
{ regularClass -> { regularClass ->
regularClass.superConeTypes.mapNotNull { regularClass.superConeTypes.mapNotNull {
it.lookupTag.toSymbol(declarationSiteSession)?.fir as? FirRegularClass it.lookupTag.toSymbol(useSiteSession)?.fir as? FirRegularClass
} }
}, },
object : DFS.AbstractNodeHandler<FirRegularClass, Unit>() { object : DFS.AbstractNodeHandler<FirRegularClass, Unit>() {
@@ -213,7 +213,7 @@ class JavaSymbolProvider(
) { ) {
replaceSuperTypeRefs( replaceSuperTypeRefs(
javaClass.supertypes.map { supertype -> javaClass.supertypes.map { supertype ->
supertype.toFirResolvedTypeRef(declarationSiteSession, javaTypeParameterStack, isForSupertypes = true, forTypeParameterBounds = false) supertype.toFirResolvedTypeRef(session, javaTypeParameterStack, isForSupertypes = true, forTypeParameterBounds = false)
} }
) )
} }
@@ -354,7 +354,7 @@ class JavaSymbolProvider(
valueParametersForAnnotationConstructor.forEach { javaMethod, firValueParameter -> valueParametersForAnnotationConstructor.forEach { javaMethod, firValueParameter ->
javaMethod.annotationParameterDefaultValue?.let { javaDefaultValue -> javaMethod.annotationParameterDefaultValue?.let { javaDefaultValue ->
firValueParameter.defaultValue = firValueParameter.defaultValue =
javaDefaultValue.toFirExpression(declarationSiteSession, javaTypeParameterStack, firValueParameter.returnTypeRef) javaDefaultValue.toFirExpression(session, javaTypeParameterStack, firValueParameter.returnTypeRef)
} }
} }
} }
@@ -402,7 +402,7 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
} else { } else {
val position = if (isLowerBound) TypeComponentPosition.FLEXIBLE_LOWER else TypeComponentPosition.FLEXIBLE_UPPER val position = if (isLowerBound) TypeComponentPosition.FLEXIBLE_LOWER else TypeComponentPosition.FLEXIBLE_UPPER
classSymbol?.fir?.createRawArguments(defaultArgs, position) ?: defaultArgs classSymbol?.fir?.createRawArguments(session, defaultArgs, position) ?: defaultArgs
} }
} else { } else {
val typeParameters = runIf(!forTypeParameterBounds && !isForSupertypes) { classSymbol?.fir?.typeParameters } ?: emptyList() val typeParameters = runIf(!forTypeParameterBounds && !isForSupertypes) { classSymbol?.fir?.typeParameters } ?: emptyList()
@@ -429,13 +429,14 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
} }
private fun FirRegularClass.createRawArguments( private fun FirRegularClass.createRawArguments(
session: FirSession,
defaultArgs: List<ConeStarProjection>, defaultArgs: List<ConeStarProjection>,
position: TypeComponentPosition position: TypeComponentPosition
) = typeParameters.filterIsInstance<FirTypeParameter>().map { typeParameter -> ): List<ConeTypeProjection> = typeParameters.filterIsInstance<FirTypeParameter>().map { typeParameter ->
val erasedUpperBound = typeParameter.getErasedUpperBound { val erasedUpperBound = typeParameter.getErasedUpperBound {
defaultType().withArguments(defaultArgs.toTypedArray()) defaultType().withArguments(defaultArgs.toTypedArray())
} }
computeRawProjection(declarationSiteSession, typeParameter, position, erasedUpperBound) computeRawProjection(session, typeParameter, position, erasedUpperBound)
} }
private fun buildEnumCall(session: FirSession, classId: ClassId?, entryName: Name?) = private fun buildEnumCall(session: FirSession, classId: ClassId?, entryName: Name?) =
@@ -382,13 +382,13 @@ class JavaClassUseSiteMemberScope(
} }
private fun FirFunction<*>.computeJvmSignature(): String? { private fun FirFunction<*>.computeJvmSignature(): String? {
return computeJvmSignature { it.toConeKotlinTypeProbablyFlexible(declarationSiteSession, typeParameterStack) } return computeJvmSignature { it.toConeKotlinTypeProbablyFlexible(session, typeParameterStack) }
} }
private fun FirFunction<*>.computeJvmDescriptor(customName: String? = null, includeReturnType: Boolean = false): String { private fun FirFunction<*>.computeJvmDescriptor(customName: String? = null, includeReturnType: Boolean = false): String {
return computeJvmDescriptor(customName, includeReturnType) { return computeJvmDescriptor(customName, includeReturnType) {
it.toConeKotlinTypeProbablyFlexible( it.toConeKotlinTypeProbablyFlexible(
declarationSiteSession, session,
typeParameterStack typeParameterStack
) )
} }
@@ -134,14 +134,14 @@ class JavaOverrideChecker internal constructor(
override fun buildTypeParametersSubstitutorIfCompatible( override fun buildTypeParametersSubstitutorIfCompatible(
overrideCandidate: FirCallableMemberDeclaration<*>, overrideCandidate: FirCallableMemberDeclaration<*>,
baseDeclaration: FirCallableMemberDeclaration<*> baseDeclaration: FirCallableMemberDeclaration<*>
): ConeSubstitutor? { ): ConeSubstitutor {
if (!overrideCandidate.isTypeParameterDependent() && !baseDeclaration.isTypeParameterDependent()) { if (!overrideCandidate.isTypeParameterDependent() && !baseDeclaration.isTypeParameterDependent()) {
return ConeSubstitutor.Empty return ConeSubstitutor.Empty
} }
val typeParameters = linkedSetOf<FirTypeParameterRef>() val typeParameters = linkedSetOf<FirTypeParameterRef>()
overrideCandidate.extractTypeParametersTo(typeParameters) overrideCandidate.extractTypeParametersTo(typeParameters)
baseDeclaration.extractTypeParametersTo(typeParameters) baseDeclaration.extractTypeParametersTo(typeParameters)
return substitutorByMap(typeParameters.buildErasure()) return substitutorByMap(typeParameters.buildErasure(), session)
} }
override fun isOverriddenFunction(overrideCandidate: FirSimpleFunction, baseDeclaration: FirSimpleFunction): Boolean { override fun isOverriddenFunction(overrideCandidate: FirSimpleFunction, baseDeclaration: FirSimpleFunction): Boolean {
@@ -35,7 +35,8 @@ class JvmMappedScope(
private val substitutor = ConeSubstitutorByMap( private val substitutor = ConeSubstitutorByMap(
firJavaClass.typeParameters.zip(firKotlinClass.typeParameters).map { (javaParameter, kotlinParameter) -> firJavaClass.typeParameters.zip(firKotlinClass.typeParameters).map { (javaParameter, kotlinParameter) ->
javaParameter.symbol to ConeTypeParameterTypeImpl(ConeTypeParameterLookupTag(kotlinParameter.symbol), isNullable = false) javaParameter.symbol to ConeTypeParameterTypeImpl(ConeTypeParameterLookupTag(kotlinParameter.symbol), isNullable = false)
}.toMap() }.toMap(),
session
) )
private val kotlinDispatchReceiverType = firKotlinClass.defaultType() private val kotlinDispatchReceiverType = firKotlinClass.defaultType()
@@ -359,51 +359,49 @@ private fun initialTypeOfCandidate(candidate: Candidate, typeRef: FirResolvedTyp
return candidate.substitutor.substituteOrSelf(typeRef.type) return candidate.substitutor.substituteOrSelf(typeRef.type)
} }
inline val FirCallableDeclaration<*>.containingClass: FirRegularClass? fun FirCallableDeclaration<*>.getContainingClass(session: FirSession): FirRegularClass? = this.containingClassAttr?.let { lookupTag ->
get() = this.containingClassAttr?.let { lookupTag -> session.symbolProvider.getSymbolByLookupTag(lookupTag)?.fir as? FirRegularClass
declarationSiteSession.symbolProvider.getSymbolByLookupTag(lookupTag)?.fir as? FirRegularClass }
}
val FirFunction<*>.asForbiddenNamedArgumentsTarget: ForbiddenNamedArgumentsTarget? fun FirFunction<*>.getAsForbiddenNamedArgumentsTarget(session: FirSession): ForbiddenNamedArgumentsTarget? {
get() { if (this is FirConstructor && this.isPrimary) {
if (this is FirConstructor && this.isPrimary) { this.getContainingClass(session)?.let { containingClass ->
this.containingClass?.let { containingClass -> if (containingClass.classKind == ClassKind.ANNOTATION_CLASS) {
if (containingClass.classKind == ClassKind.ANNOTATION_CLASS) { // Java annotation classes allow (actually require) named parameters.
// Java annotation classes allow (actually require) named parameters. return null
return null
}
} }
} }
if (this is FirMemberDeclaration && status.isExpect) {
return ForbiddenNamedArgumentsTarget.EXPECTED_CLASS_MEMBER
}
return when (origin) {
FirDeclarationOrigin.Source, FirDeclarationOrigin.Library -> null
FirDeclarationOrigin.Delegated -> delegatedWrapperData?.wrapped?.asForbiddenNamedArgumentsTarget
FirDeclarationOrigin.ImportedFromObject -> importedFromObjectData?.original?.asForbiddenNamedArgumentsTarget
// For intersection overrides, the logic in
// org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScope#selectMostSpecificMember picks the most specific one and store
// it in originalForIntersectionOverrideAttr. This follows from FE1.0 behavior which selects the most specific function
// (org.jetbrains.kotlin.resolve.OverridingUtil#selectMostSpecificMember), from which the `hasStableParameterNames` status is
// copied.
FirDeclarationOrigin.IntersectionOverride -> originalForIntersectionOverrideAttr?.asForbiddenNamedArgumentsTarget
FirDeclarationOrigin.Java, FirDeclarationOrigin.Enhancement -> ForbiddenNamedArgumentsTarget.NON_KOTLIN_FUNCTION
FirDeclarationOrigin.SamConstructor -> null
FirDeclarationOrigin.SubstitutionOverride -> originalForSubstitutionOverrideAttr?.asForbiddenNamedArgumentsTarget
// referenced function of a Kotlin function type
FirDeclarationOrigin.BuiltIns -> {
if (dispatchReceiverClassOrNull()?.isBuiltinFunctionalType() == true) {
ForbiddenNamedArgumentsTarget.INVOKE_ON_FUNCTION_TYPE
} else {
null
}
}
FirDeclarationOrigin.Synthetic -> null
is FirDeclarationOrigin.Plugin -> null // TODO: figure out what to do with plugin generated functions
}
} }
if (this is FirMemberDeclaration && status.isExpect) {
return ForbiddenNamedArgumentsTarget.EXPECTED_CLASS_MEMBER
}
return when (origin) {
FirDeclarationOrigin.Source, FirDeclarationOrigin.Library -> null
FirDeclarationOrigin.Delegated -> delegatedWrapperData?.wrapped?.getAsForbiddenNamedArgumentsTarget(session)
FirDeclarationOrigin.ImportedFromObject -> importedFromObjectData?.original?.getAsForbiddenNamedArgumentsTarget(session)
// For intersection overrides, the logic in
// org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScope#selectMostSpecificMember picks the most specific one and store
// it in originalForIntersectionOverrideAttr. This follows from FE1.0 behavior which selects the most specific function
// (org.jetbrains.kotlin.resolve.OverridingUtil#selectMostSpecificMember), from which the `hasStableParameterNames` status is
// copied.
FirDeclarationOrigin.IntersectionOverride -> originalForIntersectionOverrideAttr?.getAsForbiddenNamedArgumentsTarget(session)
FirDeclarationOrigin.Java, FirDeclarationOrigin.Enhancement -> ForbiddenNamedArgumentsTarget.NON_KOTLIN_FUNCTION
FirDeclarationOrigin.SamConstructor -> null
FirDeclarationOrigin.SubstitutionOverride -> originalForSubstitutionOverrideAttr?.getAsForbiddenNamedArgumentsTarget(session)
// referenced function of a Kotlin function type
FirDeclarationOrigin.BuiltIns -> {
if (dispatchReceiverClassOrNull()?.isBuiltinFunctionalType() == true) {
ForbiddenNamedArgumentsTarget.INVOKE_ON_FUNCTION_TYPE
} else {
null
}
}
FirDeclarationOrigin.Synthetic -> null
is FirDeclarationOrigin.Plugin -> null // TODO: figure out what to do with plugin generated functions
}
}
// TODO: handle functions with non-stable parameter names, see also // TODO: handle functions with non-stable parameter names, see also
// org.jetbrains.kotlin.fir.serialization.FirElementSerializer.functionProto // org.jetbrains.kotlin.fir.serialization.FirElementSerializer.functionProto
// org.jetbrains.kotlin.fir.serialization.FirElementSerializer.constructorProto // org.jetbrains.kotlin.fir.serialization.FirElementSerializer.constructorProto
inline val FirFunction<*>.hasStableParameterNames: Boolean get() = asForbiddenNamedArgumentsTarget == null fun FirFunction<*>.getHasStableParameterNames(session: FirSession): Boolean = getAsForbiddenNamedArgumentsTarget(session) == null
@@ -94,6 +94,7 @@ class FirSamResolverImpl(
Pair(parameterSymbol, typeArgument) Pair(parameterSymbol, typeArgument)
} }
.toMap(), .toMap(),
firSession
) )
val result = val result =
@@ -148,6 +149,7 @@ class FirSamResolverImpl(
firRegularClass.typeParameters firRegularClass.typeParameters
.map { it.symbol } .map { it.symbol }
.zip(newTypeParameterTypes).toMap(), .zip(newTypeParameterTypes).toMap(),
firSession
) )
for ((newTypeParameter, oldTypeParameter) in newTypeParameters.zip(firRegularClass.typeParameters)) { for ((newTypeParameter, oldTypeParameter) in newTypeParameters.zip(firRegularClass.typeParameters)) {
@@ -47,7 +47,7 @@ private fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: Scope
val substitution = createSubstitution(fir.typeParameters, fullyExpandedType, useSiteSession) val substitution = createSubstitution(fir.typeParameters, fullyExpandedType, useSiteSession)
fir.scopeForClass(substitutorByMap(substitution), useSiteSession, scopeSession) fir.scopeForClass(substitutorByMap(substitution, useSiteSession), useSiteSession, scopeSession)
} }
is ConeTypeParameterType -> { is ConeTypeParameterType -> {
val symbol = lookupTag.symbol val symbol = lookupTag.symbol
@@ -143,9 +143,9 @@ fun ConeClassLikeType.wrapSubstitutionScopeIfNeed(
// to determine parameter types properly (e.g. String, String instead of K, V) // to determine parameter types properly (e.g. String, String instead of K, V)
val platformTypeParameters = platformClass.typeParameters val platformTypeParameters = platformClass.typeParameters
val platformSubstitution = createSubstitution(platformTypeParameters, this, session) val platformSubstitution = createSubstitution(platformTypeParameters, this, session)
substitutorByMap(originalSubstitution + platformSubstitution) substitutorByMap(originalSubstitution + platformSubstitution, session)
} else { } else {
substitutorByMap(originalSubstitution) substitutorByMap(originalSubstitution, session)
} }
FirClassSubstitutionScope( FirClassSubstitutionScope(
session, useSiteMemberScope, substitutor, session, useSiteMemberScope, substitutor,
@@ -178,6 +178,6 @@ abstract class AbstractConeCallConflictResolver(
} }
private fun createEmptyConstraintSystem(): SimpleConstraintSystem { private fun createEmptyConstraintSystem(): SimpleConstraintSystem {
return ConeSimpleConstraintSystemImpl(inferenceComponents.createConstraintSystem()) return ConeSimpleConstraintSystemImpl(inferenceComponents.createConstraintSystem(), inferenceComponents.session)
} }
} }
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.resolve.calls package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.modality import org.jetbrains.kotlin.fir.declarations.modality
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
@@ -196,7 +197,7 @@ class ConeOverloadConflictResolver(
object NoSubstitutor : TypeSubstitutorMarker object NoSubstitutor : TypeSubstitutorMarker
class ConeSimpleConstraintSystemImpl(val system: NewConstraintSystemImpl) : SimpleConstraintSystem { class ConeSimpleConstraintSystemImpl(val system: NewConstraintSystemImpl, val session: FirSession) : SimpleConstraintSystem {
override fun registerTypeVariables(typeParameters: Collection<TypeParameterMarker>): TypeSubstitutorMarker = with(context) { override fun registerTypeVariables(typeParameters: Collection<TypeParameterMarker>): TypeSubstitutorMarker = with(context) {
val csBuilder = system.getBuilder() val csBuilder = system.getBuilder()
val substitutionMap = typeParameters.associateBy({ (it as ConeTypeParameterLookupTag).typeParameterSymbol }) { val substitutionMap = typeParameters.associateBy({ (it as ConeTypeParameterLookupTag).typeParameterSymbol }) {
@@ -206,7 +207,7 @@ class ConeSimpleConstraintSystemImpl(val system: NewConstraintSystemImpl) : Simp
variable.defaultType variable.defaultType
} }
val substitutor = substitutorByMap(substitutionMap) val substitutor = substitutorByMap(substitutionMap, session)
for (typeParameter in typeParameters) { for (typeParameter in typeParameters) {
require(typeParameter is ConeTypeParameterLookupTag) require(typeParameter is ConeTypeParameterLookupTag)
for (upperBound in typeParameter.symbol.fir.bounds) { for (upperBound in typeParameter.symbol.fir.bounds) {
@@ -156,7 +156,7 @@ private fun prepareSubstitutorForTypeAliasConstructors(
it as? ConeKotlinType ?: return null it as? ConeKotlinType ?: return null
} }
return substitutorByMap( return substitutorByMap(
expandedClass.typeParameters.map { it.symbol }.zip(resultingTypeArguments).toMap() expandedClass.typeParameters.map { it.symbol }.zip(resultingTypeArguments).toMap(), session
) )
} }
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.resolve.calls package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
import org.jetbrains.kotlin.fir.renderWithType import org.jetbrains.kotlin.fir.renderWithType
@@ -31,7 +32,7 @@ internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() {
} }
val csBuilder = candidate.system.getBuilder() val csBuilder = candidate.system.getBuilder()
val (substitutor, freshVariables) = val (substitutor, freshVariables) =
createToFreshVariableSubstitutorAndAddInitialConstraints(declaration, csBuilder) createToFreshVariableSubstitutorAndAddInitialConstraints(declaration, csBuilder, context.session)
candidate.substitutor = substitutor candidate.substitutor = substitutor
candidate.freshVariables = freshVariables candidate.freshVariables = freshVariables
@@ -110,14 +111,15 @@ internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() {
private fun createToFreshVariableSubstitutorAndAddInitialConstraints( private fun createToFreshVariableSubstitutorAndAddInitialConstraints(
declaration: FirTypeParameterRefsOwner, declaration: FirTypeParameterRefsOwner,
csBuilder: ConstraintSystemOperation csBuilder: ConstraintSystemOperation,
session: FirSession
): Pair<ConeSubstitutor, List<ConeTypeVariable>> { ): Pair<ConeSubstitutor, List<ConeTypeVariable>> {
val typeParameters = declaration.typeParameters val typeParameters = declaration.typeParameters
val freshTypeVariables = typeParameters.map { ConeTypeParameterBasedTypeVariable(it.symbol) } val freshTypeVariables = typeParameters.map { ConeTypeParameterBasedTypeVariable(it.symbol) }
val toFreshVariables = substitutorByMap(freshTypeVariables.associate { it.typeParameterSymbol to it.defaultType }) val toFreshVariables = substitutorByMap(freshTypeVariables.associate { it.typeParameterSymbol to it.defaultType }, session)
for (freshVariable in freshTypeVariables) { for (freshVariable in freshTypeVariables) {
csBuilder.registerVariable(freshVariable) csBuilder.registerVariable(freshVariable)
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.resolve.calls package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
@@ -16,7 +17,7 @@ import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
import org.jetbrains.kotlin.fir.expressions.FirSpreadArgumentExpression import org.jetbrains.kotlin.fir.expressions.FirSpreadArgumentExpression
import org.jetbrains.kotlin.fir.expressions.builder.buildNamedArgumentExpression import org.jetbrains.kotlin.fir.expressions.builder.buildNamedArgumentExpression
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
import org.jetbrains.kotlin.fir.resolve.asForbiddenNamedArgumentsTarget import org.jetbrains.kotlin.fir.resolve.getAsForbiddenNamedArgumentsTarget
import org.jetbrains.kotlin.fir.resolve.defaultParameterResolver import org.jetbrains.kotlin.fir.resolve.defaultParameterResolver
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -85,7 +86,7 @@ fun BodyResolveComponents.mapArguments(
} }
} }
val processor = FirCallArgumentsProcessor(function, this, originScope) val processor = FirCallArgumentsProcessor(session, function, this, originScope)
processor.processArgumentsInParenthesis(argumentsInParenthesis) processor.processArgumentsInParenthesis(argumentsInParenthesis)
if (externalArgument != null) { if (externalArgument != null) {
processor.processExternalArgument(externalArgument) processor.processExternalArgument(externalArgument)
@@ -96,6 +97,7 @@ fun BodyResolveComponents.mapArguments(
} }
private class FirCallArgumentsProcessor( private class FirCallArgumentsProcessor(
private val useSiteSession: FirSession,
private val function: FirFunction<*>, private val function: FirFunction<*>,
private val bodyResolveComponents: BodyResolveComponents, private val bodyResolveComponents: BodyResolveComponents,
private val originScope: FirScope?, private val originScope: FirScope?,
@@ -109,7 +111,7 @@ private class FirCallArgumentsProcessor(
val result: LinkedHashMap<FirValueParameter, ResolvedCallArgument> = LinkedHashMap(function.valueParameters.size) val result: LinkedHashMap<FirValueParameter, ResolvedCallArgument> = LinkedHashMap(function.valueParameters.size)
val forbiddenNamedArgumentsTarget: ForbiddenNamedArgumentsTarget? by lazy { val forbiddenNamedArgumentsTarget: ForbiddenNamedArgumentsTarget? by lazy {
function.asForbiddenNamedArgumentsTarget function.getAsForbiddenNamedArgumentsTarget(useSiteSession)
} }
private enum class State { private enum class State {
@@ -195,7 +195,7 @@ internal object CheckVisibility : CheckerStage() {
if (declaration is FirConstructor) { if (declaration is FirConstructor) {
// TODO: Should be some other form // TODO: Should be some other form
val classSymbol = declaration.returnTypeRef.coneTypeUnsafe<ConeClassLikeType>().lookupTag.toSymbol(declaration.declarationSiteSession) val classSymbol = declaration.returnTypeRef.coneTypeUnsafe<ConeClassLikeType>().lookupTag.toSymbol(context.session)
if (classSymbol is FirRegularClassSymbol) { if (classSymbol is FirRegularClassSymbol) {
if (classSymbol.fir.classKind.isSingleton) { if (classSymbol.fir.classKind.isSingleton) {
@@ -875,7 +875,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
val substitutionFromArguments = typeParameters.zip(qualifiedAccess.typeArguments).map { (typeParameterRef, typeArgument) -> val substitutionFromArguments = typeParameters.zip(qualifiedAccess.typeArguments).map { (typeParameterRef, typeArgument) ->
typeParameterRef.symbol to typeArgument.toConeTypeProjection().type typeParameterRef.symbol to typeArgument.toConeTypeProjection().type
}.filter { it.second != null }.toMap() as Map<FirTypeParameterSymbol, ConeKotlinType> }.filter { it.second != null }.toMap() as Map<FirTypeParameterSymbol, ConeKotlinType>
ConeSubstitutorByMap(substitutionFromArguments) ConeSubstitutorByMap(substitutionFromArguments, components.session)
} else { } else {
ConeSubstitutor.Empty ConeSubstitutor.Empty
} }
@@ -77,7 +77,7 @@ private fun extraLambdaInfo(
?: expectedType?.typeArguments?.singleOrNull()?.safeAs<ConeKotlinTypeProjection>()?.type?.takeIf { isFunctionSupertype } ?: expectedType?.typeArguments?.singleOrNull()?.safeAs<ConeKotlinTypeProjection>()?.type?.takeIf { isFunctionSupertype }
?: typeVariable.defaultType ?: typeVariable.defaultType
val nothingType = argument.declarationSiteSession.builtinTypes.nothingType.type val nothingType = session.builtinTypes.nothingType.type
val parameters = argument.valueParameters.map { val parameters = argument.valueParameters.map {
it.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: nothingType it.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: nothingType
} }
@@ -53,7 +53,7 @@ abstract class FirSymbolProvider(val session: FirSession) : FirSessionComponent
fun FirSymbolProvider.getClassDeclaredPropertySymbols(classId: ClassId, name: Name): List<FirVariableSymbol<*>> { fun FirSymbolProvider.getClassDeclaredPropertySymbols(classId: ClassId, name: Name): List<FirVariableSymbol<*>> {
val classSymbol = getClassLikeSymbolByFqName(classId) as? FirRegularClassSymbol ?: return emptyList() val classSymbol = getClassLikeSymbolByFqName(classId) as? FirRegularClassSymbol ?: return emptyList()
val declaredMemberScope = declaredMemberScope(classSymbol.fir) val declaredMemberScope = session.declaredMemberScope(classSymbol.fir)
val result = mutableListOf<FirVariableSymbol<*>>() val result = mutableListOf<FirVariableSymbol<*>>()
declaredMemberScope.processPropertiesByName(name, result::add) declaredMemberScope.processPropertiesByName(name, result::add)
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.resolve.substitution package org.jetbrains.kotlin.fir.resolve.substitution
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
@@ -130,13 +131,13 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
} }
fun substitutorByMap(substitution: Map<FirTypeParameterSymbol, ConeKotlinType>): ConeSubstitutor { fun substitutorByMap(substitution: Map<FirTypeParameterSymbol, ConeKotlinType>, useSiteSession: FirSession): ConeSubstitutor {
// If all arguments match parameters, then substitutor isn't needed // If all arguments match parameters, then substitutor isn't needed
if (substitution.all { (parameterSymbol, argumentType) -> if (substitution.all { (parameterSymbol, argumentType) ->
(argumentType as? ConeTypeParameterType)?.lookupTag?.typeParameterSymbol == parameterSymbol (argumentType as? ConeTypeParameterType)?.lookupTag?.typeParameterSymbol == parameterSymbol
} }
) return ConeSubstitutor.Empty ) return ConeSubstitutor.Empty
return ConeSubstitutorByMap(substitution) return ConeSubstitutorByMap(substitution, useSiteSession)
} }
data class ChainedSubstitutor(private val first: ConeSubstitutor, private val second: ConeSubstitutor) : ConeSubstitutor() { data class ChainedSubstitutor(private val first: ConeSubstitutor, private val second: ConeSubstitutor) : ConeSubstitutor() {
@@ -152,13 +153,15 @@ fun ConeSubstitutor.chain(other: ConeSubstitutor): ConeSubstitutor {
return ChainedSubstitutor(this, other) return ChainedSubstitutor(this, other)
} }
data class ConeSubstitutorByMap(val substitution: Map<FirTypeParameterSymbol, ConeKotlinType>) : AbstractConeSubstitutor() { data class ConeSubstitutorByMap(
val substitution: Map<FirTypeParameterSymbol, ConeKotlinType>,
val useSiteSession: FirSession
) : AbstractConeSubstitutor() {
override fun substituteType(type: ConeKotlinType): ConeKotlinType? { override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
if (type !is ConeTypeParameterType) return null if (type !is ConeTypeParameterType) return null
val result = substitution[type.lookupTag.symbol].updateNullabilityIfNeeded(type) ?: return null val result = substitution[type.lookupTag.symbol].updateNullabilityIfNeeded(type) ?: return null
val session = type.lookupTag.symbol.fir.declarationSiteSession if (type.isUnsafeVarianceType(useSiteSession)) {
if (type.isUnsafeVarianceType(session)) { return useSiteSession.inferenceComponents.approximator.approximateToSuperType(
return session.inferenceComponents.approximator.approximateToSuperType(
result, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference result, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
) ?: result ) ?: result
} }
@@ -75,11 +75,11 @@ abstract class FirAbstractTreeTransformerWithSuperTypes(
firClass.addTypeParametersScope() firClass.addTypeParametersScope()
val companionObject = firClass.companionObject val companionObject = firClass.companionObject
if (companionObject != null) { if (companionObject != null) {
nestedClassifierScope(companionObject)?.let(scopes::add) session.nestedClassifierScope(companionObject)?.let(scopes::add)
} }
} }
nestedClassifierScope(firClass)?.let(scopes::add) session.nestedClassifierScope(firClass)?.let(scopes::add)
// Note that annotations are still visited here // Note that annotations are still visited here
// again, although there's no need in it // again, although there's no need in it
@@ -100,5 +100,5 @@ fun createSubstitutionForSupertype(superType: ConeLookupTagBasedType, session: F
it as? ConeKotlinType ?: ConeClassErrorType(ConeSimpleDiagnostic("illegal projection usage", DiagnosticKind.IllegalProjectionUsage)) it as? ConeKotlinType ?: ConeClassErrorType(ConeSimpleDiagnostic("illegal projection usage", DiagnosticKind.IllegalProjectionUsage))
} }
val mapping = klass.typeParameters.map { it.symbol }.zip(arguments).toMap() val mapping = klass.typeParameters.map { it.symbol }.zip(arguments).toMap()
return ConeSubstitutorByMap(mapping) return ConeSubstitutorByMap(mapping, session)
} }
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.symbolProvider
@@ -30,11 +29,12 @@ class FirSealedClassInheritorsProcessor(
) : FirGlobalResolveProcessor(session, scopeSession) { ) : FirGlobalResolveProcessor(session, scopeSession) {
override fun process(files: Collection<FirFile>) { override fun process(files: Collection<FirFile>) {
val sealedClassInheritorsMap = mutableMapOf<FirRegularClass, MutableList<ClassId>>() val sealedClassInheritorsMap = mutableMapOf<FirRegularClass, MutableList<ClassId>>()
files.forEach { it.accept(InheritorsCollector, sealedClassInheritorsMap) } val inheritorsCollector = InheritorsCollector(session)
files.forEach { it.accept(inheritorsCollector, sealedClassInheritorsMap) }
files.forEach { it.transformSingle(InheritorsTransformer(sealedClassInheritorsMap), null) } files.forEach { it.transformSingle(InheritorsTransformer(sealedClassInheritorsMap), null) }
} }
object InheritorsCollector : FirDefaultVisitor<Unit, MutableMap<FirRegularClass, MutableList<ClassId>>>() { class InheritorsCollector(val session: FirSession) : FirDefaultVisitor<Unit, MutableMap<FirRegularClass, MutableList<ClassId>>>() {
override fun visitElement(element: FirElement, data: MutableMap<FirRegularClass, MutableList<ClassId>>) {} override fun visitElement(element: FirElement, data: MutableMap<FirRegularClass, MutableList<ClassId>>) {}
override fun visitFile(file: FirFile, data: MutableMap<FirRegularClass, MutableList<ClassId>>) { override fun visitFile(file: FirFile, data: MutableMap<FirRegularClass, MutableList<ClassId>>) {
@@ -48,7 +48,7 @@ class FirSealedClassInheritorsProcessor(
data.computeIfAbsent(regularClass) { mutableListOf() } data.computeIfAbsent(regularClass) { mutableListOf() }
} }
val symbolProvider = regularClass.declarationSiteSession.symbolProvider val symbolProvider = session.symbolProvider
for (typeRef in regularClass.superTypeRefs) { for (typeRef in regularClass.superTypeRefs) {
val parent = extractClassFromTypeRef(symbolProvider, typeRef).takeIf { it?.modality == Modality.SEALED } ?: continue val parent = extractClassFromTypeRef(symbolProvider, typeRef).takeIf { it?.modality == Modality.SEALED } ?: continue
@@ -390,7 +390,7 @@ abstract class AbstractFirStatusResolveTransformer(
return return
} }
if (regularClass.resolvePhase > FirResolvePhase.STATUS) return if (regularClass.resolvePhase > FirResolvePhase.STATUS) return
val firProvider = regularClass.declarationSiteSession.firProvider val firProvider = session.firProvider
val statusComputationStatus = statusComputationSession[regularClass] val statusComputationStatus = statusComputationSession[regularClass]
if (!statusComputationStatus.requiresComputation) return if (!statusComputationStatus.requiresComputation) return
@@ -160,9 +160,9 @@ private fun createScopesForNestedClasses(
addIfNotNull(klass.typeParametersScope()) addIfNotNull(klass.typeParametersScope())
val companionObjects = klass.declarations.filterIsInstance<FirRegularClass>().filter { it.isCompanion } val companionObjects = klass.declarations.filterIsInstance<FirRegularClass>().filter { it.isCompanion }
for (companionObject in companionObjects) { for (companionObject in companionObjects) {
addIfNotNull(nestedClassifierScope(companionObject)) addIfNotNull(session.nestedClassifierScope(companionObject))
} }
addIfNotNull(nestedClassifierScope(klass)) addIfNotNull(session.nestedClassifierScope(klass))
} }
fun FirRegularClass.resolveSupertypesInTheAir(session: FirSession): List<FirTypeRef> { fun FirRegularClass.resolveSupertypesInTheAir(session: FirSession): List<FirTypeRef> {
@@ -43,7 +43,7 @@ class FirPluginAnnotationsResolveTransformer(
override fun transformFile(file: FirFile, data: Any?): FirFile { override fun transformFile(file: FirFile, data: Any?): FirFile {
checkSessionConsistency(file) checkSessionConsistency(file)
if (!extensionService.hasPredicateBasedExtensions) return file if (!extensionService.hasPredicateBasedExtensions) return file
val registeredPluginAnnotations = file.declarationSiteSession.registeredPluginAnnotations val registeredPluginAnnotations = session.registeredPluginAnnotations
file.replaceResolvePhase(FirResolvePhase.ANNOTATIONS_FOR_PLUGINS) file.replaceResolvePhase(FirResolvePhase.ANNOTATIONS_FOR_PLUGINS)
val newAnnotations = file.resolveAnnotations(registeredPluginAnnotations.annotations, registeredPluginAnnotations.metaAnnotations) val newAnnotations = file.resolveAnnotations(registeredPluginAnnotations.annotations, registeredPluginAnnotations.metaAnnotations)
if (!newAnnotations.isEmpty) { if (!newAnnotations.isEmpty) {
@@ -32,7 +32,7 @@ class KotlinScopeProvider(
scopeSession: ScopeSession scopeSession: ScopeSession
): FirTypeScope { ): FirTypeScope {
return scopeSession.getOrBuild(klass.symbol, USE_SITE) { return scopeSession.getOrBuild(klass.symbol, USE_SITE) {
val declaredScope = declaredMemberScope(klass) val declaredScope = useSiteSession.declaredMemberScope(klass)
val decoratedDeclaredMemberScope = val decoratedDeclaredMemberScope =
declaredMemberScopeDecorator(klass, declaredScope, useSiteSession, scopeSession) declaredMemberScopeDecorator(klass, declaredScope, useSiteSession, scopeSession)
@@ -58,13 +58,13 @@ class KotlinScopeProvider(
scopeSession: ScopeSession scopeSession: ScopeSession
): FirScope? { ): FirScope? {
return when (klass.classKind) { return when (klass.classKind) {
ClassKind.ENUM_CLASS -> FirOnlyCallablesScope(FirStaticScope(declaredMemberScope(klass))) ClassKind.ENUM_CLASS -> FirOnlyCallablesScope(FirStaticScope(useSiteSession.declaredMemberScope(klass)))
else -> null else -> null
} }
} }
override fun getNestedClassifierScope(klass: FirClass<*>, useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? { override fun getNestedClassifierScope(klass: FirClass<*>, useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? {
return nestedClassifierScope(klass) return useSiteSession.nestedClassifierScope(klass)
} }
} }
@@ -125,7 +125,7 @@ fun ConeKotlinType.scopeForSupertype(
private fun substitutor(symbol: FirRegularClassSymbol, type: ConeClassLikeType, useSiteSession: FirSession): ConeSubstitutor { private fun substitutor(symbol: FirRegularClassSymbol, type: ConeClassLikeType, useSiteSession: FirSession): ConeSubstitutor {
if (type.typeArguments.isEmpty()) return ConeSubstitutor.Empty if (type.typeArguments.isEmpty()) return ConeSubstitutor.Empty
val originalSubstitution = createSubstitution(symbol.fir.typeParameters, type, useSiteSession) val originalSubstitution = createSubstitution(symbol.fir.typeParameters, type, useSiteSession)
return substitutorByMap(originalSubstitution) return substitutorByMap(originalSubstitution, useSiteSession)
} }
fun FirClass<*>.scopeForSupertype( fun FirClass<*>.scopeForSupertype(
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.scopes.impl package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
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
@@ -22,7 +23,8 @@ abstract class FirAbstractOverrideChecker : FirOverrideChecker {
fun buildSubstitutorForOverridesCheck( fun buildSubstitutorForOverridesCheck(
overrideCandidate: FirCallableMemberDeclaration<*>, overrideCandidate: FirCallableMemberDeclaration<*>,
baseDeclaration: FirCallableMemberDeclaration<*> baseDeclaration: FirCallableMemberDeclaration<*>,
useSiteSession: FirSession
): ConeSubstitutor? { ): ConeSubstitutor? {
if (overrideCandidate.typeParameters.size != baseDeclaration.typeParameters.size) return null if (overrideCandidate.typeParameters.size != baseDeclaration.typeParameters.size) return null
@@ -30,5 +32,5 @@ fun buildSubstitutorForOverridesCheck(
val types = baseDeclaration.typeParameters.map { val types = baseDeclaration.typeParameters.map {
ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false)
} }
return substitutorByMap(overrideCandidate.typeParameters.map { it.symbol }.zip(types).toMap()) return substitutorByMap(overrideCandidate.typeParameters.map { it.symbol }.zip(types).toMap(), useSiteSession)
} }
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.scopes.impl package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
@@ -16,6 +17,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
class FirClassDeclaredMemberScope( class FirClassDeclaredMemberScope(
val useSiteSession: FirSession,
klass: FirClass<*>, klass: FirClass<*>,
useLazyNestedClassifierScope: Boolean = false, useLazyNestedClassifierScope: Boolean = false,
existingNames: List<Name>? = null, existingNames: List<Name>? = null,
@@ -24,7 +26,7 @@ class FirClassDeclaredMemberScope(
private val nestedClassifierScope: FirScope? = if (useLazyNestedClassifierScope) { private val nestedClassifierScope: FirScope? = if (useLazyNestedClassifierScope) {
lazyNestedClassifierScope(klass.symbol.classId, existingNames!!, symbolProvider!!) lazyNestedClassifierScope(klass.symbol.classId, existingNames!!, symbolProvider!!)
} else { } else {
nestedClassifierScope(klass) useSiteSession.nestedClassifierScope(klass)
} }
private val callablesIndex: Map<Name, List<FirCallableSymbol<*>>> = run { private val callablesIndex: Map<Name, List<FirCallableSymbol<*>>> = run {
@@ -65,7 +67,7 @@ class FirClassDeclaredMemberScope(
val symbols = callablesIndex[name] ?: emptyList() val symbols = callablesIndex[name] ?: emptyList()
for (symbol in symbols) { for (symbol in symbols) {
if (symbol is D) { if (symbol is D) {
symbol.ensureResolvedForCalls(symbol.fir.declarationSiteSession) symbol.ensureResolvedForCalls(useSiteSession)
processor(symbol) processor(symbol)
} }
} }
@@ -204,6 +204,7 @@ class FirClassSubstitutionScope(
private fun createSubstitutedData(member: FirCallableMemberDeclaration<*>): SubstitutedData { private fun createSubstitutedData(member: FirCallableMemberDeclaration<*>): SubstitutedData {
val (newTypeParameters, substitutor) = FirFakeOverrideGenerator.createNewTypeParametersAndSubstitutor( val (newTypeParameters, substitutor) = FirFakeOverrideGenerator.createNewTypeParametersAndSubstitutor(
session,
member as FirTypeParameterRefsOwner, member as FirTypeParameterRefsOwner,
substitutor, substitutor,
forceTypeParametersRecreation = dispatchReceiverTypeForSubstitutedMembers.lookupTag != member.dispatchReceiverClassOrNull() forceTypeParametersRecreation = dispatchReceiverTypeForSubstitutedMembers.lookupTag != member.dispatchReceiverClassOrNull()
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.scopes.impl package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSessionComponent import org.jetbrains.kotlin.fir.FirSessionComponent
import org.jetbrains.kotlin.fir.ThreadSafeMutableState import org.jetbrains.kotlin.fir.ThreadSafeMutableState
import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirClass
@@ -17,7 +18,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.getOrPutNullable import org.jetbrains.kotlin.utils.getOrPutNullable
@ThreadSafeMutableState @ThreadSafeMutableState
class FirDeclaredMemberScopeProvider : FirSessionComponent { class FirDeclaredMemberScopeProvider(val useSiteSession: FirSession) : FirSessionComponent {
private val declaredMemberCache = mutableMapOf<FirClass<*>, FirClassDeclaredMemberScope>() private val declaredMemberCache = mutableMapOf<FirClass<*>, FirClassDeclaredMemberScope>()
private val nestedClassifierCache = mutableMapOf<FirClass<*>, FirNestedClassifierScope?>() private val nestedClassifierCache = mutableMapOf<FirClass<*>, FirNestedClassifierScope?>()
@@ -46,39 +47,33 @@ class FirDeclaredMemberScopeProvider : FirSessionComponent {
symbolProvider: FirSymbolProvider? symbolProvider: FirSymbolProvider?
): FirClassDeclaredMemberScope { ): FirClassDeclaredMemberScope {
return declaredMemberCache.getOrPut(klass) { return declaredMemberCache.getOrPut(klass) {
FirClassDeclaredMemberScope(klass, useLazyNestedClassifierScope, existingNames, symbolProvider) FirClassDeclaredMemberScope(useSiteSession, klass, useLazyNestedClassifierScope, existingNames, symbolProvider)
} }
} }
fun nestedClassifierScope(klass: FirClass<*>): FirNestedClassifierScope? { fun nestedClassifierScope(klass: FirClass<*>): FirNestedClassifierScope? {
return nestedClassifierCache.getOrPutNullable(klass) { return nestedClassifierCache.getOrPutNullable(klass) {
FirNestedClassifierScope(klass).takeUnless { it.isEmpty() } FirNestedClassifierScope(klass, useSiteSession).takeUnless { it.isEmpty() }
} }
} }
} }
fun declaredMemberScope(klass: FirClass<*>): FirClassDeclaredMemberScope { fun FirSession.declaredMemberScope(klass: FirClass<*>): FirClassDeclaredMemberScope {
return klass return declaredMemberScopeProvider
.declarationSiteSession
.declaredMemberScopeProvider
.declaredMemberScope(klass, useLazyNestedClassifierScope = false, existingNames = null, symbolProvider = null) .declaredMemberScope(klass, useLazyNestedClassifierScope = false, existingNames = null, symbolProvider = null)
} }
fun declaredMemberScopeWithLazyNestedScope( fun FirSession.declaredMemberScopeWithLazyNestedScope(
klass: FirClass<*>, klass: FirClass<*>,
existingNames: List<Name>, existingNames: List<Name>,
symbolProvider: FirSymbolProvider symbolProvider: FirSymbolProvider
): FirScope { ): FirScope {
return klass return declaredMemberScopeProvider
.declarationSiteSession
.declaredMemberScopeProvider
.declaredMemberScope(klass, useLazyNestedClassifierScope = true, existingNames = existingNames, symbolProvider = symbolProvider) .declaredMemberScope(klass, useLazyNestedClassifierScope = true, existingNames = existingNames, symbolProvider = symbolProvider)
} }
fun nestedClassifierScope(klass: FirClass<*>): FirNestedClassifierScope? { fun FirSession.nestedClassifierScope(klass: FirClass<*>): FirNestedClassifierScope? {
return klass return declaredMemberScopeProvider
.declarationSiteSession
.declaredMemberScopeProvider
.nestedClassifierScope(klass) .nestedClassifierScope(klass)
} }
@@ -111,7 +111,7 @@ object FirFakeOverrideGenerator {
dispatchReceiverType = newDispatchReceiverType dispatchReceiverType = newDispatchReceiverType
attributes = baseFunction.attributes.copy() attributes = baseFunction.attributes.copy()
typeParameters += configureAnnotationsTypeParametersAndSignature( typeParameters += configureAnnotationsTypeParametersAndSignature(
baseFunction, newParameterTypes, newTypeParameters, newReceiverType, newReturnType, fakeOverrideSubstitution session, baseFunction, newParameterTypes, newTypeParameters, newReceiverType, newReturnType, fakeOverrideSubstitution
).filterIsInstance<FirTypeParameter>() ).filterIsInstance<FirTypeParameter>()
} }
} }
@@ -137,7 +137,7 @@ object FirFakeOverrideGenerator {
symbol = fakeOverrideSymbol symbol = fakeOverrideSymbol
typeParameters += configureAnnotationsTypeParametersAndSignature( typeParameters += configureAnnotationsTypeParametersAndSignature(
baseConstructor, newParameterTypes, newTypeParameters, newReceiverType = null, newReturnType, fakeOverrideSubstitution session, baseConstructor, newParameterTypes, newTypeParameters, newReceiverType = null, newReturnType, fakeOverrideSubstitution
) )
dispatchReceiverType = newDispatchReceiverType dispatchReceiverType = newDispatchReceiverType
@@ -151,6 +151,7 @@ object FirFakeOverrideGenerator {
} }
private fun FirFunctionBuilder.configureAnnotationsTypeParametersAndSignature( private fun FirFunctionBuilder.configureAnnotationsTypeParametersAndSignature(
useSiteSession: FirSession,
baseFunction: FirFunction<*>, baseFunction: FirFunction<*>,
newParameterTypes: List<ConeKotlinType?>?, newParameterTypes: List<ConeKotlinType?>?,
newTypeParameters: List<FirTypeParameterRef>?, newTypeParameters: List<FirTypeParameterRef>?,
@@ -171,7 +172,7 @@ object FirFakeOverrideGenerator {
} }
newTypeParameters == null -> { newTypeParameters == null -> {
val (copiedTypeParameters, substitutor) = createNewTypeParametersAndSubstitutor( val (copiedTypeParameters, substitutor) = createNewTypeParametersAndSubstitutor(
baseFunction, ConeSubstitutor.Empty useSiteSession, baseFunction, ConeSubstitutor.Empty
) )
val copiedParameterTypes = baseFunction.valueParameters.map { val copiedParameterTypes = baseFunction.valueParameters.map {
substitutor.substituteOrNull(it.returnTypeRef.coneType) substitutor.substituteOrNull(it.returnTypeRef.coneType)
@@ -294,6 +295,7 @@ object FirFakeOverrideGenerator {
dispatchReceiverType = newDispatchReceiverType dispatchReceiverType = newDispatchReceiverType
attributes = baseProperty.attributes.copy() attributes = baseProperty.attributes.copy()
typeParameters += configureAnnotationsTypeParametersAndSignature( typeParameters += configureAnnotationsTypeParametersAndSignature(
session,
baseProperty, baseProperty,
newTypeParameters, newTypeParameters,
newReceiverType, newReceiverType,
@@ -304,6 +306,7 @@ object FirFakeOverrideGenerator {
} }
private fun FirPropertyBuilder.configureAnnotationsTypeParametersAndSignature( private fun FirPropertyBuilder.configureAnnotationsTypeParametersAndSignature(
useSiteSession: FirSession,
baseProperty: FirProperty, baseProperty: FirProperty,
newTypeParameters: List<FirTypeParameter>?, newTypeParameters: List<FirTypeParameter>?,
newReceiverType: ConeKotlinType?, newReceiverType: ConeKotlinType?,
@@ -317,7 +320,7 @@ object FirFakeOverrideGenerator {
} }
newTypeParameters == null -> { newTypeParameters == null -> {
val (copiedTypeParameters, substitutor) = createNewTypeParametersAndSubstitutor( val (copiedTypeParameters, substitutor) = createNewTypeParametersAndSubstitutor(
baseProperty, ConeSubstitutor.Empty useSiteSession, baseProperty, ConeSubstitutor.Empty
) )
val (copiedReceiverType, possibleReturnType) = substituteReceiverAndReturnType( val (copiedReceiverType, possibleReturnType) = substituteReceiverAndReturnType(
baseProperty, newReceiverType, newReturnType, substitutor baseProperty, newReceiverType, newReturnType, substitutor
@@ -456,6 +459,7 @@ object FirFakeOverrideGenerator {
// Returns a list of type parameters, and a substitutor that should be used for all other types // Returns a list of type parameters, and a substitutor that should be used for all other types
fun createNewTypeParametersAndSubstitutor( fun createNewTypeParametersAndSubstitutor(
useSiteSession: FirSession,
member: FirTypeParameterRefsOwner, member: FirTypeParameterRefsOwner,
substitutor: ConeSubstitutor, substitutor: ConeSubstitutor,
forceTypeParametersRecreation: Boolean = true forceTypeParametersRecreation: Boolean = true
@@ -481,7 +485,7 @@ object FirFakeOverrideGenerator {
else null else null
}.toMap() }.toMap()
val additionalSubstitutor = substitutorByMap(substitutionMapForNewParameters) val additionalSubstitutor = substitutorByMap(substitutionMapForNewParameters, useSiteSession)
var wereChangesInTypeParameters = forceTypeParametersRecreation var wereChangesInTypeParameters = forceTypeParametersRecreation
for ((newTypeParameter, oldTypeParameter) in newTypeParameters.zip(member.typeParameters)) { for ((newTypeParameter, oldTypeParameter) in newTypeParameters.zip(member.typeParameters)) {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.scopes.impl package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef
@@ -19,7 +20,7 @@ import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
class FirNestedClassifierScope(val klass: FirClass<*>) : FirScope(), FirContainingNamesAwareScope { class FirNestedClassifierScope(val klass: FirClass<*>, val useSiteSession: FirSession) : FirScope(), FirContainingNamesAwareScope {
private val classIndex: Map<Name, FirRegularClassSymbol> = run { private val classIndex: Map<Name, FirRegularClassSymbol> = run {
val result = mutableMapOf<Name, FirRegularClassSymbol>() val result = mutableMapOf<Name, FirRegularClassSymbol>()
for (declaration in klass.declarations) { for (declaration in klass.declarations) {
@@ -40,7 +41,7 @@ class FirNestedClassifierScope(val klass: FirClass<*>) : FirScope(), FirContaini
val substitution = klass.typeParameters.associate { val substitution = klass.typeParameters.associate {
it.symbol to it.toConeType() it.symbol to it.toConeType()
} }
processor(matchedClass, ConeSubstitutorByMap(substitution)) processor(matchedClass, ConeSubstitutorByMap(substitution, useSiteSession))
} }
override fun getClassifierNames(): Set<Name> = classIndex.keys override fun getClassifierNames(): Set<Name> = classIndex.keys
@@ -97,7 +97,7 @@ class FirStandardOverrideChecker(private val session: FirSession) : FirAbstractO
overrideCandidate: FirCallableMemberDeclaration<*>, overrideCandidate: FirCallableMemberDeclaration<*>,
baseDeclaration: FirCallableMemberDeclaration<*> baseDeclaration: FirCallableMemberDeclaration<*>
): ConeSubstitutor? { ): ConeSubstitutor? {
val substitutor = buildSubstitutorForOverridesCheck(overrideCandidate, baseDeclaration) ?: return null val substitutor = buildSubstitutorForOverridesCheck(overrideCandidate, baseDeclaration, session) ?: return null
if ( if (
overrideCandidate.typeParameters.isNotEmpty() && overrideCandidate.typeParameters.isNotEmpty() &&
overrideCandidate.typeParameters.zip(baseDeclaration.typeParameters).any { (override, base) -> overrideCandidate.typeParameters.zip(baseDeclaration.typeParameters).any { (override, base) ->
@@ -396,7 +396,7 @@ class FirTypeIntersectionScope private constructor(
val bFir = b.fir val bFir = b.fir
if (aFir !is FirCallableMemberDeclaration<*> || bFir !is FirCallableMemberDeclaration<*>) return false if (aFir !is FirCallableMemberDeclaration<*> || bFir !is FirCallableMemberDeclaration<*>) return false
val substitutor = buildSubstitutorForOverridesCheck(aFir, bFir) ?: return false val substitutor = buildSubstitutorForOverridesCheck(aFir, bFir, session) ?: return false
// NB: these lines throw CCE in modularized tests when changed to just .coneType (FirImplicitTypeRef) // NB: these lines throw CCE in modularized tests when changed to just .coneType (FirImplicitTypeRef)
val aReturnType = a.fir.returnTypeRef.coneTypeSafe<ConeKotlinType>()?.let(substitutor::substituteOrSelf) ?: return false val aReturnType = a.fir.returnTypeRef.coneTypeSafe<ConeKotlinType>()?.let(substitutor::substituteOrSelf) ?: return false
val bReturnType = b.fir.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: return false val bReturnType = b.fir.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: return false
@@ -565,7 +565,7 @@ class ConeTypeCheckerContext(
parameter.symbol to ((argument as? ConeKotlinTypeProjection)?.type parameter.symbol to ((argument as? ConeKotlinTypeProjection)?.type
?: session.builtinTypes.nullableAnyType.type)//StandardClassIds.Any(session.firSymbolProvider).constructType(emptyArray(), isNullable = true)) ?: session.builtinTypes.nullableAnyType.type)//StandardClassIds.Any(session.firSymbolProvider).constructType(emptyArray(), isNullable = true))
} }
substitutorByMap(substitution) substitutorByMap(substitution, session)
} else { } else {
ConeSubstitutor.Empty ConeSubstitutor.Empty
} }
@@ -344,9 +344,10 @@ private fun ConeTypeContext.captureArguments(type: ConeKotlinType, status: Captu
ConeCapturedType(status, lowerType, argument, typeConstructor.getParameter(index)) ConeCapturedType(status, lowerType, argument, typeConstructor.getParameter(index))
} }
val substitutor = substitutorByMap((0 until argumentsCount).map { index -> val substitution = (0 until argumentsCount).map { index ->
(typeConstructor.getParameter(index) as ConeTypeParameterLookupTag).symbol to (newArguments[index] as ConeKotlinType) (typeConstructor.getParameter(index) as ConeTypeParameterLookupTag).symbol to (newArguments[index] as ConeKotlinType)
}.toMap()) }.toMap()
val substitutor = substitutorByMap(substitution, session)
for (index in 0 until argumentsCount) { for (index in 0 until argumentsCount) {
val oldArgument = type.typeArguments[index] val oldArgument = type.typeArguments[index]
@@ -91,7 +91,7 @@ internal class KtFirScopeProvider(
override fun getDeclaredMemberScope(classSymbol: KtSymbolWithMembers): KtDeclaredMemberScope = withValidityAssertion { override fun getDeclaredMemberScope(classSymbol: KtSymbolWithMembers): KtDeclaredMemberScope = withValidityAssertion {
declaredMemberScopeCache.getOrPut(classSymbol) { declaredMemberScopeCache.getOrPut(classSymbol) {
val firScope = classSymbol.withFirForScope { val firScope = classSymbol.withFirForScope {
declaredMemberScope(it) analysisSession.rootModuleSession.declaredMemberScope(it)
} ?: return@getOrPut KtFirEmptyMemberScope(classSymbol) } ?: return@getOrPut KtFirEmptyMemberScope(classSymbol)
firScopeStorage.register(firScope) firScopeStorage.register(firScope)