New J2K: Add conversion of prefix and postfix expressions
This commit is contained in:
committed by
Ilya Kirillov
parent
3d418d8904
commit
9374816823
@@ -23,7 +23,7 @@ object ConversionsRunner {
|
|||||||
|
|
||||||
private fun createRootConversion(context: ConversionContext) =
|
private fun createRootConversion(context: ConversionContext) =
|
||||||
batchPipe {
|
batchPipe {
|
||||||
+BinaryExpressionConversion(context)
|
+OperatorExpressionConversion(context)
|
||||||
+ThrowStatementConversion()
|
+ThrowStatementConversion()
|
||||||
+ArrayInitializerConversion(context)
|
+ArrayInitializerConversion(context)
|
||||||
+TryStatementConversion(context)
|
+TryStatementConversion(context)
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.j2k.conversions
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.j2k.ConversionContext
|
|
||||||
import org.jetbrains.kotlin.j2k.tree.JKBinaryExpression
|
|
||||||
import org.jetbrains.kotlin.j2k.tree.JKBranchElement
|
|
||||||
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
|
|
||||||
import org.jetbrains.kotlin.j2k.tree.impl.JKBinaryExpressionImpl
|
|
||||||
import org.jetbrains.kotlin.j2k.tree.impl.JKJavaOperatorImpl
|
|
||||||
import org.jetbrains.kotlin.j2k.tree.impl.toKtToken
|
|
||||||
import org.jetbrains.kotlin.j2k.kotlinBinaryExpression
|
|
||||||
|
|
||||||
|
|
||||||
class BinaryExpressionConversion(private val context: ConversionContext) : RecursiveApplicableConversionBase() {
|
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
|
||||||
if (element !is JKBinaryExpression) return recurse(element)
|
|
||||||
val ktOperatorToken = (element.operator as? JKJavaOperatorImpl)?.token?.toKtToken() ?: return recurse(element)
|
|
||||||
val left = recurse(element.left)
|
|
||||||
val right = recurse(element.right)
|
|
||||||
(element as? JKBranchElement)?.invalidate()
|
|
||||||
val ktBinaryExpression = kotlinBinaryExpression(left, right, ktOperatorToken, context)
|
|
||||||
?: return JKBinaryExpressionImpl(left, right, element.operator)
|
|
||||||
return recurse(ktBinaryExpression)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.j2k.conversions
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.j2k.ConversionContext
|
||||||
|
import org.jetbrains.kotlin.j2k.kotlinBinaryExpression
|
||||||
|
import org.jetbrains.kotlin.j2k.kotlinPostfixExpression
|
||||||
|
import org.jetbrains.kotlin.j2k.kotlinPrefixExpression
|
||||||
|
import org.jetbrains.kotlin.j2k.tree.*
|
||||||
|
import org.jetbrains.kotlin.j2k.tree.impl.JKJavaOperatorImpl
|
||||||
|
import org.jetbrains.kotlin.j2k.tree.impl.toKtToken
|
||||||
|
|
||||||
|
|
||||||
|
class OperatorExpressionConversion(private val context: ConversionContext) : RecursiveApplicableConversionBase() {
|
||||||
|
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||||
|
val operatorToken =
|
||||||
|
((when (element) {
|
||||||
|
is JKBinaryExpression ->
|
||||||
|
element.operator
|
||||||
|
is JKPrefixExpression ->
|
||||||
|
element.operator
|
||||||
|
is JKPostfixExpression ->
|
||||||
|
element.operator
|
||||||
|
else -> null
|
||||||
|
} as? JKJavaOperatorImpl)?.token)?.toKtToken() ?: return recurse(element)
|
||||||
|
|
||||||
|
return when (element) {
|
||||||
|
is JKBinaryExpression -> {
|
||||||
|
val left = applyToElement(element::left.detached()) as JKExpression
|
||||||
|
val right = applyToElement(element::right.detached()) as JKExpression
|
||||||
|
recurse(kotlinBinaryExpression(left, right, operatorToken, context)!!)
|
||||||
|
}
|
||||||
|
is JKPrefixExpression -> {
|
||||||
|
val operand = applyToElement(element::expression.detached()) as JKExpression
|
||||||
|
recurse(kotlinPrefixExpression(operand, operatorToken, context))
|
||||||
|
}
|
||||||
|
is JKPostfixExpression -> {
|
||||||
|
val operand = applyToElement(element::expression.detached()) as JKExpression
|
||||||
|
recurse(kotlinPostfixExpression(operand, operatorToken, context))
|
||||||
|
}
|
||||||
|
else -> recurse(element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,28 +22,29 @@ fun kotlinTypeByName(name: String, symbolProvider: JKSymbolProvider): JKClassTyp
|
|||||||
return JKClassTypeImpl(symbol, emptyList())
|
return JKClassTypeImpl(symbol, emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JKKtOperatorToken.methodSymbol(
|
private fun JKType.classSymbol(symbolProvider: JKSymbolProvider) =
|
||||||
|
when (this) {
|
||||||
|
is JKClassType -> classReference as JKMultiverseKtClassSymbol
|
||||||
|
is JKJavaPrimitiveType -> {
|
||||||
|
val psiClass = resolveFqName(
|
||||||
|
ClassId.fromString(jvmPrimitiveType.primitiveType.typeFqName.asString()),
|
||||||
|
symbolProvider.symbolsByPsi.keys.first()
|
||||||
|
)!!
|
||||||
|
symbolProvider.provideDirectSymbol(psiClass) as JKMultiverseKtClassSymbol
|
||||||
|
}
|
||||||
|
else ->
|
||||||
|
TODO(this::class.java.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun JKKtOperatorToken.binaryExpressionMethodSymbol(
|
||||||
leftType: JKType,
|
leftType: JKType,
|
||||||
rightType: JKType,
|
rightType: JKType,
|
||||||
symbolProvider: JKSymbolProvider
|
symbolProvider: JKSymbolProvider
|
||||||
): JKMethodSymbol {
|
): JKMethodSymbol {
|
||||||
val classSymbol =
|
|
||||||
when (leftType) {
|
|
||||||
is JKClassType -> leftType.classReference as JKMultiverseKtClassSymbol
|
|
||||||
is JKJavaPrimitiveType -> {
|
|
||||||
val psiClass = resolveFqName(
|
|
||||||
ClassId.fromString(leftType.jvmPrimitiveType.primitiveType.typeFqName.asString()),
|
|
||||||
symbolProvider.symbolsByPsi.keys.first()
|
|
||||||
)!!
|
|
||||||
symbolProvider.provideDirectSymbol(psiClass) as JKMultiverseKtClassSymbol
|
|
||||||
}
|
|
||||||
else ->
|
|
||||||
TODO(leftType::class.java.toString())
|
|
||||||
}
|
|
||||||
val operatorNames =
|
val operatorNames =
|
||||||
if (operatorName == "equals") listOf("equals", "compareTo")
|
if (operatorName == "equals") listOf("equals", "compareTo")
|
||||||
else listOf(operatorName)
|
else listOf(operatorName)
|
||||||
return classSymbol.target.declarations// todo look for extensions
|
return leftType.classSymbol(symbolProvider).target.declarations// todo look for extensions
|
||||||
.asSequence()
|
.asSequence()
|
||||||
.filterIsInstance<KtNamedFunction>()
|
.filterIsInstance<KtNamedFunction>()
|
||||||
.filter { it.name in operatorNames }
|
.filter { it.name in operatorNames }
|
||||||
@@ -51,6 +52,17 @@ private fun JKKtOperatorToken.methodSymbol(
|
|||||||
.firstOrNull { it.parameterTypes.singleOrNull()?.takeIf { it.isSubtypeOf(rightType, symbolProvider) } != null }!!
|
.firstOrNull { it.parameterTypes.singleOrNull()?.takeIf { it.isSubtypeOf(rightType, symbolProvider) } != null }!!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun JKKtOperatorToken.unaryExpressionMethodSymbol(
|
||||||
|
operandType: JKType,
|
||||||
|
symbolProvider: JKSymbolProvider
|
||||||
|
): JKMethodSymbol =
|
||||||
|
operandType.classSymbol(symbolProvider).target.declarations// todo look for extensions
|
||||||
|
.asSequence()
|
||||||
|
.filterIsInstance<KtNamedFunction>()
|
||||||
|
.filter { it.name == operatorName }
|
||||||
|
.mapNotNull { symbolProvider.provideDirectSymbol(it) as? JKMethodSymbol }
|
||||||
|
.firstOrNull()!!
|
||||||
|
|
||||||
|
|
||||||
fun kotlinBinaryExpression(
|
fun kotlinBinaryExpression(
|
||||||
left: JKExpression,
|
left: JKExpression,
|
||||||
@@ -60,10 +72,32 @@ fun kotlinBinaryExpression(
|
|||||||
): JKBinaryExpression? {
|
): JKBinaryExpression? {
|
||||||
val leftType = left.type(context)
|
val leftType = left.type(context)
|
||||||
val rightType = right.type(context)
|
val rightType = right.type(context)
|
||||||
val methodSymbol = token.methodSymbol(leftType, rightType, context.symbolProvider)
|
val methodSymbol = token.binaryExpressionMethodSymbol(leftType, rightType, context.symbolProvider)
|
||||||
return JKBinaryExpressionImpl(left, right, JKKtOperatorImpl(token, methodSymbol))
|
return JKBinaryExpressionImpl(left, right, JKKtOperatorImpl(token, methodSymbol))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun kotlinPrefixExpression(
|
||||||
|
operand: JKExpression,
|
||||||
|
token: JKKtOperatorToken,
|
||||||
|
context: ConversionContext
|
||||||
|
): JKPrefixExpression {
|
||||||
|
val operandType = operand.type(context)
|
||||||
|
val methodSymbol = token.unaryExpressionMethodSymbol(operandType, context.symbolProvider)
|
||||||
|
return JKPrefixExpressionImpl(operand, JKKtOperatorImpl(token, methodSymbol))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun kotlinPostfixExpression(
|
||||||
|
operand: JKExpression,
|
||||||
|
token: JKKtOperatorToken,
|
||||||
|
context: ConversionContext
|
||||||
|
): JKPostfixExpression {
|
||||||
|
val operandType = operand.type(context)
|
||||||
|
val methodSymbol = token.unaryExpressionMethodSymbol(operandType, context.symbolProvider)
|
||||||
|
return JKPostfixExpressionImpl(operand, JKKtOperatorImpl(token, methodSymbol))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun untilToExpression(
|
fun untilToExpression(
|
||||||
from: JKExpression,
|
from: JKExpression,
|
||||||
to: JKExpression,
|
to: JKExpression,
|
||||||
|
|||||||
@@ -130,6 +130,8 @@ fun JKJavaOperatorToken.toKtToken(): JKKtOperatorToken =
|
|||||||
JavaTokenType.NE -> JKKtSingleValueOperatorToken(KtTokens.EXCLEQ)
|
JavaTokenType.NE -> JKKtSingleValueOperatorToken(KtTokens.EXCLEQ)
|
||||||
JavaTokenType.PLUSEQ -> JKKtSingleValueOperatorToken(KtTokens.PLUSEQ)
|
JavaTokenType.PLUSEQ -> JKKtSingleValueOperatorToken(KtTokens.PLUSEQ)
|
||||||
JavaTokenType.MINUSEQ -> JKKtSingleValueOperatorToken(KtTokens.MINUSEQ)
|
JavaTokenType.MINUSEQ -> JKKtSingleValueOperatorToken(KtTokens.MINUSEQ)
|
||||||
|
JavaTokenType.PLUSPLUS -> JKKtSingleValueOperatorToken(KtTokens.PLUSPLUS)
|
||||||
|
JavaTokenType.MINUSMINUS -> JKKtSingleValueOperatorToken(KtTokens.MINUSMINUS)
|
||||||
|
|
||||||
JavaTokenType.AND -> JKKtWordOperatorToken("and")
|
JavaTokenType.AND -> JKKtWordOperatorToken("and")
|
||||||
JavaTokenType.OR -> JKKtWordOperatorToken("or")
|
JavaTokenType.OR -> JKKtWordOperatorToken("or")
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ fun JKExpression.type(context: ConversionContext): JKType =
|
|||||||
kotlinTypeByName("kotlin.Boolean", context.symbolProvider)
|
kotlinTypeByName("kotlin.Boolean", context.symbolProvider)
|
||||||
} else operatorSymbol.returnType
|
} else operatorSymbol.returnType
|
||||||
}
|
}
|
||||||
|
is JKPostfixExpressionImpl ->
|
||||||
|
(operator as JKKtOperatorImpl).methodSymbol.returnType
|
||||||
|
is JKPrefixExpression ->
|
||||||
|
(operator as JKKtOperatorImpl).methodSymbol.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(context)
|
||||||
|
|||||||
Reference in New Issue
Block a user