Java to Kotlin converter: added heuristics that values of types like Integer are likely nullable

This commit is contained in:
Valentin Kipyatkov
2014-06-25 00:04:14 +04:00
parent 30a7c67aaa
commit 427280a365
12 changed files with 40 additions and 15 deletions
+27 -2
View File
@@ -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 -1
View File
@@ -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
}