Java to Kotlin converter: honor external Nullable/NotNull annotations
This commit is contained in:
@@ -2,4 +2,8 @@
|
|||||||
<item name='com.intellij.codeInsight.CodeInsightSettings com.intellij.codeInsight.CodeInsightSettings getInstance()'>
|
<item name='com.intellij.codeInsight.CodeInsightSettings com.intellij.codeInsight.CodeInsightSettings getInstance()'>
|
||||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
</item>
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.codeInsight.NullableNotNullManager com.intellij.codeInsight.NullableNotNullManager getInstance(com.intellij.openapi.project.Project)'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
</root>
|
</root>
|
||||||
@@ -28,6 +28,7 @@ import org.jetbrains.jet.j2k.ast.assignPrototype
|
|||||||
import com.intellij.psi.CommonClassNames.JAVA_LANG_OBJECT
|
import com.intellij.psi.CommonClassNames.JAVA_LANG_OBJECT
|
||||||
import org.jetbrains.jet.j2k.ast.assignNoPrototype
|
import org.jetbrains.jet.j2k.ast.assignNoPrototype
|
||||||
import org.jetbrains.jet.j2k.ast.ErrorType
|
import org.jetbrains.jet.j2k.ast.ErrorType
|
||||||
|
import com.intellij.codeInsight.NullableNotNullManager
|
||||||
|
|
||||||
class TypeConverter(val settings: ConverterSettings, val conversionScope: ConversionScope) {
|
class TypeConverter(val settings: ConverterSettings, val conversionScope: ConversionScope) {
|
||||||
private val nullabilityCache = HashMap<PsiElement, Nullability>()
|
private val nullabilityCache = HashMap<PsiElement, Nullability>()
|
||||||
@@ -274,4 +275,14 @@ class TypeConverter(val settings: ConverterSettings, val conversionScope: Conver
|
|||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun PsiModifierListOwner.nullabilityFromAnnotations(): Nullability {
|
||||||
|
val manager = NullableNotNullManager.getInstance(getProject())
|
||||||
|
return if (manager.isNotNull(this, false/* we do not check bases because they are checked by callers of this method*/))
|
||||||
|
Nullability.NotNull
|
||||||
|
else if (manager.isNullable(this, false))
|
||||||
|
Nullability.Nullable
|
||||||
|
else
|
||||||
|
Nullability.Default
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ import com.intellij.psi.util.PsiUtil
|
|||||||
import com.intellij.psi.search.LocalSearchScope
|
import com.intellij.psi.search.LocalSearchScope
|
||||||
import com.intellij.psi.search.searches.ReferencesSearch
|
import com.intellij.psi.search.searches.ReferencesSearch
|
||||||
import org.jetbrains.jet.j2k.ast.*
|
import org.jetbrains.jet.j2k.ast.*
|
||||||
|
import com.intellij.codeInsight.AnnotationUtil
|
||||||
|
import com.intellij.codeInsight.NullableNotNullManager
|
||||||
|
|
||||||
fun quoteKeywords(packageName: String): String = packageName.split("\\.").map { Identifier.toKotlin(it) }.makeString(".")
|
fun quoteKeywords(packageName: String): String = packageName.split("\\.").map { Identifier.toKotlin(it) }.makeString(".")
|
||||||
|
|
||||||
@@ -47,16 +49,6 @@ fun PsiVariable.countWriteAccesses(scope: PsiElement?): Int
|
|||||||
fun PsiVariable.hasWriteAccesses(scope: PsiElement?): Boolean
|
fun PsiVariable.hasWriteAccesses(scope: PsiElement?): Boolean
|
||||||
= if (scope != null) findVariableUsages(this, scope).any { PsiUtil.isAccessedForWriting(it) } else false
|
= if (scope != null) findVariableUsages(this, scope).any { PsiUtil.isAccessedForWriting(it) } else false
|
||||||
|
|
||||||
fun PsiModifierListOwner.nullabilityFromAnnotations(): Nullability {
|
|
||||||
val annotations = getModifierList()?.getAnnotations() ?: return Nullability.Default
|
|
||||||
return if (annotations.any { NOT_NULL_ANNOTATIONS.contains(it.getQualifiedName()) })
|
|
||||||
Nullability.NotNull
|
|
||||||
else if (annotations.any { NULLABLE_ANNOTATIONS.contains(it.getQualifiedName()) })
|
|
||||||
Nullability.Nullable
|
|
||||||
else
|
|
||||||
Nullability.Default
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getDefaultInitializer(field: Field): Expression {
|
fun getDefaultInitializer(field: Field): Expression {
|
||||||
val t = field.`type`
|
val t = field.`type`
|
||||||
val result = if (t.isNullable) {
|
val result = if (t.isNullable) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package demo
|
package demo
|
||||||
|
|
||||||
class Test() : Iterable<String> {
|
class Test() : Iterable<String> {
|
||||||
override fun iterator(): Iterator<String>? {
|
override fun iterator(): Iterator<String> {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ class Test() : Iterable<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class FullTest() : Iterable<String> {
|
class FullTest() : Iterable<String> {
|
||||||
override fun iterator(): Iterator<String>? {
|
override fun iterator(): Iterator<String> {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import java.util.*
|
|||||||
import kotlin.Iterator
|
import kotlin.Iterator
|
||||||
|
|
||||||
class Test() : Iterable<String> {
|
class Test() : Iterable<String> {
|
||||||
override fun iterator(): Iterator<String>? {
|
override fun iterator(): Iterator<String> {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ class Test() : Iterable<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class FullTest() : Iterable<String> {
|
class FullTest() : Iterable<String> {
|
||||||
override fun iterator(): Iterator<String>? {
|
override fun iterator(): Iterator<String> {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package demo
|
package demo
|
||||||
|
|
||||||
class Test() : Iterable<String> {
|
class Test() : Iterable<String> {
|
||||||
override fun iterator(): Iterator<String>? {
|
override fun iterator(): Iterator<String> {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user