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