[IR] Update inheritors of SymbolTable which override some descriptor-related methods

This commit is contained in:
Dmitriy Novozhilov
2023-07-11 12:25:59 +03:00
committed by Space Team
parent 8ad202eb8b
commit 4ec65ace1c
5 changed files with 148 additions and 102 deletions
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.IrFactory
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.util.DescriptorSymbolTableExtension
import org.jetbrains.kotlin.ir.util.IdSignatureComposer
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
@@ -44,28 +45,34 @@ class SymbolTableWithBuiltInsDeduplication(
}
}
/**
* Gets or creates the [IrClassSymbol] for [descriptor], or for the built-in descriptor with the same name if [descriptor] is a
* duplicate built-in.
*
* Note that not all built-in symbols may have been bound or created by the time [irBuiltIns] has been bound. However, [referenceClass]
* will create a symbol in such a case (via `super.referenceClass`) and [org.jetbrains.kotlin.ir.util.DeclarationStubGenerator] will
* create a stub for the symbol if [referenceClass] was invoked from the stub generator.
*/
@ObsoleteDescriptorBasedAPI
override fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol {
val irBuiltIns = this.irBuiltIns ?: return super.descriptorExtension.referenceClass(descriptor)
override fun createDescriptorExtension(): DescriptorSymbolTableExtension {
return Extension()
}
// We need to find out whether `descriptor` is possibly a built-in symbol before it's actually retrieved to break recursion as
// `irBuiltIns.findClass` uses `referenceClass` recursively.
val builtInDescriptor = irBuiltIns.findBuiltInClassDescriptor(descriptor)
if (builtInDescriptor != null) {
// We need to delegate to the supertype implementation here to break recursion. `findBuiltInClassDescriptor` will return
// `descriptor` even if `descriptor` was found via `findBuiltInClassDescriptor`.
return super.descriptorExtension.referenceClass(builtInDescriptor)
private inner class Extension : DescriptorSymbolTableExtension(this) {
/**
* Gets or creates the [IrClassSymbol] for [descriptor], or for the built-in descriptor with the same name if [descriptor] is a
* duplicate built-in.
*
* Note that not all built-in symbols may have been bound or created by the time [irBuiltIns] has been bound. However, [referenceClass]
* will create a symbol in such a case (via `super.referenceClass`) and [org.jetbrains.kotlin.ir.util.DeclarationStubGenerator] will
* create a stub for the symbol if [referenceClass] was invoked from the stub generator.
*/
@ObsoleteDescriptorBasedAPI
override fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol {
val irBuiltIns = this@SymbolTableWithBuiltInsDeduplication.irBuiltIns ?: return super.referenceClass(descriptor)
// We need to find out whether `descriptor` is possibly a built-in symbol before it's actually retrieved to break recursion as
// `irBuiltIns.findClass` uses `referenceClass` recursively.
val builtInDescriptor = irBuiltIns.findBuiltInClassDescriptor(descriptor)
if (builtInDescriptor != null) {
// We need to delegate to the supertype implementation here to break recursion. `findBuiltInClassDescriptor` will return
// `descriptor` even if `descriptor` was found via `findBuiltInClassDescriptor`.
return super.referenceClass(builtInDescriptor)
}
return super.referenceClass(descriptor)
}
return super.descriptorExtension.referenceClass(descriptor)
}
private fun IrBuiltInsOverDescriptors.findBuiltInClassDescriptor(descriptor: ClassDescriptor): ClassDescriptor? {
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.descriptors.impl.AbstractReceiverParameterDescriptor
import org.jetbrains.kotlin.ir.declarations.IrFactory
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.util.DescriptorSymbolTableExtension
import org.jetbrains.kotlin.ir.util.IdSignatureComposer
import org.jetbrains.kotlin.ir.util.NameProvider
import org.jetbrains.kotlin.ir.util.SymbolTable
@@ -28,48 +29,53 @@ class FragmentCompilerSymbolTableDecorator(
nameProvider: NameProvider = NameProvider.DEFAULT,
) : SymbolTable(signatureComposer, irFactory, nameProvider) {
override fun referenceValueParameter(descriptor: ParameterDescriptor): IrValueParameterSymbol {
val fi = fragmentInfo ?: return super.descriptorExtension.referenceValueParameter(descriptor)
if (descriptor !is ReceiverParameterDescriptor) return super.descriptorExtension.referenceValueParameter(descriptor)
val finderPredicate = when (val receiverValue = descriptor.value) {
is ExtensionReceiver, is ContextReceiver -> { (targetDescriptor, _): EvaluatorFragmentParameterInfo ->
receiverValue == (targetDescriptor as? ReceiverParameterDescriptor)?.value
}
is ThisClassReceiver -> { (targetDescriptor, _): EvaluatorFragmentParameterInfo ->
receiverValue.classDescriptor == targetDescriptor.original
}
else -> TODO("Unimplemented")
}
val parameterPosition =
fi.parameters.indexOfFirst(finderPredicate)
if (parameterPosition > -1) {
return super.descriptorExtension.referenceValueParameter(fi.methodDescriptor.valueParameters[parameterPosition])
}
return super.descriptorExtension.referenceValueParameter(descriptor)
override fun createDescriptorExtension(): DescriptorSymbolTableExtension {
return ExtensionDecorator()
}
private inner class ExtensionDecorator : DescriptorSymbolTableExtension(this) {
override fun referenceValueParameter(descriptor: ParameterDescriptor): IrValueParameterSymbol {
val fi = fragmentInfo ?: return super.referenceValueParameter(descriptor)
fun referenceValue(value: ValueDescriptor): IrValueSymbol {
val fi = fragmentInfo ?: return super.descriptorExtension.referenceValue(value)
if (descriptor !is ReceiverParameterDescriptor) return super.referenceValueParameter(descriptor)
val finderPredicate = when (value) {
is AbstractReceiverParameterDescriptor -> { (targetDescriptor, _): EvaluatorFragmentParameterInfo ->
value.containingDeclaration == targetDescriptor
val finderPredicate = when (val receiverValue = descriptor.value) {
is ExtensionReceiver, is ContextReceiver -> { (targetDescriptor, _): EvaluatorFragmentParameterInfo ->
receiverValue == (targetDescriptor as? ReceiverParameterDescriptor)?.value
}
is ThisClassReceiver -> { (targetDescriptor, _): EvaluatorFragmentParameterInfo ->
receiverValue.classDescriptor == targetDescriptor.original
}
else -> TODO("Unimplemented")
}
else -> { (targetDescriptor, _): EvaluatorFragmentParameterInfo ->
targetDescriptor == value
val parameterPosition =
fi.parameters.indexOfFirst(finderPredicate)
if (parameterPosition > -1) {
return super.referenceValueParameter(fi.methodDescriptor.valueParameters[parameterPosition])
}
return super.referenceValueParameter(descriptor)
}
val parameterPosition =
fi.parameters.indexOfFirst(finderPredicate)
if (parameterPosition > -1) {
return super.descriptorExtension.referenceValueParameter(fi.methodDescriptor.valueParameters[parameterPosition])
}
override fun referenceValue(value: ValueDescriptor): IrValueSymbol {
val fi = fragmentInfo ?: return super.referenceValue(value)
return super.descriptorExtension.referenceValue(value)
val finderPredicate = when (value) {
is AbstractReceiverParameterDescriptor -> { (targetDescriptor, _): EvaluatorFragmentParameterInfo ->
value.containingDeclaration == targetDescriptor
}
else -> { (targetDescriptor, _): EvaluatorFragmentParameterInfo ->
targetDescriptor == value
}
}
val parameterPosition =
fi.parameters.indexOfFirst(finderPredicate)
if (parameterPosition > -1) {
return super.referenceValueParameter(fi.methodDescriptor.valueParameters[parameterPosition])
}
return super.referenceValue(value)
}
}
}
@@ -9,9 +9,7 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrLock
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.*
@OptIn(ObsoleteDescriptorBasedAPI::class)
class IrLazySymbolTable(private val originalTable: SymbolTable) : ReferenceSymbolTable by originalTable {
@@ -21,73 +19,104 @@ class IrLazySymbolTable(private val originalTable: SymbolTable) : ReferenceSymbo
/*Don't force builtins class linking before unbound symbols linking: otherwise stdlib compilation will failed*/
var stubGenerator: DeclarationStubGenerator? = null
fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol {
synchronized(lock) {
return originalTable.descriptorExtension.referenceClass(descriptor).also {
if (!it.isBound) {
stubGenerator?.generateClassStub(descriptor)
@ObsoleteDescriptorBasedAPI
override val descriptorExtension: DescriptorBasedReferenceSymbolTableExtension = ExtensionWrapper()
private inner class ExtensionWrapper : DescriptorSymbolTableExtension(originalTable) {
private val delegate get() = originalTable.descriptorExtension
override fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol {
synchronized(lock) {
return delegate.referenceClass(descriptor).also {
if (!it.isBound) {
stubGenerator?.generateClassStub(descriptor)
}
}
}
}
}
fun referenceTypeAlias(descriptor: TypeAliasDescriptor): IrTypeAliasSymbol {
synchronized(lock) {
return originalTable.descriptorExtension.referenceTypeAlias(descriptor).also {
if (!it.isBound) {
stubGenerator?.generateTypeAliasStub(descriptor)
override fun referenceTypeAlias(descriptor: TypeAliasDescriptor): IrTypeAliasSymbol {
synchronized(lock) {
return delegate.referenceTypeAlias(descriptor).also {
if (!it.isBound) {
stubGenerator?.generateTypeAliasStub(descriptor)
}
}
}
}
}
fun referenceConstructor(descriptor: ClassConstructorDescriptor): IrConstructorSymbol {
synchronized(lock) {
return originalTable.descriptorExtension.referenceConstructor(descriptor).also {
if (!it.isBound) {
stubGenerator?.generateConstructorStub(descriptor)
override fun referenceConstructor(descriptor: ClassConstructorDescriptor): IrConstructorSymbol {
synchronized(lock) {
return delegate.referenceConstructor(descriptor).also {
if (!it.isBound) {
stubGenerator?.generateConstructorStub(descriptor)
}
}
}
}
}
fun referenceEnumEntry(descriptor: ClassDescriptor): IrEnumEntrySymbol {
synchronized(lock) {
return originalTable.descriptorExtension.referenceEnumEntry(descriptor).also {
if (!it.isBound) {
stubGenerator?.generateEnumEntryStub(descriptor)
override fun referenceEnumEntry(descriptor: ClassDescriptor): IrEnumEntrySymbol {
synchronized(lock) {
return delegate.referenceEnumEntry(descriptor).also {
if (!it.isBound) {
stubGenerator?.generateEnumEntryStub(descriptor)
}
}
}
}
}
fun referenceSimpleFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol {
synchronized(lock) {
return originalTable.descriptorExtension.referenceSimpleFunction(descriptor).also {
if (!it.isBound) {
stubGenerator?.generateFunctionStub(descriptor)
override fun referenceSimpleFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol {
synchronized(lock) {
return delegate.referenceSimpleFunction(descriptor).also {
if (!it.isBound) {
stubGenerator?.generateFunctionStub(descriptor)
}
}
}
}
}
fun referenceProperty(descriptor: PropertyDescriptor): IrPropertySymbol {
synchronized(lock) {
return originalTable.descriptorExtension.referenceProperty(descriptor).also {
if (!it.isBound) {
stubGenerator?.generatePropertyStub(descriptor)
override fun referenceProperty(descriptor: PropertyDescriptor): IrPropertySymbol {
synchronized(lock) {
return delegate.referenceProperty(descriptor).also {
if (!it.isBound) {
stubGenerator?.generatePropertyStub(descriptor)
}
}
}
}
}
fun referenceTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol {
synchronized(lock) {
return originalTable.descriptorExtension.referenceTypeParameter(classifier).also {
if (!it.isBound) {
stubGenerator?.generateOrGetTypeParameterStub(classifier)
override fun referenceTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol {
synchronized(lock) {
return delegate.referenceTypeParameter(classifier).also {
if (!it.isBound) {
stubGenerator?.generateOrGetTypeParameterStub(classifier)
}
}
}
}
override fun referenceValueParameter(descriptor: ParameterDescriptor): IrValueParameterSymbol {
return delegate.referenceValueParameter(descriptor)
}
override fun referenceValue(value: ValueDescriptor): IrValueSymbol {
return delegate.referenceValue(value)
}
override fun referenceScript(descriptor: ScriptDescriptor): IrScriptSymbol {
return delegate.referenceScript(descriptor)
}
override fun referenceField(descriptor: PropertyDescriptor): IrFieldSymbol {
return delegate.referenceField(descriptor)
}
override fun referenceDeclaredFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol {
return delegate.referenceDeclaredFunction(descriptor)
}
override fun referenceScopedTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol {
return delegate.referenceScopedTypeParameter(classifier)
}
}
}
@@ -27,7 +27,7 @@ typealias DescriptorBasedReferenceSymbolTableExtension = ReferenceSymbolTableExt
>
@ObsoleteDescriptorBasedAPI
class DescriptorSymbolTableExtension(table: SymbolTable) : SymbolTableExtension<
open class DescriptorSymbolTableExtension(table: SymbolTable) : SymbolTableExtension<
DeclarationDescriptor, ClassDescriptor, TypeAliasDescriptor, ScriptDescriptor, FunctionDescriptor,
ClassConstructorDescriptor, PropertyDescriptor, ParameterDescriptor, TypeParameterDescriptor>(table)
{
@@ -405,8 +405,7 @@ class DescriptorSymbolTableExtension(table: SymbolTable) : SymbolTableExtension<
}
}
// TODO: convert to extension
fun referenceValue(value: ValueDescriptor): IrValueSymbol {
open 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") }
@@ -35,7 +35,12 @@ open class SymbolTable(
@Suppress("LeakingThis")
@OptIn(ObsoleteDescriptorBasedAPI::class)
override val descriptorExtension: DescriptorSymbolTableExtension = DescriptorSymbolTableExtension(this)
override val descriptorExtension: DescriptorSymbolTableExtension = createDescriptorExtension()
@OptIn(ObsoleteDescriptorBasedAPI::class)
protected open fun createDescriptorExtension(): DescriptorSymbolTableExtension {
return DescriptorSymbolTableExtension(this)
}
// ------------------------------------ script ------------------------------------