New J2K: First conversion

This commit is contained in:
Simon Ogorodnik
2017-10-17 04:14:44 +03:00
committed by Ilya Kirillov
parent 8ac5eadadc
commit e33df530cd
18 changed files with 208 additions and 20 deletions
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.j2k
import org.jetbrains.kotlin.j2k.conversions.JavaFieldToKotlinPropertyConversion
import org.jetbrains.kotlin.j2k.tree.JKElement
object ConversionsRunner {
fun doApply(trees: List<JKElement>) {
trees.forEach {
JavaFieldToKotlinPropertyConversion().runConversion(it)
}
}
}
@@ -87,7 +87,11 @@ class JavaToJKTreeBuilder {
val type = JKJavaTypeIdentifierImpl(field.type.canonicalText)
val name = JKNameIdentifierImpl(field.name!!)
currentClass!!.declarations += JKJavaFieldImpl(type, name, initializer)
val modifierList = with(ModifierMapper) {
field.modifierList.toJK()
}
currentClass!!.declarations += JKJavaFieldImpl(modifierList, type, name, initializer)
super.visitField(field)
}
@@ -20,29 +20,33 @@ 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.tree.*
import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.j2k.tree.JKElement
import org.jetbrains.kotlin.j2k.tree.prettyDebugPrintTree
class NewJavaToKotlinConverter(
private val project: Project,
private val settings: ConverterSettings
) {
private fun List<JKElement>.prettyPrintTrees() = buildString {
for (tree in this@prettyPrintTrees) {
appendln()
appendln(tree.prettyDebugPrintTree())
appendln()
}
}
fun filesToKotlin(files: List<PsiJavaFile>, progressIndicator: ProgressIndicator = EmptyProgressIndicator()): String {
val treeBuilder = JavaToJKTreeBuilder()
val fileTrees = files.map(treeBuilder::buildTree)
val fileTrees = files.mapNotNull(treeBuilder::buildTree)
val result = buildString {
println(fileTrees.prettyPrintTrees())
for (tree in fileTrees.filterNotNull()) {
appendln()
appendln(tree.prettyDebugPrintTree())
appendln()
}
}
ConversionsRunner.doApply(fileTrees)
val result = fileTrees.prettyPrintTrees()
println(result)
return result
}
}
@@ -0,0 +1,27 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.j2k.conversions
import org.jetbrains.kotlin.j2k.tree.JKElement
abstract class BaseConversion {
/**
* @return true if something changed
*/
abstract fun runConversion(treeRoot: JKElement): Boolean
}
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.j2k.conversions
import org.jetbrains.kotlin.j2k.tree.JKDeclaration
import org.jetbrains.kotlin.j2k.tree.JKElement
import org.jetbrains.kotlin.j2k.tree.JKJavaField
import org.jetbrains.kotlin.j2k.tree.impl.JKKtPropertyImpl
class JavaFieldToKotlinPropertyConversion : TransformerBasedConversion() {
override fun visitElement(element: JKElement): JKElement = element.also { it.transformChildren(this, null) }
override fun visitJavaField(javaField: JKJavaField): JKDeclaration {
somethingChanged = true
return JKKtPropertyImpl(javaField.modifierList, javaField.type, javaField.name, javaField.initializer)
}
}
@@ -0,0 +1,30 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.j2k.conversions
import org.jetbrains.kotlin.j2k.tree.JKElement
import org.jetbrains.kotlin.j2k.tree.visitors.JKTransformerVoid
abstract class TransformerBasedConversion: BaseConversion(), JKTransformerVoid {
protected var somethingChanged = false
override fun runConversion(treeRoot: JKElement): Boolean {
somethingChanged = false
treeRoot.accept(this, null)
return somethingChanged
}
}
@@ -30,6 +30,10 @@ private class DebugTreePrinter : JKVisitorVoid {
}
printer.println("]")
}
override fun visitJavaAccessModifier(javaAccessModifier: JKJavaAccessModifier) {
printer.println(javaAccessModifier.classNameWithoutJK(), "(", javaAccessModifier.type, ")")
}
}
private fun Any.classNameWithoutJK(): String = this.javaClass.simpleName.removePrefix("JK")
@@ -20,7 +20,8 @@ import org.jetbrains.kotlin.j2k.tree.*
import org.jetbrains.kotlin.j2k.tree.visitors.JKTransformer
import org.jetbrains.kotlin.j2k.tree.visitors.JKVisitor
class JKJavaFieldImpl(override var type: JKTypeIdentifier,
class JKJavaFieldImpl(override var modifierList: JKModifierList,
override var type: JKTypeIdentifier,
override var name: JKNameIdentifier,
override var initializer: JKExpression?) : JKJavaField, JKElementBase() {
@@ -32,13 +32,20 @@ abstract class JKElementBase : JKElement {
class JKClassImpl(override var modifierList: JKModifierList, override var name: JKNameIdentifier) : JKClass, JKElementBase() {
override var declarations: List<JKDeclaration> = mutableListOf()
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitClass(this, data)
override fun <D> acceptChildren(visitor: JKVisitor<Unit, D>, data: D) {
(listOf(modifierList, name) + declarations).forEach { it.accept(visitor, data) }
}
override val declarations = mutableListOf<JKDeclaration>()
override fun <D> transformChildren(transformer: JKTransformer<D>, data: D) {
modifierList = modifierList.transform(transformer, data)
name = name.transform(transformer, data)
declarations = declarations.map { it.transform<JKDeclaration, D>(transformer, data) }
}
}
@@ -16,3 +16,14 @@
package org.jetbrains.kotlin.j2k.tree.impl
import org.jetbrains.kotlin.j2k.tree.*
class JKKtPropertyImpl(override var modifierList: JKModifierList,
override var type: JKTypeIdentifier,
override var name: JKNameIdentifier,
override var initializer: JKExpression? = null,
override var getter: JKBlock? = null,
override var setter: JKBlock? = null) : JKElementBase(), JKKtProperty {
}
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.j2k.tree
interface JKJavaField : JKDeclaration {
interface JKJavaField : JKDeclaration, JKModifierListOwner {
var type: JKTypeIdentifier
var name: JKNameIdentifier
var initializer: JKExpression?
@@ -28,10 +28,9 @@ interface JKElement {
fun <D> transformChildren(transformer: JKTransformer<D>, data: D)
}
interface JKClass : JKDeclaration {
var modifierList: JKModifierList
interface JKClass : JKDeclaration, JKModifierListOwner {
var name: JKNameIdentifier
val declarations: MutableList<JKDeclaration>
var declarations: List<JKDeclaration>
}
interface JKStatement : JKElement
@@ -42,7 +41,9 @@ interface JKLoop : JKStatement
interface JKDeclaration : JKElement
interface JKBlock : JKElement
interface JKBlock : JKElement {
var statements: List<JKStatement>
}
interface JKCall : JKExpression
@@ -24,4 +24,12 @@ interface JKKtPrimaryConstructor : JKKtConstructor
interface JKKtAssignmentStatement : JKStatement
interface JKKtCall : JKCall
interface JKKtCall : JKCall
interface JKKtProperty : JKDeclaration, JKModifierListOwner {
var type: JKTypeIdentifier
var name: JKNameIdentifier
var initializer: JKExpression?
var getter: JKBlock?
var setter: JKBlock?
}
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.j2k.tree
interface JKModifierListOwner {
var modifierList: JKModifierList
}
@@ -31,4 +31,5 @@ interface JKTransformer<in D> : JKVisitor<JKElement, D> {
override fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor, data: D): JKDeclaration = visitKtConstructor(ktPrimaryConstructor, data)
override fun visitKtAssignmentStatement(ktAssignmentStatement: JKKtAssignmentStatement, data: D): JKStatement = visitStatement(ktAssignmentStatement, data)
override fun visitKtCall(ktCall: JKKtCall, data: D): JKCall = visitCall(ktCall, data)
override fun visitKtProperty(ktProperty: JKKtProperty, data: D): JKDeclaration = visitDeclaration(ktProperty, data)
}
@@ -59,4 +59,6 @@ interface JKTransformerVoid : JKTransformer<Nothing?> {
override fun visitKtAssignmentStatement(ktAssignmentStatement: JKKtAssignmentStatement, data: Nothing?): JKStatement = visitKtAssignmentStatement(ktAssignmentStatement)
fun visitKtCall(ktCall: JKKtCall): JKCall = visitCall(ktCall)
override fun visitKtCall(ktCall: JKKtCall, data: Nothing?): JKCall = visitKtCall(ktCall)
fun visitKtProperty(ktProperty: JKKtProperty): JKDeclaration = visitDeclaration(ktProperty)
override fun visitKtProperty(ktProperty: JKKtProperty, data: Nothing?): JKDeclaration = visitKtProperty(ktProperty)
}
@@ -31,4 +31,5 @@ interface JKVisitor<out R, in D> {
fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor, data: D): R = visitKtConstructor(ktPrimaryConstructor, data)
fun visitKtAssignmentStatement(ktAssignmentStatement: JKKtAssignmentStatement, data: D): R = visitStatement(ktAssignmentStatement, data)
fun visitKtCall(ktCall: JKKtCall, data: D): R = visitCall(ktCall, data)
fun visitKtProperty(ktProperty: JKKtProperty, data: D): R = visitDeclaration(ktProperty, data)
}
@@ -59,4 +59,6 @@ interface JKVisitorVoid : JKVisitor<Unit, Nothing?> {
override fun visitKtAssignmentStatement(ktAssignmentStatement: JKKtAssignmentStatement, data: Nothing?) = visitKtAssignmentStatement(ktAssignmentStatement)
fun visitKtCall(ktCall: JKKtCall) = visitCall(ktCall, null)
override fun visitKtCall(ktCall: JKKtCall, data: Nothing?) = visitKtCall(ktCall)
fun visitKtProperty(ktProperty: JKKtProperty) = visitDeclaration(ktProperty, null)
override fun visitKtProperty(ktProperty: JKKtProperty, data: Nothing?) = visitKtProperty(ktProperty)
}