[FIR] Reorganize some utility code of tree generator
This commit is contained in:
+1
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeImplementa
|
|||||||
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation
|
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation
|
||||||
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation.Kind.Object
|
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.fir.tree.generator.model.Implementation.Kind.OpenClass
|
||||||
|
import org.jetbrains.kotlin.fir.tree.generator.util.traverseParents
|
||||||
|
|
||||||
object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() {
|
object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() {
|
||||||
private lateinit var abstractAnnotatedElement: Implementation
|
private lateinit var abstractAnnotatedElement: Implementation
|
||||||
|
|||||||
+3
-109
@@ -5,10 +5,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.tree.generator
|
package org.jetbrains.kotlin.fir.tree.generator
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder
|
|
||||||
import org.jetbrains.kotlin.fir.tree.generator.model.*
|
|
||||||
import org.jetbrains.kotlin.fir.tree.generator.printer.GENERATED_MESSAGE
|
|
||||||
import org.jetbrains.kotlin.fir.tree.generator.printer.printElements
|
import org.jetbrains.kotlin.fir.tree.generator.printer.printElements
|
||||||
|
import org.jetbrains.kotlin.fir.tree.generator.util.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
@@ -22,110 +20,6 @@ fun main(args: Array<String>) {
|
|||||||
configureInterfacesAndAbstractClasses(FirTreeBuilder)
|
configureInterfacesAndAbstractClasses(FirTreeBuilder)
|
||||||
removePreviousGeneratedFiles(generationPath)
|
removePreviousGeneratedFiles(generationPath)
|
||||||
printElements(FirTreeBuilder, generationPath)
|
printElements(FirTreeBuilder, generationPath)
|
||||||
// printTable(FirTreeBuilder)
|
// printFieldUsageTable(FirTreeBuilder)
|
||||||
// printInterfaceClassGraph(FirTreeBuilder)
|
// printHierarchyGraph(FirTreeBuilder)
|
||||||
}
|
|
||||||
|
|
||||||
fun Element.traverseParents(block: (Element) -> Unit) {
|
|
||||||
block(this)
|
|
||||||
parents.forEach { it.traverseParents(block) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun printInterfaceClassGraph(builder: AbstractFirTreeBuilder) {
|
|
||||||
fun Implementation.Kind.toColor(): String = when (this) {
|
|
||||||
Implementation.Kind.Interface -> "green"
|
|
||||||
else -> "red"
|
|
||||||
}
|
|
||||||
val elements = builder.elements + builder.elements.flatMap { it.allParents }
|
|
||||||
|
|
||||||
data class Edge(val from: String, val to: String) {
|
|
||||||
override fun toString(): String {
|
|
||||||
return "$from -> $to"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
File("FirTree.dot").printWriter().use { printer ->
|
|
||||||
with(printer) {
|
|
||||||
println("digraph FirTree {")
|
|
||||||
elements.forEach {
|
|
||||||
println(" ${it.type} [color=${it.kind!!.toColor()}]")
|
|
||||||
}
|
|
||||||
println()
|
|
||||||
val edges = mutableSetOf<Edge>()
|
|
||||||
elements.forEach { element ->
|
|
||||||
element.allParents.forEach { parent ->
|
|
||||||
edges += Edge(parent.type, element.type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
edges.forEach {
|
|
||||||
print(" ")
|
|
||||||
println(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
println("}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun detectBaseTransformerTypes(builder: AbstractFirTreeBuilder) {
|
|
||||||
val usedAsFieldType = mutableMapOf<AbstractElement, Boolean>().withDefault { false }
|
|
||||||
for (element in builder.elements) {
|
|
||||||
for (field in element.allFirFields) {
|
|
||||||
val fieldElement = when (field) {
|
|
||||||
is FirField -> field.element
|
|
||||||
is FieldList -> field.baseType as Element
|
|
||||||
else -> throw IllegalArgumentException()
|
|
||||||
}
|
|
||||||
usedAsFieldType[fieldElement] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (element in builder.elements) {
|
|
||||||
element.traverseParents {
|
|
||||||
if (usedAsFieldType.getValue(it)) {
|
|
||||||
element.baseTransformerType = it
|
|
||||||
return@traverseParents
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun removePreviousGeneratedFiles(generationPath: File) {
|
|
||||||
generationPath.walkTopDown().forEach {
|
|
||||||
if (it.isFile && it.readText().contains(GENERATED_MESSAGE)) {
|
|
||||||
it.delete()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun printTable(builder: AbstractFirTreeBuilder) {
|
|
||||||
val elements = builder.elements.filter { it.allImplementations.isNotEmpty() }
|
|
||||||
val fields = elements.flatMapTo(mutableSetOf()) { it.allFields }
|
|
||||||
|
|
||||||
val mapping = mutableMapOf<Element, Set<Field>>()
|
|
||||||
val fieldsCount = mutableMapOf<Field, Int>()
|
|
||||||
for (element in elements) {
|
|
||||||
val containingFields = mutableSetOf<Field>()
|
|
||||||
for (field in fields) {
|
|
||||||
if (field in element.allFields) {
|
|
||||||
containingFields += field
|
|
||||||
fieldsCount[field] = fieldsCount.getOrDefault(field, 0) + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mapping[element] = containingFields
|
|
||||||
}
|
|
||||||
|
|
||||||
val sortedFields = fields.sortedByDescending { fieldsCount[it] }
|
|
||||||
File("compiler/fir/tree/table.csv").printWriter().use { printer ->
|
|
||||||
with(printer) {
|
|
||||||
val delim = ","
|
|
||||||
print(delim)
|
|
||||||
println(sortedFields.joinToString(delim) { "${it.name}:${fieldsCount.getValue(it)}" })
|
|
||||||
for (element in elements) {
|
|
||||||
print(element.name + delim)
|
|
||||||
val containingFields = mapping.getValue(element)
|
|
||||||
println(sortedFields.joinToString(delim) { if (it in containingFields) "+" else "-" })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.fir.tree.generator.util
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder
|
||||||
|
import org.jetbrains.kotlin.fir.tree.generator.model.AbstractElement
|
||||||
|
import org.jetbrains.kotlin.fir.tree.generator.model.Element
|
||||||
|
import org.jetbrains.kotlin.fir.tree.generator.model.FieldList
|
||||||
|
import org.jetbrains.kotlin.fir.tree.generator.model.FirField
|
||||||
|
|
||||||
|
fun detectBaseTransformerTypes(builder: AbstractFirTreeBuilder) {
|
||||||
|
val usedAsFieldType = mutableMapOf<AbstractElement, Boolean>().withDefault { false }
|
||||||
|
for (element in builder.elements) {
|
||||||
|
for (field in element.allFirFields) {
|
||||||
|
val fieldElement = when (field) {
|
||||||
|
is FirField -> field.element
|
||||||
|
is FieldList -> field.baseType as Element
|
||||||
|
else -> throw IllegalArgumentException()
|
||||||
|
}
|
||||||
|
usedAsFieldType[fieldElement] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (element in builder.elements) {
|
||||||
|
element.traverseParents {
|
||||||
|
if (usedAsFieldType.getValue(it)) {
|
||||||
|
element.baseTransformerType = it
|
||||||
|
return@traverseParents
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.fir.tree.generator.util
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.tree.generator.printer.GENERATED_MESSAGE
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
fun removePreviousGeneratedFiles(generationPath: File) {
|
||||||
|
generationPath.walkTopDown().forEach {
|
||||||
|
if (it.isFile && it.readText().contains(GENERATED_MESSAGE)) {
|
||||||
|
it.delete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.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.Field
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
fun printFieldUsageTable(builder: AbstractFirTreeBuilder) {
|
||||||
|
val elements = builder.elements.filter { it.allImplementations.isNotEmpty() }
|
||||||
|
val fields = elements.flatMapTo(mutableSetOf()) { it.allFields }
|
||||||
|
|
||||||
|
val mapping = mutableMapOf<Element, Set<Field>>()
|
||||||
|
val fieldsCount = mutableMapOf<Field, Int>()
|
||||||
|
for (element in elements) {
|
||||||
|
val containingFields = mutableSetOf<Field>()
|
||||||
|
for (field in fields) {
|
||||||
|
if (field in element.allFields) {
|
||||||
|
containingFields += field
|
||||||
|
fieldsCount[field] = fieldsCount.getOrDefault(field, 0) + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mapping[element] = containingFields
|
||||||
|
}
|
||||||
|
|
||||||
|
val sortedFields = fields.sortedByDescending { fieldsCount[it] }
|
||||||
|
File("compiler/fir/tree/table.csv").printWriter().use { printer ->
|
||||||
|
with(printer) {
|
||||||
|
val delim = ","
|
||||||
|
print(delim)
|
||||||
|
println(sortedFields.joinToString(delim) { "${it.name}:${fieldsCount.getValue(it)}" })
|
||||||
|
for (element in elements) {
|
||||||
|
print(element.name + delim)
|
||||||
|
val containingFields = mapping.getValue(element)
|
||||||
|
println(sortedFields.joinToString(delim) { if (it in containingFields) "+" else "-" })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.fir.tree.generator.util
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder
|
||||||
|
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
fun printHierarchyGraph(builder: AbstractFirTreeBuilder) {
|
||||||
|
fun Implementation.Kind.toColor(): String = when (this) {
|
||||||
|
Implementation.Kind.Interface -> "green"
|
||||||
|
else -> "red"
|
||||||
|
}
|
||||||
|
|
||||||
|
val elements = builder.elements + builder.elements.flatMap { it.allParents }
|
||||||
|
|
||||||
|
data class Edge(val from: String, val to: String) {
|
||||||
|
override fun toString(): String {
|
||||||
|
return "$from -> $to"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
File("FirTree.dot").printWriter().use { printer ->
|
||||||
|
with(printer) {
|
||||||
|
println("digraph FirTree {")
|
||||||
|
elements.forEach {
|
||||||
|
println(" ${it.type} [color=${it.kind!!.toColor()}]")
|
||||||
|
}
|
||||||
|
println()
|
||||||
|
val edges = mutableSetOf<Edge>()
|
||||||
|
elements.forEach { element ->
|
||||||
|
element.allParents.forEach { parent ->
|
||||||
|
edges += Edge(parent.type, element.type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
edges.forEach {
|
||||||
|
print(" ")
|
||||||
|
println(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
println("}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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.fir.tree.generator
|
package org.jetbrains.kotlin.fir.tree.generator.util
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeBuilder
|
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.Element
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.fir.tree.generator.util
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.tree.generator.model.Element
|
||||||
|
|
||||||
|
fun Element.traverseParents(block: (Element) -> Unit) {
|
||||||
|
block(this)
|
||||||
|
parents.forEach { it.traverseParents(block) }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user