Java to Kotlin converter: added nullability calculation caching

This commit is contained in:
Valentin Kipyatkov
2014-06-09 15:58:31 +04:00
parent 1491e0e5a7
commit 2d4d5e2a34
3 changed files with 38 additions and 28 deletions
+28 -8
View File
@@ -20,8 +20,11 @@ import org.jetbrains.jet.j2k.ast.Type
import org.jetbrains.jet.j2k.ast.Nullability
import com.intellij.psi.*
import org.jetbrains.jet.j2k.visitors.TypeVisitor
import java.util.HashMap
class TypeConverter(val settings: ConverterSettings) {
private val nullabilityCache = HashMap<PsiElement, Nullability>()
public fun convertType(`type`: PsiType?, nullability: Nullability = Nullability.Default): Type {
if (`type` == null) return Type.Empty
@@ -33,15 +36,21 @@ class TypeConverter(val settings: ConverterSettings) {
}
}
public fun convertTypes(types: Array<PsiType>): List<Type> {
return types.map { convertType(it) }
}
public fun convertTypes(types: Array<PsiType>): List<Type>
= types.map { convertType(it) }
public fun convertVariableType(variable: PsiVariable): Type {
return convertType(variable.getType(), variableNullability(variable))
}
public fun convertVariableType(variable: PsiVariable): Type
= convertType(variable.getType(), variableNullability(variable))
public fun variableNullability(variable: PsiVariable): Nullability {
val cached = nullabilityCache[variable]
if (cached != null) return cached
val value = variableNullabilityNoCache(variable)
nullabilityCache[variable] = value
return value
}
private fun variableNullabilityNoCache(variable: PsiVariable): Nullability {
if (variable is PsiEnumConstant) return Nullability.NotNull
var nullability = variable.nullabilityFromAnnotations()
@@ -91,7 +100,18 @@ class TypeConverter(val settings: ConverterSettings) {
return nullability
}
public fun convertMethodReturnType(method: PsiMethod): Type {
public fun convertMethodReturnType(method: PsiMethod): Type
= convertType(method.getReturnType(), methodNullability(method))
public fun methodNullability(method: PsiMethod): Nullability {
val cached = nullabilityCache[method]
if (cached != null) return cached
val value = methodNullabilityNoCache(method)
nullabilityCache[method] = value
return value
}
private fun methodNullabilityNoCache(method: PsiMethod): Nullability {
var nullability = method.nullabilityFromAnnotations()
if (nullability == Nullability.Default) {
@@ -117,7 +137,7 @@ class TypeConverter(val settings: ConverterSettings) {
}
}
return convertType(method.getReturnType(), nullability)
return nullability
}
private fun searchScope(element: PsiElement): PsiElement? {
+7 -6
View File
@@ -16,7 +16,6 @@
package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.Converter
import java.util.ArrayList
import org.jetbrains.jet.j2k.ConverterSettings
@@ -29,12 +28,14 @@ enum class Nullability {
Default
}
fun Nullability.isNullable(settings: ConverterSettings) = when(this) {
Nullability.Nullable -> true
Nullability.NotNull -> false
Nullability.Default -> !settings.forceNotNullTypes
}
abstract class MayBeNullableType(nullability: Nullability, val settings: ConverterSettings) : Type {
override val isNullable: Boolean = when (nullability) {
Nullability.Nullable -> true
Nullability.NotNull -> false
Nullability.Default -> !settings.forceNotNullTypes
}
override val isNullable: Boolean = nullability.isNullable(settings)
}
trait NotNullType : Type {
@@ -34,7 +34,6 @@ import org.jetbrains.jet.lang.psi.psiUtil.isExtensionDeclaration
import org.jetbrains.jet.lang.psi.JetPropertyAccessor
import com.intellij.psi.impl.light.LightField
import org.jetbrains.jet.lang.resolve.java.JvmAbi
import org.jetbrains.jet.lang.psi.JetNullableType
class ExpressionVisitor(private val converter: Converter,
private val typeConverter: TypeConverter,
@@ -153,7 +152,7 @@ class ExpressionVisitor(private val converter: Converter,
val methodExpr = expression.getMethodExpression()
val arguments = expression.getArgumentList().getExpressions()
val target = methodExpr.resolve()
val isNullable = if (target is PsiMethod) typeConverter.convertMethodReturnType(target).isNullable else false
val isNullable = if (target is PsiMethod) typeConverter.methodNullability(target).isNullable(converter.settings) else false
val typeArguments = typeConverter.convertTypes(expression.getTypeArguments())
if (target is KotlinLightMethod) {
@@ -295,7 +294,8 @@ class ExpressionVisitor(private val converter: Converter,
}
override fun visitReferenceExpression(expression: PsiReferenceExpression) {
val isNullable = typeConverter.convertType(expression.getType(), expression.nullability()).isNullable
val target = expression.getReference()?.resolve()
val isNullable = if (target is PsiVariable) typeConverter.variableNullability(target).isNullable(converter.settings) else false
val referencedName = expression.getReferenceName()!!
var identifier: Expression = Identifier(referencedName, isNullable)
val qualifier = expression.getQualifierExpression()
@@ -314,7 +314,6 @@ class ExpressionVisitor(private val converter: Converter,
}
else if (qualifier != null) {
if (referencedName == JvmAbi.CLASS_OBJECT_FIELD || referencedName == JvmAbi.INSTANCE_FIELD) {
val target = expression.getReference()?.resolve()
if (target is LightField) { //TODO: should be KotlinLightField with check of origin here, see KT-5188
result = converter.convertExpression(qualifier)
return
@@ -322,8 +321,6 @@ class ExpressionVisitor(private val converter: Converter,
}
}
else {
val target = expression.getReference()?.resolve()
if (target is PsiClass) {
if (PrimitiveType.values() any { it.getTypeName().asString() == target.getName() }) {
result = Identifier(target.getQualifiedName()!!, false)
@@ -358,14 +355,6 @@ class ExpressionVisitor(private val converter: Converter,
result = QualifiedExpression(converter.convertExpression(qualifier), identifier)
}
private fun PsiReference.nullability(): Nullability {
val target = resolve()
return when(target) {
is PsiVariable -> typeConverter.variableNullability(target)
else -> Nullability.Default
}
}
override fun visitSuperExpression(expression: PsiSuperExpression) {
val qualifier = expression.getQualifier()
result = SuperExpression(if (qualifier != null) Identifier(qualifier.getQualifiedName()!!) else Identifier.Empty)