diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt index 197b278b588..da46bd7f3a5 100644 --- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt +++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.types.ConeAttributes +import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl @@ -161,6 +162,8 @@ fun deserializeClassToSymbol( isStatic = true } resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES + }.apply { + containingClassAttr = context.dispatchReceiver!!.lookupTag } property @@ -168,11 +171,15 @@ fun deserializeClassToSymbol( ) if (classKind == ClassKind.ENUM_CLASS) { - generateValuesFunction(session, classId.packageFqName, classId.relativeClassName) + generateValuesFunction( + session, + classId.packageFqName, + classId.relativeClassName + ) generateValueOfFunction(session, classId.packageFqName, classId.relativeClassName) } - addCloneForArrayIfNeeded(classId) + addCloneForArrayIfNeeded(classId, context.dispatchReceiver) addSerializableIfNeeded(classId) declarations.sortWith(object : Comparator { @@ -224,7 +231,7 @@ private fun FirRegularClassBuilder.addSerializableIfNeeded(classId: ClassId) { } } -private fun FirRegularClassBuilder.addCloneForArrayIfNeeded(classId: ClassId) { +private fun FirRegularClassBuilder.addCloneForArrayIfNeeded(classId: ClassId, dispatchReceiver: ConeClassLikeType?) { if (classId.packageFqName != StandardNames.BUILT_INS_PACKAGE_FQ_NAME) return if (classId.shortClassName !in ARRAY_CLASSES) return superTypeRefs += buildResolvedTypeRef { @@ -259,5 +266,6 @@ private fun FirRegularClassBuilder.addCloneForArrayIfNeeded(classId: ClassId) { } name = CLONE symbol = FirNamedFunctionSymbol(CallableId(classId, CLONE)) + dispatchReceiverType = dispatchReceiver!! } } diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt index be140999d61..ac5d59a33cd 100644 --- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt +++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt @@ -7,12 +7,14 @@ package org.jetbrains.kotlin.fir.deserialization import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.containingClassAttr import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.builder.* import org.jetbrains.kotlin.fir.declarations.impl.* import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.builder.buildExpressionStub +import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.symbols.impl.* @@ -64,6 +66,7 @@ class FirDeserializationContext( ) val memberDeserializer: FirMemberDeserializer = FirMemberDeserializer(this) + val dispatchReceiver = relativeClassName?.let { ClassId(packageFqName, it, false).defaultType(allTypeParameters) } companion object { fun createForPackage( @@ -225,6 +228,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { isExternal = Flags.IS_EXTERNAL_ACCESSOR.get(getterFlags) } this.symbol = FirPropertyAccessorSymbol() + dispatchReceiverType = c.dispatchReceiver }.apply { versionRequirementsTable = c.versionRequirementTable } @@ -256,6 +260,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { isExternal = Flags.IS_EXTERNAL_ACCESSOR.get(setterFlags) } this.symbol = FirPropertyAccessorSymbol() + dispatchReceiverType = c.dispatchReceiver valueParameters += local.memberDeserializer.valueParameters( listOf(proto.setterValueParameter), proto, @@ -288,6 +293,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { name = callableName this.isVar = isVar this.symbol = symbol + dispatchReceiverType = c.dispatchReceiver isLocal = false status = FirResolvedDeclarationStatusImpl( ProtoEnumFlags.visibility(Flags.VISIBILITY.get(flags)), @@ -365,6 +371,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { isSuspend = Flags.IS_SUSPEND.get(flags) } this.symbol = symbol + dispatchReceiverType = c.dispatchReceiver resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES typeParameters += local.typeDeserializer.ownTypeParameters.map { it.fir } valueParameters += local.memberDeserializer.valueParameters( @@ -443,6 +450,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { annotations += c.annotationDeserializer.loadConstructorAnnotations(c.containerSource, proto, local.nameResolver, local.typeTable) }.build().apply { + containingClassAttr = c.dispatchReceiver!!.lookupTag versionRequirementsTable = c.versionRequirementTable } } diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirBuiltinSymbolProvider.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirBuiltinSymbolProvider.kt index 1f92e9c3e8a..ec03ff32768 100644 --- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirBuiltinSymbolProvider.kt +++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirBuiltinSymbolProvider.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.deserialization.FirBuiltinAnnotationDeserializer import org.jetbrains.kotlin.fir.deserialization.FirConstDeserializer import org.jetbrains.kotlin.fir.deserialization.FirDeserializationContext import org.jetbrains.kotlin.fir.deserialization.deserializeClassToSymbol +import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider @@ -225,6 +226,7 @@ class FirBuiltinSymbolProvider(session: FirSession, val kotlinScopeProvider: Kot isVararg = false } } + dispatchReceiverType = classId.defaultType(typeParameters.map { it.symbol }) } ) } diff --git a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirMetadataSerializer.kt b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirMetadataSerializer.kt index d615b5c7a50..0337a03af47 100644 --- a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirMetadataSerializer.kt +++ b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirMetadataSerializer.kt @@ -11,18 +11,21 @@ import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.backend.FirMetadataSource import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.declarations.builder.* +import org.jetbrains.kotlin.fir.declarations.builder.buildAnonymousFunction +import org.jetbrains.kotlin.fir.declarations.builder.buildProperty +import org.jetbrains.kotlin.fir.declarations.builder.buildPropertyAccessor +import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameterCopy import org.jetbrains.kotlin.fir.diagnostics.ConeIntermediateDiagnostic -import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.serialization.FirElementSerializer import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirDelegateFieldSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertyAccessorSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol +import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.MetadataSource -import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.ir.util.getPackageFragment import org.jetbrains.kotlin.metadata.jvm.serialization.JvmStringTable import org.jetbrains.kotlin.protobuf.MessageLite import org.jetbrains.kotlin.types.AbstractTypeApproximator @@ -128,6 +131,8 @@ class FirMetadataSerializer( isVar = property.isVar isLocal = property.isLocal status = property.status + dispatchReceiverType = property.dispatchReceiverType + attributes = property.attributes.copy() annotations += property.annotations typeParameters += typeParameterSet }.apply { diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DataClassMembersGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DataClassMembersGenerator.kt index ac1e6109934..0a57abffb52 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DataClassMembersGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DataClassMembersGenerator.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.fir.backend.generators import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.backend.Fir2IrComponents import org.jetbrains.kotlin.fir.backend.FirMetadataSource import org.jetbrains.kotlin.fir.backend.declareThisReceiverParameter @@ -17,8 +16,11 @@ import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope import org.jetbrains.kotlin.fir.symbols.CallableId +import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol +import org.jetbrains.kotlin.fir.types.ConeStarProjection +import org.jetbrains.kotlin.fir.types.constructType import org.jetbrains.kotlin.fir.types.impl.FirImplicitBooleanTypeRef import org.jetbrains.kotlin.fir.types.impl.FirImplicitIntTypeRef import org.jetbrains.kotlin.fir.types.impl.FirImplicitNullableAnyTypeRef @@ -35,7 +37,6 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.DataClassMembersGenerator import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.descriptors.DescriptorVisibilities /** * A generator that generates synthetic members of data class as well as part of inline class. @@ -248,6 +249,11 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) { } ) } + dispatchReceiverType = + ConeClassLikeLookupTagImpl(classId) + .constructType( + (1..irClass.typeParameters.size).map { ConeStarProjection }.toTypedArray(), isNullable = false + ) } val signature = if (classId.isLocal) null else components.signatureComposer.composeSignature(firFunction) return components.declarationStorage.declareIrSimpleFunction(signature, null) { symbol -> diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt index 1187a7a5820..4c8b81fadaf 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt @@ -10,13 +10,16 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSymbolOwner import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.dispatchReceiverClassOrNull import org.jetbrains.kotlin.fir.resolve.ScopeSession +import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenProperties import org.jetbrains.kotlin.fir.scopes.impl.FirFakeOverrideGenerator import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol +import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.PossiblyFirFakeOverrideSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol @@ -30,7 +33,6 @@ import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrTypeProjection import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities -import org.jetbrains.kotlin.name.ClassId class FakeOverrideGenerator( private val session: FirSession, @@ -87,6 +89,7 @@ class FakeOverrideGenerator( createFakeOverrideSymbol = { firFunction, callableSymbol -> FirFakeOverrideGenerator.createFakeOverrideFunction( session, firFunction, callableSymbol, + newDispatchReceiverType = klass.defaultType(), derivedClassId = klass.symbol.classId, isExpect = (klass as? FirRegularClass)?.isExpect == true ) @@ -110,6 +113,7 @@ class FakeOverrideGenerator( createFakeOverrideSymbol = { firProperty, callableSymbol -> FirFakeOverrideGenerator.createFakeOverrideProperty( session, firProperty, callableSymbol, + newDispatchReceiverType = klass.defaultType(), derivedClassId = klass.symbol.classId, isExpect = (klass as? FirRegularClass)?.isExpect == true ) diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt index 0cb17a5b9f1..671723f4fe6 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt @@ -96,7 +96,7 @@ class JavaScopeProvider( val scope = buildJavaEnhancementScope(useSiteSession, symbol, scopeSession, visitedSymbols) visitedSymbols.remove(symbol) useSiteSuperType.wrapSubstitutionScopeIfNeed( - useSiteSession, scope, symbol.fir, scopeSession, regularClass.classId + useSiteSession, scope, symbol.fir, scopeSession, derivedClass = regularClass ) } else { null @@ -112,7 +112,7 @@ class JavaScopeProvider( else JavaTypeParameterStack.EMPTY ), superTypeEnhancementScopes, - regularClass.classId, + regularClass.defaultType(), ), wrappedDeclaredScope ) } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt index d11f8581b78..16f8fd00103 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt @@ -19,12 +19,14 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.builder.* import org.jetbrains.kotlin.fir.java.declarations.* import org.jetbrains.kotlin.fir.resolve.constructType +import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals import org.jetbrains.kotlin.fir.resolve.providers.SymbolProviderCache import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.impl.* +import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl @@ -187,6 +189,9 @@ class JavaSymbolProvider( buildOuterClassTypeParameterRef { symbol = it.symbol } } } + + val dispatchReceiver = classId.defaultType(typeParameters.map { it.symbol } ) + status = FirResolvedDeclarationStatusImpl( javaClass.visibility, javaClass.modality @@ -200,7 +205,7 @@ class JavaSymbolProvider( // TODO: may be we can process fields & methods later. // However, they should be built up to override resolve stage for (javaField in javaClass.fields) { - declarations += convertJavaFieldToFir(javaField, classId, javaTypeParameterStack) + declarations += convertJavaFieldToFir(javaField, classId, javaTypeParameterStack, dispatchReceiver) } val valueParametersForAnnotationConstructor = ValueParametersForAnnotationConstructor() val classIsAnnotation = classKind == ClassKind.ANNOTATION_CLASS @@ -212,7 +217,8 @@ class JavaSymbolProvider( classId, javaTypeParameterStack, classIsAnnotation, - valueParametersForAnnotationConstructor + valueParametersForAnnotationConstructor, + dispatchReceiver ) } val javaClassDeclaredConstructors = javaClass.constructors @@ -243,11 +249,16 @@ class JavaSymbolProvider( } if (classKind == ClassKind.ENUM_CLASS) { - generateValuesFunction(session, classId.packageFqName, classId.relativeClassName) + generateValuesFunction( + session, + classId.packageFqName, + classId.relativeClassName + ) generateValueOfFunction(session, classId.packageFqName, classId.relativeClassName) } if (classIsAnnotation) { - declarations += buildConstructorForAnnotationClass(constructorId, this, valueParametersForAnnotationConstructor) + declarations += + buildConstructorForAnnotationClass(constructorId, this, valueParametersForAnnotationConstructor) } parentClassTypeParameterStackCache.remove(classSymbol) } @@ -265,7 +276,8 @@ class JavaSymbolProvider( private fun convertJavaFieldToFir( javaField: JavaField, classId: ClassId, - javaTypeParameterStack: JavaTypeParameterStack + javaTypeParameterStack: JavaTypeParameterStack, + dispatchReceiver: ConeClassLikeType ): FirDeclaration { val fieldName = javaField.name val fieldId = CallableId(classId.packageFqName, classId.relativeClassName, fieldName) @@ -289,6 +301,8 @@ class JavaSymbolProvider( resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES origin = FirDeclarationOrigin.Java addAnnotationsFrom(this@JavaSymbolProvider.session, javaField, javaTypeParameterStack) + }.apply { + containingClassAttr = ConeClassLikeLookupTagImpl(classId) } else -> buildJavaField { source = (javaField as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement() @@ -311,6 +325,14 @@ class JavaSymbolProvider( isStatic = javaField.isStatic addAnnotationsFrom(this@JavaSymbolProvider.session, javaField, javaTypeParameterStack) initializer = convertJavaInitializerToFir(javaField.initializerValue) + + if (!javaField.isStatic) { + dispatchReceiverType = dispatchReceiver + } + }.apply { + if (javaField.isStatic) { + containingClassAttr = ConeClassLikeLookupTagImpl(classId) + } } } } @@ -325,7 +347,8 @@ class JavaSymbolProvider( classId: ClassId, javaTypeParameterStack: JavaTypeParameterStack, classIsAnnotation: Boolean, - valueParametersForAnnotationConstructor: ValueParametersForAnnotationConstructor + valueParametersForAnnotationConstructor: ValueParametersForAnnotationConstructor, + dispatchReceiver: ConeClassLikeType ): FirJavaMethod { val methodName = javaMethod.name val methodId = CallableId(classId.packageFqName, classId.relativeClassName, methodName) @@ -364,6 +387,14 @@ class JavaSymbolProvider( isExternal = false isSuspend = false } + + if (!javaMethod.isStatic) { + dispatchReceiverType = dispatchReceiver + } + }.apply { + if (javaMethod.isStatic) { + containingClassAttr = ConeClassLikeLookupTagImpl(classId) + } } if (classIsAnnotation) { val parameterForAnnotationConstructor = buildJavaValueParameter { @@ -425,6 +456,8 @@ class JavaSymbolProvider( ) } } + }.apply { + containingClassAttr = ownerClassBuilder.symbol.toLookupTag() } } @@ -445,6 +478,8 @@ class JavaSymbolProvider( visibility = Visibilities.Public isInner = false isPrimary = true + }.apply { + containingClassAttr = ownerClassBuilder.symbol.toLookupTag() } } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaConstructor.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaConstructor.kt index 70712a60cb7..262f4a8f8d7 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaConstructor.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaConstructor.kt @@ -5,10 +5,10 @@ package org.jetbrains.kotlin.fir.java.declarations +import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.FirImplementationDetail import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSourceElement -import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.builder.FirBuilderDsl import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.builder.FirConstructorBuilder @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol +import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.FirVisitor @@ -37,6 +38,7 @@ class FirJavaConstructor @FirImplementationDetail constructor( override val annotations: MutableList, override var status: FirDeclarationStatus, override var resolvePhase: FirResolvePhase, + override val dispatchReceiverType: ConeKotlinType?, ) : FirConstructor() { override val receiverTypeRef: FirTypeRef? get() = null @@ -154,7 +156,8 @@ class FirJavaConstructorBuilder : FirConstructorBuilder() { typeParameters, annotations, status, - resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES + resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES, + dispatchReceiverType ) } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt index 318321e4287..cc4db634ec7 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt @@ -6,10 +6,10 @@ package org.jetbrains.kotlin.fir.java.declarations import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.FirImplementationDetail import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSourceElement -import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.builder.FirBuilderDsl import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.builder.FirFieldBuilder @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.symbols.impl.FirDelegateFieldSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFieldSymbol +import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.FirVisitor @@ -42,6 +43,8 @@ class FirJavaField @FirImplementationDetail constructor( override val annotations: MutableList, override val typeParameters: MutableList, override var initializer: FirExpression?, + override val dispatchReceiverType: ConeKotlinType?, + override val attributes: FirDeclarationAttributes, ) : FirField() { init { symbol.bind(this) @@ -55,8 +58,6 @@ class FirJavaField @FirImplementationDetail constructor( override val origin: FirDeclarationOrigin get() = FirDeclarationOrigin.Java - override val attributes: FirDeclarationAttributes = FirDeclarationAttributes() - override fun transformReturnTypeRef(transformer: FirTransformer, data: D): FirField { returnTypeRef = returnTypeRef.transformSingle(transformer, data) return this @@ -163,6 +164,8 @@ internal class FirJavaFieldBuilder : FirFieldBuilder() { annotations, typeParameters, initializer, + dispatchReceiverType, + attributes, ) } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaMethod.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaMethod.kt index a0e91d3cbcc..5beda4584f5 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaMethod.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaMethod.kt @@ -6,10 +6,10 @@ package org.jetbrains.kotlin.fir.java.declarations import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.FirImplementationDetail import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSourceElement -import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.builder.FirBuilderDsl import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription import org.jetbrains.kotlin.fir.declarations.* @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirSimpleFunctionImpl import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol +import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef import org.jetbrains.kotlin.name.Name @@ -53,6 +54,7 @@ class FirJavaMethod @FirImplementationDetail constructor( containerSource: DeserializedContainerSource?, symbol: FirFunctionSymbol, annotations: MutableList, + dispatchReceiverType: ConeKotlinType?, ) : FirSimpleFunctionImpl( source, session, @@ -65,6 +67,7 @@ class FirJavaMethod @FirImplementationDetail constructor( body, status, containerSource, + dispatchReceiverType = dispatchReceiverType, contractDescription = FirEmptyContractDescription, name, symbol, @@ -107,6 +110,7 @@ class FirJavaMethodBuilder : FirSimpleFunctionBuilder() { containerSource, symbol, annotations, + dispatchReceiverType, ) } } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/SignatureEnhancement.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/SignatureEnhancement.kt index 751c0639d8f..ad4db202932 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/SignatureEnhancement.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/SignatureEnhancement.kt @@ -95,14 +95,18 @@ class FirSignatureEnhancement( session = this@FirSignatureEnhancement.session this.symbol = symbol this.name = name + returnTypeRef = newReturnTypeRef + + // TODO: Use some kind of copy mechanism visibility = firElement.visibility modality = firElement.modality - returnTypeRef = newReturnTypeRef isVar = firElement.isVar isStatic = firElement.isStatic annotations += firElement.annotations status = firElement.status initializer = firElement.initializer + dispatchReceiverType = firElement.dispatchReceiverType + attributes = firElement.attributes.copy() } return symbol } @@ -221,12 +225,16 @@ class FirSignatureEnhancement( isInner = firMethod.isInner } this.symbol = symbol + dispatchReceiverType = firMethod.dispatchReceiverType + attributes = firMethod.attributes.copy() } } else { FirConstructorBuilder().apply { returnTypeRef = newReturnTypeRef status = firMethod.status this.symbol = symbol + dispatchReceiverType = firMethod.dispatchReceiverType + attributes = firMethod.attributes.copy() } }.apply { source = firMethod.source @@ -250,6 +258,8 @@ class FirSignatureEnhancement( resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES valueParameters += newValueParameters typeParameters += firMethod.typeParameters + dispatchReceiverType = firMethod.dispatchReceiverType + attributes = firMethod.attributes.copy() } } else -> throw AssertionError("Unknown Java method to enhance: ${firMethod.render()}") diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassMembersEnhancementScope.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassMembersEnhancementScope.kt index c83bf00e6af..7ae0e0cb2b4 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassMembersEnhancementScope.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassMembersEnhancementScope.kt @@ -104,7 +104,8 @@ class JavaClassMembersEnhancementScope( FirDeclarationOrigin.Enhancement, newParameterTypes = valueParameters.zip(newParameterTypes).map { (valueParameter, newType) -> newType ?: valueParameter.returnTypeRef.coneType - } + }, + newDispatchReceiverType = dispatchReceiverType, ) } } diff --git a/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/scopes/JvmMappedScopes.kt b/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/scopes/JvmMappedScopes.kt index 2745335d041..e9d75ab0c29 100644 --- a/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/scopes/JvmMappedScopes.kt +++ b/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/scopes/JvmMappedScopes.kt @@ -46,7 +46,10 @@ fun wrapScopeWithJvmMapped( (klass.symbol.constructType( klass.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }.toTypedArray(), false - ) as ConeClassLikeType).wrapSubstitutionScopeIfNeed(useSiteSession, jvmMappedScope, klass, scopeSession, klass.classId) + ) as ConeClassLikeType).wrapSubstitutionScopeIfNeed( + useSiteSession, jvmMappedScope, klass, scopeSession, + derivedClass = klass, + ) } } } else { diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index e3b97e6c79d..8f3ea61e77f 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -415,7 +415,7 @@ class DeclarationsConverter( addCapturedTypeParameters(firTypeParameters) val selfType = classNode.toDelegatedSelfType(this) - + registerSelfType(selfType) val delegationSpecifiers = superTypeList?.let { convertDelegationSpecifiers(it, symbol, selfType) } var delegatedSuperTypeRef: FirTypeRef? = delegationSpecifiers?.delegatedSuperTypeRef @@ -500,8 +500,18 @@ class DeclarationsConverter( } if (modifiers.isEnum()) { - generateValuesFunction(baseSession, context.packageFqName, context.className, modifiers.hasExpect()) - generateValueOfFunction(baseSession, context.packageFqName, context.className, modifiers.hasExpect()) + generateValuesFunction( + baseSession, + context.packageFqName, + context.className, + modifiers.hasExpect() + ) + generateValueOfFunction( + baseSession, + context.packageFqName, + context.className, + modifiers.hasExpect() + ) } } } @@ -523,6 +533,7 @@ class DeclarationsConverter( symbol = FirAnonymousObjectSymbol() typeParameters += context.capturedTypeParameters.map { buildOuterClassTypeParameterRef { this.symbol = it } } val delegatedSelfType = objectLiteral.toDelegatedSelfType(this) + registerSelfType(delegatedSelfType) var modifiers = Modifier() var primaryConstructor: LighterASTNode? = null @@ -637,7 +648,7 @@ class DeclarationsConverter( emptyArray(), isNullable = false ) - }, + }.also { registerSelfType(it) }, delegatedSuperTypeRef = classWrapper.delegatedSelfTypeRef, superTypeCallEntry = enumSuperTypeCallEntry ) @@ -743,6 +754,8 @@ class DeclarationsConverter( this.valueParameters += valueParameters.map { it.firValueParameter } delegatedConstructor = firDelegatedCall this.body = body + }.apply { + containingClassAttr = currentDispatchReceiverType()!!.lookupTag }, valueParameters ) } @@ -814,6 +827,7 @@ class DeclarationsConverter( this.body = body context.firFunctionTargets.removeLast() }.also { + it.containingClassAttr = currentDispatchReceiverType()!!.lookupTag target.bind(it) } } @@ -969,6 +983,7 @@ class DeclarationsConverter( this.isLocal = false receiverTypeRef = receiverType symbol = FirPropertySymbol(callableIdForName(propertyName)) + dispatchReceiverType = currentDispatchReceiverType() withCapturedTypeParameters { typeParameters += firTypeParameters addCapturedTypeParameters(firTypeParameters) @@ -1292,6 +1307,7 @@ class DeclarationsConverter( } symbol = FirNamedFunctionSymbol(callableIdForName(functionName, isLocal)) + dispatchReceiverType = currentDispatchReceiverType() } } diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index cd7711679b6..7c9ffe9e39b 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -25,7 +25,6 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.* -import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock import org.jetbrains.kotlin.fir.references.builder.* import org.jetbrains.kotlin.fir.scopes.FirScopeProvider @@ -462,6 +461,8 @@ class RawFirBuilder( visibility ) else null extractAnnotationsTo(this) + + dispatchReceiverType = currentDispatchReceiverType() }.apply { isFromVararg = firParameter.isVararg } @@ -687,6 +688,8 @@ class RawFirBuilder( this@toFirConstructor?.extractAnnotationsTo(this) this@toFirConstructor?.extractValueParametersTo(this) this.body = body + }.apply { + containingClassAttr = currentDispatchReceiverType()!!.lookupTag } } @@ -750,6 +753,8 @@ class RawFirBuilder( val delegatedEntrySelfType = buildResolvedTypeRef { type = ConeClassLikeTypeImpl(this@buildAnonymousObject.symbol.toLookupTag(), emptyArray(), isNullable = false) } + registerSelfType(delegatedEntrySelfType) + superTypeRefs += delegatedEnumSelfTypeRef val superTypeCallEntry = superTypeListEntries.firstIsInstanceOrNull() val correctedEnumSelfTypeRef = buildResolvedTypeRef { @@ -777,6 +782,8 @@ class RawFirBuilder( } } } + }.apply { + containingClassAttr = currentDispatchReceiverType()!!.lookupTag } } @@ -827,6 +834,8 @@ class RawFirBuilder( addCapturedTypeParameters(typeParameters.take(classOrObject.typeParameters.size)) val delegatedSelfType = classOrObject.toDelegatedSelfType(this) + registerSelfType(delegatedSelfType) + val delegatedSuperType = classOrObject.extractSuperTypeListEntriesTo( this, delegatedSelfType, @@ -884,10 +893,14 @@ class RawFirBuilder( if (classOrObject.hasModifier(ENUM_KEYWORD)) { generateValuesFunction( - baseSession, context.packageFqName, context.className, classOrObject.hasExpectModifier() + baseSession, + context.packageFqName, + context.className, + classOrObject.hasExpectModifier() ) generateValueOfFunction( - baseSession, context.packageFqName, context.className, classOrObject.hasExpectModifier() + baseSession, context.packageFqName, context.className, + classOrObject.hasExpectModifier() ) } } @@ -907,6 +920,7 @@ class RawFirBuilder( symbol = FirAnonymousObjectSymbol() typeParameters += context.capturedTypeParameters.map { buildOuterClassTypeParameterRef { symbol = it } } val delegatedSelfType = objectDeclaration.toDelegatedSelfType(this) + registerSelfType(delegatedSelfType) objectDeclaration.extractAnnotationsTo(this) val delegatedSuperType = objectDeclaration.extractSuperTypeListEntriesTo( this, @@ -975,6 +989,7 @@ class RawFirBuilder( name = function.nameAsSafeName labelName = runIf(!name.isSpecial) { name.identifier } symbol = FirNamedFunctionSymbol(callableIdForName(function.nameAsSafeName, function.isLocal)) + dispatchReceiverType = currentDispatchReceiverType() status = FirDeclarationStatusImpl( if (function.isLocal) Visibilities.Local else function.visibility, function.modality, @@ -1170,6 +1185,7 @@ class RawFirBuilder( this.body = body this@RawFirBuilder.context.firFunctionTargets.removeLast() }.also { + it.containingClassAttr = currentDispatchReceiverType()!!.lookupTag target.bind(it) } } @@ -1244,6 +1260,7 @@ class RawFirBuilder( isLocal = false receiverTypeRef = receiverTypeReference.convertSafe() symbol = FirPropertySymbol(callableIdForName(propertyName)) + dispatchReceiverType = currentDispatchReceiverType() extractTypeParametersTo(this) withCapturedTypeParameters { addCapturedTypeParameters(this.typeParameters) diff --git a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt index ad90864de3a..5f6d441a0b8 100644 --- a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt +++ b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.references.builder.* import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.impl.* +import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef @@ -66,14 +67,27 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte ): T { context.className = context.className.child(name) context.localBits.add(isLocal) + val dispatchReceiversNumber = context.dispatchReceiverTypesStack.size return try { l() } finally { + require(context.dispatchReceiverTypesStack.size <= dispatchReceiversNumber + 1) { + "Wrong number of ${context.dispatchReceiverTypesStack.size}" + } + + if (context.dispatchReceiverTypesStack.size > dispatchReceiversNumber) { + context.dispatchReceiverTypesStack.removeAt(context.dispatchReceiverTypesStack.lastIndex) + } + context.className = context.className.parent() context.localBits.removeLast() } } + fun registerSelfType(selfType: FirResolvedTypeRef) { + context.dispatchReceiverTypesStack.add(selfType.type as ConeClassLikeType) + } + inline fun withCapturedTypeParameters(block: () -> T): T { val previous = context.capturedTypeParameters val result = block() @@ -109,6 +123,8 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte else -> CallableId(context.packageFqName, context.className, name) } + fun currentDispatchReceiverType(): ConeClassLikeType? = context.dispatchReceiverTypesStack.lastOrNull() + fun callableIdForClassConstructor() = if (context.className == FqName.ROOT) CallableId(context.packageFqName, Name.special("")) else CallableId(context.packageFqName, context.className, context.className.shortName()) @@ -1067,7 +1083,7 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte this.name = name status = FirDeclarationStatusImpl(Visibilities.Public, Modality.FINAL) symbol = FirNamedFunctionSymbol(CallableId(packageFqName, classFqName, name)) - + dispatchReceiverType = currentDispatchReceiverType() // Refer to FIR backend ClassMemberGenerator for body generation. } classBuilder.addDeclaration(componentFunction) @@ -1087,6 +1103,7 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte name = copyName status = FirDeclarationStatusImpl(Visibilities.Public, Modality.FINAL) symbol = FirNamedFunctionSymbol(CallableId(packageFqName, classFqName, copyName)) + dispatchReceiverType = currentDispatchReceiverType() for ((ktParameter, firProperty) in zippedParameters) { val propertyName = firProperty.name val parameterSource = ktParameter?.toFirSourceElement(FirFakeSourceElementKind.DataClassGeneratedMembers) diff --git a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Context.kt b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Context.kt index 12e146bc4ea..8d35e8bb7b0 100644 --- a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Context.kt +++ b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Context.kt @@ -6,9 +6,14 @@ package org.jetbrains.kotlin.fir.builder import kotlinx.collections.immutable.persistentListOf -import org.jetbrains.kotlin.fir.* +import org.jetbrains.kotlin.fir.FirFunctionTarget +import org.jetbrains.kotlin.fir.FirLabel +import org.jetbrains.kotlin.fir.FirLoopTarget +import org.jetbrains.kotlin.fir.FirSourceElementKind import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol +import org.jetbrains.kotlin.fir.types.ConeClassLikeType +import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -27,4 +32,5 @@ class Context { val arraySetArgument = mutableMapOf() var forcedElementSourceKind: FirSourceElementKind? = null + val dispatchReceiverTypesStack = mutableListOf() } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt index 31482813a43..a5e435f198a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.containingClassAttr import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.builder.FirTypeParameterBuilder import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction @@ -44,6 +45,7 @@ val SAM_PARAMETER_NAME = Name.identifier("block") class FirSamResolverImpl( private val firSession: FirSession, private val scopeSession: ScopeSession, + private val outerClassManager: FirOuterClassManager, ) : FirSamResolver() { private val resolvedFunctionType: MutableMap = mutableMapOf() @@ -197,6 +199,8 @@ class FirSamResolverImpl( } resolvePhase = FirResolvePhase.BODY_RESOLVE + }.apply { + containingClassAttr = outerClassManager.outerClass(firRegularClass.symbol)?.toLookupTag() } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ScopeUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ScopeUtils.kt index 08c565eb236..6b9db604795 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ScopeUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ScopeUtils.kt @@ -18,11 +18,13 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirScopeWithFakeOverrideTypeCalculat import org.jetbrains.kotlin.fir.scopes.impl.FirStandardOverrideChecker import org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScope import org.jetbrains.kotlin.fir.scopes.scopeForClass +import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl +import org.jetbrains.kotlin.name.ClassId fun ConeKotlinType.scope( useSiteSession: FirSession, @@ -64,7 +66,8 @@ private fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: Scope FirStandardOverrideChecker(useSiteSession), intersectedTypes.mapNotNullTo(mutableListOf()) { it.scope(useSiteSession, scopeSession, requiredPhase) - } + }, + type ) is ConeDefinitelyNotNullType -> original.scope(useSiteSession, scopeSession, requiredPhase) is ConeIntegerLiteralType -> error("ILT should not be in receiver position") @@ -72,6 +75,14 @@ private fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: Scope } } + +fun FirClass<*>.defaultType(): ConeClassLikeType = + when (this) { + is FirRegularClass -> defaultType() + is FirAnonymousObject -> defaultType() + else -> error("Unknown class ${this::class}") + } + fun FirRegularClass.defaultType(): ConeClassLikeTypeImpl { return ConeClassLikeTypeImpl( symbol.toLookupTag(), @@ -93,4 +104,16 @@ fun FirAnonymousObject.defaultType(): ConeClassLikeType { ) } +fun ClassId.defaultType(parameters: List): ConeClassLikeType = + ConeClassLikeTypeImpl( + ConeClassLikeLookupTagImpl(this), + parameters.map { + ConeTypeParameterTypeImpl( + it.toLookupTag(), + isNullable = false + ) + }.toTypedArray(), + isNullable = false, + ) + val TYPE_PARAMETER_SCOPE_KEY = scopeSessionKey() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SupertypeUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SupertypeUtils.kt index 13c7335b386..4ef186f110e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SupertypeUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SupertypeUtils.kt @@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.types.model.CaptureStatus abstract class SupertypeSupplier { @@ -91,7 +90,7 @@ fun ConeClassLikeType.wrapSubstitutionScopeIfNeed( useSiteMemberScope: FirTypeScope, declaration: FirClassLikeDeclaration<*>, builder: ScopeSession, - derivedClassId: ClassId? + derivedClass: FirRegularClass ): FirTypeScope { if (this.typeArguments.isEmpty()) return useSiteMemberScope return builder.getOrBuild(declaration.symbol, SubstitutionScopeKey(this)) { @@ -110,7 +109,8 @@ fun ConeClassLikeType.wrapSubstitutionScopeIfNeed( } FirClassSubstitutionScope( session, useSiteMemberScope, substitutor, - skipPrivateMembers = true, derivedClassId = derivedClassId + dispatchReceiverTypeForSubstitutedMembers = derivedClass.defaultType(), + skipPrivateMembers = true, ) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt index 02fe401afbe..fca0cfe2dba 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt @@ -124,8 +124,11 @@ private fun FirTypeAliasSymbol.findSAMConstructorForTypeAlias( session ) { newReturnType, newParameterTypes, newTypeParameters -> FirFakeOverrideGenerator.createFakeOverrideFunction( - session, this, namedSymbol, null, - newReturnType, newParameterTypes, newTypeParameters + session, this, namedSymbol, + newDispatchReceiverType = null, + newReceiverType = null, + newReturnType, newParameterTypes, newTypeParameters, + expansionRegularClass.classId, ).fir } ?: return null @@ -263,6 +266,7 @@ private fun prepareSubstitutingScopeForTypeAliasConstructors( valueParameters += this@factory.valueParameters } this.typeParameters += newTypeParameters + this.attributes = this@factory.attributes.copy() } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirCloneableSymbolProvider.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirCloneableSymbolProvider.kt index 7d8fd4b65e3..33825d8e5cc 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirCloneableSymbolProvider.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirCloneableSymbolProvider.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.builder.buildRegularClass import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl +import org.jetbrains.kotlin.fir.resolve.constructType import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals import org.jetbrains.kotlin.fir.scopes.FirScopeProvider @@ -47,6 +48,7 @@ class FirCloneableSymbolProvider(session: FirSession, scopeProvider: FirScopePro Modality.ABSTRACT ) classKind = ClassKind.INTERFACE + symbol = FirRegularClassSymbol(CLONEABLE_CLASS_ID) declarations += buildSimpleFunction { this.session = session resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES @@ -57,10 +59,11 @@ class FirCloneableSymbolProvider(session: FirSession, scopeProvider: FirScopePro status = FirDeclarationStatusImpl(Visibilities.Protected, Modality.OPEN) name = CLONE symbol = FirNamedFunctionSymbol(CallableId(CLONEABLE_CLASS_ID, CLONE)) + dispatchReceiverType = this@buildRegularClass.symbol.constructType(emptyArray(), isNullable = false) } this.scopeProvider = scopeProvider name = CLONEABLE - symbol = FirRegularClassSymbol(CLONEABLE_CLASS_ID) + } override fun getClassLikeSymbolByFqName(classId: ClassId): FirClassLikeSymbol<*>? { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt index 9d3cb58deff..6a9861c2657 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt @@ -122,7 +122,7 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb override val symbolProvider: FirSymbolProvider = session.firSymbolProvider override val resolutionStageRunner: ResolutionStageRunner = ResolutionStageRunner() - override val samResolver: FirSamResolver = FirSamResolverImpl(session, scopeSession) + private val qualifiedResolver: FirQualifiedNameResolver = FirQualifiedNameResolver(this) override val callResolver: FirCallResolver = FirCallResolver( this, @@ -137,5 +137,6 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb override val syntheticCallGenerator: FirSyntheticCallGenerator = FirSyntheticCallGenerator(this) override val doubleColonExpressionResolver: FirDoubleColonExpressionResolver = FirDoubleColonExpressionResolver(session) override val outerClassManager: FirOuterClassManager = FirOuterClassManager(session, context.outerLocalClassForNested) + override val samResolver: FirSamResolver = FirSamResolverImpl(session, scopeSession, outerClassManager) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/KotlinScopeProvider.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/KotlinScopeProvider.kt index 30e6d7dc0b8..50f5b0e8bbd 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/KotlinScopeProvider.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/KotlinScopeProvider.kt @@ -13,7 +13,6 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.scopes.impl.* import org.jetbrains.kotlin.fir.symbols.CallableId -import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.types.ConeClassErrorType import org.jetbrains.kotlin.fir.types.ConeClassLikeType @@ -60,9 +59,9 @@ class KotlinScopeProvider( useSiteSession, FirTypeIntersectionScope.prepareIntersectionScope( useSiteSession, FirStandardOverrideChecker(useSiteSession), scopes, - klass.classId, + klass.defaultType(), ), - decoratedDeclaredMemberScope + decoratedDeclaredMemberScope, ) } } @@ -113,7 +112,7 @@ fun FirClass<*>.scopeForClass( ): FirTypeScope = scopeForClassImpl( substitutor, useSiteSession, scopeSession, skipPrivateMembers = false, - containingClassForAdditionalMembers = symbol.toLookupTag(), + classFirDispatchReceiver = this, // TODO: why it's always false? isFromExpectClass = false ) @@ -129,12 +128,12 @@ private fun FirClass<*>.scopeForSupertype( useSiteSession, scopeSession, skipPrivateMembers = true, - containingClassForAdditionalMembers = subClass.symbol.toLookupTag(), + classFirDispatchReceiver = subClass, isFromExpectClass = (subClass as? FirRegularClass)?.isExpect == true ).let { if (delegateField != null) { scopeSession.getOrBuild(delegateField, DelegatedMemberScopeKey(delegateField.symbol.callableId)) { - FirDelegatedMemberScope(it, useSiteSession, subClass.symbol.toLookupTag(), delegateField) + FirDelegatedMemberScope(it, useSiteSession, subClass, delegateField) } } else { it @@ -146,18 +145,18 @@ private fun FirClass<*>.scopeForClassImpl( useSiteSession: FirSession, scopeSession: ScopeSession, skipPrivateMembers: Boolean, - containingClassForAdditionalMembers: ConeClassLikeLookupTag, + classFirDispatchReceiver: FirClass<*>, isFromExpectClass: Boolean ): FirTypeScope { val basicScope = unsubstitutedScope(useSiteSession, scopeSession, withForcedTypeCalculator = false) if (substitutor == ConeSubstitutor.Empty) return basicScope return scopeSession.getOrBuild( - this, ConeSubstitutionScopeKey(containingClassForAdditionalMembers.classId, isFromExpectClass, substitutor) + this, ConeSubstitutionScopeKey(classFirDispatchReceiver.classId, isFromExpectClass, substitutor) ) { FirClassSubstitutionScope( - useSiteSession, basicScope, substitutor, skipPrivateMembers, - containingClassForAdditionalMembers.classId, makeExpect = isFromExpectClass + useSiteSession, basicScope, substitutor, classFirDispatchReceiver.defaultType(), + skipPrivateMembers, makeExpect = isFromExpectClass ) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt index d77013263d6..ac4da4cc229 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt @@ -12,13 +12,11 @@ import org.jetbrains.kotlin.fir.declarations.builder.* import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.chain -import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.scopes.FakeOverrideSubstitution import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.addToStdlib.runIf @@ -26,8 +24,8 @@ class FirClassSubstitutionScope( private val session: FirSession, private val useSiteMemberScope: FirTypeScope, private val substitutor: ConeSubstitutor, + private val dispatchReceiverTypeForSubstitutedMembers: ConeClassLikeType, private val skipPrivateMembers: Boolean, - private val derivedClassId: ClassId? = null, private val makeExpect: Boolean = false ) : FirTypeScope() { @@ -35,6 +33,8 @@ class FirClassSubstitutionScope( private val fakeOverrideConstructors = mutableMapOf() private val fakeOverrideVariables = mutableMapOf, FirVariableSymbol<*>>() + private val newOwnerClassId = dispatchReceiverTypeForSubstitutedMembers.lookupTag.classId + override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) { useSiteMemberScope.processFunctionsByName(name) process@{ original -> val function = fakeOverrideFunctions.getOrPut(original) { createFakeOverrideFunction(original) } @@ -139,11 +139,12 @@ class FirClassSubstitutionScope( session, member, original, + dispatchReceiverTypeForSubstitutedMembers, newReceiverType, newReturnType, newParameterTypes, newTypeParameters as List, - derivedClassId, + newOwnerClassId, makeExpect, fakeOverrideSubstitution ) @@ -163,7 +164,8 @@ class FirClassSubstitutionScope( } return FirFakeOverrideGenerator.createFakeOverrideConstructor( FirConstructorSymbol(original.callableId, overriddenSymbol = original), - session, constructor, newReturnType, newParameterTypes, newTypeParameters, makeExpect, fakeOverrideSubstitution + session, constructor, dispatchReceiverTypeForSubstitutedMembers, + newReturnType, newParameterTypes, newTypeParameters, makeExpect, fakeOverrideSubstitution ).symbol } @@ -184,10 +186,11 @@ class FirClassSubstitutionScope( session, member, original, + dispatchReceiverTypeForSubstitutedMembers, newReceiverType, newReturnType, newTypeParameters as List, - derivedClassId, + newOwnerClassId, makeExpect, fakeOverrideSubstitution ) @@ -205,7 +208,7 @@ class FirClassSubstitutionScope( val (newTypeParameters, substitutor) = FirFakeOverrideGenerator.createNewTypeParametersAndSubstitutor( member as FirTypeParameterRefsOwner, substitutor, - forceTypeParametersRecreation = derivedClassId != null && derivedClassId != member.symbol.callableId.classId + forceTypeParametersRecreation = dispatchReceiverTypeForSubstitutedMembers.lookupTag != member.dispatchReceiverClassOrNull() ) val receiverType = member.receiverTypeRef?.coneType @@ -226,7 +229,7 @@ class FirClassSubstitutionScope( // TODO: do we have fields with implicit type? val newReturnType = returnType?.substitute() ?: return original - return FirFakeOverrideGenerator.createFakeOverrideField(session, member, original, newReturnType, derivedClassId) + return FirFakeOverrideGenerator.createFakeOverrideField(session, member, original, newReturnType, newOwnerClassId) } private fun createFakeOverrideAccessor(original: FirAccessorSymbol): FirAccessorSymbol { @@ -250,6 +253,7 @@ class FirClassSubstitutionScope( session, member, original, + dispatchReceiverTypeForSubstitutedMembers, newReturnType, newParameterTypes, fakeOverrideSubstitution diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirDelegatedMemberScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirDelegatedMemberScope.kt index 1fd0b4cb952..9614936addc 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirDelegatedMemberScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirDelegatedMemberScope.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.scopes.impl import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag @@ -17,11 +18,12 @@ import org.jetbrains.kotlin.name.Name class FirDelegatedMemberScope( private val useSiteScope: FirTypeScope, private val session: FirSession, - private val containingClass: ConeClassLikeLookupTag, + private val containingClass: FirClass<*>, private val delegateField: FirField, ) : FirTypeScope() { private val delegatedFunctionCache = mutableMapOf() private val delegatedPropertyCache = mutableMapOf() + private val dispatchReceiverType = containingClass.defaultType() override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) { useSiteScope.processFunctionsByName(name) processor@{ functionSymbol -> @@ -43,9 +45,10 @@ class FirDelegatedMemberScope( original, session, FirDeclarationOrigin.Delegated, + newDispatchReceiverType = dispatchReceiverType, newModality = Modality.OPEN, ).apply { - delegatedWrapperData = DelegatedWrapperData(functionSymbol.fir, containingClass, delegateField) + delegatedWrapperData = DelegatedWrapperData(functionSymbol.fir, containingClass.symbol.toLookupTag(), delegateField) }.symbol as FirNamedFunctionSymbol } processor(delegatedSymbol) @@ -72,8 +75,9 @@ class FirDelegatedMemberScope( original, session, newModality = Modality.OPEN, + newDispatchReceiverType = dispatchReceiverType, ).apply { - delegatedWrapperData = DelegatedWrapperData(propertySymbol.fir, containingClass, delegateField) + delegatedWrapperData = DelegatedWrapperData(propertySymbol.fir, containingClass.symbol.toLookupTag(), delegateField) }.symbol } processor(delegatedSymbol) @@ -105,7 +109,7 @@ class FirDelegatedMemberScope( ): ProcessorAction { val wrappedData = (symbol.fir as? FirCallableMemberDeclaration<*>)?.delegatedWrapperData return when { - wrappedData == null || wrappedData.containingClass != containingClass -> { + wrappedData == null || wrappedData.containingClass != containingClass.symbol.toLookupTag() -> { useSiteScope.processDirectOverriddenCallablesWithBaseScope(symbol, processor) } else -> processor(wrappedData.wrapped.symbol as D, useSiteScope) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirFakeOverrideGenerator.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirFakeOverrideGenerator.kt index 276de0851bd..454ca646a62 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirFakeOverrideGenerator.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirFakeOverrideGenerator.kt @@ -32,6 +32,7 @@ object FirFakeOverrideGenerator { session: FirSession, baseFunction: FirSimpleFunction, baseSymbol: FirNamedFunctionSymbol, + newDispatchReceiverType: ConeKotlinType?, newReceiverType: ConeKotlinType? = null, newReturnType: ConeKotlinType? = null, newParameterTypes: List? = null, @@ -45,7 +46,7 @@ object FirFakeOverrideGenerator { isFakeOverride = true, overriddenSymbol = baseSymbol ) createFakeOverrideFunction( - symbol, session, baseFunction, newReceiverType, newReturnType, + symbol, session, baseFunction, newDispatchReceiverType, newReceiverType, newReturnType, newParameterTypes, newTypeParameters, isExpect, fakeOverrideSubstitution ) return symbol @@ -55,6 +56,7 @@ object FirFakeOverrideGenerator { fakeOverrideSymbol: FirFunctionSymbol, session: FirSession, baseFunction: FirSimpleFunction, + newDispatchReceiverType: ConeKotlinType?, newReceiverType: ConeKotlinType?, newReturnType: ConeKotlinType?, newParameterTypes: List?, @@ -70,6 +72,7 @@ object FirFakeOverrideGenerator { session, FirDeclarationOrigin.SubstitutionOverride, isExpect, + newDispatchReceiverType, newParameterTypes, newTypeParameters, newReceiverType, @@ -84,6 +87,7 @@ object FirFakeOverrideGenerator { session: FirSession, origin: FirDeclarationOrigin, isExpect: Boolean = baseFunction.isExpect, + newDispatchReceiverType: ConeKotlinType?, newParameterTypes: List? = null, newTypeParameters: List? = null, newReceiverType: ConeKotlinType? = null, @@ -101,6 +105,8 @@ object FirFakeOverrideGenerator { symbol = newSymbol resolvePhase = baseFunction.resolvePhase + dispatchReceiverType = newDispatchReceiverType + attributes = baseFunction.attributes.copy() typeParameters += configureAnnotationsTypeParametersAndSignature( session, baseFunction, newParameterTypes, newTypeParameters, newReceiverType, newReturnType, fakeOverrideSubstitution @@ -112,6 +118,7 @@ object FirFakeOverrideGenerator { fakeOverrideSymbol: FirConstructorSymbol, session: FirSession, baseConstructor: FirConstructor, + newDispatchReceiverType: ConeKotlinType?, newReturnType: ConeKotlinType?, newParameterTypes: List?, newTypeParameters: List?, @@ -121,17 +128,21 @@ object FirFakeOverrideGenerator { // TODO: consider using here some light-weight functions instead of pseudo-real FirMemberFunctionImpl // As second alternative, we can invent some light-weight kind of FirRegularClass return buildConstructor { - source = baseConstructor.source this.session = session origin = FirDeclarationOrigin.SubstitutionOverride receiverTypeRef = baseConstructor.receiverTypeRef?.withReplacedConeType(null) status = baseConstructor.status.updatedStatus(isExpect) symbol = fakeOverrideSymbol - resolvePhase = baseConstructor.resolvePhase typeParameters += configureAnnotationsTypeParametersAndSignature( session, baseConstructor, newParameterTypes, newTypeParameters, newReceiverType = null, newReturnType, fakeOverrideSubstitution ) + + dispatchReceiverType = newDispatchReceiverType + + resolvePhase = baseConstructor.resolvePhase + source = baseConstructor.source + attributes = baseConstructor.attributes.copy() } } @@ -235,6 +246,7 @@ object FirFakeOverrideGenerator { session: FirSession, baseProperty: FirProperty, baseSymbol: FirPropertySymbol, + newDispatchReceiverType: ConeKotlinType?, newReceiverType: ConeKotlinType? = null, newReturnType: ConeKotlinType? = null, newTypeParameters: List? = null, @@ -248,7 +260,7 @@ object FirFakeOverrideGenerator { ) createCopyForFirProperty( symbol, baseProperty, session, isExpect, - newTypeParameters, newReceiverType, newReturnType, + newDispatchReceiverType, newTypeParameters, newReceiverType, newReturnType, fakeOverrideSubstitution = fakeOverrideSubstitution ) return symbol @@ -259,6 +271,7 @@ object FirFakeOverrideGenerator { baseProperty: FirProperty, session: FirSession, isExpect: Boolean = baseProperty.isExpect, + newDispatchReceiverType: ConeKotlinType?, newTypeParameters: List? = null, newReceiverType: ConeKotlinType? = null, newReturnType: ConeKotlinType? = null, @@ -277,6 +290,8 @@ object FirFakeOverrideGenerator { status = baseProperty.status.updatedStatus(isExpect, newModality, newVisibility) resolvePhase = baseProperty.resolvePhase + dispatchReceiverType = newDispatchReceiverType + attributes = baseProperty.attributes.copy() typeParameters += configureAnnotationsTypeParametersAndSignature( baseProperty, newTypeParameters, @@ -373,17 +388,20 @@ object FirFakeOverrideGenerator { CallableId(derivedClassId ?: baseSymbol.callableId.classId!!, baseField.name) ) buildField { - source = baseField.source this.session = session - origin = FirDeclarationOrigin.SubstitutionOverride - resolvePhase = baseField.resolvePhase - returnTypeRef = baseField.returnTypeRef.withReplacedConeType(newReturnType) - name = baseField.name this.symbol = symbol + origin = FirDeclarationOrigin.SubstitutionOverride + returnTypeRef = baseField.returnTypeRef.withReplacedConeType(newReturnType) + + source = baseField.source + resolvePhase = baseField.resolvePhase + name = baseField.name isVar = baseField.isVar status = baseField.status resolvePhase = baseField.resolvePhase annotations += baseField.annotations + attributes = baseField.attributes.copy() + dispatchReceiverType = baseField.dispatchReceiverType } return symbol } @@ -392,6 +410,7 @@ object FirFakeOverrideGenerator { session: FirSession, baseProperty: FirSyntheticProperty, baseSymbol: FirAccessorSymbol, + newDispatchReceiverType: ConeKotlinType?, newReturnType: ConeKotlinType?, newParameterTypes: List?, fakeOverrideSubstitution: FakeOverrideSubstitution? @@ -401,6 +420,7 @@ object FirFakeOverrideGenerator { functionSymbol, session, baseProperty.getter.delegate, + newDispatchReceiverType, newReceiverType = null, newReturnType, newParameterTypes, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt index c71abeac6fc..f2d8fc71c8a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt @@ -10,16 +10,13 @@ import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.dispatchReceiverClassOrNull import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.scopes.* import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.PossiblyFirFakeOverrideSymbol import org.jetbrains.kotlin.fir.symbols.impl.* -import org.jetbrains.kotlin.fir.types.ConeFlexibleType -import org.jetbrains.kotlin.fir.types.ConeKotlinType -import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext -import org.jetbrains.kotlin.fir.types.coneTypeSafe -import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeCheckerContext @@ -30,7 +27,7 @@ class FirTypeIntersectionScope private constructor( session: FirSession, overrideChecker: FirOverrideChecker, private val scopes: List, - private val derivedClassId: ClassId?, + private val dispatchReceiverType: ConeKotlinType, ) : AbstractFirOverrideScope(session, overrideChecker) { private val absentFunctions: MutableSet = mutableSetOf() private val absentProperties: MutableSet = mutableSetOf() @@ -261,9 +258,13 @@ class FirTypeIntersectionScope private constructor( newModality: Modality, newVisibility: Visibility, ): FirNamedFunctionSymbol { + val newSymbol = FirNamedFunctionSymbol( - CallableId(derivedClassId ?: mostSpecific.callableId.classId!!, mostSpecific.fir.name), + CallableId( + dispatchReceiverType.classId ?: mostSpecific.dispatchReceiverClassOrNull()?.classId!!, + mostSpecific.fir.name + ), mostSpecific.isFakeOverride, mostSpecific, isIntersectionOverride = true @@ -273,6 +274,7 @@ class FirTypeIntersectionScope private constructor( newSymbol, mostSpecificFunction, session, FirDeclarationOrigin.IntersectionOverride, mostSpecificFunction.isExpect, + newDispatchReceiverType = dispatchReceiverType, newModality = newModality, newVisibility = newVisibility, ) @@ -290,6 +292,7 @@ class FirTypeIntersectionScope private constructor( newSymbol, mostSpecificProperty, mostSpecificProperty.session, newModality = newModality, newVisibility = newVisibility, + newDispatchReceiverType = dispatchReceiverType, ) return newSymbol } @@ -486,10 +489,10 @@ class FirTypeIntersectionScope private constructor( session: FirSession, overrideChecker: FirOverrideChecker, scopes: List, - derivedClassId: ClassId? = null, + dispatchReceiverType: ConeKotlinType, ): FirTypeScope { scopes.singleOrNull()?.let { return it } - return FirTypeIntersectionScope(session, overrideChecker, scopes, derivedClassId) + return FirTypeIntersectionScope(session, overrideChecker, scopes, dispatchReceiverType) } } } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirConstructorBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirConstructorBuilder.kt index 5141013b87f..8bc8af44ab4 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirConstructorBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirConstructorBuilder.kt @@ -108,6 +108,7 @@ inline fun buildConstructorCopy(original: FirConstructor, init: FirConstructorBu copyBuilder.valueParameters.addAll(original.valueParameters) copyBuilder.status = original.status copyBuilder.containerSource = original.containerSource + copyBuilder.dispatchReceiverType = original.dispatchReceiverType copyBuilder.annotations.addAll(original.annotations) copyBuilder.symbol = original.symbol copyBuilder.delegatedConstructor = original.delegatedConstructor diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/ClassMembers.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/ClassMembers.kt new file mode 100644 index 00000000000..fa37e7f6bab --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/ClassMembers.kt @@ -0,0 +1,33 @@ +/* + * 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.fir + +import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration +import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration +import org.jetbrains.kotlin.fir.declarations.FirDeclarationDataKey +import org.jetbrains.kotlin.fir.declarations.FirDeclarationDataRegistry +import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag +import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.types.ConeClassLikeType +import org.jetbrains.kotlin.fir.types.ConeIntersectionType + +fun FirCallableSymbol<*>.dispatchReceiverClassOrNull(): ConeClassLikeLookupTag? = + (fir as? FirCallableMemberDeclaration<*>)?.dispatchReceiverClassOrNull() + +fun FirCallableDeclaration<*>.dispatchReceiverClassOrNull(): ConeClassLikeLookupTag? { + if (this !is FirCallableMemberDeclaration<*>) return null + if (symbol.isIntersectionOverride && dispatchReceiverType is ConeIntersectionType) return symbol.overriddenSymbol!!.fir.dispatchReceiverClassOrNull() + + return (dispatchReceiverType as? ConeClassLikeType)?.lookupTag +} + +fun FirCallableSymbol<*>.containingClass(): ConeClassLikeLookupTag? = fir.containingClass() +fun FirCallableDeclaration<*>.containingClass(): ConeClassLikeLookupTag? { + return (containingClassAttr ?: dispatchReceiverClassOrNull()) +} + +private object ContainingClassKey : FirDeclarationDataKey() +var FirCallableDeclaration<*>.containingClassAttr: ConeClassLikeLookupTag? by FirDeclarationDataRegistry.data(ContainingClassKey) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/EnumClassUtils.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/EnumClassUtils.kt index d247d89336f..4e502fddd80 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/EnumClassUtils.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/EnumClassUtils.kt @@ -55,6 +55,8 @@ fun FirRegularClassBuilder.generateValuesFunction( symbol = FirNamedFunctionSymbol(CallableId(packageFqName, classFqName, ENUM_VALUES)) resolvePhase = FirResolvePhase.BODY_RESOLVE body = buildEmptyExpressionBlock() + }.apply { + containingClassAttr = this@generateValuesFunction.symbol.toLookupTag() } } @@ -93,5 +95,7 @@ fun FirRegularClassBuilder.generateValueOfFunction( } resolvePhase = FirResolvePhase.BODY_RESOLVE body = buildEmptyExpressionBlock() + }.apply { + containingClassAttr = this@generateValueOfFunction.symbol.toLookupTag() } }