New J2K: Replace conversionContext to symbolProvider in JKExpression.type function

This commit is contained in:
Ilya Kirillov
2019-01-16 14:23:48 +03:00
committed by Ilya Kirillov
parent 8df99e54f8
commit 3990e1d223
10 changed files with 44 additions and 43 deletions
@@ -22,7 +22,7 @@ class ArrayOperationsConversion(private val context: ConversionContext) : Recurs
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKQualifiedExpression) return recurse(element)
val selector = element.selector as? JKFieldAccessExpression ?: return recurse(element)
if (element.receiver.type(context) !is JKJavaArrayType) return recurse(element)
if (element.receiver.type(context.symbolProvider) !is JKJavaArrayType) return recurse(element)
if (selector.identifier.name == "length") {
val sizeCall =
JKFieldAccessExpressionImpl(
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.j2k.tree.impl.JKFieldAccessExpressionImpl
class CollectionOperationsConversion(private val context: ConversionContext) : RecursiveApplicableConversionBase() {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKQualifiedExpression) return recurse(element)
val receiverType = element.receiver.type(context) ?: return recurse(element)
val receiverType = element.receiver.type(context.symbolProvider) ?: return recurse(element)
if (!receiverType.isCollectionType(context.symbolProvider)) return recurse(element)
convertSizeCall(element.selector)?.also {
@@ -25,7 +25,7 @@ class CollectionOperationsConversion(private val context: ConversionContext) : R
private fun convertSizeCall(selector: JKExpression): JKFieldAccessExpressionImpl? {
if (selector !is JKMethodCallExpression) return null
return if (selector.identifier.name =="size") {
return if (selector.identifier.name == "size") {
JKFieldAccessExpressionImpl(context.symbolProvider.provideByFqName("kotlin.collections.Collection.size"))
} else null
}
@@ -175,7 +175,7 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
start,
convertBound(bound, if (inclusiveComparison) 0 else -1),
JKKtSingleValueOperatorToken(KtTokens.RANGE),
context
context.symbolProvider
)!!
}
}
@@ -193,7 +193,7 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
bound,
JKKtLiteralExpressionImpl(Math.abs(correction).toString(), JKLiteralExpression.LiteralType.INT),
JKKtSingleValueOperatorToken(sign),
context
context.symbolProvider
)!!
}
@@ -239,7 +239,7 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
private fun indicesByCollectionSize(javaSizeCall: JKQualifiedExpression): JKQualifiedExpression? {
val methodCall = javaSizeCall.selector as? JKMethodCallExpression ?: return null
val receiverType = javaSizeCall.receiver.type(context) ?: return null
val receiverType = javaSizeCall.receiver.type(context.symbolProvider) ?: return null
if (methodCall.identifier.name == "size"
&& methodCall.arguments.expressions.isEmpty()
&& receiverType.isCollectionType(context.symbolProvider)
@@ -251,7 +251,7 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
private fun indicesByArrayLength(javaSizeCall: JKQualifiedExpression): JKQualifiedExpression? {
val methodCall = javaSizeCall.selector as? JKFieldAccessExpression ?: return null
val receiverType = javaSizeCall.receiver.type(context)
val receiverType = javaSizeCall.receiver.type(context.symbolProvider)
if (methodCall.identifier.name == "length" && receiverType is JKJavaArrayType) {
return toIndicesCall(javaSizeCall)
}
@@ -32,14 +32,14 @@ class ImplicitCastsConversion(private val context: ConversionContext) : Recursiv
}
private fun convertForInStatement(forInStatement: JKForInStatement) {
val notNullType = forInStatement.iterationExpression.type(context)?.updateNullability(Nullability.NotNull) ?: return
val notNullType = forInStatement.iterationExpression.type(context.symbolProvider)?.updateNullability(Nullability.NotNull) ?: return
forInStatement.iterationExpression.addBangBang(notNullType)?.also {
forInStatement.iterationExpression = it
}
}
private fun convertAssignmentStatement(statement: JKKtAssignmentStatement) {
val expressionType = statement.field.type(context) ?: return
val expressionType = statement.field.type(context.symbolProvider) ?: return
statement.expression.castTo(expressionType)?.also {
statement.expression = it
}
@@ -67,18 +67,19 @@ class ImplicitCastsConversion(private val context: ConversionContext) : Recursiv
private fun JKExpression.addBangBang(toType: JKType): JKExpression? {
val expressionType = type(context) as? JKClassType ?: return null
if (this is JKJavaNewExpression) return null
val expressionType = type(context.symbolProvider) as? JKClassType ?: return null
if (toType !is JKClassType) return null
if (expressionType.classReference == toType.classReference
&& expressionType.isNullable() && !toType.isNullable()
) {
return this.copyTreeAndDetach().bangedBangedExpr(context)
return this.copyTreeAndDetach().bangedBangedExpr(context.symbolProvider)
}
return null
}
private fun JKExpression.castToAsPrimitiveTypes(toType: JKType): JKExpression? {
val expressionTypeAsPrimitive = type(context)?.asPrimitiveType() ?: return null
val expressionTypeAsPrimitive = type(context.symbolProvider)?.asPrimitiveType() ?: return null
val toTypeAsPrimitive = toType.asPrimitiveType() ?: return null
if (toTypeAsPrimitive == expressionTypeAsPrimitive) return null
@@ -112,7 +113,7 @@ class ImplicitCastsConversion(private val context: ConversionContext) : Recursiv
private fun JKExpression.castTo(toType: JKType): JKExpression? {
val expressionType = type(context)
val expressionType = type(context.symbolProvider)
if (expressionType == toType) return null
castToAsPrimitiveTypes(toType)?.also { return it }
return addBangBang(toType)
@@ -15,12 +15,12 @@ class NullableQualifierConversion(private val context: ConversionContext) : Recu
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKQualifiedExpression) return recurse(element)
if (element.isSystemCall()) return recurse(element)// we don't want to have `System.err!!.println()` like expressions :)
if (element.receiver.type(context)?.nullability in listOf(Nullability.Nullable, Nullability.Default)
if (element.receiver.type(context.symbolProvider)?.nullability in listOf(Nullability.Nullable, Nullability.Default)
&& element.operator == JKJavaQualifierImpl.DOT || element.operator == JKKtQualifierImpl.DOT
) {
return recurse(
JKQualifiedExpressionImpl(
element::receiver.detached().bangedBangedExpr(context),
element::receiver.detached().bangedBangedExpr(context.symbolProvider),
element.operator,
element::selector.detached()
)
@@ -24,15 +24,15 @@ class OperatorExpressionConversion(private val context: ConversionContext) : Rec
is JKBinaryExpression -> {
val left = applyToElement(element::left.detached()) as JKExpression
val right = applyToElement(element::right.detached()) as JKExpression
kotlinBinaryExpression(left, right, operatorToken, context)?.let { recurse(it) }
kotlinBinaryExpression(left, right, operatorToken, context.symbolProvider)?.let { recurse(it) }
}
is JKPrefixExpression -> {
val operand = applyToElement(element::expression.detached()) as JKExpression
kotlinPrefixExpression(operand, operatorToken, context)?.let { recurse(it) }
kotlinPrefixExpression(operand, operatorToken, context.symbolProvider)?.let { recurse(it) }
}
is JKPostfixExpression -> {
val operand = applyToElement(element::expression.detached()) as JKExpression
kotlinPostfixExpression(operand, operatorToken, context)?.let { recurse(it) }
kotlinPostfixExpression(operand, operatorToken, context.symbolProvider)?.let { recurse(it) }
}
else -> TODO(element.javaClass.toString())
} ?: recurse(element)
@@ -38,7 +38,7 @@ class PolyadicExpressionConversion(private val context: ConversionContext) : Rec
val index = operators.indexOf(operator)
val left = convertPolyadic(operands.subList(0, index + 1), operators.subList(0, index))
val right = convertPolyadic(operands.subList(index + 1, operands.size), operators.subList(index + 1, operators.size))
kotlinBinaryExpression(left, right, token, context)!!
kotlinBinaryExpression(left, right, token, context.symbolProvider)!!
}
}
}
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.j2k.tree.impl.JKKtCallExpressionImpl
class StringMethodsConversion(private val context: ConversionContext) : RecursiveApplicableConversionBase() {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKQualifiedExpression) return recurse(element)
val receiverType = element.receiver.type(context) ?: return recurse(element)
val receiverType = element.receiver.type(context.symbolProvider) ?: return recurse(element)
if (!receiverType.isStringType()) return recurse(element)
convertLengthCall(element.selector)?.also {
@@ -118,31 +118,31 @@ fun kotlinBinaryExpression(
left: JKExpression,
right: JKExpression,
token: JKKtOperatorToken,
context: ConversionContext
symbolProvider: JKSymbolProvider
): JKBinaryExpression? {
val leftType = left.type(context) ?: return null
val rightType = right.type(context) ?: return null
val methodSymbol = token.binaryExpressionMethodSymbol(leftType, rightType, context.symbolProvider)
val leftType = left.type(symbolProvider) ?: return null
val rightType = right.type(symbolProvider) ?: return null
val methodSymbol = token.binaryExpressionMethodSymbol(leftType, rightType, symbolProvider)
return JKBinaryExpressionImpl(left, right, JKKtOperatorImpl(token, methodSymbol))
}
fun kotlinPrefixExpression(
operand: JKExpression,
token: JKKtOperatorToken,
context: ConversionContext
symbolProvider: JKSymbolProvider
): JKPrefixExpression? {
val operandType = operand.type(context) ?: return null
val methodSymbol = token.unaryExpressionMethodSymbol(operandType, context.symbolProvider)
val operandType = operand.type(symbolProvider) ?: return null
val methodSymbol = token.unaryExpressionMethodSymbol(operandType, symbolProvider)
return JKPrefixExpressionImpl(operand, JKKtOperatorImpl(token, methodSymbol))
}
fun kotlinPostfixExpression(
operand: JKExpression,
token: JKKtOperatorToken,
context: ConversionContext
symbolProvider: JKSymbolProvider
): JKPostfixExpression? {
val operandType = operand.type(context) ?: return null
val methodSymbol = token.unaryExpressionMethodSymbol(operandType, context.symbolProvider)
val operandType = operand.type(symbolProvider) ?: return null
val methodSymbol = token.unaryExpressionMethodSymbol(operandType, symbolProvider)
return JKPostfixExpressionImpl(operand, JKKtOperatorImpl(token, methodSymbol))
}
@@ -275,10 +275,10 @@ fun JKFieldAccessExpression.asAssignmentFromTarget(): JKKtAssignmentStatement? =
fun JKFieldAccessExpression.isInDecrementOrIncrement(): Boolean =
(parent as? JKUnaryExpression)?.operator?.token?.text in listOf("++", "--")
fun JKExpression.bangedBangedExpr(context: ConversionContext): JKExpression =
fun JKExpression.bangedBangedExpr(symbolProvider: JKSymbolProvider): JKExpression =
JKPostfixExpressionImpl(
this,
JKKtOperatorImpl(KtTokens.EXCLEXCL, JKExclExclMethod(type(context)!!))
JKKtOperatorImpl(KtTokens.EXCLEXCL, JKExclExclMethod(type(symbolProvider)!!))
)
fun JKVariable.hasWritableUsages(scope: JKTreeElement, context: ConversionContext): Boolean =
@@ -26,40 +26,40 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
fun JKExpression.type(context: ConversionContext): JKType? =
fun JKExpression.type(symbolProvider: JKSymbolProvider): JKType? =
when (this) {
is JKLiteralExpression -> type.toJkType(context.symbolProvider)
is JKLiteralExpression -> type.toJkType(symbolProvider)
is JKOperatorExpression -> {
if (operator !is JKKtOperatorImpl) {
error("Cannot get type of ${operator::class}, it should be first converted to KtOperator")
}
val operatorSymbol = (operator as JKKtOperatorImpl).methodSymbol
if (operatorSymbol.name == "compareTo") {
kotlinTypeByName("kotlin.Boolean", context.symbolProvider)
kotlinTypeByName("kotlin.Boolean", symbolProvider)
} else operatorSymbol.returnType
}
is JKMethodCallExpression -> identifier.returnType
is JKFieldAccessExpressionImpl -> identifier.fieldType
is JKQualifiedExpressionImpl -> this.selector.type(context)
is JKKtThrowExpression -> kotlinTypeByName(KotlinBuiltIns.FQ_NAMES.nothing.asString(), context.symbolProvider)
is JKQualifiedExpressionImpl -> this.selector.type(symbolProvider)
is JKKtThrowExpression -> kotlinTypeByName(KotlinBuiltIns.FQ_NAMES.nothing.asString(), symbolProvider)
is JKClassAccessExpression -> null
is JKJavaNewExpression -> JKClassTypeImpl(classSymbol)
is JKKtIsExpression -> kotlinTypeByName(KotlinBuiltIns.FQ_NAMES._boolean.asString(), context.symbolProvider)
is JKParenthesizedExpression -> expression.type(context)
is JKKtIsExpression -> kotlinTypeByName(KotlinBuiltIns.FQ_NAMES._boolean.asString(), symbolProvider)
is JKParenthesizedExpression -> expression.type(symbolProvider)
is JKTypeCastExpression -> type.type
is JKThisExpression -> null// TODO return actual type
is JKSuperExpression -> null// TODO return actual type
is JKStubExpression -> null
is JKIfElseExpression -> thenBranch.type(context)// TODO return actual type
is JKIfElseExpression -> thenBranch.type(symbolProvider)// TODO return actual type
is JKArrayAccessExpression ->
(expression.type(context) as? JKParametrizedType)?.parameters?.lastOrNull()
(expression.type(symbolProvider) as? JKParametrizedType)?.parameters?.lastOrNull()
is JKClassLiteralExpression -> {
val symbol = when (literalType) {
JKClassLiteralExpression.LiteralType.KOTLIN_CLASS ->
context.symbolProvider.provideByFqName<JKClassSymbol>("kotlin.reflect.KClass")
symbolProvider.provideByFqName<JKClassSymbol>("kotlin.reflect.KClass")
JKClassLiteralExpression.LiteralType.JAVA_CLASS,
JKClassLiteralExpression.LiteralType.JAVA_PRIMITIVE_CLASS, JKClassLiteralExpression.LiteralType.JAVA_VOID_TYPE ->
context.symbolProvider.provideByFqName("java.lang.Class")
symbolProvider.provideByFqName("java.lang.Class")
}
JKClassTypeImpl(symbol, listOf(classType.type), Nullability.NotNull)
}