From 11974c14d88424b7f132d45693100af47b8f0327 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 12 Jul 2023 11:56:01 +0300 Subject: [PATCH] [IR] Fix various TODOs in SymbolTable --- .../diagnostics/FirNativeDiagnosticsList.kt | 1 - ...irAnnotationArgumentsMappingTransformer.kt | 1 - .../jetbrains/kotlin/ir/util/SymbolTable.kt | 50 +++++++++++++------ .../kotlin/ir/util/SymbolTableExtension.kt | 7 ++- .../kotlin/ir/util/SymbolTableSlice.kt | 23 ++++++--- .../IncrementalCompilationSupport.kt | 2 + .../test/builders/DefaultsProviderBuilder.kt | 1 - .../jetbrains/kotlin/backend/konan/Fir2Ir.kt | 2 +- 8 files changed, 57 insertions(+), 30 deletions(-) diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirNativeDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirNativeDiagnosticsList.kt index 5b165964744..6ea06aba104 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirNativeDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirNativeDiagnosticsList.kt @@ -11,7 +11,6 @@ import org.jetbrains.kotlin.util.PrivateForInline import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.DiagnosticList import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.PositioningStrategy import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.name.FqName diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsMappingTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsMappingTransformer.kt index af057d9ba4e..0d13a22fe7c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsMappingTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsMappingTransformer.kt @@ -20,7 +20,6 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBod import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveContextCollector -import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.visitors.transformSingle open class FirAnnotationArgumentsMappingTransformer( 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 dfbd7ba0959..31d144bb1fa 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 @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.declarations.lazy.IrLazySymbolTable import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.impl.* +@OptIn(SymbolTableInternals::class) open class SymbolTable( val signaturer: IdSignatureComposer, val irFactory: IrFactory, @@ -98,7 +99,7 @@ open class SymbolTable( ) } - // TODO: add OptIn + @SymbolTableInternals internal inline fun referenceClassImpl( signature: IdSignature, publicSymbolFactory: () -> IrClassSymbol, @@ -148,7 +149,7 @@ open class SymbolTable( ) } - // TODO: add OptIn + @SymbolTableInternals internal inline fun referenceConstructorImpl( signature: IdSignature, publicSymbolFactory: () -> IrConstructorSymbol, @@ -188,7 +189,7 @@ open class SymbolTable( ) } - // TODO: add OptIn + @SymbolTableInternals internal inline fun referenceEnumEntryImpl( signature: IdSignature, publicSymbolFactory: () -> IrEnumEntrySymbol, @@ -228,7 +229,7 @@ open class SymbolTable( ) } - // TODO: add OptIn + @SymbolTableInternals internal inline fun referenceFieldImpl( signature: IdSignature, publicSymbolFactory: () -> IrFieldSymbol, @@ -280,7 +281,7 @@ open class SymbolTable( ) } - // TODO: add OptIn + @SymbolTableInternals internal inline fun referencePropertyImpl( signature: IdSignature, publicSymbolFactory: () -> IrPropertySymbol, @@ -320,7 +321,7 @@ open class SymbolTable( ) } - // TODO: add OptIn + @SymbolTableInternals internal inline fun referenceTypeAliasImpl( signature: IdSignature, publicSymbolFactory: () -> IrTypeAliasSymbol, @@ -371,7 +372,7 @@ open class SymbolTable( ) } - // TODO: add OptIn + @SymbolTableInternals internal inline fun referenceSimpleFunctionImpl( signature: IdSignature, publicSymbolFactory: () -> IrSimpleFunctionSymbol, @@ -400,7 +401,7 @@ open class SymbolTable( symbolFactory: (IdSignature) -> IrTypeParameterSymbol, typeParameterFactory: (IrTypeParameterSymbol) -> IrTypeParameter, ): IrTypeParameter { - // TODO: suspicios + // TODO: probably this function should be completely removed, since it doesn't cache anything. KT-60375 return typeParameterFactory(symbolFactory(signature)) } @@ -412,7 +413,7 @@ open class SymbolTable( ) } - // TODO: add OptIn + @SymbolTableInternals internal inline fun referenceTypeParameterImpl( signature: IdSignature, publicSymbolFactory: () -> IrTypeParameterSymbol, @@ -428,25 +429,25 @@ open class SymbolTable( // ------------------------------------ scopes ------------------------------------ - // TODO: move to extensions + // TODO: move to extensions, KT-60376 @OptIn(ObsoleteDescriptorBasedAPI::class) override fun enterScope(symbol: IrSymbol) { descriptorExtension.enterScope(symbol) } - // TODO: move to extensions + // TODO: move to extensions, KT-60376 @OptIn(ObsoleteDescriptorBasedAPI::class) override fun enterScope(owner: IrDeclaration) { descriptorExtension.enterScope(owner) } - // TODO: move to extensions + // TODO: move to extensions, KT-60376 @OptIn(ObsoleteDescriptorBasedAPI::class) override fun leaveScope(symbol: IrSymbol) { descriptorExtension.leaveScope(symbol) } - // TODO: move to extensions + // TODO: move to extensions, KT-60376 @OptIn(ObsoleteDescriptorBasedAPI::class) override fun leaveScope(owner: IrDeclaration) { descriptorExtension.leaveScope(owner) @@ -459,9 +460,8 @@ open class SymbolTable( * 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 */ + @DelicateSymbolTableApi fun forEachDeclarationSymbol(block: (IrSymbol) -> Unit) { classSlice.forEachSymbol { block(it) } constructorSlice.forEachSymbol { block(it) } @@ -472,6 +472,12 @@ open class SymbolTable( fieldSlice.forEachSymbol { block(it) } } + /** + * This method should not be used directly, because in a lot of cases there are unbound symbols + * not only in SymbolTable itself, but in descriptorExtension too + * So please use `SymbolTable.descriptorExtension.allUnboundSymbols` instead + */ + @DelicateSymbolTableApi val allUnboundSymbols: Set get() = buildSet { fun addUnbound(slice: SymbolTableSlice) { @@ -488,6 +494,20 @@ open class SymbolTable( } } +/* + * This annotation marks that some method is actually part of SymbolTable implementation and should not be called + * outside SymbolTable or its extension + */ +@RequiresOptIn +annotation class SymbolTableInternals + +/* + * This annotation marks that some method of SymbolTable is not very safe and should be used only if you really + * know what you are doing + */ +@RequiresOptIn +annotation class DelicateSymbolTableApi + inline fun SymbolTable.withScope(owner: IrSymbol, block: SymbolTable.() -> T): T { enterScope(owner) val result = block() 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 index 3e2c228d331..52cf5797247 100644 --- 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 @@ -31,6 +31,7 @@ abstract class ReferenceSymbolTableExtension = (Declaration, IdSignature?) -> Symbol typealias OwnerFactory = (Symbol) -> SymbolOwner +@OptIn(SymbolTableInternals::class) abstract class SymbolTableExtension< Declaration, Class, TypeAlias, Script, Function, Constructor, Property, ValueParameter, TypeParameter, @@ -515,8 +516,6 @@ abstract class SymbolTableExtension< 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)) }, @@ -586,9 +585,8 @@ abstract class SymbolTableExtension< * 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 */ + @DelicateSymbolTableApi fun forEachDeclarationSymbol(block: (IrSymbol) -> Unit) { table.forEachDeclarationSymbol(block) @@ -603,6 +601,7 @@ abstract class SymbolTableExtension< globalTypeParameterSlice.forEachSymbol { block(it) } } + @OptIn(DelicateSymbolTableApi::class) val allUnboundSymbols: Set get() = buildSet { fun addUnbound(slice: SymbolTableSlice<*, *, *>) { 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 index 8d2e26d19ca..c33d1f33feb 100644 --- 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 @@ -10,6 +10,7 @@ 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 +import org.jetbrains.kotlin.util.PrivateForInline abstract class SymbolTableSlice(val lock: IrLock) where SymbolOwner : IrSymbolOwner, @@ -31,6 +32,7 @@ abstract class SymbolTableSlice(val lock: IrLock) abstract fun get(key: Key): Symbol? abstract fun set(key: Key, symbol: Symbol) + @OptIn(PrivateForInline::class) inline fun declare(key: Key, createSymbol: () -> Symbol, createOwner: (Symbol) -> SymbolOwner): SymbolOwner { synchronized(lock) { val existing = get(key) @@ -55,6 +57,7 @@ abstract class SymbolTableSlice(val lock: IrLock) } } + @OptIn(PrivateForInline::class) inline fun declareIfNotExists( key: Key, createSymbol: () -> Symbol, @@ -63,7 +66,6 @@ abstract class SymbolTableSlice(val lock: IrLock) synchronized(lock) { val existing = get(key) val symbol = if (existing == null) { - // checkOriginal(descriptor) // TODO: remove? val new = createSymbol() set(key, new) new @@ -78,7 +80,7 @@ abstract class SymbolTableSlice(val lock: IrLock) } } - // TODO: add PrivateToInline + @PrivateForInline @PublishedApi internal inline fun createOwnerSafe(symbol: Symbol, createOwner: (Symbol) -> SymbolOwner): SymbolOwner { val owner = createOwner(symbol) @@ -101,7 +103,7 @@ abstract class SymbolTableSlice(val lock: IrLock) signatureToSymbol[key] = symbol } - // TODO: add some OptIn + @SymbolTableInternals internal fun forEachSymbol(block: (IrSymbol) -> Unit) { signatureToSymbol.forEach { (_, symbol) -> block(symbol) } } @@ -110,36 +112,42 @@ abstract class SymbolTableSlice(val lock: IrLock) class Scoped(lock: IrLock) : SymbolTableSlice(lock) where SymbolOwner : IrSymbolOwner, Symbol : IrBindableSymbol<*, SymbolOwner> { + @OptIn(PrivateForInline::class) override fun set(key: Key, symbol: Symbol) { val scope = currentScope ?: noScope() scope[key] = symbol } @PublishedApi - // TODO: add PrivateForInline + @PrivateForInline internal var currentScope: SliceScope? = null - private set + private set + @OptIn(PrivateForInline::class) override fun get(key: Key): Symbol? { return currentScope?.get(key) } + @OptIn(PrivateForInline::class) 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) } + @OptIn(PrivateForInline::class) fun introduceLocal(descriptor: Key, symbol: Symbol) { val scope = currentScope ?: noScope() scope[descriptor]?.let { error("$descriptor is already bound to $it") } scope[descriptor] = symbol } + @OptIn(PrivateForInline::class) fun enterScope(owner: IrSymbol) { currentScope = SliceScope(owner, currentScope) } + @OptIn(PrivateForInline::class) fun leaveScope(owner: IrSymbol) { currentScope?.owner.let { require(it == owner) { "Unexpected leaveScope: owner=$owner, currentScope.owner=$it" } @@ -153,16 +161,17 @@ abstract class SymbolTableSlice(val lock: IrLock) } } + @OptIn(PrivateForInline::class) fun dump(): String { return currentScope?.dump() ?: "" } @PublishedApi - // TODO: add PrivateForInline + @PrivateForInline internal fun noScope(): Nothing = error("No active scope") @PublishedApi - // TODO: add PrivateForInline + @PrivateForInline internal class SliceScope(val owner: IrSymbol, val parent: SliceScope?) { private val signatureToSymbol = hashMapOf() 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 107dd34f539..a7687aecfe3 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 @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.isPublicApi +import org.jetbrains.kotlin.ir.util.DelicateSymbolTableApi import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.library.IrLibrary @@ -143,6 +144,7 @@ class CurrentModuleWithICDeserializer( return this !is DeserializedDescriptor } + @OptIn(DelicateSymbolTableApi::class) override fun init(delegate: IrModuleDeserializer) { val knownBuiltIns = irBuiltIns.knownBuiltins.map { (it as IrSymbolOwner).symbol }.toSet() symbolTable.descriptorExtension.forEachDeclarationSymbol { diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/builders/DefaultsProviderBuilder.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/builders/DefaultsProviderBuilder.kt index 97e4e63522c..ec2f3d6220e 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/builders/DefaultsProviderBuilder.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/builders/DefaultsProviderBuilder.kt @@ -17,7 +17,6 @@ import org.jetbrains.kotlin.test.services.DefaultsDsl import org.jetbrains.kotlin.test.services.DefaultsProvider import org.jetbrains.kotlin.test.model.DependencyKind import org.jetbrains.kotlin.test.model.FrontendKind -import org.jetbrains.kotlin.test.model.TestArtifactKind @DefaultsDsl class DefaultsProviderBuilder { 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 027ecb34b9b..e8a1bb960c3 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 @@ -104,7 +104,7 @@ internal fun PhaseContext.fir2Ir( "`${irModuleFragment.name}` must be Name.special, since it's required by KlibMetadataModuleDescriptorFactoryImpl.createDescriptorOptionalBuiltIns()" } - @OptIn(ObsoleteDescriptorBasedAPI::class) + @OptIn(ObsoleteDescriptorBasedAPI::class, DelicateSymbolTableApi::class) val usedPackages = buildSet { components.symbolTable.descriptorExtension.forEachDeclarationSymbol { val p = it.owner as? IrDeclaration ?: return@forEachDeclarationSymbol