2 * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
3 * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
9 private val JK_ROOT = File("./nj2k/src/org/jetbrains/kotlin/nj2k/tree")
11 private val JK_OUT_ROOT = File(JK_ROOT, "visitors")
13 private val JK_TREE_FILES = listOf(
19 ).map { File(JK_ROOT, it) }
22 val elementRegex = """(class|object)\s+(JK[\w]+)(\([\w\s:,<>=\(\)\\]+\))?\s*:\s*(JK[a-zA-Z]+)""".toRegex()
25 data class InterfaceData(val name: String, val extends: String?)
27 fun File.interfaceNames() =
29 .map { it.readText() }
30 .flatMap { elementRegex.findAll(it) }
34 match.groupValues[4].let { if (it == "JKAnnotationMemberValue") "JKTreeElement" else it }
39 fun String.safeVarName() = when (this) {
45 interfaceData: List<InterfaceData>,
48 val pkg = "package org.jetbrains.kotlin.nj2k.tree.visitors"
50 File(JK_OUT_ROOT, "$visitorName.kt").writeText(buildString {
53 appendln("import org.jetbrains.kotlin.nj2k.tree.*")
55 appendln("abstract class $visitorName {")
56 interfaceData.joinTo(this, separator = "\n") { (name, ext) ->
57 val nameWithoutPrefix = name.removePrefix("JK")
58 val argName = nameWithoutPrefix.decapitalize().safeVarName()
59 val generifyCall = if (name != "JKTreeElement") "= visit${ext?.removePrefix("JK") ?: error(name)}($argName)" else ""
60 val modifier = if (name == "JKTreeElement") "abstract" else "open"
62 | $modifier fun visit$nameWithoutPrefix($argName: $name) $generifyCall
70 File(JK_OUT_ROOT, "${visitorName}WithCommentsPrinting.kt").writeText(buildString {
73 appendln("import org.jetbrains.kotlin.nj2k.tree.*")
76 appendln("abstract class ${visitorName}WithCommentsPrinting : $visitorName() {")
79 | abstract fun printLeftNonCodeElements(element: JKNonCodeElementsListOwner)
80 | abstract fun printRightNonCodeElements(element: JKNonCodeElementsListOwner)
85 interfaceData.joinTo(this, separator = "\n\n") { (name, ext) ->
86 val nameWithoutPrefix = name.removePrefix("JK")
87 val argName = nameWithoutPrefix.decapitalize().safeVarName()
88 val arg = "$argName: $name"
89 val rawVisitSuffix = "Raw"
90 val generifyCall = if (name != "JKTreeElement") "= visit${ext!!.removePrefix("JK")}$rawVisitSuffix($argName)" else ""
91 val modifier = if (name == "JKTreeElement") "abstract" else "open"
93 | final override fun visit$nameWithoutPrefix($arg) {
94 | printLeftNonCodeElements($argName)
95 | visit$nameWithoutPrefix$rawVisitSuffix($argName)
96 | printRightNonCodeElements($argName)
99 | $modifier fun visit$nameWithoutPrefix$rawVisitSuffix($arg) $generifyCall
108 genVisitors(JK_TREE_FILES.flatMap { it.interfaceNames() }, "JKVisitor")