diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrBuiltInsOverDescriptors.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrBuiltInsOverDescriptors.kt index ef4511cd3a2..c9cb6682df3 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrBuiltInsOverDescriptors.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrBuiltInsOverDescriptors.kt @@ -85,7 +85,9 @@ class IrBuiltInsOverDescriptors( override val operatorsPackageFragment: IrExternalPackageFragment = IrExternalPackageFragmentImpl(symbolTable.referenceExternalPackageFragment(packageFragmentDescriptor), KOTLIN_INTERNAL_IR_FQN) - private fun ClassDescriptor.toIrSymbol() = symbolTable.referenceClass(this) + private fun ClassDescriptor.toIrSymbol(): IrClassSymbol { + return symbolTable.referenceClass(this) + } private fun KotlinType.toIrType() = typeTranslator.translateType(this) private fun defineOperator( diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrDescriptorBasedFunctionFactory.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrDescriptorBasedFunctionFactory.kt index f325b7b9edc..75ad1495915 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrDescriptorBasedFunctionFactory.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrDescriptorBasedFunctionFactory.kt @@ -200,7 +200,7 @@ class IrDescriptorBasedFunctionFactory( override fun typeParameterDescriptor(index: Int, factory: (IrTypeParameterSymbol) -> IrTypeParameter): IrTypeParameterSymbol { val descriptor = classDescriptor.declaredTypeParameters[index] - return symbolTable.declareGlobalTypeParameter(offset, offset, classOrigin, descriptor, factory).symbol + return symbolTable.descriptorExtension.declareGlobalTypeParameter(descriptor, factory).symbol } override fun classReceiverParameterDescriptor(): ReceiverParameterDescriptor { @@ -444,7 +444,7 @@ class IrDescriptorBasedFunctionFactory( } fun createFakeOverrideProperty(descriptor: PropertyDescriptor): IrProperty { - return symbolTable.declareProperty(offset, offset, memberOrigin, descriptor) { + return symbolTable.declareProperty(descriptor) { irFactory.createProperty( startOffset = offset, endOffset = offset, diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt index 469fa9cb3dc..318876bd462 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt @@ -82,7 +82,7 @@ internal class ClassGenerator( it.toIrType() } - irClass.thisReceiver = context.symbolTable.declareValueParameter( + irClass.thisReceiver = context.symbolTable.descriptorExtension.declareValueParameter( startOffset, endOffset, IrDeclarationOrigin.INSTANCE_RECEIVER, classDescriptor.thisAsReceiverParameter, diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationGenerator.kt index a8b3949486e..b58c43a15d9 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationGenerator.kt @@ -144,7 +144,7 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator { from: List ) { generateTypeParameterDeclarations(irTypeParametersOwner, from) { startOffset, endOffset, typeParameterDescriptor -> - context.symbolTable.declareScopedTypeParameter( + context.symbolTable.descriptorExtension.declareScopedTypeParameter( startOffset, endOffset, IrDeclarationOrigin.DEFINED, diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DelegatedPropertyGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DelegatedPropertyGenerator.kt index dc4f68bb4ec..53c10a79948 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DelegatedPropertyGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DelegatedPropertyGenerator.kt @@ -263,7 +263,7 @@ internal class DelegatedPropertyGenerator( ): IrLocalDelegatedProperty { val kPropertyType = getKPropertyTypeForLocalDelegatedProperty(variableDescriptor) - val irLocalDelegatedProperty = context.symbolTable.declareLocalDelegatedProperty( + val irLocalDelegatedProperty = context.symbolTable.descriptorExtension.declareLocalDelegatedProperty( ktProperty.startOffsetSkippingComments, ktProperty.endOffset, IrDeclarationOrigin.DEFINED, variableDescriptor, variableDescriptor.type.toIrType() @@ -314,7 +314,7 @@ internal class DelegatedPropertyGenerator( val delegateType = getDelegatedPropertyDelegateType(variableDescriptor, ktDelegate) val delegateDescriptor = createLocalPropertyDelegatedDescriptor(variableDescriptor, delegateType, kPropertyType) - return context.symbolTable.declareVariable( + return context.symbolTable.descriptorExtension.declareVariable( ktDelegate.startOffsetSkippingComments, ktDelegate.endOffset, IrDeclarationOrigin.PROPERTY_DELEGATE, delegateDescriptor, delegateDescriptor.type.toIrType() ).also { irVariable -> diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt index 32a04a925fe..f983307bb4b 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt @@ -434,7 +434,7 @@ internal class FunctionGenerator(declarationGenerator: DeclarationGenerator) : D origin = IrDeclarationOrigin.DESTRUCTURED_OBJECT_PARAMETER } } - return context.symbolTable.declareValueParameter( + return context.symbolTable.descriptorExtension.declareValueParameter( ktElement?.pureStartOffset ?: irOwnerElement.startOffset, ktElement?.pureEndOffset ?: irOwnerElement.endOffset, origin, diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/PropertyGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/PropertyGenerator.kt index 0031fb36aa0..e22f35011f2 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/PropertyGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/PropertyGenerator.kt @@ -158,7 +158,7 @@ internal class PropertyGenerator(declarationGenerator: DeclarationGenerator) : D propertyDescriptor: PropertyDescriptor, generateInitializer: (IrField) -> IrExpressionBody? ): IrField = - context.symbolTable.declareField( + context.symbolTable.descriptorExtension.declareField( ktPropertyElement.startOffsetSkippingComments, ktPropertyElement.endOffset, IrDeclarationOrigin.PROPERTY_BACKING_FIELD, propertyDescriptor, propertyDescriptor.type.toIrType(), diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt index 7474cf56dc2..0bc1417059c 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt @@ -579,7 +579,7 @@ internal class ReflectionReferencesGenerator(statementGenerator: StatementGenera } else null if (!symbol.isBound) { val offset = UNDEFINED_OFFSET - context.symbolTable.declareProperty(offset, offset, IrDeclarationOrigin.SYNTHETIC_JAVA_PROPERTY_DELEGATE, descriptor) { + context.symbolTable.descriptorExtension.declareProperty(descriptor) { context.irFactory.createProperty( startOffset = offset, endOffset = offset, diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ScriptGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ScriptGenerator.kt index 1e59fc8e3be..0ff8f97c89d 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ScriptGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ScriptGenerator.kt @@ -293,7 +293,7 @@ internal class ScriptGenerator(declarationGenerator: DeclarationGenerator) : Dec } private fun ParameterDescriptor.toIrValueParameter(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin) = - context.symbolTable.declareValueParameter( + context.symbolTable.descriptorExtension.declareValueParameter( startOffset, endOffset, origin, this, type.toIrType(), diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StandaloneDeclarationGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StandaloneDeclarationGenerator.kt index d8a7183886f..42574c2377d 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StandaloneDeclarationGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StandaloneDeclarationGenerator.kt @@ -48,7 +48,7 @@ internal class StandaloneDeclarationGenerator(private val context: GeneratorCont from: List ) { generateTypeParameterDeclarations(irTypeParametersOwner, from) { startOffset, endOffset, typeParameterDescriptor -> - symbolTable.declareScopedTypeParameter(startOffset, endOffset, IrDeclarationOrigin.DEFINED, typeParameterDescriptor) + symbolTable.descriptorExtension.declareScopedTypeParameter(startOffset, endOffset, IrDeclarationOrigin.DEFINED, typeParameterDescriptor) } } @@ -90,7 +90,7 @@ internal class StandaloneDeclarationGenerator(private val context: GeneratorCont it.toIrType() } - irClass.thisReceiver = context.symbolTable.declareValueParameter( + irClass.thisReceiver = context.symbolTable.descriptorExtension.declareValueParameter( startOffset, endOffset, IrDeclarationOrigin.INSTANCE_RECEIVER, descriptor.thisAsReceiverParameter, @@ -134,7 +134,7 @@ internal class StandaloneDeclarationGenerator(private val context: GeneratorCont } protected fun declareParameter(descriptor: ParameterDescriptor, ktElement: KtPureElement?, irOwnerElement: IrElement): IrValueParameter { - return symbolTable.declareValueParameter( + return symbolTable.descriptorExtension.declareValueParameter( ktElement?.pureStartOffset ?: irOwnerElement.startOffset, ktElement?.pureEndOffset ?: irOwnerElement.endOffset, IrDeclarationOrigin.DEFINED, diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/TryCatchExpressionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/TryCatchExpressionGenerator.kt index e780543debd..387b1694a75 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/TryCatchExpressionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/TryCatchExpressionGenerator.kt @@ -39,7 +39,7 @@ internal class TryCatchExpressionGenerator(statementGenerator: StatementGenerato val irCatch = IrCatchImpl( ktCatchClause.startOffsetSkippingComments, ktCatchClause.endOffset, - context.symbolTable.declareVariable( + context.symbolTable.descriptorExtension.declareVariable( ktCatchParameter.startOffsetSkippingComments, ktCatchParameter.endOffset, IrDeclarationOrigin.CATCH_PARAMETER, catchParameterDescriptor, catchParameterDescriptor.type.toIrType() diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/fragments/FragmentCompilerSymbolTableDecorator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/fragments/FragmentCompilerSymbolTableDecorator.kt index e661e643313..c5e4e920008 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/fragments/FragmentCompilerSymbolTableDecorator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/fragments/FragmentCompilerSymbolTableDecorator.kt @@ -51,6 +51,7 @@ class FragmentCompilerSymbolTableDecorator( return super.referenceValueParameter(descriptor) } + override fun referenceValue(value: ValueDescriptor): IrValueSymbol { val fi = fragmentInfo ?: return super.referenceValue(value) @@ -71,4 +72,4 @@ class FragmentCompilerSymbolTableDecorator( return super.referenceValue(value) } -} \ No newline at end of file +} diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/fragments/FragmentDeclarationGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/fragments/FragmentDeclarationGenerator.kt index 40bbc1f7c14..6fb565d2903 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/fragments/FragmentDeclarationGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/fragments/FragmentDeclarationGenerator.kt @@ -42,7 +42,7 @@ open class FragmentDeclarationGenerator( Modality.FINAL ) }.buildWithScope { irClass -> - irClass.thisReceiver = context.symbolTable.declareValueParameter( + irClass.thisReceiver = context.symbolTable.descriptorExtension.declareValueParameter( startOffset, endOffset, IrDeclarationOrigin.INSTANCE_RECEIVER, classDescriptor.thisAsReceiverParameter, @@ -128,14 +128,14 @@ open class FragmentDeclarationGenerator( // of IR generation. The replacement is delayed because the JVM // specific infrastructure (i.e. "SharedVariableContext") is not yet // instantiated: PSI2IR is kept backend agnostic. - return context.symbolTable.declareValueParameter( + return context.symbolTable.descriptorExtension.declareValueParameter( UNDEFINED_OFFSET, UNDEFINED_OFFSET, if (shouldPromoteToSharedVariable(parameterInfo)) IrDeclarationOrigin.SHARED_VARIABLE_IN_EVALUATOR_FRAGMENT else IrDeclarationOrigin.DEFINED, descriptor, descriptor.type.toIrType(), descriptor.varargElementType?.toIrType(), - null, + name = null, isAssignable = parameterInfo.isLValue ) } @@ -157,4 +157,4 @@ open class FragmentDeclarationGenerator( } } -} \ No newline at end of file +} diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/ObsoleteDescriptorBasedAPI.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/ObsoleteDescriptorBasedAPI.kt index 5acbb896302..c9c79c00381 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/ObsoleteDescriptorBasedAPI.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/ObsoleteDescriptorBasedAPI.kt @@ -13,5 +13,12 @@ package org.jetbrains.kotlin.ir * However, more correct and universal way is to store all necessary information inside IR elements themselves * and do not use descriptors as some intermediate storage. It's planned to remove all descriptor usages from IR in future. */ +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.PROPERTY, + AnnotationTarget.VALUE_PARAMETER, + AnnotationTarget.FUNCTION, + AnnotationTarget.TYPEALIAS +) @RequiresOptIn(message = "Please use IR declaration properties and not its descriptor properties", level = RequiresOptIn.Level.ERROR) -annotation class ObsoleteDescriptorBasedAPI \ No newline at end of file +annotation class ObsoleteDescriptorBasedAPI diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeclarationStubGenerator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeclarationStubGenerator.kt index 5a15c88a7cd..b159bb863ed 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeclarationStubGenerator.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeclarationStubGenerator.kt @@ -141,9 +141,7 @@ abstract class DeclarationStubGenerator( } val origin = computeOrigin(descriptor) - return symbolTable.declareProperty( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor.original, descriptor.isDelegated - ) { + return symbolTable.descriptorExtension.declareProperty(descriptor.original) { IrLazyProperty( UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, descriptor, @@ -294,7 +292,7 @@ abstract class DeclarationStubGenerator( return referenced.owner } val origin = computeOrigin(descriptor) - return symbolTable.declareEnumEntry(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor) { + return symbolTable.declareEnumEntry(descriptor) { IrLazyEnumEntryImpl( UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, descriptor, @@ -309,7 +307,7 @@ abstract class DeclarationStubGenerator( return referenced.owner } val origin = computeOrigin(descriptor) - return symbolTable.declareGlobalTypeParameter(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor) { + return symbolTable.descriptorExtension.declareGlobalTypeParameter(descriptor) { IrLazyTypeParameter( UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, descriptor, diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DescriptorSymbolTableExtension.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DescriptorSymbolTableExtension.kt new file mode 100644 index 00000000000..de732e579fd --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DescriptorSymbolTableExtension.kt @@ -0,0 +1,498 @@ +/* + * Copyright 2010-2023 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.ir.util + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl +import org.jetbrains.kotlin.ir.declarations.impl.IrScriptImpl +import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl +import org.jetbrains.kotlin.ir.descriptors.IrBasedClassDescriptor +import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.symbols.* +import org.jetbrains.kotlin.ir.symbols.impl.* +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal +import org.jetbrains.kotlin.utils.threadLocal + +@ObsoleteDescriptorBasedAPI +typealias DescriptorBasedReferenceSymbolTableExtension = ReferenceSymbolTableExtension< + ClassDescriptor, TypeAliasDescriptor, ScriptDescriptor, FunctionDescriptor, ClassConstructorDescriptor, + PropertyDescriptor, ValueParameterDescriptor, TypeParameterDescriptor + > + +@ObsoleteDescriptorBasedAPI +class DescriptorSymbolTableExtension(table: SymbolTable) : SymbolTableExtension< + DeclarationDescriptor, ClassDescriptor, TypeAliasDescriptor, ScriptDescriptor, FunctionDescriptor, + ClassConstructorDescriptor, PropertyDescriptor, ParameterDescriptor, TypeParameterDescriptor>(table) +{ + private val irFactory: IrFactory + get() = table.irFactory + + private val nameProvider: NameProvider + get() = table.nameProvider + + private val signatureComposer: IdSignatureComposer + get() = table.signaturer + + private val externalPackageFragmentSlice: SymbolTableSlice = SymbolTableSlice.Flat(lock) + + private val valueParameterSlice: SymbolTableSlice.Scoped by threadLocal { + SymbolTableSlice.Scoped(lock) + } + + private val variableSlice: SymbolTableSlice.Scoped by threadLocal { + SymbolTableSlice.Scoped(lock) + } + + private val localDelegatedPropertySlice: SymbolTableSlice.Scoped by threadLocal { + SymbolTableSlice.Scoped(lock) + } + + override fun MutableList>.initializeScopedSlices() { + add(valueParameterSlice) + add(variableSlice) + add(localDelegatedPropertySlice) + } + + // ------------------------------------ signature ------------------------------------ + + override fun calculateSignature(declaration: DeclarationDescriptor): IdSignature? { + return signatureComposer.composeSignature(declaration) + } + + override fun calculateEnumEntrySignature(declaration: ClassDescriptor): IdSignature? { + return signatureComposer.composeEnumEntrySignature(declaration) + } + + override fun calculateFieldSignature(declaration: PropertyDescriptor): IdSignature? { + return signatureComposer.composeFieldSignature(declaration) + } + + // ------------------------------------ script ------------------------------------ + + override fun defaultScriptFactory(startOffset: Int, endOffset: Int, script: ScriptDescriptor, symbol: IrScriptSymbol): IrScript { + return IrScriptImpl(symbol, nameProvider.nameForDeclaration(script), irFactory, startOffset, endOffset) + } + + override fun createScriptSymbol(descriptor: ScriptDescriptor, signature: IdSignature?): IrScriptSymbol { + return IrScriptSymbolImpl(descriptor) + } + + // ------------------------------------ class ------------------------------------ + + override fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol { + return if (descriptor is IrBasedClassDescriptor) { + descriptor.owner.symbol + } else { + super.referenceClass(descriptor) + } + } + + fun declareClassFromLinker(descriptor: ClassDescriptor, signature: IdSignature, classFactory: (IrClassSymbol) -> IrClass): IrClass { + return declareFromLinker( + descriptor, + signature, + SymbolTable::declareClass, + ::declareClass, + ::createClassSymbol, + classFactory + ) + } + + override fun createPublicClassSymbol(descriptor: ClassDescriptor, signature: IdSignature): IrClassSymbol { + return IrClassPublicSymbolImpl(signature, descriptor) + } + + override fun createPrivateClassSymbol(descriptor: ClassDescriptor): IrClassSymbol { + return IrClassSymbolImpl(descriptor) + } + + // ------------------------------------ constructor ------------------------------------ + + fun declareConstructorFromLinker( + descriptor: ClassConstructorDescriptor, + signature: IdSignature, + constructorFactory: (IrConstructorSymbol) -> IrConstructor, + ): IrConstructor { + return declareFromLinker( + descriptor, + signature, + SymbolTable::declareConstructor, + ::declareConstructor, + ::createConstructorSymbol, + constructorFactory + ) + } + + override fun createPublicConstructorSymbol(descriptor: ClassConstructorDescriptor, signature: IdSignature): IrConstructorSymbol { + return IrConstructorPublicSymbolImpl(signature, descriptor) + } + + override fun createPrivateConstructorSymbol(descriptor: ClassConstructorDescriptor): IrConstructorSymbol { + return IrConstructorSymbolImpl(descriptor) + } + + // ------------------------------------ enum entry ------------------------------------ + + fun declareEnumEntryFromLinker( + descriptor: ClassDescriptor, + signature: IdSignature, + factory: (IrEnumEntrySymbol) -> IrEnumEntry, + ): IrEnumEntry { + return declareFromLinker( + descriptor, + signature, + SymbolTable::declareEnumEntry, + ::declareEnumEntry, + ::createEnumEntrySymbol, + factory + ) + } + + override fun createPublicEnumEntrySymbol(descriptor: ClassDescriptor, signature: IdSignature): IrEnumEntrySymbol { + return IrEnumEntryPublicSymbolImpl(signature, descriptor) + } + + override fun createPrivateEnumEntrySymbol(descriptor: ClassDescriptor): IrEnumEntrySymbol { + return IrEnumEntrySymbolImpl(descriptor) + } + + override fun defaultEnumEntryFactory( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + enumEntry: ClassDescriptor, + symbol: IrEnumEntrySymbol, + ): IrEnumEntry { + return irFactory.createEnumEntry(startOffset, endOffset, origin, nameProvider.nameForDeclaration(enumEntry), symbol) + } + + // ------------------------------------ field ------------------------------------ + + override fun createPublicFieldSymbol(descriptor: PropertyDescriptor, signature: IdSignature): IrFieldSymbol { + return IrFieldPublicSymbolImpl(signature, descriptor) + } + + override fun createPrivateFieldSymbol(descriptor: PropertyDescriptor): IrFieldSymbol { + return IrFieldSymbolImpl(descriptor) + } + + override fun defaultFieldFactory( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + descriptor: PropertyDescriptor, + type: IrType, + visibility: DescriptorVisibility?, + symbol: IrFieldSymbol, + ): IrField { + return irFactory.createField( + startOffset = startOffset, + endOffset = endOffset, + origin = origin, + name = nameProvider.nameForDeclaration(descriptor), + visibility = visibility ?: symbol.descriptor.visibility, + symbol = symbol, + type = type, + isFinal = !symbol.descriptor.isVar, + isStatic = symbol.descriptor.dispatchReceiverParameter == null, + isExternal = symbol.descriptor.isEffectivelyExternal(), + ).apply { + metadata = DescriptorMetadataSource.Property(symbol.descriptor) + } + } + + // ------------------------------------ property ------------------------------------ + + fun declarePropertyFromLinker( + descriptor: PropertyDescriptor, + signature: IdSignature, + propertyFactory: (IrPropertySymbol) -> IrProperty, + ): IrProperty { + return declareFromLinker( + descriptor, + signature, + SymbolTable::declareProperty, + ::declareProperty, + ::createPropertySymbol, + propertyFactory + ) + } + + override fun createPublicPropertySymbol(descriptor: PropertyDescriptor, signature: IdSignature): IrPropertySymbol { + return IrPropertyPublicSymbolImpl(signature, descriptor) + } + + override fun createPrivatePropertySymbol(descriptor: PropertyDescriptor): IrPropertySymbol { + return IrPropertySymbolImpl(descriptor) + } + + override fun defaultPropertyFactory( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + descriptor: PropertyDescriptor, + isDelegated: Boolean, + symbol: IrPropertySymbol, + ): IrProperty { + return irFactory.createProperty( + startOffset = startOffset, + endOffset = endOffset, + origin = origin, + name = nameProvider.nameForDeclaration(descriptor), + visibility = descriptor.visibility, + modality = descriptor.modality, + symbol = symbol, + isVar = descriptor.isVar, + isConst = descriptor.isConst, + isLateinit = descriptor.isLateInit, + isDelegated = isDelegated, + isExternal = descriptor.isEffectivelyExternal(), + isExpect = descriptor.isExpect, + isFakeOverride = descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE, + ).apply { + metadata = DescriptorMetadataSource.Property(symbol.descriptor) + } + } + + // ------------------------------------ typealias ------------------------------------ + + override fun createPublicTypeAliasSymbol(descriptor: TypeAliasDescriptor, signature: IdSignature): IrTypeAliasSymbol { + return IrTypeAliasPublicSymbolImpl(signature, descriptor) + } + + override fun createPrivateTypeAliasSymbol(descriptor: TypeAliasDescriptor): IrTypeAliasSymbol { + return IrTypeAliasSymbolImpl(descriptor) + } + + // ------------------------------------ function ------------------------------------ + + fun declareSimpleFunctionFromLinker( + descriptor: FunctionDescriptor, + signature: IdSignature, + functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction, + ): IrSimpleFunction { + return declareFromLinker( + descriptor, + signature, + SymbolTable::declareSimpleFunction, + ::declareSimpleFunction, + ::createFunctionSymbol, + functionFactory + ) + } + + override fun createPublicFunctionSymbol(descriptor: FunctionDescriptor, signature: IdSignature): IrSimpleFunctionSymbol { + return IrSimpleFunctionPublicSymbolImpl(signature, descriptor) + } + + override fun createPrivateFunctionSymbol(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol { + return IrSimpleFunctionSymbolImpl(descriptor) + } + + // ------------------------------------ type parameter ------------------------------------ + + override fun createPublicTypeParameterSymbol(descriptor: TypeParameterDescriptor, signature: IdSignature): IrTypeParameterSymbol { + return IrTypeParameterPublicSymbolImpl(signature, descriptor) + } + + override fun createPrivateTypeParameterSymbol(descriptor: TypeParameterDescriptor): IrTypeParameterSymbol { + return IrTypeParameterSymbolImpl(descriptor) + } + + override fun defaultTypeParameterFactory( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + descriptor: TypeParameterDescriptor, + symbol: IrTypeParameterSymbol, + ): IrTypeParameter { + return irFactory.createTypeParameter( + startOffset = startOffset, + endOffset = endOffset, + origin = origin, + name = nameProvider.nameForDeclaration(descriptor), + symbol = symbol, + variance = symbol.descriptor.variance, + index = symbol.descriptor.index, + isReified = symbol.descriptor.isReified + ) + } + + // ------------------------------------ package fragment ------------------------------------ + + fun referenceExternalPackageFragment(descriptor: PackageFragmentDescriptor): IrExternalPackageFragmentSymbol = + externalPackageFragmentSlice.referenced(descriptor) { IrExternalPackageFragmentSymbolImpl(descriptor) } + + fun declareExternalPackageFragment(descriptor: PackageFragmentDescriptor): IrExternalPackageFragment { + return externalPackageFragmentSlice.declare( + descriptor, + { IrExternalPackageFragmentSymbolImpl(descriptor) }, + { IrExternalPackageFragmentImpl(it, descriptor.fqName) } + ) + } + + fun declareExternalPackageFragmentIfNotExists(descriptor: PackageFragmentDescriptor): IrExternalPackageFragment { + return externalPackageFragmentSlice.declareIfNotExists( + descriptor, + { IrExternalPackageFragmentSymbolImpl(descriptor) }, + { IrExternalPackageFragmentImpl(it, descriptor.fqName) } + ) + } + + // ------------------------------------ anonymous initializer ------------------------------------ + + fun declareAnonymousInitializer( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + descriptor: ClassDescriptor + ): IrAnonymousInitializer = + irFactory.createAnonymousInitializer( + startOffset, endOffset, origin, + IrAnonymousInitializerSymbolImpl(descriptor) + ) + + // ------------------------------------ value parameter ------------------------------------ + + fun declareValueParameter( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + descriptor: ParameterDescriptor, + type: IrType, + varargElementType: IrType? = null, + name: Name? = null, + index: Int? = null, + isAssignable: Boolean = false, + valueParameterFactory: (IrValueParameterSymbol) -> IrValueParameter = { + irFactory.createValueParameter( + startOffset = startOffset, + endOffset = endOffset, + origin = origin, + name = name ?: nameProvider.nameForDeclaration(descriptor), + type = type, + isAssignable = isAssignable, + symbol = it, + index = index ?: descriptor.indexOrMinusOne, + varargElementType = varargElementType, + isCrossinline = descriptor.isCrossinline, + isNoinline = descriptor.isNoinline, + isHidden = false, + ) + } + ): IrValueParameter = + valueParameterSlice.declareLocal( + descriptor, + { IrValueParameterSymbolImpl(descriptor) }, + valueParameterFactory + ) + + @OptIn(ObsoleteDescriptorBasedAPI::class) + fun introduceValueParameter(irValueParameter: IrValueParameter) { + valueParameterSlice.introduceLocal(irValueParameter.descriptor, irValueParameter.symbol) + } + + override fun referenceValueParameter(descriptor: ParameterDescriptor): IrValueParameterSymbol { + return valueParameterSlice.referenced(descriptor) { + error("Undefined parameter referenced: $descriptor\n${valueParameterSlice.dump()}") + } + } + + // TODO: convert to extension + fun referenceValue(value: ValueDescriptor): IrValueSymbol { + return when (value) { + is ParameterDescriptor -> valueParameterSlice.referenced(value) { error("Undefined parameter referenced: $value") } + is VariableDescriptor -> variableSlice.referenced(value) { error("Undefined variable referenced: $value") } + else -> error("Unexpected value descriptor: $value") + } + } + + + // ------------------------------------ variable ------------------------------------ + + fun declareVariable( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + descriptor: VariableDescriptor, + type: IrType, + ): IrVariable = + variableSlice.declareLocal( + descriptor, + { IrVariableSymbolImpl(descriptor) } + ) { + IrVariableImpl( + startOffset, endOffset, origin, it, nameProvider.nameForDeclaration(descriptor), type, + descriptor.isVar, descriptor.isConst, descriptor.isLateInit + ) + } + + fun declareVariable( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + descriptor: VariableDescriptor, + type: IrType, + irInitializerExpression: IrExpression? + ): IrVariable = + declareVariable(startOffset, endOffset, origin, descriptor, type).apply { + initializer = irInitializerExpression + } + + // ------------------------------------ local delegated property ------------------------------------ + + fun declareLocalDelegatedProperty( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + descriptor: VariableDescriptorWithAccessors, + type: IrType + ): IrLocalDelegatedProperty { + return localDelegatedPropertySlice.declareLocal( + descriptor, + { IrLocalDelegatedPropertySymbolImpl(descriptor) }, + ) { + irFactory.createLocalDelegatedProperty( + startOffset = startOffset, + endOffset = endOffset, + origin = origin, + name = nameProvider.nameForDeclaration(descriptor), + symbol = it, + type = type, + isVar = descriptor.isVar + ) + }.apply { + metadata = DescriptorMetadataSource.LocalDelegatedProperty(descriptor) + } + } + + fun referenceLocalDelegatedProperty(descriptor: VariableDescriptorWithAccessors): IrLocalDelegatedPropertySymbol = + localDelegatedPropertySlice.referenced(descriptor) { + error("Undefined local delegated property referenced: $descriptor") + } + + // ------------------------------------ utilities ------------------------------------ + + private inline fun , SymbolOwner : IrSymbolOwner> declareFromLinker( + descriptor: D, + signature: IdSignature, + declareBySignature: SymbolTable.(IdSignature, () -> Symbol, OwnerFactory) -> SymbolOwner, + declareByDescriptor: (D, OwnerFactory) -> SymbolOwner, + crossinline symbolFactory: SymbolFactory, + noinline ownerFactory: OwnerFactory + ): SymbolOwner { + return if (signature.isPubliclyVisible) { + table.declareBySignature(signature, { symbolFactory(descriptor, signature) }, ownerFactory) + } else { + declareByDescriptor(descriptor, ownerFactory) + } + } +} + diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ExternalDependenciesGenerator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ExternalDependenciesGenerator.kt index 17ff84d6cc1..c288f8ad0c7 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ExternalDependenciesGenerator.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ExternalDependenciesGenerator.kt @@ -15,6 +15,7 @@ */ package org.jetbrains.kotlin.ir.util +import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.linkage.IrProvider import org.jetbrains.kotlin.ir.symbols.IrSymbol @@ -22,6 +23,7 @@ class ExternalDependenciesGenerator( private val symbolTable: SymbolTable, private val irProviders: List ) { + @OptIn(ObsoleteDescriptorBasedAPI::class) fun generateUnboundSymbolsAsDependencies() { // There should be at most one DeclarationStubGenerator (none in closed world?) irProviders.filterIsInstance().singleOrNull()?.run { unboundSymbolGeneration = true } @@ -30,7 +32,7 @@ class ExternalDependenciesGenerator( var unbound = emptySet() do { val prevUnbound = unbound - unbound = symbolTable.allUnbound + unbound = symbolTable.descriptorExtension.allUnboundSymbols for (symbol in unbound) { // Symbol could get bound as a side effect of deserializing other symbols. if (!symbol.isBound) { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ReferenceSymbolTable.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ReferenceSymbolTable.kt new file mode 100644 index 00000000000..d455b2ec5fa --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ReferenceSymbolTable.kt @@ -0,0 +1,63 @@ +/* + * Copyright 2010-2023 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.ir.util + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI +import org.jetbrains.kotlin.ir.declarations.IrDeclaration +import org.jetbrains.kotlin.ir.symbols.* + +interface ReferenceSymbolTable { + @ObsoleteDescriptorBasedAPI + fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol + fun referenceClass(signature: IdSignature): IrClassSymbol + + @ObsoleteDescriptorBasedAPI + fun referenceScript(descriptor: ScriptDescriptor): IrScriptSymbol + + @ObsoleteDescriptorBasedAPI + fun referenceConstructor(descriptor: ClassConstructorDescriptor): IrConstructorSymbol + fun referenceConstructor(signature: IdSignature): IrConstructorSymbol + + @ObsoleteDescriptorBasedAPI + fun referenceEnumEntry(descriptor: ClassDescriptor): IrEnumEntrySymbol + fun referenceEnumEntry(signature: IdSignature): IrEnumEntrySymbol + + @ObsoleteDescriptorBasedAPI + fun referenceField(descriptor: PropertyDescriptor): IrFieldSymbol + fun referenceField(signature: IdSignature): IrFieldSymbol + + @ObsoleteDescriptorBasedAPI + fun referenceProperty(descriptor: PropertyDescriptor): IrPropertySymbol + fun referenceProperty(signature: IdSignature): IrPropertySymbol + + @ObsoleteDescriptorBasedAPI + fun referenceSimpleFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol + fun referenceSimpleFunction(signature: IdSignature): IrSimpleFunctionSymbol + + @ObsoleteDescriptorBasedAPI + fun referenceDeclaredFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol + + @ObsoleteDescriptorBasedAPI + fun referenceValueParameter(descriptor: ParameterDescriptor): IrValueParameterSymbol + + @ObsoleteDescriptorBasedAPI + fun referenceTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol + fun referenceTypeParameter(signature: IdSignature): IrTypeParameterSymbol + + @ObsoleteDescriptorBasedAPI + fun referenceScopedTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol + + @ObsoleteDescriptorBasedAPI + fun referenceTypeAlias(descriptor: TypeAliasDescriptor): IrTypeAliasSymbol + fun referenceTypeAlias(signature: IdSignature): IrTypeAliasSymbol + + fun enterScope(symbol: IrSymbol) + fun enterScope(owner: IrDeclaration) + + fun leaveScope(symbol: IrSymbol) + fun leaveScope(owner: IrDeclaration) +} diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTable.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTable.kt index 856759e4e88..a1bbf0d30f2 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTable.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTable.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2023 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. */ @@ -9,507 +9,60 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.IrLock import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl -import org.jetbrains.kotlin.ir.declarations.impl.IrScriptImpl -import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl import org.jetbrains.kotlin.ir.declarations.lazy.IrLazySymbolTable -import org.jetbrains.kotlin.ir.descriptors.IrBasedClassDescriptor import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpressionBody import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.impl.* import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal -import org.jetbrains.kotlin.utils.threadLocal - -interface ReferenceSymbolTable { - @ObsoleteDescriptorBasedAPI - fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol - fun referenceClass(signature: IdSignature): IrClassSymbol - - @ObsoleteDescriptorBasedAPI - fun referenceScript(descriptor: ScriptDescriptor): IrScriptSymbol - - @ObsoleteDescriptorBasedAPI - fun referenceConstructor(descriptor: ClassConstructorDescriptor): IrConstructorSymbol - fun referenceConstructor(signature: IdSignature): IrConstructorSymbol - - @ObsoleteDescriptorBasedAPI - fun referenceEnumEntry(descriptor: ClassDescriptor): IrEnumEntrySymbol - fun referenceEnumEntry(signature: IdSignature): IrEnumEntrySymbol - - @ObsoleteDescriptorBasedAPI - fun referenceField(descriptor: PropertyDescriptor): IrFieldSymbol - fun referenceField(signature: IdSignature): IrFieldSymbol - - @ObsoleteDescriptorBasedAPI - fun referenceProperty(descriptor: PropertyDescriptor): IrPropertySymbol - fun referenceProperty(signature: IdSignature): IrPropertySymbol - - @ObsoleteDescriptorBasedAPI - fun referenceSimpleFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol - fun referenceSimpleFunction(signature: IdSignature): IrSimpleFunctionSymbol - - @ObsoleteDescriptorBasedAPI - fun referenceDeclaredFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol - - @ObsoleteDescriptorBasedAPI - fun referenceValueParameter(descriptor: ParameterDescriptor): IrValueParameterSymbol - - @ObsoleteDescriptorBasedAPI - fun referenceTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol - fun referenceTypeParameter(signature: IdSignature): IrTypeParameterSymbol - - @ObsoleteDescriptorBasedAPI - fun referenceScopedTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol - - @ObsoleteDescriptorBasedAPI - fun referenceTypeAlias(descriptor: TypeAliasDescriptor): IrTypeAliasSymbol - fun referenceTypeAlias(signature: IdSignature): IrTypeAliasSymbol - - fun enterScope(symbol: IrSymbol) - fun enterScope(owner: IrDeclaration) - - fun leaveScope(symbol: IrSymbol) - fun leaveScope(owner: IrDeclaration) -} open class SymbolTable( val signaturer: IdSignatureComposer, val irFactory: IrFactory, - val nameProvider: NameProvider = NameProvider.DEFAULT + val nameProvider: NameProvider = NameProvider.DEFAULT, ) : ReferenceSymbolTable { + val lock: IrLock = IrLock() - val lock = IrLock() + private val scriptSlice: SymbolTableSlice.Flat = SymbolTableSlice.Flat(lock) + private val classSlice: SymbolTableSlice.Flat = SymbolTableSlice.Flat(lock) + private val constructorSlice: SymbolTableSlice.Flat = SymbolTableSlice.Flat(lock) + private val enumEntrySlice: SymbolTableSlice.Flat = SymbolTableSlice.Flat(lock) + private val fieldSlice: SymbolTableSlice.Flat = SymbolTableSlice.Flat(lock) + private val functionSlice: SymbolTableSlice.Flat = SymbolTableSlice.Flat(lock) + private val propertySlice: SymbolTableSlice.Flat = SymbolTableSlice.Flat(lock) + private val typeAliasSlice: SymbolTableSlice.Flat = SymbolTableSlice.Flat(lock) + private val globalTypeParameterSlice: SymbolTableSlice.Flat = SymbolTableSlice.Flat(lock) @Suppress("LeakingThis") val lazyWrapper = IrLazySymbolTable(this) - @Suppress("DuplicatedCode") - private abstract class SymbolTableBase(val lock: IrLock) - where Descriptor : DeclarationDescriptor, - SymbolOwner : IrSymbolOwner, - Symbol : IrBindableSymbol { - /** - * With the partial linkage turned on it's hard to predict whether a newly created [IrSymbol] that is added to the [SymbolTable] - * via one of referenceXXX() calls will or won't be bound to some declaration. The latter may happen in certain cases, - * for example when the symbol refers from an IR expression to a non-top level declaration that was removed in newer version - * of Kotlin library (KLIB). Unless such symbol is registered as "probably unbound" it remains invisible for the linkage process. - * - * The optimization that allows to reference symbols without registering them as "probably unbound" is fragile. It's better - * to avoid calling any referenceXXX(reg = false) functions. Instead, wherever it is s suitable it is recommended to use one - * of the appropriate declareXXX() calls. - * - * For the future: Consider implementing the optimization once again for the new "flat" ID signatures. - */ - val unboundSymbols = linkedSetOf() + @Suppress("LeakingThis") + @OptIn(ObsoleteDescriptorBasedAPI::class) + val descriptorExtension: DescriptorSymbolTableExtension = DescriptorSymbolTableExtension(this) - protected abstract fun signature(descriptor: Descriptor): IdSignature? - - // TODO: consider replacing paired get/set calls by java.util.Map.computeIfAbsent() which would be more performant - abstract fun get(descriptor: Descriptor, signature: IdSignature?): Symbol? - abstract fun set(symbol: Symbol) - abstract fun get(signature: IdSignature): Symbol? - abstract fun set(signature: IdSignature, symbol: Symbol) - - inline fun declare( - descriptor: Descriptor, - createSymbol: (IdSignature?) -> Symbol, - createOwner: (Symbol) -> SymbolOwner, - ): SymbolOwner { - synchronized(lock) { - val signature = signature(descriptor) - val existing = get(descriptor, signature) - val symbol = if (existing == null) { - checkOriginal(descriptor) - val new = createSymbol(signature) - set(new) - new - } else { - unboundSymbols.remove(existing) - existing - } - return createOwnerSafe(symbol, createOwner) - } - } - - inline fun declare(signature: IdSignature, createSymbol: () -> Symbol, createOwner: (Symbol) -> SymbolOwner): SymbolOwner { - synchronized(lock) { - val existing = get(signature) - val symbol = if (existing == null) { - createSymbol() - } else { - unboundSymbols.remove(existing) - existing - } - return createOwnerSafe(symbol, createOwner) - .also { - // TODO: try to get rid of this - set(symbol) - } - } - } - - inline fun declareIfNotExists( - descriptor: Descriptor, - createSymbol: (IdSignature?) -> Symbol, - createOwner: (Symbol) -> SymbolOwner, - ): SymbolOwner { - synchronized(lock) { - val signature = signature(descriptor) - val existing = get(descriptor, signature) - val symbol = if (existing == null) { - checkOriginal(descriptor) - val new = createSymbol(signature) - set(new) - new - } else { - if (existing.isBound) { - unboundSymbols.remove(existing) - return existing.owner - } - existing - } - return createOwnerSafe(symbol, createOwner) - } - } - - inline fun declare( - signature: IdSignature, - descriptor: Descriptor?, - createSymbol: () -> Symbol, - createOwner: (Symbol) -> SymbolOwner, - ): SymbolOwner { - synchronized(lock) { - val existing = get(signature) - val symbol = if (existing == null) { - checkOriginal(descriptor) - val new = createSymbol() - set(new) - new - } else { - unboundSymbols.remove(existing) - existing - } - return createOwnerSafe(symbol, createOwner) - } - } - - inline fun referenced(descriptor: Descriptor, orElse: (IdSignature?) -> Symbol): Symbol { - synchronized(lock) { - val signature = signature(descriptor) - return get(descriptor, signature) ?: run { - checkOriginal(descriptor) - val new = orElse(signature) - assert(unboundSymbols.add(new)) { "Symbol for $new was already referenced" } - set(new) - new - } - } - } - - inline fun referenced(signature: IdSignature, orElse: () -> Symbol): Symbol { - synchronized(lock) { - return get(signature) ?: run { - val new = orElse() - assert(unboundSymbols.add(new)) { "Symbol for ${new.signature} was already referenced" } - set(new) - new - } - } - } - - private fun checkOriginal(descriptor: Descriptor?) { - @Suppress("UNCHECKED_CAST") - val descriptor0 = descriptor?.original as Descriptor - assert(descriptor0 === descriptor) { - "Non-original descriptor in declaration: $descriptor\n\tExpected: $descriptor0" - } - } - - protected inline fun createOwnerSafe(symbol: Symbol, createOwner: (Symbol) -> SymbolOwner): SymbolOwner { - val owner = createOwner(symbol) - require(symbol.isBound) - require(symbol.owner === owner) { - "Attempt to rebind an IR symbol or to re-create its owner: old owner ${symbol.owner.render()}, new owner ${owner.render()}" - } - return owner - } - } - - private open inner class FlatSymbolTable : SymbolTableBase(lock) - where Descriptor : DeclarationDescriptor, - SymbolOwner : IrSymbolOwner, - Symbol : IrBindableSymbol { - val descriptorToSymbol = hashMapOf() - val idSignatureToSymbol = hashMapOf() - - override fun signature(descriptor: Descriptor): IdSignature? = - signaturer.composeSignature(descriptor) - - override fun get(descriptor: Descriptor, signature: IdSignature?): Symbol? = - if (signature != null) { - idSignatureToSymbol[signature] - } else { - descriptorToSymbol[descriptor] - } - - @OptIn(ObsoleteDescriptorBasedAPI::class) - override fun set(symbol: Symbol) { - val signature = symbol.signature - if (signature != null) { - idSignatureToSymbol[signature] = symbol - } else if (symbol.hasDescriptor) { - descriptorToSymbol[symbol.descriptor] = symbol - } - } - - override fun get(signature: IdSignature): Symbol? = idSignatureToSymbol[signature] - - override fun set(signature: IdSignature, symbol: Symbol) { - idSignatureToSymbol[signature] = symbol - } - } - - private inner class EnumEntrySymbolTable : FlatSymbolTable() { - override fun signature(descriptor: ClassDescriptor): IdSignature? = signaturer.composeEnumEntrySignature(descriptor) - } - - private inner class FieldSymbolTable : FlatSymbolTable() { - override fun signature(descriptor: PropertyDescriptor): IdSignature? = signaturer.composeFieldSignature(descriptor) - } - - private inner class ScopedSymbolTable : SymbolTableBase(lock) - where Descriptor : DeclarationDescriptor, - SymbolOwner : IrSymbolOwner, - Symbol : IrBindableSymbol { - inner class Scope(val owner: IrSymbol, val parent: Scope?) { - private val descriptorToSymbol = hashMapOf() - private val idSignatureToSymbol = hashMapOf() - - private fun getByDescriptor(descriptor: Descriptor): Symbol? = - descriptorToSymbol[descriptor] ?: parent?.getByDescriptor(descriptor) - - private fun getByIdSignature(signature: IdSignature): Symbol? = - idSignatureToSymbol[signature] ?: parent?.getByIdSignature(signature) - - operator fun get(descriptor: Descriptor, signature: IdSignature?): Symbol? = - if (signature != null) { - getByIdSignature(signature) - } else { - getByDescriptor(descriptor) - } - - fun getLocal(descriptor: Descriptor) = descriptorToSymbol[descriptor] - - @OptIn(ObsoleteDescriptorBasedAPI::class) - operator fun set(descriptor: Descriptor, symbol: Symbol) { - symbol.signature?.let { - require(descriptor is TypeParameterDescriptor) - idSignatureToSymbol[it] = symbol - } ?: run { - assert(symbol.hasDescriptor) - descriptorToSymbol[symbol.descriptor] = symbol - } - } - - operator fun get(signature: IdSignature): Symbol? = - idSignatureToSymbol[signature] ?: parent?.get(signature) - - operator fun set(signature: IdSignature, symbol: Symbol) { - idSignatureToSymbol[signature] = symbol - } - - fun dumpTo(stringBuilder: StringBuilder): StringBuilder = - stringBuilder.also { - it.append("owner=") - it.append(owner) - it.append("; ") - descriptorToSymbol.keys.joinTo(prefix = "[", postfix = "]", buffer = it) - it.append('\n') - parent?.dumpTo(it) - } - - fun dump(): String = dumpTo(StringBuilder()).toString() - } - - private var currentScope: Scope? = null - - override fun signature(descriptor: Descriptor): IdSignature? = - signaturer.composeSignature(descriptor) - - override fun get(descriptor: Descriptor, signature: IdSignature?): Symbol? { - val scope = currentScope ?: return null - return scope[descriptor, signature] - } - - @OptIn(ObsoleteDescriptorBasedAPI::class) - override fun set(symbol: Symbol) { - val scope = currentScope ?: throw AssertionError("No active scope") - scope[symbol.descriptor] = symbol - } - - override fun get(signature: IdSignature): Symbol? { - val scope = currentScope ?: return null - return scope[signature] - } - - override fun set(signature: IdSignature, symbol: Symbol) { - val scope = currentScope ?: throw AssertionError("No active scope") - scope[signature] = symbol - } - - inline fun declareLocal(descriptor: Descriptor, createSymbol: () -> Symbol, createOwner: (Symbol) -> SymbolOwner): SymbolOwner { - val scope = currentScope ?: throw AssertionError("No active scope") - val symbol = scope.getLocal(descriptor) ?: createSymbol().also { scope[descriptor] = it } - return createOwnerSafe(symbol, createOwner) - } - - fun introduceLocal(descriptor: Descriptor, symbol: Symbol) { - val scope = currentScope ?: throw AssertionError("No active scope") - scope[descriptor, signature(descriptor)]?.let { - throw AssertionError("$descriptor is already bound to $it") - } - scope[descriptor] = symbol - } - - fun enterScope(owner: IrSymbol) { - currentScope = Scope(owner, currentScope) - } - - fun leaveScope(owner: IrSymbol) { - currentScope?.owner.let { - assert(it == owner) { "Unexpected leaveScope: owner=$owner, currentScope.owner=$it" } - } - - currentScope = currentScope?.parent - - if (currentScope != null && unboundSymbols.isNotEmpty()) { - @OptIn(ObsoleteDescriptorBasedAPI::class) - throw AssertionError("Local scope contains unbound symbols: ${unboundSymbols.joinToString { it.descriptor.toString() }}") - } - } - - fun dump(): String = - currentScope?.dump() ?: "" - } - - private val externalPackageFragmentTable = - FlatSymbolTable() - private val scriptSymbolTable = FlatSymbolTable() - private val classSymbolTable = FlatSymbolTable() - private val constructorSymbolTable = FlatSymbolTable() - private val enumEntrySymbolTable = EnumEntrySymbolTable() - private val fieldSymbolTable = FieldSymbolTable() - private val simpleFunctionSymbolTable = FlatSymbolTable() - private val propertySymbolTable = FlatSymbolTable() - private val typeAliasSymbolTable = FlatSymbolTable() - - private val globalTypeParameterSymbolTable = FlatSymbolTable() - private val scopedTypeParameterSymbolTable by threadLocal { - ScopedSymbolTable() - } - private val valueParameterSymbolTable by threadLocal { - ScopedSymbolTable() - } - private val variableSymbolTable by threadLocal { - ScopedSymbolTable() - } - private val localDelegatedPropertySymbolTable by threadLocal { - ScopedSymbolTable() - } - private val scopedSymbolTables by threadLocal { - listOf(valueParameterSymbolTable, variableSymbolTable, scopedTypeParameterSymbolTable, localDelegatedPropertySymbolTable) - } - - @ObsoleteDescriptorBasedAPI - fun referenceExternalPackageFragment(descriptor: PackageFragmentDescriptor) = - externalPackageFragmentTable.referenced(descriptor) { IrExternalPackageFragmentSymbolImpl(descriptor) } - - @ObsoleteDescriptorBasedAPI - fun declareExternalPackageFragment(descriptor: PackageFragmentDescriptor): IrExternalPackageFragment { - return externalPackageFragmentTable.declare( - descriptor, - { IrExternalPackageFragmentSymbolImpl(descriptor) }, - { IrExternalPackageFragmentImpl(it, descriptor.fqName) } - ) - } - - @ObsoleteDescriptorBasedAPI - fun declareExternalPackageFragmentIfNotExists(descriptor: PackageFragmentDescriptor): IrExternalPackageFragment { - return externalPackageFragmentTable.declareIfNotExists( - descriptor, - { IrExternalPackageFragmentSymbolImpl(descriptor) }, - { IrExternalPackageFragmentImpl(it, descriptor.fqName) } - ) - } - - @ObsoleteDescriptorBasedAPI - fun declareAnonymousInitializer( - startOffset: Int, - endOffset: Int, - origin: IrDeclarationOrigin, - descriptor: ClassDescriptor - ): IrAnonymousInitializer = - irFactory.createAnonymousInitializer( - startOffset, endOffset, origin, - IrAnonymousInitializerSymbolImpl(descriptor) - ) - - @ObsoleteDescriptorBasedAPI - fun declareScript( - startOffset: Int, - endOffset: Int, - descriptor: ScriptDescriptor, - scriptFactory: (IrScriptSymbol) -> IrScript = { symbol: IrScriptSymbol -> - IrScriptImpl(symbol, nameProvider.nameForDeclaration(descriptor), irFactory, startOffset, endOffset) - } - ): IrScript { - return scriptSymbolTable.declare( - descriptor, - { IrScriptSymbolImpl(descriptor) }, - scriptFactory - ) - } + // ------------------------------------ script ------------------------------------ fun declareScript( signature: IdSignature, symbolFactory: () -> IrScriptSymbol, - scriptFactory: (IrScriptSymbol) -> IrScript + scriptFactory: (IrScriptSymbol) -> IrScript, ): IrScript { - return scriptSymbolTable.declare( + return scriptSlice.declare( signature, symbolFactory, scriptFactory ) } - @ObsoleteDescriptorBasedAPI - override fun referenceScript(descriptor: ScriptDescriptor): IrScriptSymbol = - scriptSymbolTable.referenced(descriptor) { IrScriptSymbolImpl(descriptor) } - - private fun createClassSymbol(descriptor: ClassDescriptor, signature: IdSignature?): IrClassSymbol = - signature?.let { IrClassPublicSymbolImpl(it, descriptor) } ?: IrClassSymbolImpl(descriptor) - - @ObsoleteDescriptorBasedAPI - fun declareClass( - descriptor: ClassDescriptor, - classFactory: (IrClassSymbol) -> IrClass - ): IrClass { - return classSymbolTable.declare( - descriptor, - { createClassSymbol(descriptor, signaturer.composeSignature(descriptor)) }, - classFactory - ) - } + // ------------------------------------ class ------------------------------------ fun declareClass( signature: IdSignature, symbolFactory: () -> IrClassSymbol, - classFactory: (IrClassSymbol) -> IrClass + classFactory: (IrClassSymbol) -> IrClass, ): IrClass { - return classSymbolTable.declare( + return classSlice.declare( signature, symbolFactory, classFactory @@ -517,187 +70,549 @@ open class SymbolTable( } fun declareClassWithSignature(signature: IdSignature, symbol: IrClassSymbol) { - classSymbolTable.set(signature, symbol) + classSlice.set(signature, symbol) } - @ObsoleteDescriptorBasedAPI - fun declareClassIfNotExists(descriptor: ClassDescriptor, classFactory: (IrClassSymbol) -> IrClass): IrClass = - classSymbolTable.declareIfNotExists(descriptor, { signature -> createClassSymbol(descriptor, signature) }, classFactory) - - // Note: used in native - @ObsoleteDescriptorBasedAPI - @Suppress("unused") - fun declareClassFromLinker(descriptor: ClassDescriptor, signature: IdSignature, factory: (IrClassSymbol) -> IrClass): IrClass { - return classSymbolTable.run { - if (signature.isPubliclyVisible) { - declare(signature, descriptor, { IrClassPublicSymbolImpl(signature, descriptor) }, factory) - } else { - declare(descriptor, { IrClassSymbolImpl(descriptor) }, factory) - } - } + fun declareClassIfNotExists( + signature: IdSignature, + symbolFactory: () -> IrClassSymbol, + classFactory: (IrClassSymbol) -> IrClass, + ): IrClass { + return classSlice.declareIfNotExists(signature, symbolFactory, classFactory) } - @ObsoleteDescriptorBasedAPI - override fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol = - @Suppress("Reformat") - // This is needed for cases like kt46069.kt, where psi2ir creates descriptor-less IR elements for adapted function references. - // In JVM IR, symbols are linked via descriptors by default, so for an adapted function reference, an IrBasedClassDescriptor - // is created for any classifier used in the function parameter/return types. Any attempt to translate such type to IrType goes - // to this method, which puts the descriptor into unboundClasses, which causes an assertion failure later because we won't bind - // such symbol anywhere. - // TODO: maybe there's a better solution. - if (descriptor is IrBasedClassDescriptor) - descriptor.owner.symbol - else - classSymbolTable.referenced(descriptor) { signature -> createClassSymbol(descriptor, signature) } - fun referenceClass( signature: IdSignature, symbolFactory: () -> IrClassSymbol, - classFactory: (IrClassSymbol) -> IrClass - ) = - classSymbolTable.referenced(signature) { declareClass(signature, symbolFactory, classFactory).symbol } + classFactory: (IrClassSymbol) -> IrClass, + ): IrClassSymbol { + return classSlice.referenced(signature) { declareClass(signature, symbolFactory, classFactory).symbol } + } - override fun referenceClass(signature: IdSignature): IrClassSymbol = - classSymbolTable.run { - if (signature.isPubliclyVisible) referenced(signature) { IrClassPublicSymbolImpl(signature) } - else IrClassSymbolImpl().also { - it.privateSignature = signature - } - } - - val unboundClasses: Set get() = classSymbolTable.unboundSymbols - - private fun createConstructorSymbol(descriptor: ClassConstructorDescriptor, signature: IdSignature?): IrConstructorSymbol = - signature?.let { IrConstructorPublicSymbolImpl(it, descriptor) } ?: IrConstructorSymbolImpl(descriptor) - - @ObsoleteDescriptorBasedAPI - fun declareConstructor( - descriptor: ClassConstructorDescriptor, - constructorFactory: (IrConstructorSymbol) -> IrConstructor - ): IrConstructor = - constructorSymbolTable.declare( - descriptor, - { signature -> createConstructorSymbol(descriptor, signature) }, - constructorFactory + override fun referenceClass(signature: IdSignature): IrClassSymbol { + return referenceClassImpl( + signature, + { IrClassPublicSymbolImpl(signature) }, + { IrClassSymbolImpl().also { it.privateSignature = signature } } ) + } + + // TODO: add OptIn + internal inline fun referenceClassImpl( + signature: IdSignature, + publicSymbolFactory: () -> IrClassSymbol, + privateSymbolFactory: () -> IrClassSymbol, + ): IrClassSymbol { + return when { + signature.isPubliclyVisible -> classSlice.referenced(signature) { publicSymbolFactory() } + else -> privateSymbolFactory() + } + } + + // ------------------------------------ constructor ------------------------------------ fun declareConstructor( signature: IdSignature, symbolFactory: () -> IrConstructorSymbol, - constructorFactory: (IrConstructorSymbol) -> IrConstructor + constructorFactory: (IrConstructorSymbol) -> IrConstructor, ): IrConstructor { - return constructorSymbolTable.declare( + return constructorSlice.declare( signature, symbolFactory, constructorFactory ) } - @ObsoleteDescriptorBasedAPI fun declareConstructorIfNotExists( - descriptor: ClassConstructorDescriptor, + signature: IdSignature, + symbolFactory: () -> IrConstructorSymbol, constructorFactory: (IrConstructorSymbol) -> IrConstructor, - ): IrConstructor = - constructorSymbolTable.declareIfNotExists( - descriptor, - { signature -> createConstructorSymbol(descriptor, signature) }, - constructorFactory - ) - - fun declareConstructorWithSignature(signature: IdSignature, symbol: IrConstructorSymbol) { - constructorSymbolTable.set(signature, symbol) + ): IrConstructor { + return constructorSlice.declareIfNotExists(signature, symbolFactory, constructorFactory) } - @ObsoleteDescriptorBasedAPI - override fun referenceConstructor(descriptor: ClassConstructorDescriptor): IrConstructorSymbol = - constructorSymbolTable.referenced(descriptor) { signature -> createConstructorSymbol(descriptor, signature) } + fun declareConstructorWithSignature(signature: IdSignature, symbol: IrConstructorSymbol) { + constructorSlice.set(signature, symbol) + } - fun referenceConstructorIfAny(signature: IdSignature): IrConstructorSymbol? = - constructorSymbolTable.get(signature) + fun referenceConstructorIfAny(signature: IdSignature): IrConstructorSymbol? { + return constructorSlice.get(signature) + } - // Note: used in native - @ObsoleteDescriptorBasedAPI - @Suppress("unused") - fun declareConstructorFromLinker( - descriptor: ClassConstructorDescriptor, + override fun referenceConstructor(signature: IdSignature): IrConstructorSymbol { + return referenceConstructorImpl( + signature, + { IrConstructorPublicSymbolImpl(signature) }, + { IrConstructorSymbolImpl() } + ) + } + + // TODO: add OptIn + internal inline fun referenceConstructorImpl( signature: IdSignature, - constructorFactory: (IrConstructorSymbol) -> IrConstructor - ): IrConstructor { - return constructorSymbolTable.run { - if (signature.isPubliclyVisible) { - declare(signature, descriptor, { IrConstructorPublicSymbolImpl(signature, descriptor) }, constructorFactory) - } else { - declare(descriptor, { IrConstructorSymbolImpl(descriptor) }, constructorFactory) + publicSymbolFactory: () -> IrConstructorSymbol, + privateSymbolFactory: () -> IrConstructorSymbol, + ): IrConstructorSymbol { + return when { + signature.isPubliclyVisible -> constructorSlice.referenced(signature) { publicSymbolFactory() } + else -> privateSymbolFactory().also { + it.privateSignature = signature } } } - override fun referenceConstructor(signature: IdSignature): IrConstructorSymbol = - constructorSymbolTable.run { - if (signature.isPubliclyVisible) referenced(signature) { IrConstructorPublicSymbolImpl(signature) } - else IrConstructorSymbolImpl() - } - - val unboundConstructors: Set get() = constructorSymbolTable.unboundSymbols - - private fun createEnumEntrySymbol(descriptor: ClassDescriptor, signature: IdSignature?): IrEnumEntrySymbol = - signature?.let { IrEnumEntryPublicSymbolImpl(it, descriptor) } ?: IrEnumEntrySymbolImpl(descriptor) - - @ObsoleteDescriptorBasedAPI - fun declareEnumEntry( - startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor, - factory: (IrEnumEntrySymbol) -> IrEnumEntry = { - irFactory.createEnumEntry(startOffset, endOffset, origin, nameProvider.nameForDeclaration(descriptor), it) - } - ): IrEnumEntry = - enumEntrySymbolTable.declare( - descriptor, - { signature -> createEnumEntrySymbol(descriptor, signature) }, - factory - ) + // ------------------------------------ enum entry ------------------------------------ fun declareEnumEntry( signature: IdSignature, symbolFactory: () -> IrEnumEntrySymbol, - enumEntryFactory: (IrEnumEntrySymbol) -> IrEnumEntry - ): IrEnumEntry = enumEntrySymbolTable.declare(signature, symbolFactory, enumEntryFactory) - - @ObsoleteDescriptorBasedAPI - fun declareEnumEntryIfNotExists(descriptor: ClassDescriptor, factory: (IrEnumEntrySymbol) -> IrEnumEntry): IrEnumEntry = - enumEntrySymbolTable.declareIfNotExists(descriptor, { signature -> createEnumEntrySymbol(descriptor, signature) }, factory) - - // Note: used in native - @ObsoleteDescriptorBasedAPI - @Suppress("unused") - fun declareEnumEntryFromLinker( - descriptor: ClassDescriptor, - signature: IdSignature, - factory: (IrEnumEntrySymbol) -> IrEnumEntry + enumEntryFactory: (IrEnumEntrySymbol) -> IrEnumEntry, ): IrEnumEntry { - return enumEntrySymbolTable.run { - if (signature.isPubliclyVisible) { - declare(signature, descriptor, { IrEnumEntryPublicSymbolImpl(signature, descriptor) }, factory) - } else { - declare(descriptor, { IrEnumEntrySymbolImpl(descriptor) }, factory) + return enumEntrySlice.declare(signature, symbolFactory, enumEntryFactory) + } + + fun declareEnumEntryIfNotExists( + signature: IdSignature, + symbolFactory: () -> IrEnumEntrySymbol, + classFactory: (IrEnumEntrySymbol) -> IrEnumEntry, + ): IrEnumEntry { + return enumEntrySlice.declareIfNotExists(signature, symbolFactory, classFactory) + } + + override fun referenceEnumEntry(signature: IdSignature): IrEnumEntrySymbol { + return referenceEnumEntryImpl( + signature, + { IrEnumEntryPublicSymbolImpl(signature) }, + { IrEnumEntrySymbolImpl() } + ) + } + + // TODO: add OptIn + internal inline fun referenceEnumEntryImpl( + signature: IdSignature, + publicSymbolFactory: () -> IrEnumEntrySymbol, + privateSymbolFactory: () -> IrEnumEntrySymbol, + ): IrEnumEntrySymbol { + return when { + signature.isPubliclyVisible -> enumEntrySlice.referenced(signature) { publicSymbolFactory() } + else -> privateSymbolFactory().also { + it.privateSignature = signature } } } - @ObsoleteDescriptorBasedAPI - override fun referenceEnumEntry(descriptor: ClassDescriptor): IrEnumEntrySymbol = - enumEntrySymbolTable.referenced(descriptor) { signature -> createEnumEntrySymbol(descriptor, signature) } + // ------------------------------------ field ------------------------------------ - override fun referenceEnumEntry(signature: IdSignature) = - enumEntrySymbolTable.run { - if (signature.isPubliclyVisible) referenced(signature) { IrEnumEntryPublicSymbolImpl(signature) } - else IrEnumEntrySymbolImpl() + fun declareField( + signature: IdSignature, + symbolFactory: () -> IrFieldSymbol, + propertyFactory: (IrFieldSymbol) -> IrField, + ): IrField { + return fieldSlice.declare( + signature, + symbolFactory, + propertyFactory + ) + } + + fun declareFieldWithSignature(signature: IdSignature, symbol: IrFieldSymbol) { + fieldSlice.set(signature, symbol) + } + + override fun referenceField(signature: IdSignature): IrFieldSymbol { + return referenceFieldImpl( + signature, + { IrFieldPublicSymbolImpl(signature) }, + { IrFieldSymbolImpl() } + ) + } + + // TODO: add OptIn + internal inline fun referenceFieldImpl( + signature: IdSignature, + publicSymbolFactory: () -> IrFieldSymbol, + privateSymbolFactory: () -> IrFieldSymbol, + ): IrFieldSymbol { + return when { + signature.isPubliclyVisible -> fieldSlice.referenced(signature) { publicSymbolFactory() } + else -> privateSymbolFactory().also { + it.privateSignature = signature + } + } + } + + // ------------------------------------ property ------------------------------------ + + fun declareProperty( + signature: IdSignature, + symbolFactory: () -> IrPropertySymbol, + propertyFactory: (IrPropertySymbol) -> IrProperty, + ): IrProperty { + return propertySlice.declare( + signature, + symbolFactory, + propertyFactory + ) + } + + fun declarePropertyIfNotExists( + signature: IdSignature, + symbolFactory: () -> IrPropertySymbol, + propertyFactory: (IrPropertySymbol) -> IrProperty, + ): IrProperty { + return propertySlice.declareIfNotExists(signature, symbolFactory, propertyFactory) + } + + fun declarePropertyWithSignature(signature: IdSignature, symbol: IrPropertySymbol) { + propertySlice.set(signature, symbol) + } + + fun referencePropertyIfAny(signature: IdSignature): IrPropertySymbol? { + return propertySlice.get(signature) + } + + override fun referenceProperty(signature: IdSignature): IrPropertySymbol { + return referencePropertyImpl( + signature, + { IrPropertyPublicSymbolImpl(signature) }, + { IrPropertySymbolImpl() } + ) + } + + // TODO: add OptIn + internal inline fun referencePropertyImpl( + signature: IdSignature, + publicSymbolFactory: () -> IrPropertySymbol, + privateSymbolFactory: () -> IrPropertySymbol, + ): IrPropertySymbol { + return when { + signature.isPubliclyVisible -> propertySlice.referenced(signature) { publicSymbolFactory() } + else -> privateSymbolFactory().also { + it.privateSignature = signature + } + } + } + + // ------------------------------------ typealias ------------------------------------ + + fun declareTypeAlias( + signature: IdSignature, + symbolFactory: () -> IrTypeAliasSymbol, + factory: (IrTypeAliasSymbol) -> IrTypeAlias, + ): IrTypeAlias { + return typeAliasSlice.declare(signature, symbolFactory, factory) + } + + fun declareTypeAliasIfNotExists( + signature: IdSignature, + symbolFactory: () -> IrTypeAliasSymbol, + typeAliasFactory: (IrTypeAliasSymbol) -> IrTypeAlias, + ): IrTypeAlias { + return typeAliasSlice.declareIfNotExists(signature, symbolFactory, typeAliasFactory) + } + + override fun referenceTypeAlias(signature: IdSignature): IrTypeAliasSymbol { + return referenceTypeAliasImpl( + signature, + { IrTypeAliasPublicSymbolImpl(signature) }, + { IrTypeAliasSymbolImpl() } + ) + } + + // TODO: add OptIn + internal inline fun referenceTypeAliasImpl( + signature: IdSignature, + publicSymbolFactory: () -> IrTypeAliasSymbol, + privateSymbolFactory: () -> IrTypeAliasSymbol, + ): IrTypeAliasSymbol { + return when { + signature.isPubliclyVisible -> typeAliasSlice.referenced(signature) { publicSymbolFactory() } + else -> privateSymbolFactory().also { + it.privateSignature = signature + } + } + } + + // ------------------------------------ function ------------------------------------ + + fun declareSimpleFunction( + signature: IdSignature, + symbolFactory: () -> IrSimpleFunctionSymbol, + functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction, + ): IrSimpleFunction { + return functionSlice.declare( + signature, + symbolFactory, + functionFactory + ) + } + + fun declareSimpleFunctionIfNotExists( + signature: IdSignature, + symbolFactory: () -> IrSimpleFunctionSymbol, + functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction, + ): IrSimpleFunction { + return functionSlice.declareIfNotExists(signature, symbolFactory, functionFactory) + } + + fun declareSimpleFunctionWithSignature(signature: IdSignature, symbol: IrSimpleFunctionSymbol) { + functionSlice.set(signature, symbol) + } + + fun referenceSimpleFunctionIfAny(signature: IdSignature): IrSimpleFunctionSymbol? = + functionSlice.get(signature) + + override fun referenceSimpleFunction(signature: IdSignature): IrSimpleFunctionSymbol { + return referenceSimpleFunctionImpl( + signature, + { IrSimpleFunctionPublicSymbolImpl(signature) }, + { IrSimpleFunctionSymbolImpl().also { it.privateSignature = signature } } + ) + } + + // TODO: add OptIn + internal inline fun referenceSimpleFunctionImpl( + signature: IdSignature, + publicSymbolFactory: () -> IrSimpleFunctionSymbol, + privateSymbolFactory: () -> IrSimpleFunctionSymbol, + ): IrSimpleFunctionSymbol { + return when { + signature.isPubliclyVisible -> functionSlice.referenced(signature) { publicSymbolFactory() } + else -> privateSymbolFactory().also { + it.privateSignature = signature + } + } + } + + // ------------------------------------ type parameter ------------------------------------ + + fun declareGlobalTypeParameter( + signature: IdSignature, + symbolFactory: () -> IrTypeParameterSymbol, + typeParameterFactory: (IrTypeParameterSymbol) -> IrTypeParameter, + ): IrTypeParameter { + return globalTypeParameterSlice.declare(signature, symbolFactory, typeParameterFactory) + } + + fun declareScopedTypeParameter( + signature: IdSignature, + symbolFactory: (IdSignature) -> IrTypeParameterSymbol, + typeParameterFactory: (IrTypeParameterSymbol) -> IrTypeParameter, + ): IrTypeParameter { + // TODO: suspicios + return typeParameterFactory(symbolFactory(signature)) + } + + override fun referenceTypeParameter(signature: IdSignature): IrTypeParameterSymbol { + return referenceTypeParameterImpl( + signature, + { IrTypeParameterPublicSymbolImpl(signature) }, + { IrTypeParameterSymbolImpl() } + ) + } + + // TODO: add OptIn + internal inline fun referenceTypeParameterImpl( + signature: IdSignature, + publicSymbolFactory: () -> IrTypeParameterSymbol, + privateSymbolFactory: () -> IrTypeParameterSymbol, + ): IrTypeParameterSymbol { + return when { + signature.isPubliclyVisible -> globalTypeParameterSlice.referenced(signature) { publicSymbolFactory() } + else -> privateSymbolFactory().also { + it.privateSignature = signature + } + } + } + + // ------------------------------------ scopes ------------------------------------ + + // TODO: move to extensions + @OptIn(ObsoleteDescriptorBasedAPI::class) + override fun enterScope(symbol: IrSymbol) { + descriptorExtension.enterScope(symbol) + } + + // TODO: move to extensions + @OptIn(ObsoleteDescriptorBasedAPI::class) + override fun enterScope(owner: IrDeclaration) { + descriptorExtension.enterScope(owner) + } + + // TODO: move to extensions + @OptIn(ObsoleteDescriptorBasedAPI::class) + override fun leaveScope(symbol: IrSymbol) { + descriptorExtension.leaveScope(symbol) + } + + // TODO: move to extensions + @OptIn(ObsoleteDescriptorBasedAPI::class) + override fun leaveScope(owner: IrDeclaration) { + descriptorExtension.leaveScope(owner) + } + + // ------------------------------------ utils ------------------------------------ + + /** + * This function is quite messy and doesn't have good contract of what exactly is traversed. + * Basic idea is it traverse symbols which can be reasonable referered from other module + * + * Be careful when using it, and avoid it, except really need. + * + * TODO: add some OptIn + */ + fun forEachDeclarationSymbol(block: (IrSymbol) -> Unit) { + classSlice.forEachSymbol { block(it) } + constructorSlice.forEachSymbol { block(it) } + functionSlice.forEachSymbol { block(it) } + propertySlice.forEachSymbol { block(it) } + enumEntrySlice.forEachSymbol { block(it) } + typeAliasSlice.forEachSymbol { block(it) } + fieldSlice.forEachSymbol { block(it) } + } + + val allUnboundSymbols: Set + get() = buildSet { + fun addUnbound(slice: SymbolTableSlice) { + slice.unboundSymbols.filterTo(this) { !it.isBound } + } + + addUnbound(classSlice) + addUnbound(constructorSlice) + addUnbound(functionSlice) + addUnbound(propertySlice) + addUnbound(enumEntrySlice) + addUnbound(typeAliasSlice) + addUnbound(fieldSlice) } - val unboundEnumEntries: Set get() = enumEntrySymbolTable.unboundSymbols + // ------------------------------------ descriptors ------------------------------------ - private fun createFieldSymbol(descriptor: PropertyDescriptor, signature: IdSignature?): IrFieldSymbol = - signature?.let { IrFieldPublicSymbolImpl(it, descriptor) } ?: IrFieldSymbolImpl(descriptor) + @ObsoleteDescriptorBasedAPI + override fun referenceScript(descriptor: ScriptDescriptor): IrScriptSymbol { + return descriptorExtension.referenceScript(descriptor) + } + + @ObsoleteDescriptorBasedAPI + fun declareScript( + startOffset: Int, + endOffset: Int, + descriptor: ScriptDescriptor, + ): IrScript { + return descriptorExtension.declareScript(startOffset, endOffset, descriptor) + } + + @ObsoleteDescriptorBasedAPI + fun referenceExternalPackageFragment(descriptor: PackageFragmentDescriptor): IrExternalPackageFragmentSymbol { + return descriptorExtension.referenceExternalPackageFragment(descriptor) + } + + @ObsoleteDescriptorBasedAPI + fun declareExternalPackageFragment(descriptor: PackageFragmentDescriptor): IrExternalPackageFragment { + return descriptorExtension.declareExternalPackageFragment(descriptor) + } + + @ObsoleteDescriptorBasedAPI + fun declareExternalPackageFragmentIfNotExists(descriptor: PackageFragmentDescriptor): IrExternalPackageFragment { + return descriptorExtension.declareExternalPackageFragmentIfNotExists(descriptor) + } + + @ObsoleteDescriptorBasedAPI + fun declareAnonymousInitializer( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + descriptor: ClassDescriptor, + ): IrAnonymousInitializer { + return descriptorExtension.declareAnonymousInitializer(startOffset, endOffset, origin, descriptor) + } + + @ObsoleteDescriptorBasedAPI + fun declareClass( + descriptor: ClassDescriptor, + classFactory: (IrClassSymbol) -> IrClass, + ): IrClass { + return descriptorExtension.declareClass(descriptor, classFactory) + } + + @ObsoleteDescriptorBasedAPI + fun declareClassIfNotExists(descriptor: ClassDescriptor, classFactory: (IrClassSymbol) -> IrClass): IrClass { + return descriptorExtension.declareClassIfNotExists(descriptor, classFactory) + } + + @ObsoleteDescriptorBasedAPI + fun declareClassFromLinker(descriptor: ClassDescriptor, signature: IdSignature, factory: (IrClassSymbol) -> IrClass): IrClass { + return descriptorExtension.declareClassFromLinker(descriptor, signature, factory) + } + + @ObsoleteDescriptorBasedAPI + override fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol { + return descriptorExtension.referenceClass(descriptor) + } + + @ObsoleteDescriptorBasedAPI + fun declareConstructor( + descriptor: ClassConstructorDescriptor, + constructorFactory: (IrConstructorSymbol) -> IrConstructor, + ): IrConstructor { + return descriptorExtension.declareConstructor(descriptor, constructorFactory) + } + + @ObsoleteDescriptorBasedAPI + fun declareConstructorIfNotExists( + descriptor: ClassConstructorDescriptor, + constructorFactory: (IrConstructorSymbol) -> IrConstructor, + ): IrConstructor { + return descriptorExtension.declareConstructorIfNotExists(descriptor, constructorFactory) + } + + @ObsoleteDescriptorBasedAPI + override fun referenceConstructor(descriptor: ClassConstructorDescriptor): IrConstructorSymbol { + return descriptorExtension.referenceConstructor(descriptor) + } + + @ObsoleteDescriptorBasedAPI + fun declareConstructorFromLinker( + descriptor: ClassConstructorDescriptor, + signature: IdSignature, + constructorFactory: (IrConstructorSymbol) -> IrConstructor, + ): IrConstructor { + return descriptorExtension.declareConstructorFromLinker(descriptor, signature, constructorFactory) + } + + @ObsoleteDescriptorBasedAPI + fun declareEnumEntry( + startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor, + ): IrEnumEntry { + return descriptorExtension.declareEnumEntry(startOffset, endOffset, origin, descriptor) + } + + @ObsoleteDescriptorBasedAPI + fun declareEnumEntry( + descriptor: ClassDescriptor, + factory: (IrEnumEntrySymbol) -> IrEnumEntry, + ): IrEnumEntry { + return descriptorExtension.declareEnumEntry(descriptor, factory) + } + + @ObsoleteDescriptorBasedAPI + fun declareEnumEntryIfNotExists(descriptor: ClassDescriptor, factory: (IrEnumEntrySymbol) -> IrEnumEntry): IrEnumEntry { + return descriptorExtension.declareEnumEntryIfNotExists(descriptor, factory) + } + + @ObsoleteDescriptorBasedAPI + fun declareEnumEntryFromLinker( + descriptor: ClassDescriptor, + signature: IdSignature, + factory: (IrEnumEntrySymbol) -> IrEnumEntry, + ): IrEnumEntry { + return descriptorExtension.declareEnumEntryFromLinker(descriptor, signature, factory) + } + + @ObsoleteDescriptorBasedAPI + override fun referenceEnumEntry(descriptor: ClassDescriptor): IrEnumEntrySymbol { + return descriptorExtension.referenceEnumEntry(descriptor) + } @OptIn(ObsoleteDescriptorBasedAPI::class) fun declareField( @@ -707,28 +622,10 @@ open class SymbolTable( descriptor: PropertyDescriptor, type: IrType, visibility: DescriptorVisibility? = null, - fieldFactory: (IrFieldSymbol) -> IrField = { - irFactory.createField( - startOffset = startOffset, - endOffset = endOffset, - origin = origin, - name = nameProvider.nameForDeclaration(descriptor), - visibility = visibility ?: it.descriptor.visibility, - symbol = it, - type = type, - isFinal = !it.descriptor.isVar, - isStatic = it.descriptor.dispatchReceiverParameter == null, - isExternal = it.descriptor.isEffectivelyExternal(), - ).apply { - metadata = DescriptorMetadataSource.Property(it.descriptor) - } - } - ): IrField = - fieldSymbolTable.declare( - descriptor, - { signature -> createFieldSymbol(descriptor, signature) }, - fieldFactory - ) + fieldFactory: (IrFieldSymbol) -> IrField, + ): IrField { + return descriptorExtension.declareField(startOffset, endOffset, origin, descriptor, type, visibility, fieldFactory) + } @ObsoleteDescriptorBasedAPI fun declareField( @@ -737,43 +634,15 @@ open class SymbolTable( origin: IrDeclarationOrigin, descriptor: PropertyDescriptor, type: IrType, - irInitializer: IrExpressionBody? - ): IrField = - declareField(startOffset, endOffset, origin, descriptor, type).apply { - initializer = irInitializer - } - - fun declareField( - signature: IdSignature, - symbolFactory: () -> IrFieldSymbol, - propertyFactory: (IrFieldSymbol) -> IrField + irInitializer: IrExpressionBody?, ): IrField { - return fieldSymbolTable.declare( - signature, - symbolFactory, - propertyFactory - ) - } - - fun declareFieldWithSignature(signature: IdSignature, symbol: IrFieldSymbol) { - fieldSymbolTable.set(signature, symbol) + return descriptorExtension.declareField(startOffset, endOffset, origin, descriptor, type, irInitializer) } @ObsoleteDescriptorBasedAPI - override fun referenceField(descriptor: PropertyDescriptor): IrFieldSymbol = - fieldSymbolTable.referenced(descriptor) { signature -> createFieldSymbol(descriptor, signature) } - - override fun referenceField(signature: IdSignature): IrFieldSymbol = - fieldSymbolTable.run { - if (signature.isPubliclyVisible) { - referenced(signature) { IrFieldPublicSymbolImpl(signature) } - } else IrFieldSymbolImpl() - } - - val unboundFields: Set get() = fieldSymbolTable.unboundSymbols - - private fun createPropertySymbol(descriptor: PropertyDescriptor, signature: IdSignature?): IrPropertySymbol = - signature?.let { IrPropertyPublicSymbolImpl(it, descriptor) } ?: IrPropertySymbolImpl(descriptor) + override fun referenceField(descriptor: PropertyDescriptor): IrFieldSymbol { + return descriptorExtension.referenceField(descriptor) + } @ObsoleteDescriptorBasedAPI fun declareProperty( @@ -782,48 +651,22 @@ open class SymbolTable( origin: IrDeclarationOrigin, descriptor: PropertyDescriptor, isDelegated: Boolean = descriptor.isDelegated, - propertyFactory: (IrPropertySymbol) -> IrProperty = { symbol -> - irFactory.createProperty( - startOffset = startOffset, - endOffset = endOffset, - origin = origin, - name = nameProvider.nameForDeclaration(descriptor), - visibility = descriptor.visibility, - modality = descriptor.modality, - symbol = symbol, - isVar = descriptor.isVar, - isConst = descriptor.isConst, - isLateinit = descriptor.isLateInit, - isDelegated = isDelegated, - isExternal = descriptor.isEffectivelyExternal(), - isExpect = descriptor.isExpect, - isFakeOverride = descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE, - ).apply { - metadata = DescriptorMetadataSource.Property(symbol.descriptor) - } - } - ): IrProperty = - propertySymbolTable.declare( - descriptor, - { signature -> createPropertySymbol(descriptor, signature) }, - propertyFactory - ) - - fun declareProperty( - signature: IdSignature, - symbolFactory: () -> IrPropertySymbol, - propertyFactory: (IrPropertySymbol) -> IrProperty ): IrProperty { - return propertySymbolTable.declare( - signature, - symbolFactory, - propertyFactory - ) + return descriptorExtension.declareProperty(startOffset, endOffset, origin, descriptor, isDelegated) } @ObsoleteDescriptorBasedAPI - fun declarePropertyIfNotExists(descriptor: PropertyDescriptor, propertyFactory: (IrPropertySymbol) -> IrProperty): IrProperty = - propertySymbolTable.declareIfNotExists(descriptor, { signature -> createPropertySymbol(descriptor, signature) }, propertyFactory) + fun declareProperty( + descriptor: PropertyDescriptor, + propertyFactory: (IrPropertySymbol) -> IrProperty, + ): IrProperty { + return descriptorExtension.declareProperty(descriptor, propertyFactory) + } + + @ObsoleteDescriptorBasedAPI + fun declarePropertyIfNotExists(descriptor: PropertyDescriptor, propertyFactory: (IrPropertySymbol) -> IrProperty): IrProperty { + return descriptorExtension.declarePropertyIfNotExists(descriptor, propertyFactory) + } @ObsoleteDescriptorBasedAPI fun declarePropertyFromLinker( @@ -831,144 +674,63 @@ open class SymbolTable( signature: IdSignature, factory: (IrPropertySymbol) -> IrProperty, ): IrProperty { - return propertySymbolTable.run { - if (signature.isPubliclyVisible) { - declare(signature, descriptor, { IrPropertyPublicSymbolImpl(signature, descriptor) }, factory) - } else { - declare(descriptor, { IrPropertySymbolImpl(descriptor) }, factory) - } - } - } - - fun declarePropertyWithSignature(signature: IdSignature, symbol: IrPropertySymbol) { - propertySymbolTable.set(signature, symbol) + return descriptorExtension.declarePropertyFromLinker(descriptor, signature, factory) } @ObsoleteDescriptorBasedAPI - override fun referenceProperty(descriptor: PropertyDescriptor): IrPropertySymbol = - propertySymbolTable.referenced(descriptor) { signature -> createPropertySymbol(descriptor, signature) } - - fun referencePropertyIfAny(signature: IdSignature): IrPropertySymbol? = - propertySymbolTable.get(signature) - - override fun referenceProperty(signature: IdSignature): IrPropertySymbol = - propertySymbolTable.run { - if (signature.isPubliclyVisible) referenced(signature) { IrPropertyPublicSymbolImpl(signature) } - else IrPropertySymbolImpl() - } - - val unboundProperties: Set get() = propertySymbolTable.unboundSymbols - - private fun createTypeAliasSymbol(descriptor: TypeAliasDescriptor, signature: IdSignature?): IrTypeAliasSymbol = - signature?.let { IrTypeAliasPublicSymbolImpl(it, descriptor) } ?: IrTypeAliasSymbolImpl(descriptor) - - @ObsoleteDescriptorBasedAPI - override fun referenceTypeAlias(descriptor: TypeAliasDescriptor): IrTypeAliasSymbol = - typeAliasSymbolTable.referenced(descriptor) { signature -> createTypeAliasSymbol(descriptor, signature) } - - override fun referenceTypeAlias(signature: IdSignature) = - typeAliasSymbolTable.run { - if (signature.isPubliclyVisible) referenced(signature) { IrTypeAliasPublicSymbolImpl(signature) } - else IrTypeAliasSymbolImpl() - } - - @ObsoleteDescriptorBasedAPI - fun declareTypeAlias(descriptor: TypeAliasDescriptor, factory: (IrTypeAliasSymbol) -> IrTypeAlias): IrTypeAlias = - typeAliasSymbolTable.declare(descriptor, { signature -> createTypeAliasSymbol(descriptor, signature) }, factory) - - fun declareTypeAlias( - signature: IdSignature, - symbolFactory: () -> IrTypeAliasSymbol, - factory: (IrTypeAliasSymbol) -> IrTypeAlias - ): IrTypeAlias { - return typeAliasSymbolTable.declare(signature, symbolFactory, factory) + override fun referenceProperty(descriptor: PropertyDescriptor): IrPropertySymbol { + return descriptorExtension.referenceProperty(descriptor) } @ObsoleteDescriptorBasedAPI - fun declareTypeAliasIfNotExists(descriptor: TypeAliasDescriptor, factory: (IrTypeAliasSymbol) -> IrTypeAlias): IrTypeAlias = - typeAliasSymbolTable.declareIfNotExists(descriptor, { signature -> createTypeAliasSymbol(descriptor, signature) }, factory) + override fun referenceTypeAlias(descriptor: TypeAliasDescriptor): IrTypeAliasSymbol { + return descriptorExtension.referenceTypeAlias(descriptor) + } - val unboundTypeAliases: Set get() = typeAliasSymbolTable.unboundSymbols + @ObsoleteDescriptorBasedAPI + fun declareTypeAlias(descriptor: TypeAliasDescriptor, factory: (IrTypeAliasSymbol) -> IrTypeAlias): IrTypeAlias { + return descriptorExtension.declareTypeAlias(descriptor, factory) + } - private fun createSimpleFunctionSymbol(descriptor: FunctionDescriptor, signature: IdSignature?): IrSimpleFunctionSymbol = - signature?.let { IrSimpleFunctionPublicSymbolImpl(it, descriptor) } ?: IrSimpleFunctionSymbolImpl(descriptor) + @ObsoleteDescriptorBasedAPI + fun declareTypeAliasIfNotExists(descriptor: TypeAliasDescriptor, factory: (IrTypeAliasSymbol) -> IrTypeAlias): IrTypeAlias { + return descriptorExtension.declareTypeAliasIfNotExists(descriptor, factory) + } @ObsoleteDescriptorBasedAPI fun declareSimpleFunction( descriptor: FunctionDescriptor, - functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction + functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction, ): IrSimpleFunction { - return simpleFunctionSymbolTable.declare( - descriptor, - { signature -> createSimpleFunctionSymbol(descriptor, signature) }, - functionFactory - ) - } - - fun declareSimpleFunction( - signature: IdSignature, - symbolFactory: () -> IrSimpleFunctionSymbol, - functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction - ): IrSimpleFunction { - return simpleFunctionSymbolTable.declare( - signature, - symbolFactory, - functionFactory - ) + return descriptorExtension.declareSimpleFunction(descriptor, functionFactory) } @ObsoleteDescriptorBasedAPI fun declareSimpleFunctionIfNotExists( descriptor: FunctionDescriptor, - functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction - ): IrSimpleFunction = - simpleFunctionSymbolTable.declareIfNotExists( - descriptor, { signature -> createSimpleFunctionSymbol(descriptor, signature) }, functionFactory - ) + functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction, + ): IrSimpleFunction { + return descriptorExtension.declareSimpleFunctionIfNotExists(descriptor, functionFactory) + } @ObsoleteDescriptorBasedAPI fun declareSimpleFunctionFromLinker( - descriptor: FunctionDescriptor?, + descriptor: FunctionDescriptor, signature: IdSignature, - functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction + functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction, ): IrSimpleFunction { - return simpleFunctionSymbolTable.run { - if (signature.isPubliclyVisible) { - declare(signature, descriptor, { IrSimpleFunctionPublicSymbolImpl(signature, descriptor) }, functionFactory) - } else { - declare(descriptor!!, { IrSimpleFunctionSymbolImpl(descriptor) }, functionFactory) - } - } - } - - fun declareSimpleFunctionWithSignature(signature: IdSignature, symbol: IrSimpleFunctionSymbol) { - simpleFunctionSymbolTable.set(signature, symbol) + return descriptorExtension.declareSimpleFunctionFromLinker(descriptor, signature, functionFactory) } @ObsoleteDescriptorBasedAPI - override fun referenceSimpleFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol = - simpleFunctionSymbolTable.referenced(descriptor) { signature -> createSimpleFunctionSymbol(descriptor, signature) } - - fun referenceSimpleFunctionIfAny(signature: IdSignature): IrSimpleFunctionSymbol? = - simpleFunctionSymbolTable.get(signature) - - override fun referenceSimpleFunction(signature: IdSignature): IrSimpleFunctionSymbol { - return simpleFunctionSymbolTable.run { - if (signature.isPubliclyVisible) referenced(signature) { IrSimpleFunctionPublicSymbolImpl(signature) } - else IrSimpleFunctionSymbolImpl().also { - it.privateSignature = signature - } - } + override fun referenceSimpleFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol { + return descriptorExtension.referenceSimpleFunction(descriptor) } @ObsoleteDescriptorBasedAPI - override fun referenceDeclaredFunction(descriptor: FunctionDescriptor) = - simpleFunctionSymbolTable.referenced(descriptor) { throw AssertionError("Function is not declared: $descriptor") } - - val unboundSimpleFunctions: Set get() = simpleFunctionSymbolTable.unboundSymbols - - private fun createTypeParameterSymbol(descriptor: TypeParameterDescriptor, signature: IdSignature?): IrTypeParameterSymbol = - signature?.let { IrTypeParameterPublicSymbolImpl(it, descriptor) } ?: IrTypeParameterSymbolImpl(descriptor) + override fun referenceDeclaredFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol { + return descriptorExtension.referenceDeclaredFunction(descriptor) + } @ObsoleteDescriptorBasedAPI fun declareGlobalTypeParameter( @@ -976,31 +738,8 @@ open class SymbolTable( endOffset: Int, origin: IrDeclarationOrigin, descriptor: TypeParameterDescriptor, - typeParameterFactory: (IrTypeParameterSymbol) -> IrTypeParameter = { - irFactory.createTypeParameter( - startOffset = startOffset, - endOffset = endOffset, - origin = origin, - name = nameProvider.nameForDeclaration(descriptor), - symbol = it, - variance = it.descriptor.variance, - index = it.descriptor.index, - isReified = it.descriptor.isReified - ) - } - ): IrTypeParameter = - globalTypeParameterSymbolTable.declare( - descriptor, - { signature -> createTypeParameterSymbol(descriptor, signature) }, - typeParameterFactory - ) - - fun declareGlobalTypeParameter( - signature: IdSignature, - symbolFactory: () -> IrTypeParameterSymbol, - typeParameterFactory: (IrTypeParameterSymbol) -> IrTypeParameter ): IrTypeParameter { - return globalTypeParameterSymbolTable.declare(signature, symbolFactory, typeParameterFactory) + return descriptorExtension.declareGlobalTypeParameter(startOffset, endOffset, origin, descriptor) } @ObsoleteDescriptorBasedAPI @@ -1009,35 +748,11 @@ open class SymbolTable( endOffset: Int, origin: IrDeclarationOrigin, descriptor: TypeParameterDescriptor, - typeParameterFactory: (IrTypeParameterSymbol) -> IrTypeParameter = { - irFactory.createTypeParameter( - startOffset = startOffset, - endOffset = endOffset, - origin = origin, - name = nameProvider.nameForDeclaration(descriptor), - symbol = it, - variance = it.descriptor.variance, - index = it.descriptor.index, - isReified = it.descriptor.isReified - ) - } - ): IrTypeParameter = - scopedTypeParameterSymbolTable.declare( - descriptor, - { signature -> createTypeParameterSymbol(descriptor, signature) }, - typeParameterFactory - ) - - fun declareScopedTypeParameter( - signature: IdSignature, - symbolFactory: (IdSignature) -> IrTypeParameterSymbol, - typeParameterFactory: (IrTypeParameterSymbol) -> IrTypeParameter + typeParameterFactory: (IrTypeParameterSymbol) -> IrTypeParameter, ): IrTypeParameter { - return typeParameterFactory(symbolFactory(signature)) + return descriptorExtension.declareScopedTypeParameter(startOffset, endOffset, origin, descriptor, typeParameterFactory) } - val unboundTypeParameters: Set get() = globalTypeParameterSymbolTable.unboundSymbols - @ObsoleteDescriptorBasedAPI fun declareValueParameter( startOffset: Int, @@ -1049,53 +764,46 @@ open class SymbolTable( name: Name? = null, index: Int? = null, isAssignable: Boolean = false, - valueParameterFactory: (IrValueParameterSymbol) -> IrValueParameter = { - irFactory.createValueParameter( - startOffset = startOffset, - endOffset = endOffset, - origin = origin, - name = name ?: nameProvider.nameForDeclaration(descriptor), - type = type, - isAssignable = isAssignable, - symbol = it, - index = index ?: descriptor.indexOrMinusOne, - varargElementType = varargElementType, - isCrossinline = descriptor.isCrossinline, - isNoinline = descriptor.isNoinline, - isHidden = false, - ) - } - ): IrValueParameter = - valueParameterSymbolTable.declareLocal( + valueParameterFactory: (IrValueParameterSymbol) -> IrValueParameter, + ): IrValueParameter { + return descriptorExtension.declareValueParameter( + startOffset, + endOffset, + origin, descriptor, - { IrValueParameterSymbolImpl(descriptor) }, + type, + varargElementType, + name, + index, + isAssignable, valueParameterFactory ) + } @OptIn(ObsoleteDescriptorBasedAPI::class) fun introduceValueParameter(irValueParameter: IrValueParameter) { - valueParameterSymbolTable.introduceLocal(irValueParameter.descriptor, irValueParameter.symbol) + descriptorExtension.introduceValueParameter(irValueParameter) } @ObsoleteDescriptorBasedAPI - override fun referenceValueParameter(descriptor: ParameterDescriptor) = - valueParameterSymbolTable.referenced(descriptor) { - throw AssertionError("Undefined parameter referenced: $descriptor\n${valueParameterSymbolTable.dump()}") - } + open fun referenceValue(value: ValueDescriptor): IrValueSymbol { + return descriptorExtension.referenceValue(value) + } @ObsoleteDescriptorBasedAPI - override fun referenceTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol = - scopedTypeParameterSymbolTable.get(classifier, signaturer.composeSignature(classifier)) - ?: globalTypeParameterSymbolTable.referenced(classifier) { signature -> createTypeParameterSymbol(classifier, signature) } + override fun referenceValueParameter(descriptor: ParameterDescriptor): IrValueParameterSymbol { + return descriptorExtension.referenceValueParameter(descriptor) + } @ObsoleteDescriptorBasedAPI - override fun referenceScopedTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol = - scopedTypeParameterSymbolTable.referenced(classifier) { signature -> createTypeParameterSymbol(classifier, signature) } + override fun referenceTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol { + return descriptorExtension.referenceTypeParameter(classifier) + } - override fun referenceTypeParameter(signature: IdSignature): IrTypeParameterSymbol = - globalTypeParameterSymbolTable.referenced(signature) { - if (signature.isPubliclyVisible) IrTypeParameterPublicSymbolImpl(signature) else IrTypeParameterSymbolImpl() - } + @ObsoleteDescriptorBasedAPI + override fun referenceScopedTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol { + return descriptorExtension.referenceScopedTypeParameter(classifier) + } @ObsoleteDescriptorBasedAPI fun declareVariable( @@ -1104,18 +812,10 @@ open class SymbolTable( origin: IrDeclarationOrigin, descriptor: VariableDescriptor, type: IrType, - variableFactory: (IrVariableSymbol) -> IrVariable = { - IrVariableImpl( - startOffset, endOffset, origin, it, nameProvider.nameForDeclaration(descriptor), type, - descriptor.isVar, descriptor.isConst, descriptor.isLateInit - ) - } - ): IrVariable = - variableSymbolTable.declareLocal( - descriptor, - { IrVariableSymbolImpl(descriptor) }, - variableFactory - ) + variableFactory: (IrVariableSymbol) -> IrVariable, + ): IrVariable { + return descriptorExtension.declareVariable(startOffset, endOffset, origin, descriptor, type, variableFactory) + } @ObsoleteDescriptorBasedAPI fun declareVariable( @@ -1124,11 +824,10 @@ open class SymbolTable( origin: IrDeclarationOrigin, descriptor: VariableDescriptor, type: IrType, - irInitializerExpression: IrExpression? - ): IrVariable = - declareVariable(startOffset, endOffset, origin, descriptor, type).apply { - initializer = irInitializerExpression - } + irInitializerExpression: IrExpression?, + ): IrVariable { + return descriptorExtension.declareVariable(startOffset, endOffset, origin, descriptor, type, irInitializerExpression) + } @ObsoleteDescriptorBasedAPI fun declareLocalDelegatedProperty( @@ -1137,82 +836,14 @@ open class SymbolTable( origin: IrDeclarationOrigin, descriptor: VariableDescriptorWithAccessors, type: IrType, - factory: (IrLocalDelegatedPropertySymbol) -> IrLocalDelegatedProperty = { - irFactory.createLocalDelegatedProperty( - startOffset = startOffset, - endOffset = endOffset, - origin = origin, - name = nameProvider.nameForDeclaration(descriptor), - symbol = it, - type = type, - isVar = descriptor.isVar - ) - } - ): IrLocalDelegatedProperty = - localDelegatedPropertySymbolTable.declareLocal( - descriptor, - { IrLocalDelegatedPropertySymbolImpl(descriptor) }, - factory - ).apply { - metadata = DescriptorMetadataSource.LocalDelegatedProperty(descriptor) - } - - @ObsoleteDescriptorBasedAPI - fun referenceLocalDelegatedProperty(descriptor: VariableDescriptorWithAccessors) = - localDelegatedPropertySymbolTable.referenced(descriptor) { - throw AssertionError("Undefined local delegated property referenced: $descriptor") - } - - override fun enterScope(symbol: IrSymbol) { - scopedSymbolTables.forEach { it.enterScope(symbol) } - } - - override fun enterScope(owner: IrDeclaration) { - enterScope(owner.symbol) - } - - override fun leaveScope(symbol: IrSymbol) { - scopedSymbolTables.forEach { it.leaveScope(symbol) } - } - - override fun leaveScope(owner: IrDeclaration) { - leaveScope(owner.symbol) + factory: (IrLocalDelegatedPropertySymbol) -> IrLocalDelegatedProperty, + ): IrLocalDelegatedProperty { + return descriptorExtension.declareLocalDelegatedProperty(startOffset, endOffset, origin, descriptor, type, factory) } @ObsoleteDescriptorBasedAPI - open fun referenceValue(value: ValueDescriptor): IrValueSymbol = - when (value) { - is ParameterDescriptor -> - valueParameterSymbolTable.referenced(value) { throw AssertionError("Undefined parameter referenced: $value") } - is VariableDescriptor -> - variableSymbolTable.referenced(value) { throw AssertionError("Undefined variable referenced: $value") } - else -> - throw IllegalArgumentException("Unexpected value descriptor: $value") - } - - private inline fun FlatSymbolTable.forEachSymbolImpl(block: (IrSymbol) -> Unit) - where Descriptor : DeclarationDescriptor, - Owner : IrSymbolOwner, - Symbol : IrBindableSymbol { - idSignatureToSymbol.forEach { (_, symbol) -> - block(symbol) - } - } - - /** - * This function is quite messy and doesn't have good contract of what exactly is traversed. - * Basic idea is it traverse symbols which can be reasonable referered from other module - * - * Be careful when using it, and avoid it, except really need. - */ - fun forEachDeclarationSymbol(block: (IrSymbol) -> Unit) { - classSymbolTable.forEachSymbolImpl { block(it) } - constructorSymbolTable.forEachSymbolImpl { block(it) } - simpleFunctionSymbolTable.forEachSymbolImpl { block(it) } - propertySymbolTable.forEachSymbolImpl { block(it) } - enumEntrySymbolTable.forEachSymbolImpl { block(it) } - typeAliasSymbolTable.forEachSymbolImpl { block(it) } - fieldSymbolTable.forEachSymbolImpl { block(it) } + fun referenceLocalDelegatedProperty(descriptor: VariableDescriptorWithAccessors): IrLocalDelegatedPropertySymbol { + return descriptorExtension.referenceLocalDelegatedProperty(descriptor) } } @@ -1236,19 +867,3 @@ inline fun ReferenceSymbolTable.withReferenceScope(owner: IrDeclaration, blo leaveScope(owner) return result } - -val SymbolTable.allUnbound: Set - get() = buildSet { - fun addUnbound(symbols: Collection) { - symbols.filterTo(this) { !it.isBound } - } - - addUnbound(unboundClasses) - addUnbound(unboundConstructors) - addUnbound(unboundEnumEntries) - addUnbound(unboundFields) - addUnbound(unboundSimpleFunctions) - addUnbound(unboundProperties) - addUnbound(unboundTypeAliases) - addUnbound(unboundTypeParameters) - } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTableExtension.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTableExtension.kt new file mode 100644 index 00000000000..6d2fb3dc70b --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTableExtension.kt @@ -0,0 +1,695 @@ +/* + * Copyright 2010-2023 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.ir.util + +import org.jetbrains.kotlin.descriptors.DescriptorVisibility +import org.jetbrains.kotlin.ir.IrLock +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.expressions.IrExpressionBody +import org.jetbrains.kotlin.ir.symbols.* +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.utils.threadLocal + +abstract class ReferenceSymbolTableExtension { + abstract fun referenceScript(descriptor: Script): IrScriptSymbol + abstract fun referenceClass(descriptor: Class): IrClassSymbol + abstract fun referenceConstructor(descriptor: Constructor): IrConstructorSymbol + abstract fun referenceEnumEntry(descriptor: Class): IrEnumEntrySymbol + abstract fun referenceField(descriptor: Property): IrFieldSymbol + abstract fun referenceProperty(descriptor: Property): IrPropertySymbol + abstract fun referenceSimpleFunction(descriptor: Function): IrSimpleFunctionSymbol + abstract fun referenceDeclaredFunction(descriptor: Function): IrSimpleFunctionSymbol + abstract fun referenceValueParameter(descriptor: ValueParameter): IrValueParameterSymbol + abstract fun referenceTypeParameter(classifier: TypeParameter): IrTypeParameterSymbol + abstract fun referenceScopedTypeParameter(classifier: TypeParameter): IrTypeParameterSymbol + abstract fun referenceTypeAlias(descriptor: TypeAlias): IrTypeAliasSymbol +} + +typealias SymbolFactory = (Declaration, IdSignature?) -> Symbol +typealias OwnerFactory = (Symbol) -> SymbolOwner + +abstract class SymbolTableExtension< + Declaration, Class, TypeAlias, Script, Function, Constructor, + Property, ValueParameter, TypeParameter, + >( + val table: SymbolTable, +) : ReferenceSymbolTableExtension() + where Class : Declaration, + TypeAlias : Declaration, + Script : Declaration, + Function : Declaration, + Constructor : Declaration, + Property : Declaration, + ValueParameter : Declaration, + TypeParameter : Declaration { + protected val lock: IrLock + get() = table.lock + + private val scriptSlice: SymbolTableSlice.Flat = + SymbolTableSlice.Flat(lock) + private val classSlice: SymbolTableSlice.Flat = + SymbolTableSlice.Flat(lock) + private val constructorSlice: SymbolTableSlice.Flat = + SymbolTableSlice.Flat(lock) + private val enumEntrySlice: SymbolTableSlice.Flat = + SymbolTableSlice.Flat(lock) + private val fieldSlice: SymbolTableSlice.Flat = + SymbolTableSlice.Flat(lock) + private val functionSlice: SymbolTableSlice.Flat = + SymbolTableSlice.Flat(lock) + private val propertySlice: SymbolTableSlice.Flat = + SymbolTableSlice.Flat(lock) + private val typeAliasSlice: SymbolTableSlice.Flat = + SymbolTableSlice.Flat(lock) + private val globalTypeParameterSlice: SymbolTableSlice.Flat = + SymbolTableSlice.Flat(lock) + + private val scopedTypeParameterSlice: SymbolTableSlice.Scoped by threadLocal { + SymbolTableSlice.Scoped(lock) + } + + protected abstract fun MutableList>.initializeScopedSlices() + + private val scopedSlices: List> by lazy(LazyThreadSafetyMode.PUBLICATION) { + buildList { + add(scopedTypeParameterSlice) + initializeScopedSlices() + } + } + + // ------------------------------------ signature ------------------------------------ + + protected abstract fun calculateSignature(declaration: Declaration): IdSignature? + protected abstract fun calculateEnumEntrySignature(declaration: Class): IdSignature? + protected abstract fun calculateFieldSignature(declaration: Property): IdSignature? + + // ------------------------------------ script ------------------------------------ + + fun declareScript( + startOffset: Int, + endOffset: Int, + descriptor: Script, + ): IrScript { + return declare( + descriptor, + scriptSlice, + SymbolTable::declareScript, + symbolFactory = { createScriptSymbol(descriptor, it) }, + ownerFactory = { defaultScriptFactory(startOffset, endOffset, descriptor, it) } + ) + } + + override fun referenceScript(descriptor: Script): IrScriptSymbol { + return scriptSlice.referenced(descriptor) { createScriptSymbol(descriptor, signature = null) } + } + + protected abstract fun defaultScriptFactory(startOffset: Int, endOffset: Int, script: Script, symbol: IrScriptSymbol): IrScript + + protected abstract fun createScriptSymbol(descriptor: Script, signature: IdSignature?): IrScriptSymbol + + // ------------------------------------ script ------------------------------------ + + fun declareClass(descriptor: Class, classFactory: (IrClassSymbol) -> IrClass): IrClass { + return declare( + descriptor, + classSlice, + SymbolTable::declareClass, + { createClassSymbol(descriptor, it) }, + classFactory + ) + } + + fun declareClassIfNotExists(descriptor: Class, classFactory: (IrClassSymbol) -> IrClass): IrClass { + return declareIfNotExist( + descriptor, + classSlice, + SymbolTable::declareClassIfNotExists, + { createClassSymbol(descriptor, it) }, + classFactory + ) + } + + override fun referenceClass(descriptor: Class): IrClassSymbol { + return reference( + descriptor, + classSlice, + SymbolTable::referenceClassImpl, + ::createClassSymbol, + ::createPublicClassSymbol, + ::createPrivateClassSymbol + ) + } + + protected fun createClassSymbol(descriptor: Class, signature: IdSignature?): IrClassSymbol { + return signature?.let { createPublicClassSymbol(descriptor, signature) } ?: createPrivateClassSymbol(descriptor) + } + + protected abstract fun createPublicClassSymbol(descriptor: Class, signature: IdSignature): IrClassSymbol + protected abstract fun createPrivateClassSymbol(descriptor: Class): IrClassSymbol + + // ------------------------------------ constructor ------------------------------------ + + fun declareConstructor(descriptor: Constructor, constructorFactory: (IrConstructorSymbol) -> IrConstructor): IrConstructor { + return declare( + descriptor, + constructorSlice, + SymbolTable::declareConstructor, + { createConstructorSymbol(descriptor, it) }, + constructorFactory + ) + } + + fun declareConstructorIfNotExists( + descriptor: Constructor, + constructorFactory: (IrConstructorSymbol) -> IrConstructor, + ): IrConstructor { + return declareIfNotExist( + descriptor, + constructorSlice, + SymbolTable::declareConstructorIfNotExists, + { createConstructorSymbol(descriptor, it) }, + constructorFactory + ) + } + + override fun referenceConstructor(descriptor: Constructor): IrConstructorSymbol { + return reference( + descriptor, + constructorSlice, + SymbolTable::referenceConstructorImpl, + ::createConstructorSymbol, + ::createPublicConstructorSymbol, + ::createPrivateConstructorSymbol + ) + } + + protected fun createConstructorSymbol(descriptor: Constructor, signature: IdSignature?): IrConstructorSymbol { + return signature?.let { createPublicConstructorSymbol(descriptor, signature) } ?: createPrivateConstructorSymbol(descriptor) + } + + protected abstract fun createPublicConstructorSymbol(descriptor: Constructor, signature: IdSignature): IrConstructorSymbol + protected abstract fun createPrivateConstructorSymbol(descriptor: Constructor): IrConstructorSymbol + + // ------------------------------------ enum entry ------------------------------------ + + fun declareEnumEntry(descriptor: Class, enumEntryFactory: (IrEnumEntrySymbol) -> IrEnumEntry): IrEnumEntry { + return declare( + descriptor, + enumEntrySlice, + SymbolTable::declareEnumEntry, + { createEnumEntrySymbol(descriptor, it) }, + enumEntryFactory, + ::calculateEnumEntrySignature + ) + } + + fun declareEnumEntry(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: Class): IrEnumEntry { + return declareEnumEntry( + descriptor + ) { enumEntrySymbol -> defaultEnumEntryFactory(startOffset, endOffset, origin, descriptor, enumEntrySymbol) } + } + + fun declareEnumEntryIfNotExists(descriptor: Class, enumEntryFactory: (IrEnumEntrySymbol) -> IrEnumEntry): IrEnumEntry { + return declareIfNotExist( + descriptor, + enumEntrySlice, + SymbolTable::declareEnumEntryIfNotExists, + { createEnumEntrySymbol(descriptor, it) }, + enumEntryFactory, + ::calculateEnumEntrySignature + ) + } + + override fun referenceEnumEntry(descriptor: Class): IrEnumEntrySymbol { + return reference( + descriptor, + enumEntrySlice, + SymbolTable::referenceEnumEntryImpl, + ::createEnumEntrySymbol, + ::createPublicEnumEntrySymbol, + ::createPrivateEnumEntrySymbol, + ::calculateEnumEntrySignature + ) + } + + protected fun createEnumEntrySymbol(descriptor: Class, signature: IdSignature?): IrEnumEntrySymbol { + return signature?.let { createPublicEnumEntrySymbol(descriptor, signature) } ?: createPrivateEnumEntrySymbol(descriptor) + } + + protected abstract fun createPublicEnumEntrySymbol(descriptor: Class, signature: IdSignature): IrEnumEntrySymbol + protected abstract fun createPrivateEnumEntrySymbol(descriptor: Class): IrEnumEntrySymbol + + protected abstract fun defaultEnumEntryFactory( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + enumEntry: Class, + symbol: IrEnumEntrySymbol, + ): IrEnumEntry + + // ------------------------------------ field ------------------------------------ + + fun declareField( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + descriptor: Property, + type: IrType, + visibility: DescriptorVisibility? = null, + fieldFactory: (IrFieldSymbol) -> IrField = { + defaultFieldFactory( + startOffset, + endOffset, + origin, + descriptor, + type, + visibility, + it + ) + }, + ): IrField { + return declare( + descriptor, + fieldSlice, + SymbolTable::declareField, + { createFieldSymbol(descriptor, it) }, + fieldFactory, + ::calculateFieldSignature + ) + } + + fun declareField( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + descriptor: Property, + type: IrType, + irInitializer: IrExpressionBody?, + ): IrField { + return declareField(startOffset, endOffset, origin, descriptor, type).apply { + initializer = irInitializer + } + } + + override fun referenceField(descriptor: Property): IrFieldSymbol { + return reference( + descriptor, + fieldSlice, + SymbolTable::referenceFieldImpl, + ::createFieldSymbol, + ::createPublicFieldSymbol, + ::createPrivateFieldSymbol, + ::calculateFieldSignature + ) + } + + protected fun createFieldSymbol(descriptor: Property, signature: IdSignature?): IrFieldSymbol { + return signature?.let { createPublicFieldSymbol(descriptor, signature) } ?: createPrivateFieldSymbol(descriptor) + } + + protected abstract fun createPublicFieldSymbol(descriptor: Property, signature: IdSignature): IrFieldSymbol + protected abstract fun createPrivateFieldSymbol(descriptor: Property): IrFieldSymbol + + protected abstract fun defaultFieldFactory( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + descriptor: Property, + type: IrType, + visibility: DescriptorVisibility?, + symbol: IrFieldSymbol, + ): IrField + + // ------------------------------------ property ------------------------------------ + + fun declareProperty(descriptor: Property, propertyFactory: (IrPropertySymbol) -> IrProperty): IrProperty { + return declare( + descriptor, + propertySlice, + SymbolTable::declareProperty, + { createPropertySymbol(descriptor, it) }, + propertyFactory + ) + } + + fun declareProperty( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + descriptor: Property, + isDelegated: Boolean,/* = descriptor.isDelegated*/ + ): IrProperty { + return declareProperty(descriptor) { propertySymbol -> + defaultPropertyFactory(startOffset, endOffset, origin, descriptor, isDelegated, propertySymbol) + } + } + + fun declarePropertyIfNotExists(descriptor: Property, propertyFactory: (IrPropertySymbol) -> IrProperty): IrProperty { + return declareIfNotExist( + descriptor, + propertySlice, + SymbolTable::declarePropertyIfNotExists, + { createPropertySymbol(descriptor, it) }, + propertyFactory + ) + } + + override fun referenceProperty(descriptor: Property): IrPropertySymbol { + return reference( + descriptor, + propertySlice, + SymbolTable::referencePropertyImpl, + ::createPropertySymbol, + ::createPublicPropertySymbol, + ::createPrivatePropertySymbol + ) + } + + protected fun createPropertySymbol(descriptor: Property, signature: IdSignature?): IrPropertySymbol { + return signature?.let { createPublicPropertySymbol(descriptor, signature) } ?: createPrivatePropertySymbol(descriptor) + } + + protected abstract fun createPublicPropertySymbol(descriptor: Property, signature: IdSignature): IrPropertySymbol + protected abstract fun createPrivatePropertySymbol(descriptor: Property): IrPropertySymbol + + protected abstract fun defaultPropertyFactory( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + descriptor: Property, + isDelegated: Boolean, + symbol: IrPropertySymbol, + ): IrProperty + + // ------------------------------------ typealias ------------------------------------ + + fun declareTypeAlias(descriptor: TypeAlias, typeAliasFactory: (IrTypeAliasSymbol) -> IrTypeAlias): IrTypeAlias { + return declare( + descriptor, + typeAliasSlice, + SymbolTable::declareTypeAlias, + { createTypeAliasSymbol(descriptor, it) }, + typeAliasFactory + ) + } + + fun declareTypeAliasIfNotExists(descriptor: TypeAlias, typeAliasFactory: (IrTypeAliasSymbol) -> IrTypeAlias): IrTypeAlias { + return declareIfNotExist( + descriptor, + typeAliasSlice, + SymbolTable::declareTypeAliasIfNotExists, + { createTypeAliasSymbol(descriptor, it) }, + typeAliasFactory + ) + } + + override fun referenceTypeAlias(descriptor: TypeAlias): IrTypeAliasSymbol { + return reference( + descriptor, + typeAliasSlice, + SymbolTable::referenceTypeAliasImpl, + ::createTypeAliasSymbol, + ::createPublicTypeAliasSymbol, + ::createPrivateTypeAliasSymbol + ) + } + + protected fun createTypeAliasSymbol(descriptor: TypeAlias, signature: IdSignature?): IrTypeAliasSymbol { + return signature?.let { createPublicTypeAliasSymbol(descriptor, signature) } ?: createPrivateTypeAliasSymbol(descriptor) + } + + protected abstract fun createPublicTypeAliasSymbol(descriptor: TypeAlias, signature: IdSignature): IrTypeAliasSymbol + protected abstract fun createPrivateTypeAliasSymbol(descriptor: TypeAlias): IrTypeAliasSymbol + + // ------------------------------------ function ------------------------------------ + + fun declareSimpleFunction(descriptor: Function, functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction): IrSimpleFunction { + return declare( + descriptor, + functionSlice, + SymbolTable::declareSimpleFunction, + { createFunctionSymbol(descriptor, it) }, + functionFactory + ) + } + + fun declareSimpleFunctionIfNotExists( + descriptor: Function, + functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction, + ): IrSimpleFunction { + return declareIfNotExist( + descriptor, + functionSlice, + SymbolTable::declareSimpleFunctionIfNotExists, + { createFunctionSymbol(descriptor, it) }, + functionFactory + ) + } + + override fun referenceSimpleFunction(descriptor: Function): IrSimpleFunctionSymbol { + return reference( + descriptor, + functionSlice, + SymbolTable::referenceSimpleFunctionImpl, + ::createFunctionSymbol, + ::createPublicFunctionSymbol, + ::createPrivateFunctionSymbol + ) + } + + override fun referenceDeclaredFunction(descriptor: Function): IrSimpleFunctionSymbol { + fun throwError(): Nothing = error("Function is not declared: $descriptor") + + return reference( + descriptor, + functionSlice, + SymbolTable::referenceSimpleFunctionImpl, + { _, _ -> throwError() }, + { _, _ -> throwError() }, + { throwError() }, + ) + } + + protected fun createFunctionSymbol(descriptor: Function, signature: IdSignature?): IrSimpleFunctionSymbol { + return signature?.let { createPublicFunctionSymbol(descriptor, signature) } ?: createPrivateFunctionSymbol(descriptor) + } + + protected abstract fun createPublicFunctionSymbol(descriptor: Function, signature: IdSignature): IrSimpleFunctionSymbol + protected abstract fun createPrivateFunctionSymbol(descriptor: Function): IrSimpleFunctionSymbol + + // ------------------------------------ type parameter ------------------------------------ + + fun declareGlobalTypeParameter( + descriptor: TypeParameter, + typeParameterFactory: (IrTypeParameterSymbol) -> IrTypeParameter, + ): IrTypeParameter { + return declare( + descriptor, + globalTypeParameterSlice, + SymbolTable::declareGlobalTypeParameter, + { createTypeParameterSymbol(descriptor, it) }, + typeParameterFactory + ) + } + + fun declareGlobalTypeParameter( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + descriptor: TypeParameter, + ): IrTypeParameter { + return declareGlobalTypeParameter(descriptor) { + defaultTypeParameterFactory(startOffset, endOffset, origin, descriptor, it) + } + } + + fun declareScopedTypeParameter( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + descriptor: TypeParameter, + typeParameterFactory: (IrTypeParameterSymbol) -> IrTypeParameter = { + defaultTypeParameterFactory(startOffset, endOffset, origin, descriptor, it) + }, + ): IrTypeParameter { + // TODO: looks little suspicious + // Is it correct that we never create scoped type parameters by signatures? + return scopedTypeParameterSlice.declare( + descriptor, + { createTypeParameterSymbol(descriptor, calculateSignature(descriptor)) }, + typeParameterFactory + ) + } + + override fun referenceTypeParameter(classifier: TypeParameter): IrTypeParameterSymbol { + scopedTypeParameterSlice.get(classifier)?.let { return it } + return reference( + classifier, + globalTypeParameterSlice, + SymbolTable::referenceTypeParameterImpl, + ::createTypeParameterSymbol, + ::createPublicTypeParameterSymbol, + ::createPrivateTypeParameterSymbol + ) + } + + override fun referenceScopedTypeParameter(classifier: TypeParameter): IrTypeParameterSymbol { + return scopedTypeParameterSlice.referenced(classifier) { createTypeParameterSymbol(classifier, calculateSignature(classifier)) } + } + + protected fun createTypeParameterSymbol(descriptor: TypeParameter, signature: IdSignature?): IrTypeParameterSymbol { + return signature?.let { createPublicTypeParameterSymbol(descriptor, signature) } ?: createPrivateTypeParameterSymbol(descriptor) + } + + protected abstract fun createPublicTypeParameterSymbol(descriptor: TypeParameter, signature: IdSignature): IrTypeParameterSymbol + protected abstract fun createPrivateTypeParameterSymbol(descriptor: TypeParameter): IrTypeParameterSymbol + + protected abstract fun defaultTypeParameterFactory( + startOffset: Int, + endOffset: Int, + origin: IrDeclarationOrigin, + descriptor: TypeParameter, + symbol: IrTypeParameterSymbol, + ): IrTypeParameter + + // ------------------------------------ value parameter ------------------------------------ + + override fun referenceValueParameter(descriptor: ValueParameter): IrValueParameterSymbol { + error("There is no default implementation for any symbol table extension") + } + + // ------------------------------------ scopes ------------------------------------ + + fun enterScope(symbol: IrSymbol) { + scopedSlices.forEach { it.enterScope(symbol) } + } + + fun enterScope(owner: IrDeclaration) { + enterScope(owner.symbol) + } + + fun leaveScope(symbol: IrSymbol) { + scopedSlices.forEach { it.leaveScope(symbol) } + } + + fun leaveScope(owner: IrDeclaration) { + leaveScope(owner.symbol) + } + + // ------------------------------------ utilities ------------------------------------ + + /** + * This function is quite messy and doesn't have good contract of what exactly is traversed. + * Basic idea is it traverse symbols which can be reasonable referered from other module + * + * Be careful when using it, and avoid it, except really need. + * + * TODO: add some OptIn + */ + fun forEachDeclarationSymbol(block: (IrSymbol) -> Unit) { + table.forEachDeclarationSymbol(block) + + scriptSlice.forEachSymbol { block(it) } + classSlice.forEachSymbol { block(it) } + constructorSlice.forEachSymbol { block(it) } + enumEntrySlice.forEachSymbol { block(it) } + fieldSlice.forEachSymbol { block(it) } + functionSlice.forEachSymbol { block(it) } + propertySlice.forEachSymbol { block(it) } + typeAliasSlice.forEachSymbol { block(it) } + globalTypeParameterSlice.forEachSymbol { block(it) } + } + + val allUnboundSymbols: Set + get() = buildSet { + fun addUnbound(slice: SymbolTableSlice<*, *, *>) { + slice.unboundSymbols.filterTo(this) { !it.isBound } + } + addAll(table.allUnboundSymbols) + + addUnbound(scriptSlice) + addUnbound(classSlice) + addUnbound(constructorSlice) + addUnbound(enumEntrySlice) + addUnbound(fieldSlice) + addUnbound(functionSlice) + addUnbound(propertySlice) + addUnbound(typeAliasSlice) + addUnbound(globalTypeParameterSlice) + } + + private inline fun , SymbolOwner : IrSymbolOwner> declare( + descriptor: D, + slice: SymbolTableSlice, + declareBySignature: SymbolTable.(IdSignature, () -> Symbol, OwnerFactory) -> SymbolOwner, + crossinline symbolFactory: (IdSignature?) -> Symbol, + noinline ownerFactory: OwnerFactory, + specificCalculateSignature: (D) -> IdSignature? = { calculateSignature(it) } + ): SymbolOwner { + return declare( + descriptor, + slice, + declareBySignature, + SymbolTableSlice::declare, + symbolFactory, + ownerFactory, + specificCalculateSignature + ) + } + + private inline fun , SymbolOwner : IrSymbolOwner> declareIfNotExist( + descriptor: D, + slice: SymbolTableSlice, + declareBySignature: SymbolTable.(IdSignature, () -> Symbol, OwnerFactory) -> SymbolOwner, + crossinline symbolFactory: (IdSignature?) -> Symbol, + noinline ownerFactory: OwnerFactory, + specificCalculateSignature: (D) -> IdSignature? = { calculateSignature(it) } + ): SymbolOwner { + return declare( + descriptor, + slice, + declareBySignature, + SymbolTableSlice::declareIfNotExists, + symbolFactory, + ownerFactory, + specificCalculateSignature + ) + } + + private inline fun , SymbolOwner : IrSymbolOwner> declare( + descriptor: D, + slice: SymbolTableSlice, + declareBySignature: SymbolTable.(IdSignature, () -> Symbol, OwnerFactory) -> SymbolOwner, + declareByDeclaration: SymbolTableSlice.(D, () -> Symbol, OwnerFactory) -> SymbolOwner, + crossinline symbolFactory: (IdSignature?) -> Symbol, + noinline ownerFactory: OwnerFactory, + specificCalculateSignature: (D) -> IdSignature? + ): SymbolOwner { + return when (val signature = specificCalculateSignature(descriptor)) { + null -> slice.declareByDeclaration(descriptor, { symbolFactory(signature) }, ownerFactory) + else -> table.declareBySignature(signature, { symbolFactory(signature) }, ownerFactory) + } + } + + private inline fun , SymbolOwner : IrSymbolOwner> reference( + descriptor: D, + slice: SymbolTableSlice, + referenceBySignature: SymbolTable.(IdSignature, () -> Symbol, () -> Symbol) -> Symbol, + crossinline symbolFactory: (D, IdSignature?) -> Symbol, + crossinline publicSymbolFactory: (D, IdSignature) -> Symbol, + crossinline privateSymbolFactory: (D) -> Symbol, + specificCalculateSignature: (D) -> IdSignature? = { calculateSignature(it) } + ): Symbol { + return when (val signature = specificCalculateSignature(descriptor)) { + null -> slice.referenced(descriptor) { symbolFactory(descriptor, signature) } + else -> table.referenceBySignature( + signature, + { publicSymbolFactory(descriptor, signature) }, + { privateSymbolFactory(descriptor) } + ) + } + } +} diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTableSlice.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTableSlice.kt new file mode 100644 index 00000000000..8d2e26d19ca --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTableSlice.kt @@ -0,0 +1,195 @@ +/* + * Copyright 2010-2023 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.ir.util + +import org.jetbrains.kotlin.ir.IrLock +import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI +import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner +import org.jetbrains.kotlin.ir.symbols.IrBindableSymbol +import org.jetbrains.kotlin.ir.symbols.IrSymbol + +abstract class SymbolTableSlice(val lock: IrLock) + where SymbolOwner : IrSymbolOwner, + Symbol : IrBindableSymbol<*, SymbolOwner> { + /** + * With the partial linkage turned on it's hard to predict whether a newly created [IrSymbol] that is added to the [SymbolTable] + * via one of referenceXXX() calls will or won't be bound to some declaration. The latter may happen in certain cases, + * for example when the symbol refers from an IR expression to a non-top level declaration that was removed in newer version + * of Kotlin library (KLIB). Unless such symbol is registered as "probably unbound" it remains invisible for the linkage process. + * + * The optimization that allows to reference symbols without registering them as "probably unbound" is fragile. It's better + * to avoid calling any referenceXXX(reg = false) functions. Instead, wherever it is s suitable it is recommended to use one + * of the appropriate declareXXX() calls. + * + * For the future: Consider implementing the optimization once again for the new "flat" ID signatures. + */ + val unboundSymbols = linkedSetOf() + + abstract fun get(key: Key): Symbol? + abstract fun set(key: Key, symbol: Symbol) + + inline fun declare(key: Key, createSymbol: () -> Symbol, createOwner: (Symbol) -> SymbolOwner): SymbolOwner { + synchronized(lock) { + val existing = get(key) + val symbol = if (existing == null) { + createSymbol().also { set(key, it) } + } else { + unboundSymbols.remove(existing) + existing + } + return createOwnerSafe(symbol, createOwner) + } + } + + inline fun referenced(key: Key, orElse: () -> Symbol): Symbol { + synchronized(lock) { + return get(key) ?: run { + val new = orElse() + assert(unboundSymbols.add(new)) { "Symbol for ${new.signature} was already referenced" } + set(key, new) + new + } + } + } + + inline fun declareIfNotExists( + key: Key, + createSymbol: () -> Symbol, + createOwner: (Symbol) -> SymbolOwner, + ): SymbolOwner { + synchronized(lock) { + val existing = get(key) + val symbol = if (existing == null) { + // checkOriginal(descriptor) // TODO: remove? + val new = createSymbol() + set(key, new) + new + } else { + if (existing.isBound) { + unboundSymbols.remove(existing) + return existing.owner + } + existing + } + return createOwnerSafe(symbol, createOwner) + } + } + + // TODO: add PrivateToInline + @PublishedApi + internal inline fun createOwnerSafe(symbol: Symbol, createOwner: (Symbol) -> SymbolOwner): SymbolOwner { + val owner = createOwner(symbol) + require(symbol.isBound) + require(symbol.owner === owner) { + "Attempt to rebind an IR symbol or to re-create its owner: old owner ${symbol.owner.render()}, new owner ${owner.render()}" + } + return owner + } + + class Flat(lock: IrLock) : SymbolTableSlice(lock) + where SymbolOwner : IrSymbolOwner, Symbol : IrBindableSymbol<*, SymbolOwner> { + private val signatureToSymbol = hashMapOf() + + override fun get(key: Key): Symbol? { + return signatureToSymbol[key] + } + + override fun set(key: Key, symbol: Symbol) { + signatureToSymbol[key] = symbol + } + + // TODO: add some OptIn + internal fun forEachSymbol(block: (IrSymbol) -> Unit) { + signatureToSymbol.forEach { (_, symbol) -> block(symbol) } + } + } + + class Scoped(lock: IrLock) : SymbolTableSlice(lock) + where SymbolOwner : IrSymbolOwner, Symbol : IrBindableSymbol<*, SymbolOwner> { + + override fun set(key: Key, symbol: Symbol) { + val scope = currentScope ?: noScope() + scope[key] = symbol + } + + @PublishedApi + // TODO: add PrivateForInline + internal var currentScope: SliceScope? = null + private set + + override fun get(key: Key): Symbol? { + return currentScope?.get(key) + } + + inline fun declareLocal(key: Key, createSymbol: () -> Symbol, createOwner: (Symbol) -> SymbolOwner): SymbolOwner { + val scope = currentScope ?: noScope() + val symbol = scope.getLocal(key) ?: createSymbol().also { scope[key] = it } + return createOwnerSafe(symbol, createOwner) + } + + fun introduceLocal(descriptor: Key, symbol: Symbol) { + val scope = currentScope ?: noScope() + scope[descriptor]?.let { error("$descriptor is already bound to $it") } + scope[descriptor] = symbol + } + + fun enterScope(owner: IrSymbol) { + currentScope = SliceScope(owner, currentScope) + } + + fun leaveScope(owner: IrSymbol) { + currentScope?.owner.let { + require(it == owner) { "Unexpected leaveScope: owner=$owner, currentScope.owner=$it" } + } + + currentScope = currentScope?.parent + + if (currentScope != null && unboundSymbols.isNotEmpty()) { + @OptIn(ObsoleteDescriptorBasedAPI::class) + error("Local scope contains unbound symbols: ${unboundSymbols.joinToString { it.descriptor.toString() }}") + } + } + + fun dump(): String { + return currentScope?.dump() ?: "" + } + + @PublishedApi + // TODO: add PrivateForInline + internal fun noScope(): Nothing = error("No active scope") + + @PublishedApi + // TODO: add PrivateForInline + internal class SliceScope(val owner: IrSymbol, val parent: SliceScope?) { + private val signatureToSymbol = hashMapOf() + + operator fun get(descriptor: Key): Symbol? { + return signatureToSymbol[descriptor] ?: parent?.get(descriptor) + } + + fun getLocal(descriptor: Key): Symbol? { + return signatureToSymbol[descriptor] + } + + operator fun set(descriptor: Key, symbol: Symbol) { + signatureToSymbol[descriptor] = symbol + } + + fun dumpTo(stringBuilder: StringBuilder): StringBuilder { + return stringBuilder.also { + it.append("owner=") + it.append(owner) + it.append("; ") + signatureToSymbol.keys.joinTo(prefix = "[", postfix = "]", buffer = it) + it.append('\n') + parent?.dumpTo(it) + } + } + + fun dump(): String = dumpTo(StringBuilder()).toString() + } + } +} diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/issues/checks.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/issues/checks.kt index afe2fec85fc..f834cae01fa 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/issues/checks.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/issues/checks.kt @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.serialization.KotlinIrLinker import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.ir.util.IrMessageLogger import org.jetbrains.kotlin.ir.util.SymbolTable -import org.jetbrains.kotlin.ir.util.allUnbound import org.jetbrains.kotlin.ir.util.irMessageLogger // N.B. Checks for absence of unbound symbols only when unbound symbols are not allowed. @@ -18,14 +17,14 @@ fun KotlinIrLinker.checkNoUnboundSymbols(symbolTable: SymbolTable, whenDetected: // N.B. Always checks for absence of unbound symbols. The condition whether this check should be applied is controlled outside. fun IrMessageLogger.checkNoUnboundSymbols(symbolTable: SymbolTable, whenDetected: String) { - val unboundSymbols = symbolTable.allUnbound + val unboundSymbols = symbolTable.descriptorExtension.allUnboundSymbols if (unboundSymbols.isNotEmpty()) UnexpectedUnboundIrSymbols(unboundSymbols, whenDetected).raiseIssue(this) } // N.B. Always checks for absence of unbound symbols. The condition whether this check should be applied is controlled outside. fun CompilerConfiguration.checkNoUnboundSymbols(symbolTable: SymbolTable, whenDetected: String) { - val unboundSymbols = symbolTable.allUnbound + val unboundSymbols = symbolTable.descriptorExtension.allUnboundSymbols if (unboundSymbols.isNotEmpty()) UnexpectedUnboundIrSymbols(unboundSymbols, whenDetected).raiseIssue(irMessageLogger) } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinkerImpl.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinkerImpl.kt index b92e4f15d8d..eb7098b947d 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinkerImpl.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinkerImpl.kt @@ -15,7 +15,6 @@ import org.jetbrains.kotlin.ir.linkage.partial.PartialLinkageLogger import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.IrMessageLogger import org.jetbrains.kotlin.ir.util.SymbolTable -import org.jetbrains.kotlin.ir.util.allUnbound fun createPartialLinkageSupportForLinker( partialLinkageConfig: PartialLinkageConfig, @@ -73,7 +72,7 @@ internal class PartialLinkageSupportForLinkerImpl( private fun generateStubsAndPatchUsagesInternal(symbolTable: SymbolTable, patchIrTree: () -> Unit) { // Generate stubs. - for (symbol in symbolTable.allUnbound) { + for (symbol in symbolTable.descriptorExtension.allUnboundSymbols) { stubGenerator.getDeclaration(symbol) } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt index 2a85957def8..107dd34f539 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt @@ -145,7 +145,7 @@ class CurrentModuleWithICDeserializer( override fun init(delegate: IrModuleDeserializer) { val knownBuiltIns = irBuiltIns.knownBuiltins.map { (it as IrSymbolOwner).symbol }.toSet() - symbolTable.forEachDeclarationSymbol { + symbolTable.descriptorExtension.forEachDeclarationSymbol { assert(it.isPublicApi) if (it.descriptor.isDirtyDescriptor()) { // public && non-deserialized should be dirty symbol if (it !in knownBuiltIns) { @@ -172,4 +172,4 @@ class CurrentModuleWithICDeserializer( override fun fileDeserializers(): Collection { return delegate.fileDeserializers() } -} \ No newline at end of file +} diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/IrInlineBodiesHandler.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/IrInlineBodiesHandler.kt index 98cae5ce890..1e4ecb41bdb 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/IrInlineBodiesHandler.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/IrInlineBodiesHandler.kt @@ -7,12 +7,12 @@ package org.jetbrains.kotlin.test.backend.handlers import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment +import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.lazy.AbstractIrLazyFunction import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression import org.jetbrains.kotlin.ir.util.DeserializableClass import org.jetbrains.kotlin.ir.util.IdSignature -import org.jetbrains.kotlin.ir.util.allUnbound import org.jetbrains.kotlin.ir.util.resolveFakeOverride import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid @@ -24,13 +24,14 @@ import org.jetbrains.kotlin.test.services.TestServices class IrInlineBodiesHandler(testServices: TestServices) : AbstractIrHandler(testServices) { val declaredInlineFunctionSignatures = mutableSetOf() + @OptIn(ObsoleteDescriptorBasedAPI::class) override fun processModule(module: TestModule, info: IrBackendInput) { info.processAllIrModuleFragments(module) { irModule, _ -> irModule.acceptChildrenVoid(InlineFunctionsCollector()) irModule.acceptChildrenVoid(InlineCallBodiesCheck(firEnabled = module.frontendKind == FrontendKinds.FIR)) } - assertions.assertTrue((info as IrBackendInput.JvmIrBackendInput).backendInput.symbolTable.allUnbound.isEmpty()) + assertions.assertTrue((info as IrBackendInput.JvmIrBackendInput).backendInput.symbolTable.descriptorExtension.allUnboundSymbols.isEmpty()) } override fun processAfterAllModules(someAssertionWasFailed: Boolean) { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/BuiltInFictitiousFunctionIrClassFactory.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/BuiltInFictitiousFunctionIrClassFactory.kt index 762f3005830..07d22d15512 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/BuiltInFictitiousFunctionIrClassFactory.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/BuiltInFictitiousFunctionIrClassFactory.kt @@ -371,7 +371,7 @@ internal class BuiltInFictitiousFunctionIrClassFactory( isExpect = descriptor.isExpect, isFakeOverride = true) } - val property = symbolTable.declareProperty(offset, offset, memberOrigin, descriptor, propertyFactory = propertyDeclare) + val property = symbolTable.declareProperty(descriptor, propertyFactory = propertyDeclare) property.parent = this property.getter = descriptor.getter?.let { g -> createFakeOverrideFunction(g, property.symbol) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt index 31f0303998b..027ecb34b9b 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor import org.jetbrains.kotlin.fir.pipeline.convertToIrAndActualize import org.jetbrains.kotlin.fir.signaturer.Ir2FirManglerAdapter import org.jetbrains.kotlin.incremental.components.LookupTracker +import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl @@ -103,8 +104,9 @@ internal fun PhaseContext.fir2Ir( "`${irModuleFragment.name}` must be Name.special, since it's required by KlibMetadataModuleDescriptorFactoryImpl.createDescriptorOptionalBuiltIns()" } + @OptIn(ObsoleteDescriptorBasedAPI::class) val usedPackages = buildSet { - components.symbolTable.forEachDeclarationSymbol { + components.symbolTable.descriptorExtension.forEachDeclarationSymbol { val p = it.owner as? IrDeclaration ?: return@forEachDeclarationSymbol val fragment = (p.getPackageFragment() as? IrExternalPackageFragment) ?: return@forEachDeclarationSymbol add(fragment.packageFqName) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/DescriptorToIrTranslationUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/DescriptorToIrTranslationUtils.kt index a62bfdb0160..b984b99d0b1 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/DescriptorToIrTranslationUtils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/DescriptorToIrTranslationUtils.kt @@ -94,7 +94,7 @@ internal interface DescriptorToIrTranslationMixin { } } irConstructor.valueParameters += constructorDescriptor.valueParameters.map { valueParameterDescriptor -> - symbolTable.declareValueParameter( + symbolTable.descriptorExtension.declareValueParameter( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.DEFINED, valueParameterDescriptor, valueParameterDescriptor.type.toIrType()).also { @@ -127,10 +127,10 @@ internal interface DescriptorToIrTranslationMixin { symbolTable.withScope(irFunction) { irFunction.returnType = functionDescriptor.returnType!!.toIrType() irFunction.valueParameters += functionDescriptor.valueParameters.map { - symbolTable.declareValueParameter(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.DEFINED, it, it.type.toIrType()) + symbolTable.descriptorExtension.declareValueParameter(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.DEFINED, it, it.type.toIrType()) } irFunction.dispatchReceiverParameter = functionDescriptor.dispatchReceiverParameter?.let { - symbolTable.declareValueParameter(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.DEFINED, it, it.type.toIrType()) + symbolTable.descriptorExtension.declareValueParameter(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.DEFINED, it, it.type.toIrType()) } irFunction.generateAnnotations() } @@ -182,4 +182,4 @@ internal fun IrSymbol.findCStructDescriptor(): ClassDescriptor? = internal fun DeclarationDescriptor.findCStructDescriptor(): ClassDescriptor? = parentsWithSelf.filterIsInstance().firstOrNull { it.inheritsFromCStructVar() || it.annotations.hasAnnotation(RuntimeNames.managedType) - } \ No newline at end of file + } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumClassGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumClassGenerator.kt index d2128b141ac..998bec3eb4b 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumClassGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumClassGenerator.kt @@ -96,7 +96,7 @@ internal class CEnumClassGenerator( ?: error("No `value` property in ${irClass.name}") val irProperty = createProperty(propertyDescriptor) symbolTable.withScope(irProperty) { - irProperty.backingField = symbolTable.declareField( + irProperty.backingField = symbolTable.descriptorExtension.declareField( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.PROPERTY_BACKING_FIELD, propertyDescriptor, propertyDescriptor.type.toIrType(), DescriptorVisibilities.PRIVATE ).also { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cstruct/CStructVarClassGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cstruct/CStructVarClassGenerator.kt index 8824bbb5e10..849fd79d917 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cstruct/CStructVarClassGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cstruct/CStructVarClassGenerator.kt @@ -148,7 +148,7 @@ internal class CStructVarClassGenerator( val managedValType = managedVal.getter!!.returnType - managedVal.backingField = symbolTable.declareField( + managedVal.backingField = symbolTable.descriptorExtension.declareField( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.PROPERTY_BACKING_FIELD,