New J2K: WIP: Field to property conversion
This commit is contained in:
committed by
Ilya Kirillov
parent
dbf4ba536f
commit
e0d3ff7507
@@ -5,10 +5,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.conversions
|
||||
|
||||
import org.jetbrains.kotlin.j2k.ast.Mutability
|
||||
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.j2k.tree.impl.mutability
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.visibility
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class FieldToPropertyConversion : RecursiveApplicableConversionBase() {
|
||||
|
||||
@@ -35,14 +39,14 @@ class FieldToPropertyConversion : RecursiveApplicableConversionBase() {
|
||||
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 }
|
||||
propertyNameFromGet(it)?.let { fieldName -> propertyInfoFor(fieldName).getter = it }
|
||||
?: propertyNameFromSet(it)?.let { fieldName -> propertyInfoFor(fieldName).setter = it }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
propertyInfos.forEach { (_, info) ->
|
||||
for ((_, info) in propertyInfos) {
|
||||
val field = info.field
|
||||
|
||||
if (field != null) {
|
||||
@@ -52,8 +56,19 @@ class FieldToPropertyConversion : RecursiveApplicableConversionBase() {
|
||||
JKKtPropertyImpl(field.modifierList, field.type, field.name, field.initializer, JKBlockImpl(), JKBlockImpl())
|
||||
|
||||
declarations.remove(field)
|
||||
declarations.remove(info.getter)
|
||||
declarations.remove(info.setter)
|
||||
|
||||
val getter = info.getter
|
||||
if (getter?.fieldFromGetter(field.name.value) == field) {
|
||||
declarations.remove(getter)
|
||||
property.modifierList.mutability = Mutability.NonMutable
|
||||
property.modifierList.visibility = minOf(getter.modifierList.visibility, property.modifierList.visibility)
|
||||
}
|
||||
val setter = info.setter
|
||||
if (setter?.fieldFromSetter(field.name.value) == field) {
|
||||
declarations.remove(setter)
|
||||
property.modifierList.mutability = Mutability.Mutable
|
||||
property.modifierList.visibility = minOf(setter.modifierList.visibility, property.modifierList.visibility)
|
||||
}
|
||||
declarations.add(property)
|
||||
}
|
||||
}
|
||||
@@ -64,19 +79,55 @@ class FieldToPropertyConversion : RecursiveApplicableConversionBase() {
|
||||
}
|
||||
|
||||
|
||||
private fun JKMethod.getterFor(): JKJavaField? {
|
||||
if (JvmAbi.isGetterName(name.value)) return null
|
||||
if (this.parameters.isNotEmpty()) return null
|
||||
private fun propertyNameFromGet(method: JKMethod): String? {
|
||||
if (!JvmAbi.isGetterName(method.name.value)) return null
|
||||
if (method.parameters.isNotEmpty()) return null
|
||||
if (method !is JKJavaMethod) return null
|
||||
return method.name.value
|
||||
.removePrefix("get")
|
||||
.removePrefix("is")
|
||||
.decapitalize()
|
||||
}
|
||||
|
||||
private fun propertyNameFromSet(method: JKMethod): String? {
|
||||
if (!JvmAbi.isSetterName(method.name.value)) return null
|
||||
if (method.parameters.size != 1) return null
|
||||
if (method !is JKJavaMethod) return null
|
||||
return method.name.value
|
||||
.removePrefix("set")
|
||||
.decapitalize()
|
||||
}
|
||||
|
||||
private fun JKExpression.unboxFieldReference(): JKFieldAccessExpression? = when {
|
||||
this is JKFieldAccessExpression -> this
|
||||
this is JKQualifiedExpression && receiver is JKThisExpression -> selector as? JKFieldAccessExpression
|
||||
else -> null
|
||||
}
|
||||
|
||||
private fun JKMethod.fieldFromGetter(propertyName: String): JKJavaField? {
|
||||
if (this !is JKJavaMethod) return null
|
||||
val returnStatement = block.statements.singleOrNull() as? JKReturnStatement ?: return null
|
||||
val fieldAccess = returnStatement.expression as? JKFieldAccessExpression ?: return null
|
||||
val fieldAccess = returnStatement.expression.unboxFieldReference() ?: return null
|
||||
val field = fieldAccess.identifier.target as? JKJavaField ?: return null
|
||||
if (name.value.endsWith(field.name.value)) return field
|
||||
return null
|
||||
if (propertyName != field.name.value) return null
|
||||
return field
|
||||
}
|
||||
|
||||
fun JKMethod.setterFor(): JKJavaField? {
|
||||
return null
|
||||
private fun JKMethod.fieldFromSetter(propertyName: String): JKJavaField? {
|
||||
if (this !is JKJavaMethod) return null
|
||||
val expressionStatement = this.block.statements.singleOrNull() as? JKExpressionStatement ?: return null
|
||||
val assignment = expressionStatement.expression as? JKJavaAssignmentExpression ?: return null
|
||||
val lhs = assignment.field
|
||||
val fieldAccess = lhs.unboxFieldReference()
|
||||
val target = fieldAccess?.identifier?.target as? JKJavaField ?: return null
|
||||
if (propertyName != target.name.value) return null
|
||||
return target
|
||||
}
|
||||
|
||||
|
||||
private data class AccessorInfo(
|
||||
val method: JKMethod,
|
||||
val field: JKField?,
|
||||
val propertyName: String
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user