Generate references to superclasses

This commit is contained in:
Dmitry Petrov
2018-02-16 15:15:19 +03:00
parent e5295d0f78
commit d29a47ec7f
9 changed files with 83 additions and 25 deletions
@@ -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
)
@@ -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()