[IR] Fix various TODOs in SymbolTable

This commit is contained in:
Dmitriy Novozhilov
2023-07-12 11:56:01 +03:00
committed by Space Team
parent 73b580572b
commit 11974c14d8
8 changed files with 57 additions and 30 deletions
@@ -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
@@ -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(
@@ -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<IrSymbol>
get() = buildSet {
fun addUnbound(slice: SymbolTableSlice<IdSignature, *, *>) {
@@ -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 <T> SymbolTable.withScope(owner: IrSymbol, block: SymbolTable.() -> T): T {
enterScope(owner)
val result = block()
@@ -31,6 +31,7 @@ abstract class ReferenceSymbolTableExtension<Class, TypeAlias, Script, Function,
typealias SymbolFactory<Declaration, Symbol> = (Declaration, IdSignature?) -> Symbol
typealias OwnerFactory<Symbol, SymbolOwner> = (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<IrSymbol>
get() = buildSet {
fun addUnbound(slice: SymbolTableSlice<*, *, *>) {
@@ -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<Key, SymbolOwner, Symbol>(val lock: IrLock)
where SymbolOwner : IrSymbolOwner,
@@ -31,6 +32,7 @@ abstract class SymbolTableSlice<Key, SymbolOwner, Symbol>(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<Key, SymbolOwner, Symbol>(val lock: IrLock)
}
}
@OptIn(PrivateForInline::class)
inline fun declareIfNotExists(
key: Key,
createSymbol: () -> Symbol,
@@ -63,7 +66,6 @@ abstract class SymbolTableSlice<Key, SymbolOwner, Symbol>(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<Key, SymbolOwner, Symbol>(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<Key, SymbolOwner, Symbol>(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<Key, SymbolOwner, Symbol>(val lock: IrLock)
class Scoped<Key, SymbolOwner, Symbol>(lock: IrLock) : SymbolTableSlice<Key, SymbolOwner, Symbol>(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<Key, Symbol>? = 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<Key, SymbolOwner, Symbol>(val lock: IrLock)
}
}
@OptIn(PrivateForInline::class)
fun dump(): String {
return currentScope?.dump() ?: "<none>"
}
@PublishedApi
// TODO: add PrivateForInline
@PrivateForInline
internal fun noScope(): Nothing = error("No active scope")
@PublishedApi
// TODO: add PrivateForInline
@PrivateForInline
internal class SliceScope<Key, Symbol>(val owner: IrSymbol, val parent: SliceScope<Key, Symbol>?) {
private val signatureToSymbol = hashMapOf<Key, Symbol>()
@@ -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 {
@@ -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 {
@@ -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