[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:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+52
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
+181
@@ -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
|
||||
}
|
||||
}
|
||||
+182
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user