[FIR] Remove old visitor generator and configure gradle task for tree generator
This commit is contained in:
@@ -27,25 +27,17 @@ sourceSets {
|
||||
val generatorClasspath by configurations.creating
|
||||
|
||||
dependencies {
|
||||
generatorClasspath(project("visitors-generator"))
|
||||
generatorClasspath(project("tree-generator"))
|
||||
}
|
||||
|
||||
val generateVisitors by tasks.registering(NoDebugJavaExec::class) {
|
||||
val generationRoot = "$projectDir/src/org/jetbrains/kotlin/fir/"
|
||||
val output = "$projectDir/visitors"
|
||||
|
||||
val allSourceFiles = fileTree(generationRoot) {
|
||||
include("**/*.kt")
|
||||
}
|
||||
|
||||
inputs.files(allSourceFiles)
|
||||
outputs.dirs(output)
|
||||
val generateTree by tasks.registering(NoDebugJavaExec::class) {
|
||||
val generationRoot = "$projectDir/src/"
|
||||
|
||||
args(generationRoot)
|
||||
classpath = generatorClasspath
|
||||
args(generationRoot, output)
|
||||
main = "org.jetbrains.kotlin.fir.visitors.generator.VisitorsGeneratorKt"
|
||||
main = "org.jetbrains.kotlin.fir.tree.generator.MainKt"
|
||||
}
|
||||
|
||||
val compileKotlin by tasks
|
||||
|
||||
compileKotlin.dependsOn(generateVisitors)
|
||||
compileKotlin.dependsOn(generateTree)
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2018 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.visitors.generator
|
||||
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
abstract class AbstractVisitorGenerator(val referencesData: DataCollector.ReferencesData) {
|
||||
fun Printer.generateFunction(
|
||||
name: String,
|
||||
parameters: Map<String, DataCollector.NameWithTypeParameters>,
|
||||
returnType: String,
|
||||
override: Boolean = false,
|
||||
final: Boolean = false,
|
||||
typeParametersWithBounds: List<String> = emptyList(),
|
||||
body: (Printer.() -> Unit)?
|
||||
) {
|
||||
|
||||
if (body == null) {
|
||||
print("abstract ")
|
||||
} else {
|
||||
printIndent()
|
||||
if (!final) {
|
||||
printWithNoIndent("open ")
|
||||
}
|
||||
if (override) {
|
||||
if (final) {
|
||||
printWithNoIndent("final ")
|
||||
}
|
||||
printWithNoIndent("override ")
|
||||
}
|
||||
}
|
||||
printWithNoIndent("fun ")
|
||||
if (typeParametersWithBounds.isNotEmpty()) {
|
||||
printWithNoIndent("<")
|
||||
separatedOneLine(typeParametersWithBounds, ", ")
|
||||
printWithNoIndent("> ")
|
||||
}
|
||||
printWithNoIndent(name, "(")
|
||||
parameters
|
||||
.flatMap { (parameterName, typeNameWithTypeParameters) ->
|
||||
listOf(parameterName, ": ", typeNameWithTypeParameters.asStringWithoutBounds(), ", ")
|
||||
}.dropLast(1)
|
||||
.forEach {
|
||||
printWithNoIndent(it)
|
||||
}
|
||||
printWithNoIndent(")")
|
||||
if (returnType != "Unit") {
|
||||
printWithNoIndent(": ", returnType)
|
||||
}
|
||||
if (body != null) {
|
||||
printlnWithNoIndent(" {")
|
||||
indented {
|
||||
body()
|
||||
}
|
||||
println("}")
|
||||
} else {
|
||||
printlnWithNoIndent()
|
||||
}
|
||||
println()
|
||||
}
|
||||
|
||||
protected inline fun Printer.indented(l: () -> Unit) {
|
||||
pushIndent()
|
||||
l()
|
||||
popIndent()
|
||||
}
|
||||
|
||||
protected fun Printer.generateCall(name: String, args: List<String>) {
|
||||
printWithNoIndent(name, "(")
|
||||
separatedOneLine(args, ", ")
|
||||
printWithNoIndent(")")
|
||||
}
|
||||
|
||||
private fun Printer.separatedOneLine(iterable: Iterable<Any>, separator: Any) {
|
||||
var first = true
|
||||
for (element in iterable) {
|
||||
if (!first) {
|
||||
printWithNoIndent(separator)
|
||||
} else {
|
||||
first = false
|
||||
}
|
||||
printWithNoIndent(element)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Printer.generateDefaultImports() {
|
||||
referencesData.usedPackages.forEach {
|
||||
println("import ", it.asString(), ".*")
|
||||
}
|
||||
println()
|
||||
println()
|
||||
}
|
||||
|
||||
val String.safeName
|
||||
get() = when (this) {
|
||||
"class" -> "klass"
|
||||
else -> this
|
||||
}
|
||||
|
||||
fun generate(): String {
|
||||
val builder = StringBuilder()
|
||||
val printer = Printer(builder, " ")
|
||||
printer.apply {
|
||||
println(javaClass.getResource("/notice.txt").readText())
|
||||
|
||||
println("package $VISITOR_PACKAGE")
|
||||
println()
|
||||
generateDefaultImports()
|
||||
println(WARNING_GENERATED_FILE)
|
||||
|
||||
printer.generateContent()
|
||||
}
|
||||
return builder.toString()
|
||||
}
|
||||
|
||||
|
||||
fun allElementTypes() =
|
||||
referencesData.direct.let { map ->
|
||||
map.keys + map.values.flatten()
|
||||
}.distinct()
|
||||
|
||||
abstract fun Printer.generateContent()
|
||||
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2018 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.visitors.generator
|
||||
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType
|
||||
|
||||
class DataCollector {
|
||||
|
||||
class NameWithTypeParameters private constructor(
|
||||
val name: String,
|
||||
val typeParameters: List<String>,
|
||||
private val typeParameterBounds: Map<String, String>
|
||||
) : Comparable<NameWithTypeParameters> {
|
||||
|
||||
override fun compareTo(other: NameWithTypeParameters): Int = name.compareTo(other.name)
|
||||
|
||||
private constructor(name: String, typeParameters: Pair<List<String>, Map<String, String>>) :
|
||||
this(name, typeParameters.first, typeParameters.second)
|
||||
|
||||
constructor(name: String, typeParameterString: String) :
|
||||
this(name, typeParameterString.splitToParametersAndBounds())
|
||||
|
||||
constructor(name: String) : this(name, emptyList(), emptyMap())
|
||||
|
||||
fun typeParametersWithBounds(): List<String> =
|
||||
typeParameters.map { parameter ->
|
||||
parameter + (typeParameterBounds[parameter]?.let { " : $it" } ?: "")
|
||||
}
|
||||
|
||||
fun asStringWithoutBounds(): String =
|
||||
name + if (typeParameters.isEmpty()) "" else typeParameters.joinToString(prefix = "<", postfix = ">", separator = ", ")
|
||||
|
||||
override fun equals(other: Any?): Boolean =
|
||||
other is NameWithTypeParameters && name == other.name
|
||||
|
||||
override fun hashCode(): Int = name.hashCode()
|
||||
|
||||
override fun toString(): String =
|
||||
name + if (typeParameters.isEmpty()) "" else typeParameters.joinToString(prefix = "<", postfix = ">", separator = ", ") {
|
||||
val bound = typeParameterBounds[it]
|
||||
if (bound == null) it else "$it : $bound"
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun String.splitToParametersAndBounds(): Pair<List<String>, Map<String, String>> {
|
||||
val typeParametersWithBounds = drop(1).dropLast(1).split(",").map { it.trim() }.filter { it.isNotBlank() }
|
||||
val typeParameters = mutableListOf<String>()
|
||||
val bounds = mutableMapOf<String, String>()
|
||||
for (parameterWithBounds in typeParametersWithBounds) {
|
||||
val parts = parameterWithBounds.split(":").map { it.trim() }
|
||||
typeParameters += parts[0]
|
||||
if (parts.size > 1) {
|
||||
bounds[parts[0]] = parts[1]
|
||||
}
|
||||
}
|
||||
return typeParameters to bounds
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val references = mutableMapOf<NameWithTypeParameters, List<NameWithTypeParameters>>()
|
||||
private val packagePerClass = mutableMapOf<NameWithTypeParameters, FqName>()
|
||||
private val baseTransformedTypes = mutableListOf<NameWithTypeParameters>()
|
||||
|
||||
private fun KtSuperTypeListEntry.toNameWithTypeParameters(): NameWithTypeParameters? {
|
||||
val type = typeAsUserType ?: return null
|
||||
val name = type.referencedName ?: return null
|
||||
val typeArguments = type.typeArgumentList?.text ?: ""
|
||||
return NameWithTypeParameters(name, typeArguments)
|
||||
}
|
||||
|
||||
fun readFile(file: KtFile) {
|
||||
file.acceptChildren(object : KtVisitorVoid() {
|
||||
|
||||
override fun visitKtElement(element: KtElement) {
|
||||
super.visitKtElement(element)
|
||||
element.acceptChildren(this)
|
||||
}
|
||||
|
||||
override fun visitClass(klass: KtClass) {
|
||||
val className = klass.name ?: run {
|
||||
super.visitClass(klass)
|
||||
return
|
||||
}
|
||||
val classNameWithParameters = NameWithTypeParameters(className, klass.typeParameterList?.text ?: "")
|
||||
if (klass.isInterface() || (klass.hasModifier(KtTokens.ABSTRACT_KEYWORD) && "Abstract" !in (klass.name ?: ""))) {
|
||||
packagePerClass[classNameWithParameters] = file.packageFqName
|
||||
val isBaseTT = klass.annotationEntries.any {
|
||||
it.shortName?.asString() == BASE_TRANSFORMED_TYPE_ANNOTATION_NAME
|
||||
}
|
||||
if (isBaseTT) {
|
||||
baseTransformedTypes += classNameWithParameters
|
||||
}
|
||||
|
||||
val manual = klass.superTypeListEntries.find {
|
||||
it.typeReference?.findDescendantOfType<KtAnnotationEntry> { annotationEntry ->
|
||||
annotationEntry.shortName?.asString() == VISITED_SUPERTYPE_ANNOTATION_NAME
|
||||
} != null
|
||||
}
|
||||
if (manual != null) {
|
||||
references[classNameWithParameters] = listOfNotNull(manual.toNameWithTypeParameters())
|
||||
} else {
|
||||
references[classNameWithParameters] =
|
||||
klass.superTypeListEntries.mapNotNull {
|
||||
it.toNameWithTypeParameters()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.visitClass(klass)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
private fun <K> Map<K, List<K>>.computeBackReferences(): Map<K, List<K>> {
|
||||
val result = mutableMapOf<K, List<K>>()
|
||||
|
||||
this.forEach { (k, v) ->
|
||||
v.forEach {
|
||||
result.merge(it, listOf(k)) { a, b -> a + b }
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun <K : Comparable<K>> Map<K, List<K>>.sortedMap(): Map<K, List<K>> {
|
||||
return this.toSortedMap().mapValues { (_, v) -> v.sorted() }
|
||||
}
|
||||
|
||||
fun computeResult(): ReferencesData {
|
||||
val back = references.computeBackReferences()
|
||||
|
||||
val keysToKeep =
|
||||
generateSequence(listOf(FIR_ELEMENT_CLASS_NAME)) { firName ->
|
||||
firName.flatMap { back[it].orEmpty() }.takeUnless { it.isEmpty() }
|
||||
}.flatten().toSet()
|
||||
|
||||
val cleanBack = back.filterKeys { it in keysToKeep }
|
||||
return ReferencesData(
|
||||
cleanBack.computeBackReferences().sortedMap(),
|
||||
cleanBack.sortedMap(),
|
||||
packagePerClass.filterKeys { it in keysToKeep }.values.distinct().sortedBy { it.asString() },
|
||||
baseTransformedTypes.sorted()
|
||||
)
|
||||
}
|
||||
|
||||
data class ReferencesData(
|
||||
val direct: Map<NameWithTypeParameters, List<NameWithTypeParameters>>,
|
||||
val back: Map<NameWithTypeParameters, List<NameWithTypeParameters>>,
|
||||
val usedPackages: List<FqName>,
|
||||
val baseTransformedTypes: List<NameWithTypeParameters>
|
||||
)
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2018 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.visitors.generator
|
||||
|
||||
import org.jetbrains.kotlin.fir.visitors.generator.DataCollector.NameWithTypeParameters
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
class ParametricTransformerGenerator(data: DataCollector.ReferencesData) : AbstractVisitorGenerator(data) {
|
||||
override fun Printer.generateContent() {
|
||||
println("abstract class $PARAMETRIC_TRANSFORMER_NAME<in D> : $SIMPLE_VISITOR_NAME<$TRANSFORMER_RESULT_NAME<$FIR_ELEMENT_CLASS_NAME>, D>() {")
|
||||
indented {
|
||||
|
||||
generateFunction(
|
||||
"transformElement",
|
||||
mapOf(
|
||||
"element" to NameWithTypeParameters("E"),
|
||||
"data" to NameWithTypeParameters("D")
|
||||
),
|
||||
constructCompositeBoxType("E"),
|
||||
typeParametersWithBounds = listOf("E : $FIR_ELEMENT_CLASS_NAME"),
|
||||
body = null
|
||||
)
|
||||
|
||||
referencesData.walkHierarchyTopDown(FIR_ELEMENT_CLASS_NAME) { parent, className ->
|
||||
generateTransformMethod(className, parent)
|
||||
}
|
||||
|
||||
allElementTypes().forEach {
|
||||
generateTrampolineVisit(it)
|
||||
}
|
||||
|
||||
}
|
||||
println("}")
|
||||
}
|
||||
|
||||
|
||||
fun constructCompositeBoxType(type: String): String {
|
||||
return "$TRANSFORMER_RESULT_NAME<$type>"
|
||||
}
|
||||
|
||||
val baseTypes = mutableMapOf<NameWithTypeParameters, NameWithTypeParameters>().also {
|
||||
for (baseTransformedType in referencesData.baseTransformedTypes) {
|
||||
it[baseTransformedType] = baseTransformedType
|
||||
}
|
||||
|
||||
data.walkHierarchyTopDown(FIR_ELEMENT_CLASS_NAME) { parent, element ->
|
||||
it[element] = it[parent] ?: return@walkHierarchyTopDown
|
||||
}
|
||||
}
|
||||
|
||||
fun Printer.generateTrampolineVisit(className: NameWithTypeParameters) {
|
||||
val shortcutName = className.name.classNameWithoutFir
|
||||
val parameterName = shortcutName.decapitalize().safeName
|
||||
generateFunction(
|
||||
name = "visit$shortcutName",
|
||||
parameters = mapOf(
|
||||
parameterName to className,
|
||||
"data" to NameWithTypeParameters("D")
|
||||
),
|
||||
returnType = constructCompositeBoxType(FIR_ELEMENT_CLASS_NAME.name),
|
||||
override = true,
|
||||
final = true,
|
||||
typeParametersWithBounds = className.typeParametersWithBounds()
|
||||
) {
|
||||
print("return ")
|
||||
generateCall("transform$shortcutName", listOf(parameterName, "data"))
|
||||
println()
|
||||
}
|
||||
}
|
||||
|
||||
fun Printer.generateTransformMethod(
|
||||
className: NameWithTypeParameters,
|
||||
parent: NameWithTypeParameters
|
||||
) {
|
||||
val baseType = baseTypes[className]
|
||||
|
||||
val shortcutName = className.name.classNameWithoutFir
|
||||
val parameterName = shortcutName.decapitalize().safeName
|
||||
if (baseType == null) {
|
||||
generateFunction(
|
||||
"transform$shortcutName",
|
||||
mapOf(
|
||||
parameterName to NameWithTypeParameters("E"),
|
||||
"data" to NameWithTypeParameters("D")
|
||||
),
|
||||
constructCompositeBoxType("E"),
|
||||
typeParametersWithBounds = listOf("E : $parent") + className.typeParametersWithBounds()
|
||||
) {
|
||||
print("return ")
|
||||
generateCall("transformElement", listOf(parameterName, "data"))
|
||||
printlnWithNoIndent()
|
||||
}
|
||||
} else {
|
||||
generateFunction(
|
||||
"transform$shortcutName",
|
||||
mapOf(
|
||||
parameterName to className,
|
||||
"data" to NameWithTypeParameters("D")
|
||||
),
|
||||
constructCompositeBoxType(baseType.name),
|
||||
typeParametersWithBounds = className.typeParametersWithBounds()
|
||||
) {
|
||||
print("return ")
|
||||
generateCall("transformElement", listOf(parameterName, "data"))
|
||||
printlnWithNoIndent()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2018 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.visitors.generator
|
||||
|
||||
import com.intellij.core.CoreApplicationEnvironment
|
||||
import com.intellij.core.CoreProjectEnvironment
|
||||
import com.intellij.lang.MetaLanguage
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
||||
|
||||
internal data class PsiSetup(
|
||||
val applicationEnvironment: CoreApplicationEnvironment,
|
||||
val projectEnvironment: CoreProjectEnvironment,
|
||||
val project: Project,
|
||||
val disposable: Disposable
|
||||
)
|
||||
|
||||
internal fun setup(): PsiSetup {
|
||||
val disposable = Disposer.newDisposable()
|
||||
|
||||
val applicationEnvironment = CoreApplicationEnvironment(disposable, false)
|
||||
|
||||
val projectEnvironment = CoreProjectEnvironment(disposable, applicationEnvironment)
|
||||
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), MetaLanguage.EP_NAME, MetaLanguage::class.java)
|
||||
|
||||
|
||||
applicationEnvironment.registerFileType(KotlinFileType.INSTANCE, "kt")
|
||||
applicationEnvironment.registerParserDefinition(KotlinParserDefinition())
|
||||
|
||||
|
||||
val project = projectEnvironment.project
|
||||
return PsiSetup(applicationEnvironment, projectEnvironment, project, disposable)
|
||||
}
|
||||
|
||||
internal inline fun <T> withPsiSetup(l: PsiSetup.() -> T): T {
|
||||
val setup = setup()
|
||||
val t = setup.l()
|
||||
Disposer.dispose(setup.disposable)
|
||||
return t
|
||||
}
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2018 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.visitors.generator
|
||||
|
||||
import org.jetbrains.kotlin.fir.visitors.generator.DataCollector.NameWithTypeParameters
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
class SimpleVisitorGenerator(referencesData: DataCollector.ReferencesData) : AbstractVisitorGenerator(referencesData) {
|
||||
override fun Printer.generateContent() {
|
||||
println("abstract class $SIMPLE_VISITOR_NAME<out R, in D> {")
|
||||
indented {
|
||||
generateFunction(
|
||||
"visitElement",
|
||||
parameters = mapOf(
|
||||
"element" to FIR_ELEMENT_CLASS_NAME,
|
||||
"data" to NameWithTypeParameters("D")
|
||||
),
|
||||
returnType = "R",
|
||||
body = null
|
||||
)
|
||||
|
||||
referencesData.walkHierarchyTopDown(from = FIR_ELEMENT_CLASS_NAME) { parent, element ->
|
||||
generateVisit(element, parent)
|
||||
}
|
||||
}
|
||||
println("}")
|
||||
}
|
||||
|
||||
|
||||
private fun Printer.generateVisit(
|
||||
className: NameWithTypeParameters,
|
||||
parent: NameWithTypeParameters
|
||||
) {
|
||||
val shortcutName = className.name.classNameWithoutFir
|
||||
val parameterName = shortcutName.decapitalize().safeName
|
||||
generateFunction(
|
||||
name = "visit$shortcutName",
|
||||
parameters = mapOf(
|
||||
parameterName to className,
|
||||
"data" to NameWithTypeParameters("D")
|
||||
),
|
||||
returnType = "R",
|
||||
typeParametersWithBounds = className.typeParametersWithBounds()
|
||||
) {
|
||||
print("return ")
|
||||
generateCall("visitElement", listOf(parameterName, "data"))
|
||||
println()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2018 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.visitors.generator
|
||||
|
||||
import org.jetbrains.kotlin.fir.visitors.generator.DataCollector.NameWithTypeParameters
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
class UnitVisitorGenerator(referencesData: DataCollector.ReferencesData) : AbstractVisitorGenerator(referencesData) {
|
||||
override fun Printer.generateContent() {
|
||||
println("abstract class $UNIT_VISITOR_NAME : $SIMPLE_VISITOR_NAME<Unit, Nothing?>() {")
|
||||
indented {
|
||||
generateFunction(
|
||||
"visitElement",
|
||||
parameters = mapOf(
|
||||
"element" to FIR_ELEMENT_CLASS_NAME
|
||||
),
|
||||
returnType = "Unit",
|
||||
body = null
|
||||
)
|
||||
|
||||
referencesData.walkHierarchyTopDown(from = FIR_ELEMENT_CLASS_NAME) { parent, element ->
|
||||
generateVisit(element, parent)
|
||||
}
|
||||
|
||||
allElementTypes().forEach {
|
||||
generateTrampolineVisit(it)
|
||||
}
|
||||
|
||||
}
|
||||
println("}")
|
||||
}
|
||||
|
||||
|
||||
private fun Printer.generateVisit(
|
||||
className: NameWithTypeParameters,
|
||||
parent: NameWithTypeParameters
|
||||
) {
|
||||
val shortcutName = className.name.classNameWithoutFir
|
||||
val parameterName = shortcutName.decapitalize().safeName
|
||||
generateFunction(
|
||||
name = "visit$shortcutName",
|
||||
parameters = mapOf(
|
||||
parameterName to className
|
||||
),
|
||||
returnType = "Unit",
|
||||
typeParametersWithBounds = className.typeParametersWithBounds()
|
||||
) {
|
||||
printIndent()
|
||||
generateCall("visitElement", listOf(parameterName, "null"))
|
||||
println()
|
||||
}
|
||||
}
|
||||
|
||||
private fun Printer.generateTrampolineVisit(className: NameWithTypeParameters) {
|
||||
val shortcutName = className.name.classNameWithoutFir
|
||||
val parameterName = shortcutName.decapitalize().safeName
|
||||
generateFunction(
|
||||
name = "visit$shortcutName",
|
||||
parameters = mapOf(
|
||||
parameterName to className,
|
||||
"data" to NameWithTypeParameters("Nothing?")
|
||||
),
|
||||
returnType = "Unit",
|
||||
override = true,
|
||||
final = true,
|
||||
typeParametersWithBounds = className.typeParametersWithBounds()
|
||||
) {
|
||||
printIndent()
|
||||
generateCall("visit$shortcutName", listOf(parameterName))
|
||||
println()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2018 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.visitors.generator
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.openapi.vfs.local.CoreLocalFileSystem
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.SingleRootFileViewProvider
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import java.io.File
|
||||
|
||||
|
||||
val FIR_ELEMENT_CLASS_NAME = DataCollector.NameWithTypeParameters("FirElement")
|
||||
const val VISITOR_PACKAGE = "org.jetbrains.kotlin.fir.visitors"
|
||||
const val SIMPLE_VISITOR_NAME = "FirVisitor"
|
||||
const val UNIT_VISITOR_NAME = "FirVisitorVoid"
|
||||
const val PARAMETRIC_TRANSFORMER_NAME = "FirTransformer"
|
||||
const val TRANSFORMER_RESULT_NAME = "CompositeTransformResult"
|
||||
|
||||
const val BASE_TRANSFORMED_TYPE_ANNOTATION_NAME = "BaseTransformedType"
|
||||
const val VISITED_SUPERTYPE_ANNOTATION_NAME = "VisitedSupertype"
|
||||
|
||||
const val WARNING_GENERATED_FILE =
|
||||
"""/** This file generated by :compiler:fir:tree:generateVisitors. DO NOT MODIFY MANUALLY! */"""
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
// val rootPath = File(args[0])
|
||||
// val output = File(args[1])
|
||||
//
|
||||
// val packageDirectory = output.resolve(VISITOR_PACKAGE.replace('.', '/'))
|
||||
// packageDirectory.mkdirs()
|
||||
//
|
||||
// withPsiSetup {
|
||||
// val psiManager = PsiManager.getInstance(project)
|
||||
// val vfm = VirtualFileManager.getInstance()
|
||||
//
|
||||
//
|
||||
// val dataCollector = DataCollector()
|
||||
//
|
||||
// rootPath.walkTopDown()
|
||||
// .filter {
|
||||
// it.extension == "kt"
|
||||
// }.map {
|
||||
// (vfm.getFileSystem(StandardFileSystems.FILE_PROTOCOL) as CoreLocalFileSystem).findFileByIoFile(it)
|
||||
// }.flatMap {
|
||||
// SingleRootFileViewProvider(psiManager, it!!).allFiles.asSequence()
|
||||
// }
|
||||
// .filterIsInstance<KtFile>()
|
||||
// .forEach(dataCollector::readFile)
|
||||
//
|
||||
//
|
||||
// val data = dataCollector.computeResult()
|
||||
//
|
||||
//
|
||||
// SimpleVisitorGenerator(data).runGenerator(packageDirectory.resolve("${SIMPLE_VISITOR_NAME}Generated.kt"))
|
||||
// UnitVisitorGenerator(data).runGenerator(packageDirectory.resolve("${UNIT_VISITOR_NAME}Generated.kt"))
|
||||
// ParametricTransformerGenerator(data).runGenerator(packageDirectory.resolve("${PARAMETRIC_TRANSFORMER_NAME}Generated.kt"))
|
||||
// }
|
||||
}
|
||||
|
||||
fun AbstractVisitorGenerator.runGenerator(file: File) {
|
||||
file.writeText(StringUtil.convertLineSeparators(this.generate(), System.lineSeparator()))
|
||||
}
|
||||
|
||||
|
||||
val String.classNameWithoutFir get() = this.removePrefix("Fir")
|
||||
|
||||
|
||||
fun DataCollector.ReferencesData.walkHierarchyTopDown(
|
||||
from: DataCollector.NameWithTypeParameters,
|
||||
l: (p: DataCollector.NameWithTypeParameters, e: DataCollector.NameWithTypeParameters) -> Unit
|
||||
) {
|
||||
val referents = back[from] ?: return
|
||||
for (referent in referents) {
|
||||
l(from, referent)
|
||||
walkHierarchyTopDown(referent, l)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ include ":kotlin-build-common",
|
||||
":compiler:visualizer:render-psi",
|
||||
":compiler:fir:cones",
|
||||
":compiler:fir:tree",
|
||||
":compiler:fir:tree:visitors-generator",
|
||||
":compiler:fir:tree:tree-generator",
|
||||
":compiler:fir:psi2fir",
|
||||
":compiler:fir:lightTree",
|
||||
":compiler:fir:fir2ir",
|
||||
|
||||
Reference in New Issue
Block a user