[FIR generator] Move Implementation.Kind to common module

This is a step towards commonizing the code generator between
FIR and IR: KT-61970
This commit is contained in:
Sergej Jaskiewicz
2023-09-04 20:23:25 +02:00
committed by Space Team
parent e62343427d
commit 0dd01279da
13 changed files with 95 additions and 64 deletions
@@ -6,8 +6,8 @@
package org.jetbrains.kotlin.fir.tree.generator
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeImplementationConfigurator
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation.Kind.Object
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation.Kind.OpenClass
import org.jetbrains.kotlin.generators.tree.ImplementationKind.Object
import org.jetbrains.kotlin.generators.tree.ImplementationKind.OpenClass
object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() {
fun configureImplementations() {
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.tree.generator.context
import org.jetbrains.kotlin.fir.tree.generator.model.*
import org.jetbrains.kotlin.generators.tree.ImplementationKind
import org.jetbrains.kotlin.generators.tree.Importable
abstract class AbstractFieldConfigurator<T : AbstractFirTreeBuilder>(private val builder: T) {
@@ -67,11 +68,11 @@ abstract class AbstractFieldConfigurator<T : AbstractFirTreeBuilder>(private val
}
fun shouldBeAnInterface() {
element.kind = Implementation.Kind.Interface
element.kind = ImplementationKind.Interface
}
fun shouldBeAbstractClass() {
element.kind = Implementation.Kind.AbstractClass
element.kind = ImplementationKind.AbstractClass
}
}
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.tree.generator.constructClassLikeTypeImport
import org.jetbrains.kotlin.fir.tree.generator.model.*
import org.jetbrains.kotlin.fir.tree.generator.printer.call
import org.jetbrains.kotlin.fir.tree.generator.standardClassIdsType
import org.jetbrains.kotlin.generators.tree.ImplementationKind
import org.jetbrains.kotlin.generators.tree.Importable
abstract class AbstractFirTreeImplementationConfigurator {
@@ -180,7 +181,7 @@ abstract class AbstractFirTreeImplementationConfigurator {
}
}
var kind: Implementation.Kind?
var kind: ImplementationKind?
get() = implementation.kind
set(value) {
implementation.kind = value
@@ -9,14 +9,11 @@ import org.jetbrains.kotlin.fir.tree.generator.printer.BASE_PACKAGE
import org.jetbrains.kotlin.fir.tree.generator.printer.typeWithArguments
import org.jetbrains.kotlin.fir.tree.generator.util.set
import org.jetbrains.kotlin.generators.tree.FieldContainer
import org.jetbrains.kotlin.generators.tree.ImplementationKind
import org.jetbrains.kotlin.generators.tree.Importable
import org.jetbrains.kotlin.generators.tree.ImplementationKindOwner
interface KindOwner : Importable {
var kind: Implementation.Kind?
val allParents: List<KindOwner>
}
interface AbstractElement : FieldContainer, KindOwner {
interface AbstractElement : FieldContainer, ImplementationKindOwner {
val name: String
val fields: Set<Field>
val parents: List<AbstractElement>
@@ -36,16 +33,16 @@ interface AbstractElement : FieldContainer, KindOwner {
val isSealed: Boolean
get() = false
override val allParents: List<KindOwner> get() = parents
override val allParents: List<ImplementationKindOwner> get() = parents
}
class Element(override val name: String, kind: Kind) : AbstractElement {
companion object {
private val allowedKinds = setOf(
Implementation.Kind.Interface,
Implementation.Kind.SealedInterface,
Implementation.Kind.AbstractClass,
Implementation.Kind.SealedClass
ImplementationKind.Interface,
ImplementationKind.SealedInterface,
ImplementationKind.AbstractClass,
ImplementationKind.SealedClass
)
}
@@ -58,7 +55,7 @@ class Element(override val name: String, kind: Kind) : AbstractElement {
override val customImplementations = mutableListOf<Implementation>()
override val typeArguments = mutableListOf<TypeArgument>()
override val parentsArguments = mutableMapOf<AbstractElement, MutableMap<Importable, Importable>>()
override var kind: Implementation.Kind? = null
override var kind: ImplementationKind? = null
set(value) {
if (value !in allowedKinds) {
throw IllegalArgumentException(value.toString())
@@ -5,31 +5,29 @@
package org.jetbrains.kotlin.fir.tree.generator.model
import org.jetbrains.kotlin.generators.tree.ArbitraryImportable
import org.jetbrains.kotlin.generators.tree.FieldContainer
import org.jetbrains.kotlin.generators.tree.Importable
import org.jetbrains.kotlin.generators.tree.*
class ImplementationWithArg(
val implementation: Implementation,
val argument: Importable?
) : FieldContainer by implementation, KindOwner by implementation {
) : FieldContainer by implementation, ImplementationKindOwner by implementation {
val element: Element get() = implementation.element
}
class Implementation(val element: Element, val name: String?) : FieldContainer, KindOwner {
class Implementation(val element: Element, val name: String?) : FieldContainer, ImplementationKindOwner {
private val _parents = mutableListOf<ImplementationWithArg>()
val parents: List<ImplementationWithArg> get() = _parents
override val allParents: List<KindOwner> get() = listOf(element) + parents
override val allParents: List<ImplementationKindOwner> get() = listOf(element) + parents
val isDefault = name == null
override val type = name ?: element.type + "Impl"
override val allFields = element.allFields.toMutableList().mapTo(mutableListOf()) {
FieldWithDefault(it)
}
override var kind: Kind? = null
override var kind: ImplementationKind? = null
set(value) {
field = value
if (kind != Kind.FinalClass) {
if (kind != ImplementationKind.FinalClass) {
isPublic = true
}
if (value?.hasLeafBuilder == true) {
@@ -78,13 +76,7 @@ class Implementation(val element: Element, val name: String?) : FieldContainer,
val fieldsWithoutDefault by lazy { allFields.filter { it.defaultValueInImplementation == null } }
val fieldsWithDefault by lazy { allFields.filter { it.defaultValueInImplementation != null } }
enum class Kind(val title: String, val hasLeafBuilder: Boolean, val isInterface: Boolean) {
Interface("interface", hasLeafBuilder = false, isInterface = true),
FinalClass("class", hasLeafBuilder = true, isInterface = false),
OpenClass("open class", hasLeafBuilder = true, isInterface = false),
AbstractClass("abstract class", hasLeafBuilder = false, isInterface = false),
SealedClass("sealed class", hasLeafBuilder = false, isInterface = false),
SealedInterface("sealed interface", hasLeafBuilder = false, isInterface = true),
Object("object", hasLeafBuilder = false, isInterface = false),
}
}
val ImplementationKind.hasLeafBuilder: Boolean
get() = this == ImplementationKind.FinalClass || this == ImplementationKind.OpenClass
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.fir.tree.generator.printer
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder
import org.jetbrains.kotlin.fir.tree.generator.model.Element
import org.jetbrains.kotlin.fir.tree.generator.model.Field
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation.Kind
import org.jetbrains.kotlin.generators.tree.ImplementationKind
import org.jetbrains.kotlin.generators.tree.Importable
import org.jetbrains.kotlin.fir.tree.generator.pureAbstractElementType
import org.jetbrains.kotlin.fir.tree.generator.util.get
@@ -37,7 +37,7 @@ fun Element.generateCode(generationPath: File): GeneratedFile {
fun SmartPrinter.printElement(element: Element) {
with(element) {
val isInterface = kind == Kind.Interface || kind == Kind.SealedInterface
val isInterface = kind == ImplementationKind.Interface || kind == ImplementationKind.SealedInterface
fun abstract() {
if (!isInterface) {
print("abstract ")
@@ -54,7 +54,7 @@ fun SmartPrinter.printElement(element: Element) {
if (typeArguments.isNotEmpty()) {
print(typeArguments.joinToString(", ", "<", ">") { it.toString() })
}
val needPureAbstractElement = !isInterface && !allParents.any { it.kind == Kind.AbstractClass || it.kind == Kind.SealedClass }
val needPureAbstractElement = !isInterface && !allParents.any { it.kind == ImplementationKind.AbstractClass || it.kind == ImplementationKind.SealedClass }
if (parents.isNotEmpty() || needPureAbstractElement) {
print(" : ")
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.fir.tree.generator.printer
import org.jetbrains.kotlin.fir.tree.generator.model.*
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation.Kind
import org.jetbrains.kotlin.generators.tree.ImplementationKind
import org.jetbrains.kotlin.fir.tree.generator.pureAbstractElementType
import org.jetbrains.kotlin.generators.tree.Importable
import org.jetbrains.kotlin.utils.SmartPrinter
@@ -70,8 +70,8 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
print("${kind!!.title} $type")
print(element.typeParameters)
val isInterface = kind == Kind.Interface || kind == Kind.SealedInterface
val isAbstract = kind == Kind.AbstractClass || kind == Kind.SealedClass
val isInterface = kind == ImplementationKind.Interface || kind == ImplementationKind.SealedInterface
val isAbstract = kind == ImplementationKind.AbstractClass || kind == ImplementationKind.SealedClass
fun abstract() {
if (isAbstract) {
@@ -97,7 +97,7 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
}
print(" : ")
if (!isInterface && !allParents.any { it.kind == Kind.AbstractClass || it.kind == Kind.SealedClass }) {
if (!isInterface && !allParents.any { it.kind == ImplementationKind.AbstractClass || it.kind == ImplementationKind.SealedClass }) {
print("${pureAbstractElementType.type}(), ")
}
print(allParents.joinToString { "${it.typeWithArguments}${it.kind.braces()}" })
@@ -8,9 +8,10 @@ package org.jetbrains.kotlin.fir.tree.generator.printer
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder
import org.jetbrains.kotlin.fir.tree.generator.firImplementationDetailType
import org.jetbrains.kotlin.fir.tree.generator.model.*
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation.Kind
import org.jetbrains.kotlin.generators.tree.ImplementationKind
import org.jetbrains.kotlin.fir.tree.generator.pureAbstractElementType
import org.jetbrains.kotlin.generators.tree.Importable
import org.jetbrains.kotlin.generators.tree.ImplementationKindOwner
import java.io.File
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
@@ -113,8 +114,8 @@ private fun List<String>.filterRedundantImports(
}
val KindOwner.needPureAbstractElement: Boolean
get() = (kind != Kind.Interface && kind != Kind.SealedInterface) && !allParents.any { it.kind == Kind.AbstractClass || it.kind == Kind.SealedClass }
val ImplementationKindOwner.needPureAbstractElement: Boolean
get() = (kind != ImplementationKind.Interface && kind != ImplementationKind.SealedInterface) && !allParents.any { it.kind == ImplementationKind.AbstractClass || it.kind == ImplementationKind.SealedClass }
val Field.isVal: Boolean
@@ -159,9 +160,9 @@ fun Element.multipleUpperBoundsList(): String {
} ?: " "
}
fun Kind?.braces(): String = when (this) {
Kind.Interface, Kind.SealedInterface -> ""
Kind.OpenClass, Kind.AbstractClass, Kind.SealedClass -> "()"
fun ImplementationKind?.braces(): String = when (this) {
ImplementationKind.Interface, ImplementationKind.SealedInterface -> ""
ImplementationKind.OpenClass, ImplementationKind.AbstractClass, ImplementationKind.SealedClass -> "()"
else -> throw IllegalStateException(this.toString())
}
@@ -6,14 +6,14 @@
package org.jetbrains.kotlin.fir.tree.generator.util
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation
import org.jetbrains.kotlin.generators.tree.ImplementationKind
import java.io.File
// It's used to generate a graph in dot format (it's useful for debugging)
@Suppress("unused")
fun printHierarchyGraph(builder: AbstractFirTreeBuilder) {
fun Implementation.Kind.toColor(): String = when (this) {
Implementation.Kind.Interface -> "green"
fun ImplementationKind.toColor(): String = when (this) {
ImplementationKind.Interface -> "green"
else -> "red"
}
@@ -25,7 +25,7 @@ fun printHierarchyGraph(builder: AbstractFirTreeBuilder) {
}
}
val (interfaces, classes) = elements.partition { it.kind == Implementation.Kind.Interface }
val (interfaces, classes) = elements.partition { it.kind == ImplementationKind.Interface }
println("Interfaces: ${interfaces.size}")
println("Classes: ${classes.size}")
@@ -6,14 +6,13 @@
package org.jetbrains.kotlin.fir.tree.generator.util
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder
import org.jetbrains.kotlin.fir.tree.generator.model.Element
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation
import org.jetbrains.kotlin.fir.tree.generator.model.ImplementationWithArg
import org.jetbrains.kotlin.fir.tree.generator.model.KindOwner
import org.jetbrains.kotlin.fir.tree.generator.model.*
import org.jetbrains.kotlin.generators.tree.ImplementationKindOwner
import org.jetbrains.kotlin.generators.tree.ImplementationKind
import org.jetbrains.kotlin.generators.util.Node
import org.jetbrains.kotlin.generators.util.solveGraphForClassVsInterface
private class NodeImpl(val element: KindOwner) : Node {
private class NodeImpl(val element: ImplementationKindOwner) : Node {
override val parents: List<Node>
get() = element.allParents.map(::NodeImpl)
@@ -51,23 +50,23 @@ private fun updateKinds(nodes: List<NodeImpl>, solution: List<Boolean>) {
val element = node.element
val existingKind = element.kind
if (isClass) {
if (existingKind == Implementation.Kind.Interface)
if (existingKind == ImplementationKind.Interface)
throw IllegalStateException(element.toString())
if (existingKind == null) {
element.kind = when (element) {
is Implementation -> {
if (node in allParents)
Implementation.Kind.AbstractClass
ImplementationKind.AbstractClass
else
Implementation.Kind.FinalClass
ImplementationKind.FinalClass
}
is Element -> Implementation.Kind.AbstractClass
is Element -> ImplementationKind.AbstractClass
else -> throw IllegalStateException()
}
}
} else {
element.kind = Implementation.Kind.Interface
element.kind = ImplementationKind.Interface
}
}
}
@@ -78,8 +77,8 @@ private fun updateSealedKinds(nodes: Collection<NodeImpl>) {
if (element is Element) {
if (element.isSealed) {
element.kind = when (element.kind) {
Implementation.Kind.AbstractClass -> Implementation.Kind.SealedClass
Implementation.Kind.Interface -> Implementation.Kind.SealedInterface
ImplementationKind.AbstractClass -> ImplementationKind.SealedClass
ImplementationKind.Interface -> ImplementationKind.SealedInterface
else -> error("element $element with kind ${element.kind} can not be sealed")
}
}
@@ -87,4 +86,4 @@ private fun updateSealedKinds(nodes: Collection<NodeImpl>) {
}
}
private val KindOwner.origin: KindOwner get() = if (this is ImplementationWithArg) implementation else this
private val ImplementationKindOwner.origin: ImplementationKindOwner get() = if (this is ImplementationWithArg) implementation else this
@@ -0,0 +1,19 @@
/*
* Copyright 2010-2023 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.generators.tree
enum class ImplementationKind(val title: String, val typeKind: TypeKind) {
Interface("interface", TypeKind.Interface),
FinalClass("class", TypeKind.Class),
OpenClass("open class", TypeKind.Class),
AbstractClass("abstract class", TypeKind.Class),
SealedClass("sealed class", TypeKind.Class),
SealedInterface("sealed interface", TypeKind.Interface),
Object("object", TypeKind.Class);
val isInterface: Boolean
get() = typeKind == TypeKind.Interface
}
@@ -0,0 +1,11 @@
/*
* Copyright 2010-2023 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.generators.tree
interface ImplementationKindOwner : Importable {
var kind: ImplementationKind?
val allParents: List<ImplementationKindOwner>
}
@@ -0,0 +1,10 @@
/*
* Copyright 2010-2023 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.generators.tree
enum class TypeKind {
Class, Interface
}