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 {
|
||||
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()
|
||||
|
||||
@@ -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 (variable is PsiParameter) {
|
||||
// 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 {
|
||||
if (method.getReturnType() is PsiPrimitiveType) return Nullability.NotNull
|
||||
val returnType = method.getReturnType()
|
||||
if (returnType is PsiPrimitiveType) return Nullability.NotNull
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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 (nullability == Nullability.Default) {
|
||||
@@ -265,4 +277,17 @@ class TypeConverter(val settings: ConverterSettings, val conversionScope: Conver
|
||||
else
|
||||
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() {
|
||||
private var i = getByte().toInt()
|
||||
private var i: Int? = getByte().toInt()
|
||||
|
||||
fun foo() {
|
||||
i = 10
|
||||
|
||||
@@ -5,7 +5,7 @@ class F() {
|
||||
|
||||
fun f2() {
|
||||
}
|
||||
var i = 0
|
||||
var i: Int? = 0
|
||||
|
||||
fun f3() {
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class F() {
|
||||
|
||||
fun f2() {
|
||||
}
|
||||
var i = 0
|
||||
var i: Int? = 0
|
||||
|
||||
fun f3() {
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ class F() {
|
||||
|
||||
fun f1() {
|
||||
}
|
||||
var i = 0
|
||||
var i: Int? = 0
|
||||
|
||||
//c5
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ class F() {
|
||||
|
||||
fun f2() {
|
||||
}
|
||||
var i = 0
|
||||
var i: Int? = 0
|
||||
|
||||
fun f3() {
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package demo
|
||||
|
||||
class Test() {
|
||||
fun putInt(i: Int) {
|
||||
fun putInt(i: Int?) {
|
||||
}
|
||||
|
||||
fun test() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package demo
|
||||
|
||||
class Test() {
|
||||
fun putInt(i: Int) {
|
||||
fun putInt(i: Int?) {
|
||||
}
|
||||
|
||||
fun test() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package demo
|
||||
|
||||
class Test(i: Int) {
|
||||
class Test(i: Int?) {
|
||||
|
||||
fun test() {
|
||||
val i = 10
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package demo
|
||||
|
||||
class Test() {
|
||||
fun getInteger(i: Int): Int {
|
||||
fun getInteger(i: Int?): Int? {
|
||||
return i
|
||||
}
|
||||
|
||||
fun test() {
|
||||
val i = getInteger(10)
|
||||
val i = getInteger(10)!!
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
fun foo(i: Int) {
|
||||
var i1 = i
|
||||
fun foo(i: Int?) {
|
||||
var i1 = i!!
|
||||
i1++
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
fun foo(b: Byte) {
|
||||
var i = b.toInt()
|
||||
var i: Int? = b.toInt()
|
||||
if (p) i = 10
|
||||
}
|
||||
Reference in New Issue
Block a user