New J2K: WIP: New field to property conversion
This commit is contained in:
committed by
Ilya Kirillov
parent
edd23c7a83
commit
a55591011a
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.j2k
|
package org.jetbrains.kotlin.j2k
|
||||||
|
|
||||||
import org.jetbrains.kotlin.j2k.conversions.JavaFieldToKotlinPropertyConversion
|
import org.jetbrains.kotlin.j2k.conversions.FieldToPropertyConversion
|
||||||
import org.jetbrains.kotlin.j2k.conversions.JavaMethodToKotlinFunctionConversion
|
import org.jetbrains.kotlin.j2k.conversions.JavaMethodToKotlinFunctionConversion
|
||||||
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
|
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ object ConversionsRunner {
|
|||||||
fun doApply(trees: List<JKTreeElement>) {
|
fun doApply(trees: List<JKTreeElement>) {
|
||||||
|
|
||||||
trees.forEach {
|
trees.forEach {
|
||||||
JavaFieldToKotlinPropertyConversion().runConversion(it)
|
FieldToPropertyConversion().runConversion(it)
|
||||||
JavaMethodToKotlinFunctionConversion().runConversion(it)
|
JavaMethodToKotlinFunctionConversion().runConversion(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. 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.j2k.conversions
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.j2k.tree.*
|
||||||
|
import org.jetbrains.kotlin.j2k.tree.impl.JKBlockImpl
|
||||||
|
import org.jetbrains.kotlin.j2k.tree.impl.JKKtPropertyImpl
|
||||||
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
|
|
||||||
|
class FieldToPropertyConversion : MatchBasedConversion() {
|
||||||
|
override fun onElementChanged(new: JKTreeElement, old: JKTreeElement) {
|
||||||
|
somethingChanged = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var somethingChanged = false
|
||||||
|
|
||||||
|
override fun runConversion(treeRoot: JKTreeElement): Boolean {
|
||||||
|
val root = applyToElement(treeRoot)
|
||||||
|
assert(root === treeRoot)
|
||||||
|
return somethingChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
data class PropertyInfo(
|
||||||
|
val name: String,
|
||||||
|
var setter: JKMethod? = null,
|
||||||
|
var getter: JKMethod? = null,
|
||||||
|
var field: JKJavaField? = null
|
||||||
|
)
|
||||||
|
|
||||||
|
fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||||
|
if (element !is JKUDeclarationList) return applyRecursive(element, this::applyToElement)
|
||||||
|
|
||||||
|
val propertyInfos = mutableMapOf<String, PropertyInfo>()
|
||||||
|
|
||||||
|
fun propertyInfoFor(name: String): PropertyInfo {
|
||||||
|
return propertyInfos.getOrPut(name) {
|
||||||
|
PropertyInfo(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val declarations = element.declarations.toMutableList()
|
||||||
|
declarations.forEach {
|
||||||
|
when (it) {
|
||||||
|
is JKJavaField -> propertyInfoFor(it.name.value).field = it
|
||||||
|
is JKJavaMethod -> {
|
||||||
|
it.getterFor()?.let { field -> propertyInfoFor(field.name.value).getter = it }
|
||||||
|
?: it.setterFor()?.let { field -> propertyInfoFor(field.name.value).setter = it }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
propertyInfos.forEach { (_, info) ->
|
||||||
|
val field = info.field
|
||||||
|
|
||||||
|
if (field != null) {
|
||||||
|
// TODO: proper accessors
|
||||||
|
val property =
|
||||||
|
JKKtPropertyImpl(field.modifierList, field.type, field.name, field.initializer, JKBlockImpl(), JKBlockImpl())
|
||||||
|
|
||||||
|
declarations.remove(field)
|
||||||
|
declarations.remove(info.getter)
|
||||||
|
declarations.remove(info.setter)
|
||||||
|
declarations.add(property)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
element.declarations = declarations
|
||||||
|
|
||||||
|
return element
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun JKMethod.getterFor(): JKJavaField? {
|
||||||
|
if (JvmAbi.isGetterName(name.value)) return null
|
||||||
|
if (this.valueArguments.isNotEmpty()) return null
|
||||||
|
if (this !is JKJavaMethod) return null
|
||||||
|
val returnStatement = block.statements.singleOrNull() as? JKReturnStatement ?: return null
|
||||||
|
val fieldAccess = returnStatement.expression as? JKFieldAccessExpression ?: return null
|
||||||
|
val field = fieldAccess.identifier.target as? JKJavaField ?: return null
|
||||||
|
if (name.value.endsWith(field.name.value)) return field
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun JKMethod.setterFor(): JKJavaField? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
-20
@@ -25,26 +25,6 @@ import org.jetbrains.kotlin.j2k.tree.impl.JKJavaPrimitiveTypeImpl
|
|||||||
import org.jetbrains.kotlin.j2k.tree.impl.JKKtFunctionImpl
|
import org.jetbrains.kotlin.j2k.tree.impl.JKKtFunctionImpl
|
||||||
import org.jetbrains.kotlin.j2k.tree.impl.JKKtPropertyImpl
|
import org.jetbrains.kotlin.j2k.tree.impl.JKKtPropertyImpl
|
||||||
|
|
||||||
class JavaFieldToKotlinPropertyConversion : TransformerBasedConversion() {
|
|
||||||
override fun visitElement(element: JKTreeElement) {
|
|
||||||
element.acceptChildren(this, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitUniverseClass(universeClass: JKUniverseClass) {
|
|
||||||
somethingChanged = true
|
|
||||||
universeClass.declarationList.declarations = universeClass.declarationList.declarations.map {
|
|
||||||
if (it is JKJavaField) JKKtPropertyImpl(
|
|
||||||
it.modifierList,
|
|
||||||
it.type,
|
|
||||||
it.name,
|
|
||||||
it.initializer,
|
|
||||||
JKBlockImpl(),
|
|
||||||
JKBlockImpl()
|
|
||||||
) else it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class JavaMethodToKotlinFunctionConversion : TransformerBasedConversion() {
|
class JavaMethodToKotlinFunctionConversion : TransformerBasedConversion() {
|
||||||
override fun visitElement(element: JKTreeElement) {
|
override fun visitElement(element: JKTreeElement) {
|
||||||
element.acceptChildren(this, null)
|
element.acceptChildren(this, null)
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. 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.j2k.conversions
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
|
||||||
|
import org.jetbrains.kotlin.j2k.tree.impl.JKMutableBranchElement
|
||||||
|
|
||||||
|
abstract class MatchBasedConversion : BaseConversion() {
|
||||||
|
|
||||||
|
fun applyRecursive(element: JKTreeElement, func: (JKTreeElement) -> JKTreeElement): JKTreeElement {
|
||||||
|
if (element is JKMutableBranchElement) {
|
||||||
|
val iter = element.children.listIterator()
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
val child = iter.next()
|
||||||
|
val newChild = func(child)
|
||||||
|
if (child !== newChild) {
|
||||||
|
onElementChanged(newChild, child)
|
||||||
|
child.parent = null
|
||||||
|
newChild.parent = element
|
||||||
|
iter.set(newChild)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return element
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun onElementChanged(new: JKTreeElement, old: JKTreeElement)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user