Java to Kotlin converter: more cases when field can be declared as val
This commit is contained in:
@@ -285,7 +285,7 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
else {
|
||||
val initializer = field.getInitializer()
|
||||
val convertedType = typeConverter.convertVariableType(field)
|
||||
val isVal = field.isEffectivelyFinal()
|
||||
val isVal = isVal(field)
|
||||
val omitType = !settings.specifyFieldTypeByDefault &&
|
||||
initializer != null &&
|
||||
(modifiers.isPrivate && (isVal || convertedType == typeConverter.convertExpressionType(initializer)) ||
|
||||
@@ -302,6 +302,29 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
return converted.assignPrototype(field)
|
||||
}
|
||||
|
||||
private fun isVal(field: PsiField): Boolean {
|
||||
if (field.hasModifierProperty(PsiModifier.FINAL)) return true
|
||||
if (!field.hasModifierProperty(PsiModifier.PRIVATE)) return false
|
||||
val containingClass = field.getContainingClass() ?: return false
|
||||
val writes = findVariableUsages(field, containingClass).filter { PsiUtil.isAccessedForWriting(it) }
|
||||
if (writes.size == 0) return true
|
||||
if (writes.size > 1) return false
|
||||
val write = writes.single()
|
||||
val parent = write.getParent()
|
||||
if (parent is PsiAssignmentExpression &&
|
||||
parent.getOperationSign().getTokenType() == JavaTokenType.EQ &&
|
||||
isQualifierEmptyOrThis(write)) {
|
||||
val constructor = write.getContainingConstructor()
|
||||
if (constructor != null &&
|
||||
constructor.getContainingClass() == containingClass &&
|
||||
parent.getParent() is PsiExpressionStatement &&
|
||||
parent.getParent()?.getParent() == constructor.getBody()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun convertMethod(method: PsiMethod, membersToRemove: MutableSet<PsiMember>): Function {
|
||||
return withMethodReturnType(method.getReturnType()).doConvertMethod(method, membersToRemove).assignPrototype(method)
|
||||
}
|
||||
@@ -428,7 +451,7 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
val (field, `type`) = parameterToField[parameter]!!
|
||||
Parameter(field.declarationIdentifier(),
|
||||
`type`,
|
||||
if (field.hasModifierProperty(PsiModifier.FINAL)) Parameter.VarValModifier.Val else Parameter.VarValModifier.Var,
|
||||
if (isVal(field)) Parameter.VarValModifier.Val else Parameter.VarValModifier.Var,
|
||||
convertAnnotations(parameter) + convertAnnotations(field),
|
||||
convertModifiers(field).filter { it in ACCESS_MODIFIERS }).assignPrototypes(listOf(parameter, field), inheritBlankLinesBefore = false)
|
||||
}
|
||||
|
||||
@@ -263,4 +263,13 @@ class TypeConverter(val settings: ConverterSettings, val conversionScope: Conver
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun PsiVariable.isEffectivelyFinal(): Boolean {
|
||||
if (hasModifierProperty(PsiModifier.FINAL)) return true
|
||||
return when(this) {
|
||||
is PsiLocalVariable -> !hasWriteAccesses(getContainingMethod())
|
||||
is PsiField -> if (hasModifierProperty(PsiModifier.PRIVATE)) !hasWriteAccesses(getContainingClass()) else false
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,12 +93,3 @@ fun PsiElement.isInSingleLine(): Boolean {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun PsiVariable.isEffectivelyFinal(): Boolean {
|
||||
if (hasModifierProperty(PsiModifier.FINAL)) return true
|
||||
return when(this) {
|
||||
is PsiLocalVariable -> !hasWriteAccesses(getContainingMethod())
|
||||
is PsiField -> if (hasModifierProperty(PsiModifier.PRIVATE)) !hasWriteAccesses(getContainingClass()) else false
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
public class Identifier<T> private(private val myName: T, private var myHasDollar: Boolean) {
|
||||
public class Identifier<T> private(private val myName: T, private val myHasDollar: Boolean) {
|
||||
private var myNullable = true
|
||||
|
||||
public fun getName(): T {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
public class Identifier private(private val myName: String, private var myHasDollar: Boolean) {
|
||||
public class Identifier private(private val myName: String, private val myHasDollar: Boolean) {
|
||||
private var myNullable = true
|
||||
|
||||
public fun getName(): String {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
enum class Color private(private var code: Int) {
|
||||
enum class Color private(private val code: Int) {
|
||||
WHITE : Color(21)
|
||||
BLACK : Color(22)
|
||||
RED : Color(23)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package demo
|
||||
|
||||
enum class Color private(private var code: Int) {
|
||||
enum class Color private(private val code: Int) {
|
||||
|
||||
public fun getCode(): Int {
|
||||
return code
|
||||
|
||||
@@ -5,6 +5,23 @@ class A {
|
||||
private int field3 = 0;
|
||||
final int field4 = 0;
|
||||
int field5 = 0;
|
||||
private int field6;
|
||||
private int field7;
|
||||
private int field8;
|
||||
private int field9;
|
||||
private int field10;
|
||||
private int field11;
|
||||
|
||||
A(int p1, int p2, A a) {
|
||||
field6 = p1;
|
||||
field7 = 10;
|
||||
this.field8 = p2;
|
||||
this.field9 = 10;
|
||||
if (p1 > 0) {
|
||||
this.field10 = 10;
|
||||
}
|
||||
a.field11 = 10;
|
||||
}
|
||||
|
||||
void foo() {
|
||||
field3 = field2;
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
class A() {
|
||||
class A(private val field6: Int, private val field8: Int, a: A) {
|
||||
private val field1 = 0
|
||||
private val field2 = 0
|
||||
private var field3 = 0
|
||||
val field4 = 0
|
||||
var field5 = 0
|
||||
private val field7: Int
|
||||
private val field9: Int
|
||||
private var field10: Int = 0
|
||||
private var field11: Int = 0
|
||||
|
||||
fun foo() {
|
||||
field3 = field2
|
||||
}
|
||||
|
||||
{
|
||||
field7 = 10
|
||||
this.field9 = 10
|
||||
if (field6 > 0) {
|
||||
this.field10 = 10
|
||||
}
|
||||
a.field11 = 10
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
class Base<T>(name: T)
|
||||
|
||||
class One<T, K>(name: T, private var mySecond: K) : Base<T>(name)
|
||||
class One<T, K>(name: T, private val mySecond: K) : Base<T>(name)
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
class Base(name: String)
|
||||
|
||||
class One(name: String, private var mySecond: String) : Base(name)
|
||||
class One(name: String, private val mySecond: String) : Base(name)
|
||||
@@ -1,4 +1,4 @@
|
||||
public class Identifier<T> private(private val myName: T, private var myHasDollar: Boolean) {
|
||||
public class Identifier<T> private(private val myName: T, private val myHasDollar: Boolean) {
|
||||
private var myNullable = true
|
||||
|
||||
public fun getName(): T {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
class C(private var s: String?) {
|
||||
class C(private val s: String?) {
|
||||
|
||||
fun foo() {
|
||||
if (s != null) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
class C(private var s: String?) {
|
||||
class C(private val s: String?) {
|
||||
{
|
||||
if (s == null) {
|
||||
System.out.print("null")
|
||||
|
||||
Reference in New Issue
Block a user