[PSi2IR] Generate synthetic declaration during psi2ir

- Make sure any declaration from currently generating module is bound.
 - Implement standalone declaration generator
This commit is contained in:
Roman Artemev
2020-04-17 12:35:23 +03:00
committed by romanart
parent 66543131c2
commit 5ea309d578
7 changed files with 498 additions and 20 deletions
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.generators.*
@@ -83,11 +84,13 @@ class Psi2IrTranslator(
expectDescriptorToSymbol?.let { referenceExpectsForUsedActuals(it, context.symbolTable, irModule) }
postprocess(context, irModule)
irProviders.filterIsInstance<IrDeserializer>().forEach { it.init(irModule, pluginExtensions) }
irProviders.filterIsInstance<IrDeserializer>().forEach { it.init(irModule, emptyList()) }
moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)
assert(context.symbolTable.allUnbound.isEmpty())
postprocessingSteps.forEach { it.invoke(irModule) }
// assert(context.symbolTable.allUnbound.isEmpty()) // TODO: fix IrPluginContext to make it not produce additional external reference
// TODO: remove it once plugin API improved
moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)
@@ -96,6 +99,7 @@ class Psi2IrTranslator(
}
private fun postprocess(context: GeneratorContext, irElement: IrModuleFragment) {
generateSyntheticDeclarations(irElement, context)
insertImplicitCasts(irElement, context)
generateAnnotationsForDeclarations(context, irElement)
@@ -106,4 +110,9 @@ class Psi2IrTranslator(
val annotationGenerator = AnnotationGenerator(context)
irElement.acceptVoid(annotationGenerator)
}
private fun generateSyntheticDeclarations(moduleFragment: IrModuleFragment, context: GeneratorContext) {
val generator = IrSyntheticDeclarationGenerator(context)
moduleFragment.acceptChildrenVoid(generator)
}
}
@@ -0,0 +1,52 @@
/*
* Copyright 2010-2020 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.psi2ir.generators
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.util.withScope
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.resolve.DescriptorUtils
class IrSyntheticDeclarationGenerator(context: GeneratorContext) : IrElementVisitorVoid {
private val descriptorGenerator = SyntheticDeclarationsGenerator(context, emptyList())
private val symbolTable = context.symbolTable
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
private fun collectDescriptors(descriptor: ClassDescriptor): MutableList<DeclarationDescriptor> {
val result = mutableListOf<DeclarationDescriptor>()
result.addAll(DescriptorUtils.getAllDescriptors(descriptor.unsubstitutedMemberScope))
result.addAll(descriptor.constructors)
result.addAll(descriptor.sealedSubclasses)
descriptor.companionObjectDescriptor?.let { result.add(it) }
return result
}
private fun ensureMemberScope(irClass: IrClass) {
val declaredDescriptors = irClass.declarations.map { it.descriptor }
val contributedDescriptors = collectDescriptors(irClass.descriptor)
contributedDescriptors.removeAll(declaredDescriptors)
symbolTable.withScope(irClass.descriptor) {
contributedDescriptors.forEach { it.accept(descriptorGenerator, irClass) }
}
}
override fun visitClass(declaration: IrClass) {
ensureMemberScope(declaration)
declaration.acceptChildrenVoid(this)
}
}
@@ -0,0 +1,181 @@
/*
* Copyright 2010-2020 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.psi2ir.generators
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType
import org.jetbrains.kotlin.ir.util.withScope
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtPureElement
import org.jetbrains.kotlin.psi.psiUtil.pureEndOffset
import org.jetbrains.kotlin.psi.psiUtil.pureStartOffset
import org.jetbrains.kotlin.psi2ir.endOffsetOrUndefined
import org.jetbrains.kotlin.psi2ir.startOffsetOrUndefined
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.types.KotlinType
class StandaloneDeclarationGenerator(private val context: GeneratorContext) {
private val typeTranslator = context.typeTranslator
private val symbolTable = context.symbolTable
// TODO: use this generator in psi2ir too
fun KotlinType.toIrType() = typeTranslator.translateType(this)
protected fun generateGlobalTypeParametersDeclarations(
irTypeParametersOwner: IrTypeParametersContainer,
from: List<TypeParameterDescriptor>
) {
generateTypeParameterDeclarations(irTypeParametersOwner, from) { startOffset, endOffset, typeParameterDescriptor ->
symbolTable.declareGlobalTypeParameter(startOffset, endOffset, IrDeclarationOrigin.DEFINED, typeParameterDescriptor)
}
}
fun generateScopedTypeParameterDeclarations(
irTypeParametersOwner: IrTypeParametersContainer,
from: List<TypeParameterDescriptor>
) {
generateTypeParameterDeclarations(irTypeParametersOwner, from) { startOffset, endOffset, typeParameterDescriptor ->
symbolTable.declareScopedTypeParameter(startOffset, endOffset, IrDeclarationOrigin.DEFINED, typeParameterDescriptor)
}
}
private fun generateTypeParameterDeclarations(
irTypeParametersOwner: IrTypeParametersContainer,
from: List<TypeParameterDescriptor>,
declareTypeParameter: (Int, Int, TypeParameterDescriptor) -> IrTypeParameter
) {
irTypeParametersOwner.typeParameters += from.map { typeParameterDescriptor ->
val ktTypeParameterDeclaration = DescriptorToSourceUtils.getSourceFromDescriptor(typeParameterDescriptor)
val startOffset = ktTypeParameterDeclaration.startOffsetOrUndefined
val endOffset = ktTypeParameterDeclaration.endOffsetOrUndefined
declareTypeParameter(
startOffset,
endOffset,
typeParameterDescriptor
).also {
it.parent = irTypeParametersOwner
}
}
for (irTypeParameter in irTypeParametersOwner.typeParameters) {
irTypeParameter.descriptor.upperBounds.mapTo(irTypeParameter.superTypes) {
it.toIrType()
}
}
}
fun generateClass(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor, symbol: IrClassSymbol): IrClass {
val irClass = IrClassImpl(startOffset, endOffset, origin, symbol)
symbolTable.withScope(descriptor) {
irClass.metadata = MetadataSource.Class(descriptor)
generateGlobalTypeParametersDeclarations(irClass, descriptor.declaredTypeParameters)
irClass.superTypes = descriptor.typeConstructor.supertypes.map {
it.toIrType()
}
irClass.thisReceiver = context.symbolTable.declareValueParameter(
startOffset, endOffset,
IrDeclarationOrigin.INSTANCE_RECEIVER,
descriptor.thisAsReceiverParameter,
descriptor.thisAsReceiverParameter.type.toIrType()
).also { it.parent = irClass }
}
return irClass
}
fun generateEnumEntry(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor, symbol: IrEnumEntrySymbol): IrEnumEntry {
// TODO: corresponging class?
val irEntry = IrEnumEntryImpl(startOffset, endOffset, origin, symbol)
return irEntry
}
fun generateTypeAlias(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: TypeAliasDescriptor, symbol: IrTypeAliasSymbol): IrTypeAlias {
val irAlias = IrTypeAliasImpl.fromSymbolDescriptor(startOffset, endOffset, symbol, descriptor.expandedType.toIrType(), origin)
generateGlobalTypeParametersDeclarations(irAlias, descriptor.declaredTypeParameters)
return irAlias
}
protected fun declareParameter(descriptor: ParameterDescriptor, ktElement: KtPureElement?, irOwnerElement: IrElement): IrValueParameter {
return symbolTable.declareValueParameter(
ktElement?.pureStartOffset ?: irOwnerElement.startOffset,
ktElement?.pureEndOffset ?: irOwnerElement.endOffset,
IrDeclarationOrigin.DEFINED,
descriptor, descriptor.type.toIrType(),
(descriptor as? ValueParameterDescriptor)?.varargElementType?.toIrType()
)
}
protected fun generateValueParameterDeclarations(irFunction: IrFunction, functionDescriptor: FunctionDescriptor) {
// TODO: KtElements
irFunction.dispatchReceiverParameter = functionDescriptor.dispatchReceiverParameter?.let {
declareParameter(it, null, irFunction)
}
irFunction.extensionReceiverParameter = functionDescriptor.extensionReceiverParameter?.let {
declareParameter(it, null, irFunction)
}
// Declare all the value parameters up first.
irFunction.valueParameters = functionDescriptor.valueParameters.map { valueParameterDescriptor ->
val ktParameter = DescriptorToSourceUtils.getSourceFromDescriptor(valueParameterDescriptor) as? KtParameter
declareParameter(valueParameterDescriptor, ktParameter, irFunction)
}
}
fun generateConstructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassConstructorDescriptor, symbol: IrConstructorSymbol): IrConstructor {
val irConstructor = IrConstructorImpl(startOffset, endOffset, origin, symbol, IrUninitializedType)
irConstructor.metadata = MetadataSource.Function(descriptor)
symbolTable.withScope(descriptor) {
val ctorTypeParameters = descriptor.typeParameters.filter { it.containingDeclaration === descriptor }
generateScopedTypeParameterDeclarations(irConstructor, ctorTypeParameters)
generateValueParameterDeclarations(irConstructor, descriptor)
irConstructor.returnType = descriptor.returnType.toIrType()
}
return irConstructor
}
protected fun generateOverridenSymbols(irFunction: IrSimpleFunction, overridens: Collection<FunctionDescriptor>) {
irFunction.overriddenSymbols = overridens.map { symbolTable.referenceSimpleFunction(it.original) }
}
fun generateSimpleFunction(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: FunctionDescriptor, symbol: IrSimpleFunctionSymbol): IrSimpleFunction {
val irFunction = IrFunctionImpl(startOffset, endOffset, origin, symbol, IrUninitializedType)
irFunction.metadata = MetadataSource.Function(descriptor)
symbolTable.withScope(descriptor) {
generateOverridenSymbols(irFunction, descriptor.overriddenDescriptors)
generateScopedTypeParameterDeclarations(irFunction, descriptor.typeParameters)
generateValueParameterDeclarations(irFunction, descriptor)
irFunction.returnType = descriptor.returnType?.toIrType() ?: error("Expected return type $descriptor")
}
return irFunction
}
fun generateProperty(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: PropertyDescriptor, symbol: IrPropertySymbol): IrProperty {
val irProperty = IrPropertyImpl(startOffset, endOffset, origin, symbol, isDelegated = false)
irProperty.metadata = MetadataSource.Property(descriptor)
return irProperty
}
}
@@ -0,0 +1,182 @@
/*
* Copyright 2010-2020 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.psi2ir.generators
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.util.IrExtensionGenerator
import org.jetbrains.kotlin.resolve.DescriptorUtils
class SyntheticDeclarationsGenerator(
private val context: GeneratorContext,
private val pluginProviders: Collection<IrExtensionGenerator>
) : DeclarationDescriptorVisitor<Unit, IrDeclarationContainer?> {
private val generator = StandaloneDeclarationGenerator(context)
private val symbolTable = context.symbolTable
companion object {
private const val offset = UNDEFINED_OFFSET
}
private fun <D : IrDeclaration> D.insertDeclaration(declarationContainer: IrDeclarationContainer): D {
parent = declarationContainer
declarationContainer.declarations.add(this)
return this
}
private inline fun <S : IrSymbol, R : IrDeclaration> generateOrDefault(symbol: S, onDefault: (S) -> R): R {
for (p in pluginProviders) {
p.declare(symbol)?.let {
@Suppress("UNCHECKED_CAST")
return it as R
}
}
return onDefault(symbol)
}
override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor, data: IrDeclarationContainer?) {
error("Unexpected declaration descriptor $descriptor")
}
override fun visitPackageViewDescriptor(descriptor: PackageViewDescriptor, data: IrDeclarationContainer?) {
error("Unexpected declaration descriptor $descriptor")
}
override fun visitVariableDescriptor(descriptor: VariableDescriptor, data: IrDeclarationContainer?) {
error("Unexpected declaration descriptor $descriptor")
}
private fun createFunctionStub(descriptor: FunctionDescriptor, symbol: IrSimpleFunctionSymbol): IrSimpleFunction {
return generateOrDefault(symbol) {
generator.generateSimpleFunction(offset, offset, IrDeclarationOrigin.DEFINED, descriptor, symbol)
}
}
override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: IrDeclarationContainer?) {
require(data != null)
if (descriptor.visibility != Visibilities.INVISIBLE_FAKE) {
symbolTable.declareSimpleFunctionIfNotExists(descriptor) {
createFunctionStub(descriptor, it).insertDeclaration(data)
}
}
}
override fun visitTypeParameterDescriptor(descriptor: TypeParameterDescriptor, data: IrDeclarationContainer?) {
error("Unexpected declaration descriptor $descriptor")
}
private fun createClassStub(descriptor: ClassDescriptor, symbol: IrClassSymbol): IrClass {
assert(!DescriptorUtils.isEnumEntry(descriptor))
return generateOrDefault(symbol) {
generator.generateClass(offset, offset, IrDeclarationOrigin.DEFINED, descriptor, symbol)
}
}
private fun createEnumEntruStub(descriptor: ClassDescriptor, symbol: IrEnumEntrySymbol): IrEnumEntry {
assert(DescriptorUtils.isEnumEntry(descriptor))
return generateOrDefault(symbol) {
generator.generateEnumEntry(offset, offset, IrDeclarationOrigin.DEFINED, descriptor, symbol)
}
}
override fun visitClassDescriptor(descriptor: ClassDescriptor, data: IrDeclarationContainer?) {
require(data != null)
if (DescriptorUtils.isEnumEntry(descriptor)) {
symbolTable.declareEnumEntryIfNotExists(descriptor) {
createEnumEntruStub(descriptor, it).insertDeclaration(data)
}
} else {
symbolTable.declareClassIfNotExists(descriptor) {
createClassStub(descriptor, it).insertDeclaration(data)
}
}
}
private fun declareTypeAliasStub(descriptor: TypeAliasDescriptor, symbol: IrTypeAliasSymbol): IrTypeAlias {
return generateOrDefault(symbol) {
generator.generateTypeAlias(offset, offset, IrDeclarationOrigin.DEFINED, descriptor, symbol)
}
}
override fun visitTypeAliasDescriptor(descriptor: TypeAliasDescriptor, data: IrDeclarationContainer?) {
require(data != null)
symbolTable.declareTypeAliasIfNotExists(descriptor) {
declareTypeAliasStub(descriptor, it).insertDeclaration(data)
}
}
override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: IrDeclarationContainer?) {
error("Unreachable execution $descriptor")
}
private fun createConstructorStub(descriptor: ClassConstructorDescriptor, symbol: IrConstructorSymbol): IrConstructor {
return generateOrDefault(symbol) {
generator.generateConstructor(offset, offset, IrDeclarationOrigin.DEFINED, descriptor, symbol)
}
}
override fun visitConstructorDescriptor(constructorDescriptor: ConstructorDescriptor, data: IrDeclarationContainer?) {
require(data != null)
assert(constructorDescriptor is ClassConstructorDescriptor)
symbolTable.declareConstructorIfNotExists(constructorDescriptor as ClassConstructorDescriptor) {
createConstructorStub(constructorDescriptor, it).insertDeclaration(data)
}
}
override fun visitScriptDescriptor(scriptDescriptor: ScriptDescriptor, data: IrDeclarationContainer?) {
assert(symbolTable.referenceScript(scriptDescriptor).isBound) { "Script $scriptDescriptor isn't declared" }
}
private fun createPropertyStub(descriptor: PropertyDescriptor, symbol: IrPropertySymbol): IrProperty {
return generateOrDefault(symbol) {
generator.generateProperty(offset, offset, IrDeclarationOrigin.DEFINED, descriptor, symbol)
}
}
private fun declareAccessor(accessorDescriptor: PropertyAccessorDescriptor, property: IrProperty): IrSimpleFunction {
// TODO: type parameters
return symbolTable.declareSimpleFunctionIfNotExists(accessorDescriptor) {
createFunctionStub(accessorDescriptor, it).also { acc ->
acc.parent = property.parent
acc.correspondingPropertySymbol = property.symbol
}
}
}
override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: IrDeclarationContainer?) {
require(data != null)
if (descriptor.visibility != Visibilities.INVISIBLE_FAKE) {
symbolTable.declarePropertyIfNotExists(descriptor) {
createPropertyStub(descriptor, it).insertDeclaration(data).also { p ->
descriptor.getter?.let { g -> p.getter = declareAccessor(g, p) }
descriptor.setter?.let { s -> p.setter = declareAccessor(s, p) }
}
}
}
}
override fun visitValueParameterDescriptor(descriptor: ValueParameterDescriptor, data: IrDeclarationContainer?) {
error("Unreachable execution $descriptor")
}
override fun visitPropertyGetterDescriptor(descriptor: PropertyGetterDescriptor, data: IrDeclarationContainer?) {
error("Unreachable execution $descriptor")
}
override fun visitPropertySetterDescriptor(descriptor: PropertySetterDescriptor, data: IrDeclarationContainer?) {
error("Unreachable execution $descriptor")
}
override fun visitReceiverParameterDescriptor(descriptor: ReceiverParameterDescriptor, data: IrDeclarationContainer?) {
error("Unreachable execution $descriptor")
}
}
@@ -55,22 +55,6 @@ class ExternalDependenciesGenerator(
}
} while (unbound.isNotEmpty())
}
private val SymbolTable.allUnbound: List<IrSymbol>
get() {
val r = mutableListOf<IrSymbol>()
r.addAll(unboundClasses)
r.addAll(unboundConstructors)
r.addAll(unboundEnumEntries)
r.addAll(unboundFields)
r.addAll(unboundSimpleFunctions)
r.addAll(unboundProperties)
r.addAll(unboundTypeAliases)
if (!languageVersionSettings.supportsFeature(LanguageFeature.NewInference)) {
r.addAll(unboundTypeParameters)
}
return r
}
}
fun List<IrProvider>.getDeclaration(symbol: IrSymbol): IrDeclaration =
@@ -18,6 +18,7 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.*
@@ -61,6 +62,8 @@ interface ReferenceSymbolTable {
fun referenceEnumEntry(descriptor: ClassDescriptor): IrEnumEntrySymbol
fun referenceField(descriptor: PropertyDescriptor): IrFieldSymbol
fun referenceProperty(descriptor: PropertyDescriptor): IrPropertySymbol
fun referenceProperty(descriptor: PropertyDescriptor, generate: () -> IrProperty): IrProperty
fun referenceSimpleFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol
@@ -119,6 +122,24 @@ open class SymbolTable(
return createOwner(symbol)
}
inline fun declareIfNotExists(d: D, createSymbol: () -> S, createOwner: (S) -> B): B {
@Suppress("UNCHECKED_CAST")
val d0 = d.original as D
assert(d0 === d) {
"Non-original descriptor in declaration: $d\n\tExpected: $d0"
}
val existing = get(d0)
val symbol = if (existing == null) {
val new = createSymbol()
set(d0, new)
new
} else {
if (!existing.isBound) unboundSymbols.remove(existing)
existing
}
return if (symbol.isBound) symbol.owner else createOwner(symbol)
}
inline fun declare(sig: IdSignature, d: D, createSymbol: () -> S, createOwner: (S) -> B): B {
@Suppress("UNCHECKED_CAST")
val d0 = d.original as D
@@ -393,6 +414,10 @@ open class SymbolTable(
)
}
fun declareClassIfNotExists(descriptor: ClassDescriptor, classFactory: (IrClassSymbol) -> IrClass): IrClass {
return classSymbolTable.declareIfNotExists(descriptor, { createClassSymbol(descriptor) }, classFactory)
}
fun declareClassFromLinker(descriptor: ClassDescriptor, sig: IdSignature, factory: (IrClassSymbol) -> IrClass): IrClass {
return classSymbolTable.run {
if (sig.isPublic) {
@@ -441,6 +466,13 @@ open class SymbolTable(
constructorFactory
)
fun declareConstructorIfNotExists(descriptor: ClassConstructorDescriptor, constructorFactory: (IrConstructorSymbol) -> IrConstructor): IrConstructor =
constructorSymbolTable.declareIfNotExists(
descriptor,
{ createConstructorSymbol(descriptor) },
constructorFactory
)
override fun referenceConstructor(descriptor: ClassConstructorDescriptor) =
constructorSymbolTable.referenced(descriptor) { createConstructorSymbol(descriptor) }
@@ -483,6 +515,10 @@ open class SymbolTable(
factory
)
fun declareEnumEntryIfNotExists(descriptor: ClassDescriptor, factory: (IrEnumEntrySymbol) -> IrEnumEntry): IrEnumEntry {
return enumEntrySymbolTable.declareIfNotExists(descriptor, { createEnumEntrySymbol(descriptor) }, factory)
}
fun declareEnumEntryFromLinker(
descriptor: ClassDescriptor,
sig: IdSignature,
@@ -599,6 +635,9 @@ open class SymbolTable(
propertyFactory
)
fun declarePropertyIfNotExists(descriptor: PropertyDescriptor, propertyFactory: (IrPropertySymbol) -> IrProperty): IrProperty =
propertySymbolTable.declareIfNotExists(descriptor, { createPropertySymbol(descriptor) }, propertyFactory)
fun declarePropertyFromLinker(descriptor: PropertyDescriptor, sig: IdSignature, factory: (IrPropertySymbol) -> IrProperty): IrProperty {
return propertySymbolTable.run {
if (sig.isPublic) {
@@ -609,7 +648,7 @@ open class SymbolTable(
}
}
fun referenceProperty(descriptor: PropertyDescriptor): IrPropertySymbol =
override fun referenceProperty(descriptor: PropertyDescriptor): IrPropertySymbol =
propertySymbolTable.referenced(descriptor) { createPropertySymbol(descriptor) }
override fun referencePropertyFromLinker(descriptor: PropertyDescriptor, sig: IdSignature): IrPropertySymbol =
@@ -652,6 +691,9 @@ open class SymbolTable(
fun declareTypeAlias(descriptor: TypeAliasDescriptor, factory: (IrTypeAliasSymbol) -> IrTypeAlias): IrTypeAlias =
typeAliasSymbolTable.declare(descriptor, { createTypeAliasSymbol(descriptor) }, factory)
fun declareTypeAliasIfNotExists(descriptor: TypeAliasDescriptor, factory: (IrTypeAliasSymbol) -> IrTypeAlias): IrTypeAlias =
typeAliasSymbolTable.declareIfNotExists(descriptor, { createTypeAliasSymbol(descriptor) }, factory)
val unboundTypeAliases: Set<IrTypeAliasSymbol> get() = typeAliasSymbolTable.unboundSymbols
private fun createSimpleFunctionSymbol(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol {
@@ -681,6 +723,13 @@ open class SymbolTable(
)
}
fun declareSimpleFunctionIfNotExists(
descriptor: FunctionDescriptor,
functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction
): IrSimpleFunction {
return simpleFunctionSymbolTable.declareIfNotExists(descriptor, { createSimpleFunctionSymbol(descriptor) }, functionFactory)
}
fun declareSimpleFunctionFromLinker(
descriptor: FunctionDescriptor,
sig: IdSignature,
@@ -913,4 +962,25 @@ inline fun <T, D : DeclarationDescriptor> SymbolTable.withScope(owner: D, block:
val result = block(owner)
leaveScope(owner)
return result
}
}
inline fun <T, D : DeclarationDescriptor> ReferenceSymbolTable.withReferenceScope(owner: D, block: ReferenceSymbolTable.(D) -> T): T {
enterScope(owner)
val result = block(owner)
leaveScope(owner)
return result
}
val SymbolTable.allUnbound: List<IrSymbol>
get() {
val r = mutableListOf<IrSymbol>()
r.addAll(unboundClasses)
r.addAll(unboundConstructors)
r.addAll(unboundEnumEntries)
r.addAll(unboundFields)
r.addAll(unboundSimpleFunctions)
r.addAll(unboundProperties)
r.addAll(unboundTypeAliases)
r.addAll(unboundTypeParameters)
return r.filter { !it.isBound }
}
@@ -25,7 +25,7 @@ fun SymbolTable.declareSimpleFunctionWithOverrides(
fun generateOverriddenFunctionSymbols(
declaration: IrSimpleFunction,
symbolTable: SymbolTable
symbolTable: ReferenceSymbolTable
) {
declaration.overriddenSymbols = declaration.descriptor.overriddenDescriptors.map {
symbolTable.referenceSimpleFunction(it.original)