Generate references to superclasses
This commit is contained in:
@@ -38,14 +38,20 @@ import java.lang.AssertionError
|
||||
class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
|
||||
fun generateClass(ktClassOrObject: KtClassOrObject): IrClass {
|
||||
val descriptor = getOrFail(BindingContext.CLASS, ktClassOrObject)
|
||||
val startOffset = ktClassOrObject.startOffset
|
||||
val endOffset = ktClassOrObject.endOffset
|
||||
|
||||
return context.symbolTable.declareClass(
|
||||
ktClassOrObject.startOffset, ktClassOrObject.endOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
descriptor
|
||||
startOffset, endOffset, IrDeclarationOrigin.DEFINED, descriptor
|
||||
).buildWithScope { irClass ->
|
||||
descriptor.typeConstructor.supertypes.mapNotNullTo(irClass.superClasses) {
|
||||
it.constructor.declarationDescriptor?.safeAs<ClassDescriptor>()?.let {
|
||||
context.symbolTable.referenceClass(it)
|
||||
}
|
||||
}
|
||||
|
||||
irClass.thisReceiver = context.symbolTable.declareValueParameter(
|
||||
ktClassOrObject.startOffset, ktClassOrObject.endOffset,
|
||||
startOffset, endOffset,
|
||||
IrDeclarationOrigin.INSTANCE_RECEIVER,
|
||||
irClass.descriptor.thisAsReceiverParameter
|
||||
)
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
||||
fun generateClassOrObjectDeclaration(ktClassOrObject: KtClassOrObject): IrClass =
|
||||
ClassGenerator(this).generateClass(ktClassOrObject)
|
||||
|
||||
fun generateTypeAliasDeclaration(ktDeclaration: KtTypeAlias): IrDeclaration =
|
||||
private fun generateTypeAliasDeclaration(ktDeclaration: KtTypeAlias): IrDeclaration =
|
||||
IrTypeAliasImpl(
|
||||
ktDeclaration.startOffset, ktDeclaration.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
getOrFail(BindingContext.TYPE_ALIAS, ktDeclaration)
|
||||
|
||||
@@ -36,6 +36,9 @@ interface IrClass : IrSymbolDeclaration<IrClassSymbol>, IrDeclarationContainer,
|
||||
val isCompanion: Boolean
|
||||
val isData: Boolean
|
||||
|
||||
// NB type parameters can't be top-level classifiers in supetypes of a class
|
||||
val superClasses: MutableList<IrClassSymbol>
|
||||
|
||||
var thisReceiver: IrValueParameter?
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,8 @@ class IrClassImpl(
|
||||
|
||||
override val typeParameters: MutableList<IrTypeParameter> = SmartList()
|
||||
|
||||
override val superClasses: MutableList<IrClassSymbol> = SmartList()
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitClass(this, data)
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class DeclarationStubGenerator(
|
||||
val symbolTable: SymbolTable,
|
||||
@@ -56,7 +57,7 @@ class DeclarationStubGenerator(
|
||||
throw AssertionError("Unexpected member descriptor: $descriptor")
|
||||
}
|
||||
|
||||
fun generatePropertyStub(descriptor: PropertyDescriptor): IrProperty =
|
||||
private fun generatePropertyStub(descriptor: PropertyDescriptor): IrProperty =
|
||||
IrPropertyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor).also { irProperty ->
|
||||
val getterDescriptor = descriptor.getter
|
||||
if (getterDescriptor == null) {
|
||||
@@ -75,16 +76,16 @@ class DeclarationStubGenerator(
|
||||
generateValueParametersStubs(descriptor.valueParameters, irFunction)
|
||||
}
|
||||
|
||||
fun generateConstructorStub(descriptor: ClassConstructorDescriptor): IrConstructor =
|
||||
private fun generateConstructorStub(descriptor: ClassConstructorDescriptor): IrConstructor =
|
||||
symbolTable.declareConstructor(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor.original).also { irConstructor ->
|
||||
generateValueParametersStubs(descriptor.valueParameters, irConstructor)
|
||||
}
|
||||
|
||||
fun generateValueParametersStubs(valueParameters: Collection<ValueParameterDescriptor>, function: IrFunction) {
|
||||
private fun generateValueParametersStubs(valueParameters: Collection<ValueParameterDescriptor>, function: IrFunction) {
|
||||
valueParameters.mapTo(function.valueParameters) { generateValueParameterStub(it) }
|
||||
}
|
||||
|
||||
fun generateValueParameterStub(descriptor: ValueParameterDescriptor): IrValueParameter =
|
||||
private fun generateValueParameterStub(descriptor: ValueParameterDescriptor): IrValueParameter =
|
||||
IrValueParameterImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor).also { irValueParameter ->
|
||||
if (descriptor.declaresDefaultValue()) {
|
||||
irValueParameter.defaultValue =
|
||||
@@ -97,29 +98,36 @@ class DeclarationStubGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
fun generateClassStub(descriptor: ClassDescriptor): IrClass =
|
||||
private fun generateClassStub(descriptor: ClassDescriptor): IrClass =
|
||||
symbolTable.declareClass(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor).also { irClass ->
|
||||
// TODO get rid of code duplication, see ClassGenerator#generateClass
|
||||
descriptor.typeConstructor.supertypes.mapNotNullTo(irClass.superClasses) {
|
||||
it.constructor.declarationDescriptor?.safeAs<ClassDescriptor>()?.let {
|
||||
symbolTable.referenceClass(it)
|
||||
}
|
||||
}
|
||||
|
||||
generateTypeParameterStubs(descriptor.declaredTypeParameters, irClass)
|
||||
generateChildStubs(descriptor.constructors, irClass)
|
||||
generateMemberStubs(descriptor.defaultType.memberScope, irClass)
|
||||
generateMemberStubs(descriptor.staticScope, irClass)
|
||||
}
|
||||
|
||||
fun generateEnumEntryStub(descriptor: ClassDescriptor): IrEnumEntry =
|
||||
private fun generateEnumEntryStub(descriptor: ClassDescriptor): IrEnumEntry =
|
||||
symbolTable.declareEnumEntry(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor)
|
||||
|
||||
fun generateTypeParameterStubs(typeParameters: List<TypeParameterDescriptor>, container: IrTypeParametersContainer) {
|
||||
private fun generateTypeParameterStubs(typeParameters: List<TypeParameterDescriptor>, container: IrTypeParametersContainer) {
|
||||
typeParameters.mapTo(container.typeParameters) { generateTypeParameterStub(it) }
|
||||
}
|
||||
|
||||
fun generateTypeParameterStub(descriptor: TypeParameterDescriptor): IrTypeParameter =
|
||||
private fun generateTypeParameterStub(descriptor: TypeParameterDescriptor): IrTypeParameter =
|
||||
IrTypeParameterImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor)
|
||||
|
||||
fun generateMemberStubs(memberScope: MemberScope, container: IrDeclarationContainer) {
|
||||
private fun generateMemberStubs(memberScope: MemberScope, container: IrDeclarationContainer) {
|
||||
generateChildStubs(memberScope.getContributedDescriptors(), container)
|
||||
}
|
||||
|
||||
fun generateChildStubs(descriptors: Collection<DeclarationDescriptor>, container: IrDeclarationContainer) {
|
||||
private fun generateChildStubs(descriptors: Collection<DeclarationDescriptor>, container: IrDeclarationContainer) {
|
||||
descriptors.sortedWith(StableDescriptorsComparator).mapTo(container.declarations) { generateMemberStub(it) }
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||
@@ -96,6 +97,19 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
|
||||
).apply {
|
||||
thisReceiver = declaration.thisReceiver?.withDescriptor(descriptor.thisAsReceiverParameter)
|
||||
transformTypeParameters(declaration, descriptor.declaredTypeParameters)
|
||||
|
||||
descriptor.typeConstructor.supertypes.forEachIndexed { index, supertype ->
|
||||
val superclassDescriptor = supertype.constructor.declarationDescriptor
|
||||
if (superclassDescriptor is ClassDescriptor) {
|
||||
val oldSuperclassSymbol = declaration.superClasses.getOrNull(index)
|
||||
val newSuperclassSymbol =
|
||||
if (superclassDescriptor == oldSuperclassSymbol?.descriptor)
|
||||
oldSuperclassSymbol
|
||||
else
|
||||
IrClassSymbolImpl(superclassDescriptor)
|
||||
superClasses.add(newSuperclassSymbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrValueParameter.withDescriptor(newDescriptor: ParameterDescriptor) =
|
||||
|
||||
@@ -88,6 +88,9 @@ open class DeepCopyIrTreeWithSymbols(private val symbolRemapper: SymbolRemapper)
|
||||
mapDeclarationOrigin(declaration.origin),
|
||||
symbolRemapper.getDeclaredClass(declaration.symbol)
|
||||
).apply {
|
||||
declaration.superClasses.mapTo(superClasses) {
|
||||
symbolRemapper.getReferencedClass(it)
|
||||
}
|
||||
thisReceiver = declaration.thisReceiver?.transform()
|
||||
declaration.typeParameters.transformTo(typeParameters)
|
||||
declaration.transformDeclarationsTo(this)
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
|
||||
|
||||
class DependenciesCollector {
|
||||
private val modulesForDependencyDescriptors = LinkedHashSet<ModuleDescriptor>()
|
||||
@@ -41,6 +42,14 @@ class DependenciesCollector {
|
||||
assert(symbolTable.unboundValueParameters.isEmpty()) { "Unbound value parameters: ${symbolTable.unboundValueParameters}" }
|
||||
assert(symbolTable.unboundVariables.isEmpty()) { "Unbound variables: ${symbolTable.unboundVariables}" }
|
||||
|
||||
for (unboundClass in symbolTable.unboundClasses.toTypedArray()) {
|
||||
for (superClassifier in unboundClass.descriptor.getAllSuperClassifiers()) {
|
||||
if (superClassifier is ClassDescriptor) {
|
||||
symbolTable.referenceClass(superClassifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
symbolTable.unboundClasses.addTopLevelDeclarations()
|
||||
symbolTable.unboundConstructors.addTopLevelDeclarations()
|
||||
symbolTable.unboundEnumEntries.addTopLevelDeclarations()
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.util
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.SourceManager
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrBindableSymbol
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
@@ -78,6 +80,7 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
|
||||
override fun visitClass(declaration: IrClass, data: String) {
|
||||
declaration.dumpLabeledElementWith(data) {
|
||||
declaration.thisReceiver?.accept(this, "\$this")
|
||||
declaration.superClasses.renderDeclarationElementsOrDescriptors("superClasses")
|
||||
declaration.typeParameters.dumpElements()
|
||||
declaration.declarations.dumpElements()
|
||||
}
|
||||
@@ -85,16 +88,7 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
|
||||
|
||||
override fun visitSimpleFunction(declaration: IrSimpleFunction, data: String) {
|
||||
declaration.dumpLabeledElementWith(data) {
|
||||
if (declaration.overriddenSymbols.isNotEmpty()) {
|
||||
indented("overridden") {
|
||||
for (overriddenSymbol in declaration.overriddenSymbols) {
|
||||
if (overriddenSymbol.isBound)
|
||||
overriddenSymbol.owner.render()
|
||||
else
|
||||
printer.println("UNBOUND: ", DescriptorRenderer.COMPACT.render(overriddenSymbol.descriptor))
|
||||
}
|
||||
}
|
||||
}
|
||||
declaration.overriddenSymbols.renderDeclarationElementsOrDescriptors("overridden")
|
||||
declaration.typeParameters.dumpElements()
|
||||
declaration.dispatchReceiverParameter?.accept(this, "\$this")
|
||||
declaration.extensionReceiverParameter?.accept(this, "\$receiver")
|
||||
@@ -103,6 +97,25 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
|
||||
}
|
||||
}
|
||||
|
||||
private fun <D : DeclarationDescriptor, B : IrSymbolOwner> Collection<IrBindableSymbol<D, B>>.renderDeclarationElementsOrDescriptors(
|
||||
caption: String
|
||||
) {
|
||||
if (isNotEmpty()) {
|
||||
indented(caption) {
|
||||
for (symbol in this) {
|
||||
symbol.renderDeclarationElementOrDescriptor()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <D : DeclarationDescriptor, B : IrSymbolOwner> IrBindableSymbol<D, B>.renderDeclarationElementOrDescriptor() {
|
||||
if (isBound)
|
||||
owner.render()
|
||||
else
|
||||
printer.println("UNBOUND: ", DescriptorRenderer.COMPACT.render(descriptor))
|
||||
}
|
||||
|
||||
override fun visitConstructor(declaration: IrConstructor, data: String) {
|
||||
declaration.dumpLabeledElementWith(data) {
|
||||
declaration.typeParameters.dumpElements()
|
||||
|
||||
Reference in New Issue
Block a user