New J2K: Implement basic output generation
This commit is contained in:
committed by
Ilya Kirillov
parent
5fd3a78dbe
commit
66d6ac745f
@@ -40,14 +40,16 @@ val JK_JAVA_FILE = File(JK_ROOT, "j.kt")
|
||||
val JK_COMMON_FILE = File(JK_ROOT, "jk.kt")
|
||||
|
||||
|
||||
val interfaceRegex = "interface (JK[a-zA-Z]+)".toRegex()
|
||||
val interfaceRegex = "interface (JK[a-zA-Z]+)\\s?:?\\s?(JK[a-zA-Z]+)?".toRegex()
|
||||
|
||||
|
||||
data class InterfaceData(val name: String, val extends: String?)
|
||||
|
||||
fun File.interfaceNames() =
|
||||
sequenceOf(this)
|
||||
.map { it.readText() }
|
||||
.flatMap { interfaceRegex.findAll(it) }
|
||||
.map { match -> match.groupValues[1] }
|
||||
.map { match -> InterfaceData(match.groupValues[1], match.groupValues.getOrNull(2)) }
|
||||
.toList()
|
||||
|
||||
|
||||
@@ -56,7 +58,7 @@ fun String.safeVarName() = when (this) {
|
||||
else -> this
|
||||
}
|
||||
|
||||
fun genVisitors(interfaceNames: List<String>, visitorName: String, extends: String = "") {
|
||||
fun genVisitors(interfaceData: List<InterfaceData>, visitorName: String, extends: String = "") {
|
||||
|
||||
val outFile = File(JK_ROOT, "$visitorName.kt")
|
||||
|
||||
@@ -65,30 +67,33 @@ fun genVisitors(interfaceNames: List<String>, visitorName: String, extends: Stri
|
||||
appendln()
|
||||
val extends = if (extends.isNotBlank()) ": $extends<R, D>" else ""
|
||||
appendln("interface $visitorName<R, D> $extends {")
|
||||
interfaceNames.joinTo(this, separator = "\n") { name ->
|
||||
interfaceData.joinTo(this, separator = "\n") { (name, ext) ->
|
||||
val nameWithoutPrefix = name.removePrefix("JK")
|
||||
val argName = nameWithoutPrefix.decapitalize().safeVarName()
|
||||
val generifyCall = if (name != "JKElement") "= visit${ext!!.removePrefix("JK")}($argName, data)" else ""
|
||||
"""
|
||||
| fun visit$nameWithoutPrefix(${nameWithoutPrefix.decapitalize().safeVarName()}: $name, data: D): R
|
||||
| fun visit$nameWithoutPrefix($argName: $name, data: D): R $generifyCall
|
||||
""".trimMargin()
|
||||
}
|
||||
appendln()
|
||||
appendln("}")
|
||||
})
|
||||
|
||||
|
||||
val outVoidFile = File(JK_ROOT, "${visitorName}Void.kt")
|
||||
|
||||
outVoidFile.writeText(buildString {
|
||||
appendln("package org.jetbrains.kotlin.j2k.tree")
|
||||
appendln()
|
||||
val extends = if (extends.isNotBlank()) ", ${extends}Void" else ""
|
||||
|
||||
appendln("interface ${visitorName}Void : $visitorName<Unit, Nothing?>$extends {")
|
||||
interfaceNames.joinTo(this, separator = "\n") { name ->
|
||||
interfaceData.joinTo(this, separator = "\n") { (name, ext) ->
|
||||
val nameWithoutPrefix = name.removePrefix("JK")
|
||||
val argName = nameWithoutPrefix.decapitalize().safeVarName()
|
||||
val arg = "$argName: $name"
|
||||
val generifyCall = if (name != "JKElement") "= visit${ext!!.removePrefix("JK")}($argName, null)" else ""
|
||||
"""
|
||||
| fun visit$nameWithoutPrefix($arg)
|
||||
| fun visit$nameWithoutPrefix($arg) $generifyCall
|
||||
| override fun visit$nameWithoutPrefix($arg, data: Nothing?) = visit$nameWithoutPrefix($argName)
|
||||
""".trimMargin()
|
||||
}
|
||||
@@ -101,11 +106,9 @@ fun genVisitors(interfaceNames: List<String>, visitorName: String, extends: Stri
|
||||
genVisitors(JK_COMMON_FILE.interfaceNames(), "JKVisitor")
|
||||
genVisitors(JK_JAVA_FILE.interfaceNames(), "JKJavaVisitor", "JKVisitor")
|
||||
genVisitors(JK_KT_FILE.interfaceNames(), "JKKtVisitor", "JKVisitor")
|
||||
genVisitors(JK_JAVA_FILE.interfaceNames() + JK_KT_FILE.interfaceNames(), "JKJavaKtVisitor", "JKVisitor")
|
||||
|
||||
/* JKKtVisitor<R,D> : JKVisitor<R,D> + Void
|
||||
JKJavaVisitor<R,D> : JKVisitor<R,D> + Void
|
||||
JKJavaKtVisitor<R, D> : JKVisitor<R,D> + Void
|
||||
*/
|
||||
|
||||
//val visitNames =
|
||||
|
||||
@@ -28,10 +28,12 @@ import org.jetbrains.kotlin.j2k.tree.impl.JKJavaFieldImpl
|
||||
|
||||
class JavaToJKTreeBuilder {
|
||||
|
||||
|
||||
|
||||
private class ElementVisitor : JavaElementVisitor() {
|
||||
|
||||
override fun visitElement(element: PsiElement) {
|
||||
element.acceptChildren(this)
|
||||
}
|
||||
|
||||
var currentClass: JKClass? = null
|
||||
|
||||
override fun visitClass(aClass: PsiClass) {
|
||||
@@ -40,7 +42,7 @@ class JavaToJKTreeBuilder {
|
||||
}
|
||||
|
||||
override fun visitField(field: PsiField) {
|
||||
currentClass!!.declarations.add(JKJavaFieldImpl(field.name!!))
|
||||
currentClass!!.declarations += JKJavaFieldImpl(field.name!!)
|
||||
super.visitField(field)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,17 +20,44 @@ import com.intellij.openapi.progress.EmptyProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiJavaFile
|
||||
import org.jetbrains.kotlin.j2k.ConverterSettings
|
||||
import org.jetbrains.kotlin.j2k.tree.JKClass
|
||||
import org.jetbrains.kotlin.j2k.tree.JKElement
|
||||
import org.jetbrains.kotlin.j2k.tree.JKJavaField
|
||||
import org.jetbrains.kotlin.j2k.tree.JKJavaKtVisitorVoid
|
||||
|
||||
class NewJavaToKotlinConverter(
|
||||
private val project: Project,
|
||||
private val settings: ConverterSettings
|
||||
) {
|
||||
|
||||
fun filesToKotlin(files: List<PsiJavaFile>, progressIndicator: ProgressIndicator = EmptyProgressIndicator()): Nothing {
|
||||
fun filesToKotlin(files: List<PsiJavaFile>, progressIndicator: ProgressIndicator = EmptyProgressIndicator()): String {
|
||||
val treeBuilder = JavaToJKTreeBuilder()
|
||||
val fileTrees = files.map(treeBuilder::buildTree)
|
||||
|
||||
TODO("Output generation")
|
||||
val result = buildString {
|
||||
|
||||
for (tree in fileTrees.filterNotNull()) {
|
||||
appendln()
|
||||
tree.accept(object : JKJavaKtVisitorVoid {
|
||||
override fun visitElement(element: JKElement) {
|
||||
element.acceptChildren(this, null)
|
||||
}
|
||||
|
||||
override fun visitClass(klass: JKClass) {
|
||||
appendln("class")
|
||||
super.visitClass(klass)
|
||||
}
|
||||
|
||||
override fun visitJavaField(javaField: JKJavaField, data: Nothing?) {
|
||||
appendln("java field ${javaField.name}")
|
||||
super.visitJavaField(javaField, data)
|
||||
}
|
||||
|
||||
}, null)
|
||||
appendln()
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,3 @@
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKJavaKtVisitor<R, D> : JKVisitor<R, D> {
|
||||
fun visitJavaElement(javaElement: JKJavaElement, data: D): R
|
||||
fun visitJavaField(javaField: JKJavaField, data: D): R
|
||||
fun visitJavaMethod(javaMethod: JKJavaMethod, data: D): R
|
||||
fun visitJavaForLoop(javaForLoop: JKJavaForLoop, data: D): R
|
||||
fun visitKtElement(ktElement: JKKtElement, data: D): R
|
||||
fun visitKtFun(ktFun: JKKtFun, data: D): R
|
||||
fun visitKtConstructor(ktConstructor: JKKtConstructor, data: D): R
|
||||
fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor, data: D): R
|
||||
}
|
||||
interface JKJavaKtVisitor<R, D> : JKJavaVisitor<R, D>, JKKtVisitor<R, D>
|
||||
|
||||
@@ -1,20 +1,3 @@
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKJavaKtVisitorVoid : JKJavaKtVisitor<Unit, Nothing?>, JKVisitorVoid {
|
||||
fun visitJavaElement(javaElement: JKJavaElement)
|
||||
override fun visitJavaElement(javaElement: JKJavaElement, data: Nothing?) = visitJavaElement(javaElement)
|
||||
fun visitJavaField(javaField: JKJavaField)
|
||||
override fun visitJavaField(javaField: JKJavaField, data: Nothing?) = visitJavaField(javaField)
|
||||
fun visitJavaMethod(javaMethod: JKJavaMethod)
|
||||
override fun visitJavaMethod(javaMethod: JKJavaMethod, data: Nothing?) = visitJavaMethod(javaMethod)
|
||||
fun visitJavaForLoop(javaForLoop: JKJavaForLoop)
|
||||
override fun visitJavaForLoop(javaForLoop: JKJavaForLoop, data: Nothing?) = visitJavaForLoop(javaForLoop)
|
||||
fun visitKtElement(ktElement: JKKtElement)
|
||||
override fun visitKtElement(ktElement: JKKtElement, data: Nothing?) = visitKtElement(ktElement)
|
||||
fun visitKtFun(ktFun: JKKtFun)
|
||||
override fun visitKtFun(ktFun: JKKtFun, data: Nothing?) = visitKtFun(ktFun)
|
||||
fun visitKtConstructor(ktConstructor: JKKtConstructor)
|
||||
override fun visitKtConstructor(ktConstructor: JKKtConstructor, data: Nothing?) = visitKtConstructor(ktConstructor)
|
||||
fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor)
|
||||
override fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor, data: Nothing?) = visitKtPrimaryConstructor(ktPrimaryConstructor)
|
||||
}
|
||||
interface JKJavaKtVisitorVoid : JKJavaKtVisitor<Unit, Nothing?>, JKJavaVisitorVoid, JKKtVisitorVoid
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKJavaVisitor<R, D> : JKVisitor<R, D> {
|
||||
fun visitJavaElement(javaElement: JKJavaElement, data: D): R
|
||||
fun visitJavaField(javaField: JKJavaField, data: D): R
|
||||
fun visitJavaMethod(javaMethod: JKJavaMethod, data: D): R
|
||||
fun visitJavaForLoop(javaForLoop: JKJavaForLoop, data: D): R
|
||||
fun visitJavaField(javaField: JKJavaField, data: D): R = visitDeclaration(javaField, data)
|
||||
fun visitJavaMethod(javaMethod: JKJavaMethod, data: D): R = visitDeclaration(javaMethod, data)
|
||||
fun visitJavaForLoop(javaForLoop: JKJavaForLoop, data: D): R = visitLoop(javaForLoop, data)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKJavaVisitorVoid : JKJavaVisitor<Unit, Nothing?>, JKVisitorVoid {
|
||||
fun visitJavaElement(javaElement: JKJavaElement)
|
||||
override fun visitJavaElement(javaElement: JKJavaElement, data: Nothing?) = visitJavaElement(javaElement)
|
||||
fun visitJavaField(javaField: JKJavaField)
|
||||
fun visitJavaField(javaField: JKJavaField) = visitDeclaration(javaField, null)
|
||||
override fun visitJavaField(javaField: JKJavaField, data: Nothing?) = visitJavaField(javaField)
|
||||
fun visitJavaMethod(javaMethod: JKJavaMethod)
|
||||
fun visitJavaMethod(javaMethod: JKJavaMethod) = visitDeclaration(javaMethod, null)
|
||||
override fun visitJavaMethod(javaMethod: JKJavaMethod, data: Nothing?) = visitJavaMethod(javaMethod)
|
||||
fun visitJavaForLoop(javaForLoop: JKJavaForLoop)
|
||||
fun visitJavaForLoop(javaForLoop: JKJavaForLoop) = visitLoop(javaForLoop, null)
|
||||
override fun visitJavaForLoop(javaForLoop: JKJavaForLoop, data: Nothing?) = visitJavaForLoop(javaForLoop)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKKtVisitor<R, D> : JKVisitor<R, D> {
|
||||
fun visitKtElement(ktElement: JKKtElement, data: D): R
|
||||
fun visitKtFun(ktFun: JKKtFun, data: D): R
|
||||
fun visitKtConstructor(ktConstructor: JKKtConstructor, data: D): R
|
||||
fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor, data: D): R
|
||||
fun visitKtFun(ktFun: JKKtFun, data: D): R = visitDeclaration(ktFun, data)
|
||||
fun visitKtConstructor(ktConstructor: JKKtConstructor, data: D): R = visitDeclaration(ktConstructor, data)
|
||||
fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor, data: D): R = visitKtConstructor(ktPrimaryConstructor, data)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKKtVisitorVoid : JKKtVisitor<Unit, Nothing?>, JKVisitorVoid {
|
||||
fun visitKtElement(ktElement: JKKtElement)
|
||||
override fun visitKtElement(ktElement: JKKtElement, data: Nothing?) = visitKtElement(ktElement)
|
||||
fun visitKtFun(ktFun: JKKtFun)
|
||||
fun visitKtFun(ktFun: JKKtFun) = visitDeclaration(ktFun, null)
|
||||
override fun visitKtFun(ktFun: JKKtFun, data: Nothing?) = visitKtFun(ktFun)
|
||||
fun visitKtConstructor(ktConstructor: JKKtConstructor)
|
||||
fun visitKtConstructor(ktConstructor: JKKtConstructor) = visitDeclaration(ktConstructor, null)
|
||||
override fun visitKtConstructor(ktConstructor: JKKtConstructor, data: Nothing?) = visitKtConstructor(ktConstructor)
|
||||
fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor)
|
||||
fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor) = visitKtConstructor(ktPrimaryConstructor, null)
|
||||
override fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor, data: Nothing?) = visitKtPrimaryConstructor(ktPrimaryConstructor)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKVisitor<R, D> {
|
||||
fun visitElement(element: JKElement, data: D): R
|
||||
fun visitClass(klass: JKClass, data: D): R
|
||||
fun visitMember(member: JKMember, data: D): R
|
||||
fun visitExpression(expression: JKExpression, data: D): R
|
||||
fun visitStatement(statement: JKStatement, data: D): R
|
||||
fun visitLoop(loop: JKLoop, data: D): R
|
||||
fun visitDeclaration(declaration: JKDeclaration, data: D): R
|
||||
fun visitElement(element: JKElement, data: D): R
|
||||
fun visitClass(klass: JKClass, data: D): R = visitDeclaration(klass, data)
|
||||
fun visitExpression(expression: JKExpression, data: D): R = visitElement(expression, data)
|
||||
fun visitStatement(statement: JKStatement, data: D): R = visitElement(statement, data)
|
||||
fun visitLoop(loop: JKLoop, data: D): R = visitStatement(loop, data)
|
||||
fun visitDeclaration(declaration: JKDeclaration, data: D): R = visitElement(declaration, data)
|
||||
}
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKVisitorVoid : JKVisitor<Unit, Nothing?> {
|
||||
fun visitElement(element: JKElement)
|
||||
fun visitElement(element: JKElement)
|
||||
override fun visitElement(element: JKElement, data: Nothing?) = visitElement(element)
|
||||
fun visitClass(klass: JKClass)
|
||||
fun visitClass(klass: JKClass) = visitDeclaration(klass, null)
|
||||
override fun visitClass(klass: JKClass, data: Nothing?) = visitClass(klass)
|
||||
fun visitMember(member: JKMember)
|
||||
override fun visitMember(member: JKMember, data: Nothing?) = visitMember(member)
|
||||
fun visitExpression(expression: JKExpression)
|
||||
fun visitExpression(expression: JKExpression) = visitElement(expression, null)
|
||||
override fun visitExpression(expression: JKExpression, data: Nothing?) = visitExpression(expression)
|
||||
fun visitStatement(statement: JKStatement)
|
||||
fun visitStatement(statement: JKStatement) = visitElement(statement, null)
|
||||
override fun visitStatement(statement: JKStatement, data: Nothing?) = visitStatement(statement)
|
||||
fun visitLoop(loop: JKLoop)
|
||||
fun visitLoop(loop: JKLoop) = visitStatement(loop, null)
|
||||
override fun visitLoop(loop: JKLoop, data: Nothing?) = visitLoop(loop)
|
||||
fun visitDeclaration(declaration: JKDeclaration)
|
||||
fun visitDeclaration(declaration: JKDeclaration) = visitElement(declaration, null)
|
||||
override fun visitDeclaration(declaration: JKDeclaration, data: Nothing?) = visitDeclaration(declaration)
|
||||
}
|
||||
|
||||
@@ -16,26 +16,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.tree.impl
|
||||
|
||||
import org.jetbrains.kotlin.j2k.tree.JKJavaElement
|
||||
import org.jetbrains.kotlin.j2k.tree.JKJavaField
|
||||
import org.jetbrains.kotlin.j2k.tree.JKJavaVisitor
|
||||
import org.jetbrains.kotlin.j2k.tree.JKVisitor
|
||||
|
||||
abstract class JKJavaElementBase : JKJavaElement {
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R {
|
||||
return if (visitor is JKJavaVisitor) {
|
||||
visitor.visitJavaElement(this, data)
|
||||
}
|
||||
else {
|
||||
visitor.visitElement(this, data)
|
||||
}
|
||||
}
|
||||
class JKJavaFieldImpl(override val name: String) : JKJavaField, JKElementBase() {
|
||||
|
||||
override fun <D> acceptChildren(visitor: JKVisitor<Unit, D>, data: D) {}
|
||||
}
|
||||
|
||||
|
||||
class JKJavaFieldImpl(val name: String) : JKJavaField, JKJavaElementBase() {
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R {
|
||||
return if (visitor is JKJavaVisitor) {
|
||||
visitor.visitJavaField(this, data)
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKJavaElement : JKElement
|
||||
interface JKJavaField : JKDeclaration {
|
||||
val name: String
|
||||
}
|
||||
|
||||
interface JKJavaField : JKJavaElement, JKDeclaration, JKMember
|
||||
interface JKJavaMethod : JKDeclaration
|
||||
|
||||
interface JKJavaMethod : JKJavaElement, JKDeclaration, JKMember
|
||||
|
||||
interface JKJavaForLoop : JKJavaElement, JKLoop
|
||||
interface JKJavaForLoop : JKLoop
|
||||
@@ -23,12 +23,10 @@ interface JKElement {
|
||||
fun <D> acceptChildren(visitor: JKVisitor<Unit, D>, data: D)
|
||||
}
|
||||
|
||||
interface JKClass : JKElement {
|
||||
interface JKClass : JKDeclaration {
|
||||
val declarations: MutableList<JKDeclaration>
|
||||
}
|
||||
|
||||
interface JKMember : JKElement
|
||||
|
||||
interface JKExpression : JKElement
|
||||
|
||||
interface JKStatement : JKElement
|
||||
|
||||
@@ -16,10 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
interface JKKtElement: JKElement
|
||||
interface JKKtFun: JKDeclaration
|
||||
|
||||
interface JKKtFun: JKKtElement, JKDeclaration
|
||||
interface JKKtConstructor: JKDeclaration
|
||||
|
||||
interface JKKtConstructor: JKKtElement, JKDeclaration
|
||||
|
||||
interface JKKtPrimaryConstructor: JKKtElement, JKKtConstructor
|
||||
interface JKKtPrimaryConstructor: JKKtConstructor
|
||||
|
||||
+1
-1
@@ -22,6 +22,6 @@ abstract class AbstractNewJavaToKotlinConverterSingleFileTest : AbstractJavaToKo
|
||||
|
||||
override fun fileToKotlin(text: String, settings: ConverterSettings, project: Project): String {
|
||||
val file = createJavaFile(text)
|
||||
NewJavaToKotlinConverter(project, settings).filesToKotlin(listOf(file))
|
||||
return NewJavaToKotlinConverter(project, settings).filesToKotlin(listOf(file))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user