[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:
committed by
Space Team
parent
e62343427d
commit
0dd01279da
+2
-2
@@ -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() {
|
||||
|
||||
+3
-2
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -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
-12
@@ -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())
|
||||
|
||||
+9
-17
@@ -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
|
||||
|
||||
+3
-3
@@ -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(" : ")
|
||||
|
||||
+4
-4
@@ -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()}" })
|
||||
|
||||
+7
-6
@@ -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())
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -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}")
|
||||
|
||||
|
||||
+12
-13
@@ -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
|
||||
|
||||
+19
@@ -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
|
||||
}
|
||||
+11
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user