[FIR] Introduce different synthetic origins for FIR declarations

This is needed to be able to precisely distinguish different synthetic
  declarations (like fields for delegates and functions for data classes)
  in fir2ir
This commit is contained in:
Dmitriy Novozhilov
2023-07-27 15:07:29 +03:00
committed by Space Team
parent 5b7b885dac
commit 69a35970eb
20 changed files with 45 additions and 27 deletions
@@ -64,10 +64,10 @@ internal tailrec fun FirDeclaration.ktSymbolOrigin(): KtSymbolOrigin = when (ori
FirDeclarationOrigin.Enhancement -> KtSymbolOrigin.JAVA FirDeclarationOrigin.Enhancement -> KtSymbolOrigin.JAVA
FirDeclarationOrigin.IntersectionOverride -> KtSymbolOrigin.INTERSECTION_OVERRIDE FirDeclarationOrigin.IntersectionOverride -> KtSymbolOrigin.INTERSECTION_OVERRIDE
FirDeclarationOrigin.Delegated -> KtSymbolOrigin.DELEGATED FirDeclarationOrigin.Delegated -> KtSymbolOrigin.DELEGATED
FirDeclarationOrigin.Synthetic -> { is FirDeclarationOrigin.Synthetic -> {
when { when {
source?.kind == KtFakeSourceElementKind.DataClassGeneratedMembers -> KtSymbolOrigin.SOURCE_MEMBER_GENERATED source?.kind == KtFakeSourceElementKind.DataClassGeneratedMembers -> KtSymbolOrigin.SOURCE_MEMBER_GENERATED
this is FirValueParameter && this.containingFunctionSymbol.origin == FirDeclarationOrigin.Synthetic -> KtSymbolOrigin.SOURCE_MEMBER_GENERATED this is FirValueParameter && this.containingFunctionSymbol.origin is FirDeclarationOrigin.Synthetic -> KtSymbolOrigin.SOURCE_MEMBER_GENERATED
this is FirSyntheticProperty || this is FirSyntheticPropertyAccessor -> KtSymbolOrigin.JAVA_SYNTHETIC_PROPERTY this is FirSyntheticProperty || this is FirSyntheticPropertyAccessor -> KtSymbolOrigin.JAVA_SYNTHETIC_PROPERTY
else -> errorWithAttachment("Invalid FirDeclarationOrigin ${origin::class.simpleName}") { else -> errorWithAttachment("Invalid FirDeclarationOrigin ${origin::class.simpleName}") {
@@ -8,7 +8,7 @@ D:
[Source]: public abstract val x: R|kotlin/Int| from Use site scope of /A [id: 1] [Source]: public abstract val x: R|kotlin/Int| from Use site scope of /A [id: 1]
[Source]: public abstract val x: R|kotlin/String| from Use site scope of /B [id: 2] [Source]: public abstract val x: R|kotlin/String| from Use site scope of /B [id: 2]
[Java(Source)]: private open field y: R|kotlin/Int| from Java enhancement scope for /D [id: 0] [Java(Source)]: private open field y: R|kotlin/Int| from Java enhancement scope for /D [id: 0]
[Synthetic]: public abstract val y: R|kotlin/Int| from Java enhancement scope for /D [id: 0] [JavaProperty]: public abstract val y: R|kotlin/Int| from Java enhancement scope for /D [id: 0]
[Source]: public abstract val y: R|kotlin/Int| from Use site scope of /A [id: 1] [Source]: public abstract val y: R|kotlin/Int| from Use site scope of /A [id: 1]
[Source]: public abstract val y: R|kotlin/Int| from Use site scope of /B [id: 2] [Source]: public abstract val y: R|kotlin/Int| from Use site scope of /B [id: 2]
[Enhancement]: public abstract fun getX(): R|kotlin/Any!| from Java enhancement scope for /D [id: 0] [Enhancement]: public abstract fun getX(): R|kotlin/Any!| from Java enhancement scope for /D [id: 0]
@@ -1,4 +1,4 @@
C: C:
[Synthetic]: public open val foo: R|kotlin/Int| from Java enhancement scope for /C [id: 0] [JavaProperty]: public open val foo: R|kotlin/Int| from Java enhancement scope for /C [id: 0]
[Source]: public abstract val foo: R|kotlin/Int| from Use site scope of /B [id: 1] [Source]: public abstract val foo: R|kotlin/Int| from Use site scope of /B [id: 1]
@@ -1,8 +1,8 @@
D: D:
[Synthetic]: public open val x: R|kotlin/Int| from Java enhancement scope for /D [id: 0] [JavaProperty]: public open val x: R|kotlin/Int| from Java enhancement scope for /D [id: 0]
[Synthetic]: public open val x: R|kotlin/Int| from Java enhancement scope for /B [id: 1] [JavaProperty]: public open val x: R|kotlin/Int| from Java enhancement scope for /B [id: 1]
[Source]: public open val x: R|kotlin/Int| from Use site scope of /A [id: 2] [Source]: public open val x: R|kotlin/Int| from Use site scope of /A [id: 2]
[Synthetic]: public open val y: R|kotlin/Int| from Java enhancement scope for /D [id: 0] [JavaProperty]: public open val y: R|kotlin/Int| from Java enhancement scope for /D [id: 0]
[Source]: public open val y: R|kotlin/Int| from Java enhancement scope for /B [id: 1] [Source]: public open val y: R|kotlin/Int| from Java enhancement scope for /B [id: 1]
[Source]: public open val y: R|kotlin/Int| from Use site scope of /A [id: 1] [Source]: public open val y: R|kotlin/Int| from Use site scope of /A [id: 1]
@@ -87,7 +87,7 @@ class NativeForwardDeclarationsSymbolProvider(
buildRegularClass { buildRegularClass {
moduleData = forwardDeclarationsModuleData moduleData = forwardDeclarationsModuleData
origin = FirDeclarationOrigin.Synthetic origin = FirDeclarationOrigin.Synthetic.ForwardDeclaration
check(!classId.isNestedClass) { "Expected top-level class when building forward declaration, got $classId" } check(!classId.isNestedClass) { "Expected top-level class when building forward declaration, got $classId" }
name = classId.shortClassName name = classId.shortClassName
status = FirResolvedDeclarationStatusImpl( status = FirResolvedDeclarationStatusImpl(
@@ -598,7 +598,7 @@ class FirElementSerializer private constructor(
private fun FirFunction.memberKind(): MemberKind { private fun FirFunction.memberKind(): MemberKind {
return when (origin) { return when (origin) {
FirDeclarationOrigin.Delegated -> MemberKind.DELEGATION FirDeclarationOrigin.Delegated -> MemberKind.DELEGATION
FirDeclarationOrigin.Synthetic -> MemberKind.SYNTHESIZED is FirDeclarationOrigin.Synthetic -> MemberKind.SYNTHESIZED
else -> MemberKind.DECLARATION else -> MemberKind.DECLARATION
} }
} }
@@ -699,7 +699,7 @@ fun FirSession.createFilesWithGeneratedDeclarations(): List<FirFile> {
moduleData = this@createFilesWithGeneratedDeclarations.moduleData moduleData = this@createFilesWithGeneratedDeclarations.moduleData
containingFileSymbol = this@buildFile.symbol containingFileSymbol = this@buildFile.symbol
} }
origin = FirDeclarationOrigin.Synthetic origin = FirDeclarationOrigin.Synthetic.PluginFile
moduleData = this@createFilesWithGeneratedDeclarations.moduleData moduleData = this@createFilesWithGeneratedDeclarations.moduleData
packageDirective = buildPackageDirective { packageDirective = buildPackageDirective {
this.packageFqName = packageFqName this.packageFqName = packageFqName
@@ -137,7 +137,7 @@ class Fir2IrConverter(
else -> else ->
NaiveSourceBasedFileEntryImpl(file.sourceFile?.path ?: file.sourceFile?.name ?: file.name) NaiveSourceBasedFileEntryImpl(file.sourceFile?.path ?: file.sourceFile?.name ?: file.name)
} }
FirDeclarationOrigin.Synthetic -> NaiveSourceBasedFileEntryImpl(file.name) is FirDeclarationOrigin.Synthetic -> NaiveSourceBasedFileEntryImpl(file.name)
else -> error("Unsupported file origin: ${file.origin}") else -> error("Unsupported file origin: ${file.origin}")
} }
val irFile = IrFileImpl( val irFile = IrFileImpl(
@@ -160,7 +160,7 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) : Fir2IrCompon
for (name in listOf(EQUALS, HASHCODE_NAME, TO_STRING)) { for (name in listOf(EQUALS, HASHCODE_NAME, TO_STRING)) {
scope.processFunctionsByName(name) { scope.processFunctionsByName(name) {
// We won't synthesize a function if there is a user-contributed (non-synthetic) one. // We won't synthesize a function if there is a user-contributed (non-synthetic) one.
if (it.origin != FirDeclarationOrigin.Synthetic) return@processFunctionsByName if (it.origin !is FirDeclarationOrigin.Synthetic) return@processFunctionsByName
if (it.containingClassLookupTag() != klass.symbol.toLookupTag()) return@processFunctionsByName if (it.containingClassLookupTag() != klass.symbol.toLookupTag()) return@processFunctionsByName
require(!contains(name)) { require(!contains(name)) {
"Two synthetic functions $name were found in data/value class ${klass.name}:\n" + "Two synthetic functions $name were found in data/value class ${klass.name}:\n" +
@@ -25,6 +25,9 @@ import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.isEquals import org.jetbrains.kotlin.fir.declarations.isEquals
import org.jetbrains.kotlin.fir.declarations.utils.isData
import org.jetbrains.kotlin.fir.declarations.utils.isInline
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
@@ -52,6 +55,11 @@ class FirClassAnySynthesizedMemberScope(
klass: FirRegularClass, klass: FirRegularClass,
scopeSession: ScopeSession, scopeSession: ScopeSession,
) : FirContainingNamesAwareScope() { ) : FirContainingNamesAwareScope() {
private val originForFunctions = when {
klass.isData -> FirDeclarationOrigin.Synthetic.DataClassMember
klass.isInline -> FirDeclarationOrigin.Synthetic.ValueClassMember
else -> error("This scope should not be created for non-data and non-value class. ${klass.render()}")
}
private val lookupTag = klass.symbol.toLookupTag() private val lookupTag = klass.symbol.toLookupTag()
private val baseModuleData = klass.moduleData private val baseModuleData = klass.moduleData
@@ -139,7 +147,7 @@ class FirClassAnySynthesizedMemberScope(
this.valueParameters.add( this.valueParameters.add(
buildValueParameter { buildValueParameter {
this.name = Name.identifier("other") this.name = Name.identifier("other")
origin = FirDeclarationOrigin.Synthetic origin = originForFunctions
moduleData = baseModuleData moduleData = baseModuleData
this.returnTypeRef = FirImplicitNullableAnyTypeRef(null) this.returnTypeRef = FirImplicitNullableAnyTypeRef(null)
this.symbol = FirValueParameterSymbol(this.name) this.symbol = FirValueParameterSymbol(this.name)
@@ -169,7 +177,7 @@ class FirClassAnySynthesizedMemberScope(
) { ) {
this.source = synthesizedSource this.source = synthesizedSource
moduleData = baseModuleData moduleData = baseModuleData
origin = FirDeclarationOrigin.Synthetic origin = originForFunctions
this.name = name this.name = name
status = FirResolvedDeclarationStatusImpl(Visibilities.Public, Modality.OPEN, EffectiveVisibility.Public).apply { status = FirResolvedDeclarationStatusImpl(Visibilities.Public, Modality.OPEN, EffectiveVisibility.Public).apply {
this.isOperator = isOperator this.isOperator = isOperator
@@ -1915,7 +1915,7 @@ class LightTreeRawFirDeclarationBuilder(
buildField { buildField {
source = explicitDelegation.toFirSourceElement().fakeElement(KtFakeSourceElementKind.ClassDelegationField) source = explicitDelegation.toFirSourceElement().fakeElement(KtFakeSourceElementKind.ClassDelegationField)
moduleData = baseModuleData moduleData = baseModuleData
origin = FirDeclarationOrigin.Synthetic origin = FirDeclarationOrigin.Synthetic.DelegateField
name = NameUtils.delegateFieldName(delegateFieldsMap.size) name = NameUtils.delegateFieldName(delegateFieldsMap.size)
returnTypeRef = firTypeRef returnTypeRef = firTypeRef
symbol = FirFieldSymbol(CallableId(context.currentClassId, name)) symbol = FirFieldSymbol(CallableId(context.currentClassId, name))
@@ -880,7 +880,7 @@ open class PsiRawFirBuilder(
return buildField { return buildField {
source = delegateSource source = delegateSource
moduleData = baseModuleData moduleData = baseModuleData
origin = FirDeclarationOrigin.Synthetic origin = FirDeclarationOrigin.Synthetic.DelegateField
name = NameUtils.delegateFieldName(fieldOrd) name = NameUtils.delegateFieldName(fieldOrd)
returnTypeRef = type returnTypeRef = type
symbol = FirFieldSymbol(CallableId(this@PsiRawFirBuilder.context.currentClassId, name)) symbol = FirFieldSymbol(CallableId(this@PsiRawFirBuilder.context.currentClassId, name))
@@ -907,7 +907,7 @@ abstract class AbstractRawFirBuilder<T>(val baseSession: FirSession, val context
val componentFunction = buildSimpleFunction { val componentFunction = buildSimpleFunction {
source = sourceNode?.toFirSourceElement(KtFakeSourceElementKind.DataClassGeneratedMembers) source = sourceNode?.toFirSourceElement(KtFakeSourceElementKind.DataClassGeneratedMembers)
moduleData = baseModuleData moduleData = baseModuleData
origin = FirDeclarationOrigin.Synthetic origin = FirDeclarationOrigin.Synthetic.DataClassMember
returnTypeRef = firProperty.returnTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.DataClassGeneratedMembers) returnTypeRef = firProperty.returnTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.DataClassGeneratedMembers)
this.name = name this.name = name
status = FirDeclarationStatusImpl(firProperty.visibility, Modality.FINAL).apply { status = FirDeclarationStatusImpl(firProperty.visibility, Modality.FINAL).apply {
@@ -1100,7 +1100,7 @@ fun <TBase, TSource : TBase, TParameter : TBase> FirRegularClassBuilder.createDa
val classTypeRef = createClassTypeRefWithSourceKind(KtFakeSourceElementKind.DataClassGeneratedMembers) val classTypeRef = createClassTypeRefWithSourceKind(KtFakeSourceElementKind.DataClassGeneratedMembers)
this.source = toFirSource(sourceElement, KtFakeSourceElementKind.DataClassGeneratedMembers) this.source = toFirSource(sourceElement, KtFakeSourceElementKind.DataClassGeneratedMembers)
moduleData = this@createDataClassCopyFunction.moduleData moduleData = this@createDataClassCopyFunction.moduleData
origin = FirDeclarationOrigin.Synthetic origin = FirDeclarationOrigin.Synthetic.DataClassMember
returnTypeRef = classTypeRef returnTypeRef = classTypeRef
name = StandardNames.DATA_CLASS_COPY name = StandardNames.DATA_CLASS_COPY
status = FirDeclarationStatusImpl(Visibilities.Public, Modality.FINAL) status = FirDeclarationStatusImpl(Visibilities.Public, Modality.FINAL)
@@ -1116,7 +1116,7 @@ fun <TBase, TSource : TBase, TParameter : TBase> FirRegularClassBuilder.createDa
source = parameterSource source = parameterSource
containingFunctionSymbol = this@buildSimpleFunction.symbol containingFunctionSymbol = this@buildSimpleFunction.symbol
moduleData = this@createDataClassCopyFunction.moduleData moduleData = this@createDataClassCopyFunction.moduleData
origin = FirDeclarationOrigin.Synthetic origin = FirDeclarationOrigin.Synthetic.DataClassMember
returnTypeRef = propertyReturnTypeRef returnTypeRef = propertyReturnTypeRef
name = propertyName name = propertyName
symbol = FirValueParameterSymbol(propertyName) symbol = FirValueParameterSymbol(propertyName)
@@ -166,7 +166,7 @@ class CandidateFactory private constructor(
buildErrorFunction { buildErrorFunction {
moduleData = context.session.moduleData moduleData = context.session.moduleData
resolvePhase = FirResolvePhase.BODY_RESOLVE resolvePhase = FirResolvePhase.BODY_RESOLVE
origin = FirDeclarationOrigin.Synthetic origin = FirDeclarationOrigin.Synthetic.Error
this.diagnostic = diagnostic this.diagnostic = diagnostic
symbol = it symbol = it
} }
@@ -178,7 +178,7 @@ class CandidateFactory private constructor(
buildErrorProperty { buildErrorProperty {
moduleData = context.session.moduleData moduleData = context.session.moduleData
resolvePhase = FirResolvePhase.BODY_RESOLVE resolvePhase = FirResolvePhase.BODY_RESOLVE
origin = FirDeclarationOrigin.Synthetic origin = FirDeclarationOrigin.Synthetic.Error
name = FirErrorPropertySymbol.NAME name = FirErrorPropertySymbol.NAME
this.diagnostic = diagnostic this.diagnostic = diagnostic
symbol = it symbol = it
@@ -229,7 +229,7 @@ private class TypeAliasConstructorsSubstitutingScope(
processor( processor(
buildConstructorCopy(originalConstructorSymbol.fir) { buildConstructorCopy(originalConstructorSymbol.fir) {
symbol = FirConstructorSymbol(originalConstructorSymbol.callableId) symbol = FirConstructorSymbol(originalConstructorSymbol.callableId)
origin = FirDeclarationOrigin.Synthetic origin = FirDeclarationOrigin.Synthetic.TypeAliasConstructor
this.typeParameters.clear() this.typeParameters.clear()
this.typeParameters += typeParameters.map { buildConstructedClassTypeParameterRef { symbol = it.symbol } } this.typeParameters += typeParameters.map { buildConstructedClassTypeParameterRef { symbol = it.symbol } }
@@ -436,7 +436,7 @@ class FirSyntheticCallGenerator(
): FirSimpleFunctionBuilder { ): FirSimpleFunctionBuilder {
return FirSimpleFunctionBuilder().apply { return FirSimpleFunctionBuilder().apply {
moduleData = session.moduleData moduleData = session.moduleData
origin = FirDeclarationOrigin.Synthetic origin = FirDeclarationOrigin.Synthetic.FakeFunction
this.symbol = symbol this.symbol = symbol
this.name = name this.name = name
status = FirDeclarationStatusImpl(Visibilities.Public, Modality.FINAL) status = FirDeclarationStatusImpl(Visibilities.Public, Modality.FINAL)
@@ -23,7 +23,17 @@ sealed class FirDeclarationOrigin(
object Library : Java("Java(Library)") object Library : Java("Java(Library)")
} }
object Synthetic : FirDeclarationOrigin() sealed class Synthetic : FirDeclarationOrigin() {
object DataClassMember : Synthetic()
object ValueClassMember : Synthetic()
object JavaProperty : Synthetic()
object DelegateField : Synthetic()
object PluginFile : Synthetic()
object Error : Synthetic()
object TypeAliasConstructor : Synthetic()
object FakeFunction : Synthetic()
object ForwardDeclaration : Synthetic()
}
object DynamicScope : FirDeclarationOrigin() object DynamicScope : FirDeclarationOrigin()
object SamConstructor : FirDeclarationOrigin() object SamConstructor : FirDeclarationOrigin()
object Enhancement : FirDeclarationOrigin() object Enhancement : FirDeclarationOrigin()
@@ -51,7 +51,7 @@ class FirSyntheticProperty(
get() = null get() = null
override val origin: FirDeclarationOrigin override val origin: FirDeclarationOrigin
get() = FirDeclarationOrigin.Synthetic get() = FirDeclarationOrigin.Synthetic.JavaProperty
override val initializer: FirExpression? override val initializer: FirExpression?
get() = null get() = null
@@ -34,7 +34,7 @@ class FirSyntheticPropertyAccessor(
get() = delegate.moduleData get() = delegate.moduleData
override val origin: FirDeclarationOrigin override val origin: FirDeclarationOrigin
get() = FirDeclarationOrigin.Synthetic get() = FirDeclarationOrigin.Synthetic.JavaProperty
override val returnTypeRef: FirTypeRef override val returnTypeRef: FirTypeRef
get() = delegate.returnTypeRef get() = delegate.returnTypeRef
@@ -34,7 +34,7 @@ inline val FirDeclaration.isFromLibrary: Boolean
inline val FirDeclaration.isPrecompiled: Boolean inline val FirDeclaration.isPrecompiled: Boolean
get() = origin == FirDeclarationOrigin.Precompiled get() = origin == FirDeclarationOrigin.Precompiled
inline val FirDeclaration.isSynthetic: Boolean inline val FirDeclaration.isSynthetic: Boolean
get() = origin == FirDeclarationOrigin.Synthetic get() = origin is FirDeclarationOrigin.Synthetic
// NB: This function checks transitive localness. That is, // NB: This function checks transitive localness. That is,
// if a declaration `isNonLocal`, then its parent also `isNonLocal`. // if a declaration `isNonLocal`, then its parent also `isNonLocal`.