Java to Kotlin converter: added heuristics that values of types like Integer are likely nullable
This commit is contained in:
@@ -72,7 +72,8 @@ class TypeConverter(val settings: ConverterSettings, val conversionScope: Conver
|
|||||||
|
|
||||||
private fun variableNullabilityNoCache(variable: PsiVariable): Nullability {
|
private fun variableNullabilityNoCache(variable: PsiVariable): Nullability {
|
||||||
if (variable is PsiEnumConstant) return Nullability.NotNull
|
if (variable is PsiEnumConstant) return Nullability.NotNull
|
||||||
if (variable.getType() is PsiPrimitiveType) return Nullability.NotNull
|
val variableType = variable.getType()
|
||||||
|
if (variableType is PsiPrimitiveType) return Nullability.NotNull
|
||||||
|
|
||||||
var nullability = variable.nullabilityFromAnnotations()
|
var nullability = variable.nullabilityFromAnnotations()
|
||||||
|
|
||||||
@@ -102,6 +103,11 @@ class TypeConverter(val settings: ConverterSettings, val conversionScope: Conver
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// variables of types like Integer are most likely nullable
|
||||||
|
if (nullability == Nullability.Default && variableType.getCanonicalText() in boxingTypes) {
|
||||||
|
return Nullability.Nullable
|
||||||
|
}
|
||||||
|
|
||||||
if (!conversionScope.contains(variable)) { // do not analyze usages out of our conversion scope
|
if (!conversionScope.contains(variable)) { // do not analyze usages out of our conversion scope
|
||||||
if (variable is PsiParameter) {
|
if (variable is PsiParameter) {
|
||||||
// Object.equals corresponds to Any.equals which has nullable parameter:
|
// Object.equals corresponds to Any.equals which has nullable parameter:
|
||||||
@@ -158,7 +164,8 @@ class TypeConverter(val settings: ConverterSettings, val conversionScope: Conver
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun methodNullabilityNoCache(method: PsiMethod): Nullability {
|
private fun methodNullabilityNoCache(method: PsiMethod): Nullability {
|
||||||
if (method.getReturnType() is PsiPrimitiveType) return Nullability.NotNull
|
val returnType = method.getReturnType()
|
||||||
|
if (returnType is PsiPrimitiveType) return Nullability.NotNull
|
||||||
|
|
||||||
var nullability = method.nullabilityFromAnnotations()
|
var nullability = method.nullabilityFromAnnotations()
|
||||||
|
|
||||||
@@ -167,6 +174,11 @@ class TypeConverter(val settings: ConverterSettings, val conversionScope: Conver
|
|||||||
nullability = superSignatures.map { methodNullability(it.getMethod()) }.firstOrNull { it != Nullability.Default } ?: Nullability.Default
|
nullability = superSignatures.map { methodNullability(it.getMethod()) }.firstOrNull { it != Nullability.Default } ?: Nullability.Default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// methods of types like Integer are most likely nullable
|
||||||
|
if (nullability == Nullability.Default && returnType?.getCanonicalText() in boxingTypes) {
|
||||||
|
return Nullability.Nullable
|
||||||
|
}
|
||||||
|
|
||||||
if (!conversionScope.contains(method)) return nullability // do not analyze body and usages of methods out of our conversion scope
|
if (!conversionScope.contains(method)) return nullability // do not analyze body and usages of methods out of our conversion scope
|
||||||
|
|
||||||
if (nullability == Nullability.Default) {
|
if (nullability == Nullability.Default) {
|
||||||
@@ -265,4 +277,17 @@ class TypeConverter(val settings: ConverterSettings, val conversionScope: Conver
|
|||||||
else
|
else
|
||||||
Nullability.Default
|
Nullability.Default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class object {
|
||||||
|
private val boxingTypes: Set<String> = setOf(
|
||||||
|
CommonClassNames.JAVA_LANG_BYTE,
|
||||||
|
CommonClassNames.JAVA_LANG_CHARACTER,
|
||||||
|
CommonClassNames.JAVA_LANG_DOUBLE,
|
||||||
|
CommonClassNames.JAVA_LANG_FLOAT,
|
||||||
|
CommonClassNames.JAVA_LANG_INTEGER,
|
||||||
|
CommonClassNames.JAVA_LANG_LONG,
|
||||||
|
CommonClassNames.JAVA_LANG_SHORT,
|
||||||
|
CommonClassNames.JAVA_LANG_BOOLEAN
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
class A() {
|
class A() {
|
||||||
private var i = getByte().toInt()
|
private var i: Int? = getByte().toInt()
|
||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
i = 10
|
i = 10
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ class F() {
|
|||||||
|
|
||||||
fun f2() {
|
fun f2() {
|
||||||
}
|
}
|
||||||
var i = 0
|
var i: Int? = 0
|
||||||
|
|
||||||
fun f3() {
|
fun f3() {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class F() {
|
|||||||
|
|
||||||
fun f2() {
|
fun f2() {
|
||||||
}
|
}
|
||||||
var i = 0
|
var i: Int? = 0
|
||||||
|
|
||||||
fun f3() {
|
fun f3() {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class F() {
|
|||||||
|
|
||||||
fun f1() {
|
fun f1() {
|
||||||
}
|
}
|
||||||
var i = 0
|
var i: Int? = 0
|
||||||
|
|
||||||
//c5
|
//c5
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class F() {
|
|||||||
|
|
||||||
fun f2() {
|
fun f2() {
|
||||||
}
|
}
|
||||||
var i = 0
|
var i: Int? = 0
|
||||||
|
|
||||||
fun f3() {
|
fun f3() {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package demo
|
package demo
|
||||||
|
|
||||||
class Test() {
|
class Test() {
|
||||||
fun putInt(i: Int) {
|
fun putInt(i: Int?) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package demo
|
package demo
|
||||||
|
|
||||||
class Test() {
|
class Test() {
|
||||||
fun putInt(i: Int) {
|
fun putInt(i: Int?) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package demo
|
package demo
|
||||||
|
|
||||||
class Test(i: Int) {
|
class Test(i: Int?) {
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
val i = 10
|
val i = 10
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package demo
|
package demo
|
||||||
|
|
||||||
class Test() {
|
class Test() {
|
||||||
fun getInteger(i: Int): Int {
|
fun getInteger(i: Int?): Int? {
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
val i = getInteger(10)
|
val i = getInteger(10)!!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
fun foo(i: Int) {
|
fun foo(i: Int?) {
|
||||||
var i1 = i
|
var i1 = i!!
|
||||||
i1++
|
i1++
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
fun foo(b: Byte) {
|
fun foo(b: Byte) {
|
||||||
var i = b.toInt()
|
var i: Int? = b.toInt()
|
||||||
if (p) i = 10
|
if (p) i = 10
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user