IrTypes: IrClass.superTypes, IrTypeParameter.superTypes

This commit is contained in:
Dmitry Petrov
2018-05-21 15:20:01 +03:00
parent 353076f596
commit 0ffef64428
11 changed files with 72 additions and 113 deletions
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.backend.common.descriptors.substitute
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.*
@@ -28,15 +27,17 @@ import org.jetbrains.kotlin.ir.expressions.putTypeArguments
import org.jetbrains.kotlin.ir.expressions.typeParametersCount
import org.jetbrains.kotlin.ir.util.StableDescriptorsComparator
import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides
import org.jetbrains.kotlin.ir.util.isEnumClass
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
import org.jetbrains.kotlin.psi.KtEnumEntry
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeProjectionImpl
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.kotlin.utils.newHashMapWithExpectedSize
import java.lang.AssertionError
@@ -46,27 +47,25 @@ class ClassGenerator(
) : DeclarationGeneratorExtension(declarationGenerator) {
fun generateClass(ktClassOrObject: KtClassOrObject): IrClass {
val descriptor = getOrFail(BindingContext.CLASS, ktClassOrObject)
val classDescriptor = getOrFail(BindingContext.CLASS, ktClassOrObject)
val startOffset = ktClassOrObject.startOffset
val endOffset = ktClassOrObject.endOffset
return context.symbolTable.declareClass(
startOffset, endOffset, IrDeclarationOrigin.DEFINED, descriptor
startOffset, endOffset, IrDeclarationOrigin.DEFINED, classDescriptor
).buildWithScope { irClass ->
descriptor.typeConstructor.supertypes.mapNotNullTo(irClass.superClasses) {
it.constructor.declarationDescriptor?.safeAs<ClassDescriptor>()?.let {
context.symbolTable.referenceClass(it)
}
classDescriptor.typeConstructor.supertypes.mapTo(irClass.superTypes) {
it.toIrType()
}
irClass.thisReceiver = context.symbolTable.declareValueParameter(
startOffset, endOffset,
IrDeclarationOrigin.INSTANCE_RECEIVER,
irClass.descriptor.thisAsReceiverParameter,
irClass.descriptor.thisAsReceiverParameter.type.toIrType()
classDescriptor.thisAsReceiverParameter,
classDescriptor.thisAsReceiverParameter.type.toIrType()
)
declarationGenerator.generateGlobalTypeParametersDeclarations(irClass, descriptor.declaredTypeParameters)
declarationGenerator.generateGlobalTypeParametersDeclarations(irClass, classDescriptor.declaredTypeParameters)
val irPrimaryConstructor = generatePrimaryConstructor(irClass, ktClassOrObject)
if (irPrimaryConstructor != null) {
@@ -83,7 +82,7 @@ class ClassGenerator(
generateAdditionalMembersForDataClass(irClass, ktClassOrObject)
}
if (irClass.isEnumClass) {
if (DescriptorUtils.isEnumClass(classDescriptor)) {
generateAdditionalMembersForEnumClass(irClass)
}
}
@@ -275,8 +274,14 @@ class ClassGenerator(
return if (overridden is PropertyAccessorDescriptor)
overridden
else {
val typeArguments = zipTypeParametersToDefaultTypes(overridden, delegated)
overridden.substitute(typeArguments)
val substitutor =
TypeSubstitutor.create(
overridden.original.typeParameters.associate {
val delegatedDefaultType = delegated.typeParameters[it.index].defaultType
it.typeConstructor to TypeProjectionImpl(delegatedDefaultType)
}
)
overridden.substitute(substitutor)!!
}
}
@@ -128,24 +128,9 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
)
}
irTypeParameters.forEach {
mapSuperClassifiers(it.descriptor, it)
}
irTypeParametersOwner.typeParameters.addAll(irTypeParameters)
}
private fun mapSuperClassifiers(
descriptor: TypeParameterDescriptor,
irTypeParameter: IrTypeParameter
) {
descriptor.typeConstructor.supertypes.mapNotNullTo(irTypeParameter.superClassifiers) {
it.constructor.declarationDescriptor?.let {
context.symbolTable.referenceClassifier(it)
}
}
}
fun generateInitializerBody(scopeOwnerSymbol: IrSymbol, ktBody: KtExpression): IrExpressionBody =
createBodyGenerator(scopeOwnerSymbol).generateExpressionBody(ktBody)
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.name.Name
interface IrClass : IrSymbolDeclaration<IrClassSymbol>, IrDeclarationContainer, IrTypeParametersContainer {
@@ -35,9 +36,7 @@ interface IrClass : IrSymbolDeclaration<IrClassSymbol>, IrDeclarationContainer,
val isData: Boolean
val isExternal: Boolean
// NB type parameters can't be top-level classifiers in supetypes of a class
// TODO val superTypes: MutableList<IrType>
val superClasses: MutableList<IrClassSymbol>
val superTypes: MutableList<IrType>
var thisReceiver: IrValueParameter?
}
@@ -30,9 +30,7 @@ interface IrTypeParameter : IrSymbolDeclaration<IrTypeParameterSymbol> {
val name: Name
val variance: Variance
val index: Int
val upperBounds: List<IrType>
val superClassifiers: MutableList<IrClassifierSymbol>
val superTypes: List<IrType>
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrTypeParameter
}
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.transform
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -43,7 +44,8 @@ class IrClassImpl(
override val isInner: Boolean,
override val isData: Boolean,
override val isExternal: Boolean
) : IrDeclarationBase(startOffset, endOffset, origin),
) :
IrDeclarationBase(startOffset, endOffset, origin),
IrClass {
constructor(
@@ -71,7 +73,10 @@ class IrClassImpl(
this(startOffset, endOffset, origin, IrClassSymbolImpl(descriptor))
constructor(
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor,
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
descriptor: ClassDescriptor,
members: List<IrDeclaration>
) : this(startOffset, endOffset, origin, descriptor) {
addAll(members)
@@ -89,7 +94,7 @@ class IrClassImpl(
override val typeParameters: MutableList<IrTypeParameter> = SmartList()
override val superClasses: MutableList<IrClassSymbol> = SmartList()
override val superTypes: MutableList<IrType> = SmartList()
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitClass(this, data)
@@ -37,7 +37,7 @@ class IrTypeParameterImpl(
override val name: Name,
override val index: Int,
override val variance: Variance,
override val upperBounds: List<IrType>
override val superTypes: List<IrType>
) :
IrDeclarationBase(startOffset, endOffset, origin),
IrTypeParameter {
@@ -72,8 +72,6 @@ class IrTypeParameterImpl(
override val descriptor: TypeParameterDescriptor get() = symbol.descriptor
override val superClassifiers: MutableList<IrClassifierSymbol> = SmartList()
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitTypeParameter(this, data)
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.propertyIfAccessor
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class DeclarationStubGenerator(
moduleDescriptor: ModuleDescriptor,
@@ -134,10 +133,8 @@ class DeclarationStubGenerator(
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)
}
descriptor.typeConstructor.supertypes.mapNotNullTo(irClass.superTypes) {
it.toIrType()
}
generateTypeParameterStubs(descriptor.declaredTypeParameters, irClass)
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
inline fun <reified T : IrElement> T.deepCopyOld(): T =
@@ -100,18 +99,7 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
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)
}
}
superTypes.addAll(declaration.superTypes) // TODO
}
override fun visitTypeAlias(declaration: IrTypeAlias): IrTypeAlias =
@@ -203,19 +191,9 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
originalTypeParameter.startOffset, originalTypeParameter.endOffset,
mapDeclarationOrigin(originalTypeParameter.origin),
newTypeParameterDescriptor,
originalTypeParameter.upperBounds // TODO
originalTypeParameter.superTypes // TODO
).apply {
transformAnnotations(originalTypeParameter)
for (i in upperBounds.indices) {
val upperBoundClassifier = upperBounds[i].classifierOrFail.descriptor // TODO
val oldSuperClassifierSymbol = originalTypeParameter.superClassifiers[i]
val newSuperClassifierSymbol =
if (upperBoundClassifier == oldSuperClassifierSymbol.descriptor)
oldSuperClassifierSymbol
else
createUnboundClassifierSymbol(upperBoundClassifier)
superClassifiers.add(newSuperClassifierSymbol)
}
}
protected fun createUnboundClassifierSymbol(classifier: ClassifierDescriptor): IrClassifierSymbol =
@@ -99,8 +99,8 @@ open class DeepCopyIrTreeWithSymbols(
symbolRemapper.getDeclaredClass(declaration.symbol)
).apply {
transformAnnotations(declaration)
declaration.superClasses.mapTo(superClasses) {
symbolRemapper.getReferencedClass(it)
declaration.superTypes.mapTo(superTypes) {
it.remapType()
}
thisReceiver = declaration.thisReceiver?.transform()
declaration.typeParameters.transformTo(typeParameters)
@@ -227,12 +227,9 @@ open class DeepCopyIrTreeWithSymbols(
declaration.startOffset, declaration.endOffset,
mapDeclarationOrigin(declaration.origin),
symbolRemapper.getDeclaredTypeParameter(declaration.symbol),
declaration.upperBounds.map { it.remapType() }
declaration.superTypes.map { it.remapType() }
).apply {
transformAnnotations(declaration)
declaration.superClassifiers.mapTo(superClassifiers) {
symbolRemapper.getReferencedClassifier(it)
}
}
override fun visitValueParameter(declaration: IrValueParameter): IrValueParameter =
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.SourceManager
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
@@ -42,6 +43,7 @@ fun IrFile.dumpTreesFromLineNumber(lineNumber: Int): String {
}
class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
private val printer = Printer(out, " ")
private val elementRenderer = RenderIrElementVisitor()
@@ -70,13 +72,8 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
override fun visitFile(declaration: IrFile, data: String) {
declaration.dumpLabeledElementWith(data) {
if (declaration.fileAnnotations.isNotEmpty()) {
printer.println("fileAnnotations:")
indented {
declaration.fileAnnotations.forEach {
printer.println(ANNOTATIONS_RENDERER.renderAnnotation(it))
}
}
declaration.fileAnnotations.dumpItemsWith("fileAnnotations") {
ANNOTATIONS_RENDERER.renderAnnotation(it)
}
dumpAnnotations(declaration)
declaration.declarations.dumpElements()
@@ -87,7 +84,6 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
declaration.dumpLabeledElementWith(data) {
dumpAnnotations(declaration)
declaration.thisReceiver?.accept(this, "\$this")
declaration.superClasses.renderDeclarationElementsOrDescriptors("superClasses")
declaration.typeParameters.dumpElements()
declaration.declarations.dumpElements()
}
@@ -96,7 +92,6 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
override fun visitTypeParameter(declaration: IrTypeParameter, data: String) {
declaration.dumpLabeledElementWith(data) {
dumpAnnotations(declaration)
declaration.superClassifiers.renderDeclarationElementsOrDescriptors("superClassifiers")
}
}
@@ -104,7 +99,9 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
declaration.dumpLabeledElementWith(data) {
dumpAnnotations(declaration)
declaration.correspondingProperty?.render("correspondingProperty")
declaration.overriddenSymbols.renderDeclarationElementsOrDescriptors("overridden")
declaration.overriddenSymbols.dumpItems<IrSymbol>("overridden") {
it.dumpDeclarationElementOrDescriptor()
}
declaration.typeParameters.dumpElements()
declaration.dispatchReceiverParameter?.accept(this, "\$this")
declaration.extensionReceiverParameter?.accept(this, "\$receiver")
@@ -114,27 +111,15 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
}
private fun dumpAnnotations(element: IrAnnotationContainer) {
if (element.annotations.isNotEmpty()) {
indented("annotations") {
element.annotations.dumpElements()
}
element.annotations.dumpItems("annotations") {
element.annotations.dumpElements()
}
}
private fun Collection<IrSymbol>.renderDeclarationElementsOrDescriptors(caption: String) {
if (isNotEmpty()) {
indented(caption) {
for (symbol in this) {
symbol.renderDeclarationElementOrDescriptor()
}
}
}
}
private fun IrSymbol.renderDeclarationElementOrDescriptor(label: String? = null) {
private fun IrSymbol.dumpDeclarationElementOrDescriptor(label: String? = null) {
when {
isBound ->
owner.render(label)
owner.dumpInternal(label)
label != null ->
printer.println("$label: ", "UNBOUND: ", DescriptorRenderer.COMPACT.render(descriptor))
else ->
@@ -261,7 +246,7 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: String) {
expression.dumpLabeledElementWith(data) {
expression.typeOperandClassifier.renderDeclarationElementOrDescriptor("typeOperand")
expression.typeOperandClassifier.dumpDeclarationElementOrDescriptor("typeOperand")
expression.acceptChildren(this, "")
}
}
@@ -271,7 +256,25 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
indented(body)
}
private fun IrElement.render(label: String? = null) {
private inline fun <T> Collection<T>.dumpItems(caption: String, renderElement: (T) -> Unit) {
if (isEmpty()) return
indented(caption) {
forEach {
renderElement(it)
}
}
}
private inline fun <T> Collection<T>.dumpItemsWith(caption: String, renderElement: (T) -> String) {
if (isEmpty()) return
indented(caption) {
forEach {
printer.println(renderElement(it))
}
}
}
private fun IrElement.dumpInternal(label: String? = null) {
if (label != null) {
printer.println("$label: ", accept(elementRenderer, null))
} else {
@@ -280,13 +283,6 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
}
private fun IrElement.dumpLabeledSubTree(label: String) {
printer.println(accept(elementRenderer, null).withLabel(label))
indented {
acceptChildren(this@DumpIrTreeVisitor, "")
}
}
private inline fun indented(label: String, body: () -> Unit) {
printer.println("$label:")
indented(body)
@@ -129,7 +129,8 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
declaration.run {
"CLASS ${renderOriginIfNonTrivial()}" +
"$kind name:$name modality:$modality visibility:$visibility " +
"flags:${renderClassFlags()}"
"flags:${renderClassFlags()} " +
"superTypes:[${superTypes.joinToString(separator = "; ") { it.render() }}]"
}
private fun IrClass.renderClassFlags() =
@@ -164,7 +165,7 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
declaration.run {
"TYPE_PARAMETER ${renderOriginIfNonTrivial()}" +
"name:$name index:$index variance:$variance " +
"upperBounds:[${upperBounds.joinToString(separator = "; ") { it.render() }}]"
"superTypes:[${superTypes.joinToString(separator = "; ") { it.render() }}]"
}
override fun visitValueParameter(declaration: IrValueParameter, data: Nothing?): String =