New J2K: Add calculating type for binary expressions & building binary expression with correct return type
This commit is contained in:
committed by
Ilya Kirillov
parent
5e4b39f10f
commit
cd2a17ae56
@@ -23,6 +23,7 @@ object ConversionsRunner {
|
|||||||
|
|
||||||
private fun createRootConversion(context: ConversionContext) =
|
private fun createRootConversion(context: ConversionContext) =
|
||||||
batchPipe {
|
batchPipe {
|
||||||
|
+BinaryExpressionConversion(context)
|
||||||
+ArrayInitializerConversion(context)
|
+ArrayInitializerConversion(context)
|
||||||
+ModalityConversion(context)
|
+ModalityConversion(context)
|
||||||
+ImplicitInitializerConversion()
|
+ImplicitInitializerConversion()
|
||||||
@@ -47,7 +48,6 @@ object ConversionsRunner {
|
|||||||
+StaticsToCompanionExtractConversion()
|
+StaticsToCompanionExtractConversion()
|
||||||
+ClassToObjectPromotionConversion()
|
+ClassToObjectPromotionConversion()
|
||||||
+PolyadicExpressionConversion()
|
+PolyadicExpressionConversion()
|
||||||
+BinaryExpressionConversion()
|
|
||||||
+SwitchStatementConversion(context)
|
+SwitchStatementConversion(context)
|
||||||
+InstanceofConversion()
|
+InstanceofConversion()
|
||||||
+ForConversion(context)
|
+ForConversion(context)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class JKSymbolProvider {
|
|||||||
is KtClassOrObject -> JKMultiverseKtClassSymbol(psi)
|
is KtClassOrObject -> JKMultiverseKtClassSymbol(psi)
|
||||||
is PsiMethod -> JKMultiverseMethodSymbol(psi, this)
|
is PsiMethod -> JKMultiverseMethodSymbol(psi, this)
|
||||||
is PsiField -> JKMultiverseFieldSymbol(psi)
|
is PsiField -> JKMultiverseFieldSymbol(psi)
|
||||||
is KtNamedFunction -> JKMultiverseFunctionSymbol(psi)
|
is KtNamedFunction -> JKMultiverseFunctionSymbol(psi, this)
|
||||||
is KtProperty -> JKMultiversePropertySymbol(psi)
|
is KtProperty -> JKMultiversePropertySymbol(psi)
|
||||||
else -> TODO(psi::class.toString())
|
else -> TODO(psi::class.toString())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) {
|
|||||||
fun PsiArrayInitializerExpression.toJK(): JKExpression {
|
fun PsiArrayInitializerExpression.toJK(): JKExpression {
|
||||||
return JKJavaNewArrayImpl(
|
return JKJavaNewArrayImpl(
|
||||||
initializers.map { it.toJK() },
|
initializers.map { it.toJK() },
|
||||||
JKTypeElementImpl(type?.toJK().safeAs<JKJavaArrayType>()?.type ?: JKContextType)
|
JKTypeElementImpl(type?.toJK(symbolProvider).safeAs<JKJavaArrayType>()?.type ?: JKContextType)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) {
|
|||||||
}
|
}
|
||||||
JKJavaNewEmptyArrayImpl(
|
JKJavaNewEmptyArrayImpl(
|
||||||
dimensions.map { it?.toJK() ?: JKStubExpressionImpl() },
|
dimensions.map { it?.toJK() ?: JKStubExpressionImpl() },
|
||||||
JKTypeElementImpl(generateSequence(type?.toJK()) { it.safeAs<JKJavaArrayType>()?.type }.last())
|
JKTypeElementImpl(generateSequence(type?.toJK(symbolProvider)) { it.safeAs<JKJavaArrayType>()?.type }.last())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -226,32 +226,10 @@ class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun PsiTypeElement.toJK(): JKTypeElement {
|
fun PsiTypeElement.toJK(): JKTypeElement {
|
||||||
return JKTypeElementImpl(type.toJK()).also {
|
return JKTypeElementImpl(type.toJK(symbolProvider)).also {
|
||||||
backAnnotation[it] = this
|
backAnnotation[it] = this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PsiType.toJK(nullability: Nullability = Nullability.Default): JKType {
|
|
||||||
return when (this) {
|
|
||||||
is PsiClassType -> {
|
|
||||||
val target = resolve()
|
|
||||||
val parameters = parameters.map { it.toJK() }
|
|
||||||
if (target != null) {
|
|
||||||
JKClassTypeImpl(
|
|
||||||
target.let { symbolProvider.provideDirectSymbol(it) as JKClassSymbol },
|
|
||||||
parameters,
|
|
||||||
nullability
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
JKUnresolvedClassType(this.rawType().canonicalText, parameters, nullability)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is PsiArrayType -> JKJavaArrayTypeImpl(componentType.toJK(), nullability)
|
|
||||||
is PsiPrimitiveType -> JKJavaPrimitiveTypeImpl.KEYWORD_TO_INSTANCE[presentableText]
|
|
||||||
?: error("Invalid primitive type $presentableText")
|
|
||||||
else -> throw Exception("Invalid PSI")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class DeclarationMapper(val expressionTreeMapper: ExpressionTreeMapper) {
|
private inner class DeclarationMapper(val expressionTreeMapper: ExpressionTreeMapper) {
|
||||||
@@ -264,7 +242,7 @@ class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun PsiReferenceList.mapTypes() =
|
fun PsiReferenceList.mapTypes() =
|
||||||
this.referencedTypes.map { with(expressionTreeMapper) { JKTypeElementImpl(it.toJK(Nullability.NotNull)) } }
|
this.referencedTypes.map { with(expressionTreeMapper) { JKTypeElementImpl(it.toJK(symbolProvider, Nullability.NotNull)) } }
|
||||||
|
|
||||||
val implTypes = this.implementsList?.mapTypes().orEmpty()
|
val implTypes = this.implementsList?.mapTypes().orEmpty()
|
||||||
val extTypes = this.extendsList?.mapTypes().orEmpty()
|
val extTypes = this.extendsList?.mapTypes().orEmpty()
|
||||||
|
|||||||
+11
-10
@@ -16,16 +16,17 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
|||||||
|
|
||||||
class AssignmentStatementOperatorConversion : RecursiveApplicableConversionBase() {
|
class AssignmentStatementOperatorConversion : RecursiveApplicableConversionBase() {
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||||
if (element !is JKKtAssignmentStatement) return recurse(element)
|
//todo fix
|
||||||
val newOperator = JKKtOperatorImpl.javaToKotlinOperator[element.operator] ?: return recurse(element)
|
// if (element !is JKKtAssignmentStatement) return recurse(element)
|
||||||
if (newOperator is JKKtWordOperatorImpl) {
|
// val newOperator = JKKtOperatorImpl.javaToKotlinOperator[element.operator] ?: return recurse(element)
|
||||||
element.operator = JKKtOperatorImpl.tokenToOperator[KtTokens.EQ] ?: return recurse(element)
|
// if (newOperator is JKKtWordOperatorImpl) {
|
||||||
val expr = element.expression
|
// element.operator = JKKtOperatorImpl.tokenToOperator[KtTokens.EQ] ?: return recurse(element)
|
||||||
element.expression = JKStubExpressionImpl()
|
// val expr = element.expression
|
||||||
element.expression = JKBinaryExpressionImpl(element.field.copyTree(), expr, newOperator)
|
// element.expression = JKStubExpressionImpl()
|
||||||
} else {
|
// element.expression = JKBinaryExpressionImpl(element.field.copyTree(), expr, newOperator)
|
||||||
element.operator = newOperator
|
// } else {
|
||||||
}
|
// element.operator = newOperator
|
||||||
|
// }
|
||||||
return recurse(element)
|
return recurse(element)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,15 +5,25 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.j2k.conversions
|
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.JKBinaryExpression
|
||||||
|
import org.jetbrains.kotlin.j2k.tree.JKBranchElement
|
||||||
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
|
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
|
||||||
import org.jetbrains.kotlin.j2k.tree.impl.JKKtOperatorImpl
|
import org.jetbrains.kotlin.j2k.tree.impl.JKBinaryExpressionImpl
|
||||||
|
import org.jetbrains.kotlin.j2k.tree.impl.JKJavaOperatorImpl
|
||||||
|
import org.jetbrains.kotlin.j2k.tree.impl.toKtToken
|
||||||
|
|
||||||
|
|
||||||
class BinaryExpressionConversion : RecursiveApplicableConversionBase() {
|
class BinaryExpressionConversion(private val context: ConversionContext) : RecursiveApplicableConversionBase() {
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||||
if (element is JKBinaryExpression)
|
if (element !is JKBinaryExpression) return recurse(element)
|
||||||
element.operator = JKKtOperatorImpl.javaToKotlinOperator[element.operator] ?: element.operator
|
val ktOperator = (element.operator as? JKJavaOperatorImpl)?.toKtToken() ?: return recurse(element)
|
||||||
return recurse(element)
|
val left = recurse(element.left)
|
||||||
|
val right = recurse(element.right)
|
||||||
|
(element as? JKBranchElement)?.invalidate()
|
||||||
|
val ktBinaryExpression = JKBinaryExpressionImpl.createKotlinBinaryExpression(left, right, ktOperator, context)
|
||||||
|
?: return JKBinaryExpressionImpl(left, right, element.operator)
|
||||||
|
return recurse(ktBinaryExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -157,11 +157,12 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
|
|||||||
context,
|
context,
|
||||||
psiContext
|
psiContext
|
||||||
)
|
)
|
||||||
else -> JKBinaryExpressionImpl(
|
else -> JKBinaryExpressionImpl.createKotlinBinaryExpression(
|
||||||
start,
|
start,
|
||||||
convertBound(bound, if (inclusiveComparison) 0 else -1),
|
convertBound(bound, if (inclusiveComparison) 0 else -1),
|
||||||
JKKtOperatorImpl.tokenToOperator[KtTokens.RANGE]!!
|
KtTokens.RANGE,
|
||||||
)
|
context
|
||||||
|
)!!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,11 +175,11 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
|
|||||||
}
|
}
|
||||||
|
|
||||||
val sign = if (correction > 0) KtTokens.PLUS else KtTokens.MINUS
|
val sign = if (correction > 0) KtTokens.PLUS else KtTokens.MINUS
|
||||||
return JKBinaryExpressionImpl(
|
return JKBinaryExpressionImpl.createKotlinBinaryExpression(
|
||||||
bound,
|
bound,
|
||||||
JKKtLiteralExpressionImpl(Math.abs(correction).toString(), JKLiteralExpression.LiteralType.INT),
|
JKKtLiteralExpressionImpl(Math.abs(correction).toString(), JKLiteralExpression.LiteralType.INT),
|
||||||
JKKtOperatorImpl.tokenToOperator[sign]!!
|
sign,
|
||||||
)
|
context)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun indicesIterationRange(
|
private fun indicesIterationRange(
|
||||||
|
|||||||
@@ -18,16 +18,21 @@ package org.jetbrains.kotlin.j2k.tree.impl
|
|||||||
|
|
||||||
import com.intellij.psi.PsiClass
|
import com.intellij.psi.PsiClass
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.j2k.ConversionContext
|
||||||
import org.jetbrains.kotlin.j2k.JKSymbolProvider
|
import org.jetbrains.kotlin.j2k.JKSymbolProvider
|
||||||
import org.jetbrains.kotlin.j2k.ast.Mutability
|
import org.jetbrains.kotlin.j2k.ast.Mutability
|
||||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||||
|
import org.jetbrains.kotlin.j2k.conversions.resolveFqName
|
||||||
import org.jetbrains.kotlin.j2k.tree.*
|
import org.jetbrains.kotlin.j2k.tree.*
|
||||||
import org.jetbrains.kotlin.j2k.tree.JKLiteralExpression.LiteralType
|
import org.jetbrains.kotlin.j2k.tree.JKLiteralExpression.LiteralType
|
||||||
import org.jetbrains.kotlin.j2k.tree.JKLiteralExpression.LiteralType.BOOLEAN
|
import org.jetbrains.kotlin.j2k.tree.JKLiteralExpression.LiteralType.BOOLEAN
|
||||||
import org.jetbrains.kotlin.j2k.tree.JKLiteralExpression.LiteralType.NULL
|
import org.jetbrains.kotlin.j2k.tree.JKLiteralExpression.LiteralType.NULL
|
||||||
import org.jetbrains.kotlin.j2k.tree.visitors.JKVisitor
|
import org.jetbrains.kotlin.j2k.tree.visitors.JKVisitor
|
||||||
|
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.psi.KtClass
|
import org.jetbrains.kotlin.psi.KtClass
|
||||||
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
|
|
||||||
class JKFileImpl : JKFile, JKBranchElementBase() {
|
class JKFileImpl : JKFile, JKBranchElementBase() {
|
||||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitFile(this, data)
|
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitFile(this, data)
|
||||||
@@ -104,7 +109,7 @@ class JKBlockImpl(statements: List<JKStatement> = emptyList()) : JKBlock, JKBran
|
|||||||
override var statements by children(statements)
|
override var statements by children(statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//todo split to java and kt sbinary expression
|
||||||
class JKBinaryExpressionImpl(
|
class JKBinaryExpressionImpl(
|
||||||
left: JKExpression,
|
left: JKExpression,
|
||||||
right: JKExpression,
|
right: JKExpression,
|
||||||
@@ -112,11 +117,61 @@ class JKBinaryExpressionImpl(
|
|||||||
) : JKBinaryExpression,
|
) : JKBinaryExpression,
|
||||||
JKBranchElementBase() {
|
JKBranchElementBase() {
|
||||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitBinaryExpression(this, data)
|
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitBinaryExpression(this, data)
|
||||||
|
|
||||||
override var right by child(right)
|
override var right by child(right)
|
||||||
override var left by child(left)
|
override var left by child(left)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private fun methodSymbolForToken(
|
||||||
|
token: KtSingleValueToken,
|
||||||
|
leftType: JKType,
|
||||||
|
rightType: JKType,
|
||||||
|
symbolProvider: JKSymbolProvider
|
||||||
|
): 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())
|
||||||
|
}
|
||||||
|
return classSymbol.target.declarations// todo look for extensions
|
||||||
|
.asSequence()
|
||||||
|
.filterIsInstance<KtNamedFunction>()
|
||||||
|
.filter { it.name == operatorName }
|
||||||
|
.mapNotNull { symbolProvider.provideDirectSymbol(it) as? JKMethodSymbol }
|
||||||
|
.firstOrNull { it.parameterTypes.singleOrNull()?.takeIf { it.isSubtypeOf(rightType, symbolProvider) } != null }!!
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun createKotlinBinaryExpression(
|
||||||
|
left: JKExpression,
|
||||||
|
right: JKExpression,
|
||||||
|
token: KtSingleValueToken,
|
||||||
|
context: ConversionContext
|
||||||
|
): JKBinaryExpression? {
|
||||||
|
val leftType = left.type(context)
|
||||||
|
val rightType = right.type(context)
|
||||||
|
val methodSymbol = methodSymbolForToken(token, leftType, rightType, context.symbolProvider)
|
||||||
|
return JKBinaryExpressionImpl(left, right, JKKtOperatorImpl(token, methodSymbol))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
infix fun JKType?.equalsIgnoreMutability(other: JKType?) =
|
||||||
|
when {
|
||||||
|
(this is JKClassTypeImpl && other is JKClassTypeImpl) ->
|
||||||
|
this.classReference == other.classReference && this.parameters == other.parameters
|
||||||
|
else -> TODO("No comparation for $this and $other")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class JKPrefixExpressionImpl(expression: JKExpression, override var operator: JKOperator) : JKPrefixExpression, JKBranchElementBase() {
|
class JKPrefixExpressionImpl(expression: JKExpression, override var operator: JKOperator) : JKPrefixExpression, JKBranchElementBase() {
|
||||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitPrefixExpression(this, data)
|
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitPrefixExpression(this, data)
|
||||||
|
|
||||||
@@ -236,19 +291,27 @@ class JKBooleanLiteral(val value: Boolean) : JKLiteralExpression, JKElementBase(
|
|||||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitLiteralExpression(this, data)
|
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitLiteralExpression(this, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun JKLiteralExpression.LiteralType.toJkType(symbolProvider: JKSymbolProvider): JKType =
|
fun JKLiteralExpression.LiteralType.toJkType(symbolProvider: JKSymbolProvider): JKType {
|
||||||
when (this) {
|
fun defaultTypeByName(name: String) =
|
||||||
JKLiteralExpression.LiteralType.CHAR -> JKJavaPrimitiveTypeImpl.CHAR
|
JKClassTypeImpl(
|
||||||
JKLiteralExpression.LiteralType.BOOLEAN -> JKJavaPrimitiveTypeImpl.BOOLEAN
|
symbolProvider.provideDirectSymbol(
|
||||||
JKLiteralExpression.LiteralType.INT -> JKJavaPrimitiveTypeImpl.INT
|
resolveFqName(ClassId.fromString("kotlin.$name"), symbolProvider.symbolsByPsi.keys.first())!!
|
||||||
JKLiteralExpression.LiteralType.LONG -> JKJavaPrimitiveTypeImpl.LONG
|
) as JKClassSymbol, emptyList(), Nullability.NotNull
|
||||||
JKLiteralExpression.LiteralType.FLOAT -> JKJavaPrimitiveTypeImpl.FLOAT
|
)
|
||||||
JKLiteralExpression.LiteralType.DOUBLE -> JKJavaPrimitiveTypeImpl.DOUBLE
|
|
||||||
|
return when (this) {
|
||||||
|
JKLiteralExpression.LiteralType.CHAR -> defaultTypeByName("Char")
|
||||||
|
JKLiteralExpression.LiteralType.BOOLEAN -> defaultTypeByName("Boolean")
|
||||||
|
JKLiteralExpression.LiteralType.INT -> defaultTypeByName("Int")
|
||||||
|
JKLiteralExpression.LiteralType.LONG -> defaultTypeByName("Long")
|
||||||
|
JKLiteralExpression.LiteralType.FLOAT -> defaultTypeByName("Float")
|
||||||
|
JKLiteralExpression.LiteralType.DOUBLE -> defaultTypeByName("Double")
|
||||||
JKLiteralExpression.LiteralType.NULL ->
|
JKLiteralExpression.LiteralType.NULL ->
|
||||||
ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.unit.toSafe()).toKtClassType(symbolProvider)
|
ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.unit.toSafe()).toKtClassType(symbolProvider)
|
||||||
JKLiteralExpression.LiteralType.STRING ->
|
JKLiteralExpression.LiteralType.STRING ->
|
||||||
ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.string.toSafe()).toKtClassType(symbolProvider)
|
ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.string.toSafe()).toKtClassType(symbolProvider)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class JKLocalVariableImpl(modifierList: JKModifierList, type: JKTypeElement, name: JKNameIdentifier, initializer: JKExpression) :
|
class JKLocalVariableImpl(modifierList: JKModifierList, type: JKTypeElement, name: JKNameIdentifier, initializer: JKExpression) :
|
||||||
JKLocalVariable, JKBranchElementBase() {
|
JKLocalVariable, JKBranchElementBase() {
|
||||||
|
|||||||
@@ -83,56 +83,27 @@ class JKKtLiteralExpressionImpl(
|
|||||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitKtLiteralExpression(this, data)
|
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitKtLiteralExpression(this, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
class JKKtOperatorImpl private constructor(val token: KtSingleValueToken) : JKOperator, JKElementBase() {
|
fun JKJavaOperatorImpl.toKtToken(): KtSingleValueToken =
|
||||||
|
when (this.token) {
|
||||||
|
JavaTokenType.DIV -> KtTokens.DIV
|
||||||
|
JavaTokenType.MINUS -> KtTokens.MINUS
|
||||||
|
JavaTokenType.ANDAND -> KtTokens.ANDAND
|
||||||
|
JavaTokenType.OROR -> KtTokens.OROR
|
||||||
|
JavaTokenType.PLUS -> KtTokens.PLUS
|
||||||
|
JavaTokenType.ASTERISK -> KtTokens.MUL
|
||||||
|
JavaTokenType.GT -> KtTokens.GT
|
||||||
|
JavaTokenType.GE -> KtTokens.GTEQ
|
||||||
|
JavaTokenType.LT -> KtTokens.LT
|
||||||
|
JavaTokenType.LE -> KtTokens.LTEQ
|
||||||
|
JavaTokenType.PERC -> KtTokens.PERC
|
||||||
|
else -> TODO(this.token::class.java.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
class JKKtOperatorImpl(val token: KtSingleValueToken, val methodSymbol: JKMethodSymbol) : JKOperator, JKElementBase() {
|
||||||
override val precedence: Int
|
override val precedence: Int
|
||||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||||
override val operatorText: String
|
override val operatorText: String
|
||||||
get() = token.value
|
get() = token.value
|
||||||
|
|
||||||
companion object {
|
|
||||||
val tokenToOperator = KtTokens.OPERATIONS.types.filter { it is KtSingleValueToken }.associate {
|
|
||||||
it to JKKtOperatorImpl(it as KtSingleValueToken)
|
|
||||||
}
|
|
||||||
|
|
||||||
val javaToKotlinOperator = mutableMapOf<JKOperator, JKOperator>()
|
|
||||||
|
|
||||||
init {
|
|
||||||
javaToKotlinOperator.apply {
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.DIV]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.DIV]!!
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.MINUS]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.MINUS]!!
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.ANDAND]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.ANDAND]!!
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.OROR]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.OROR]!!
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.PLUS]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.PLUS]!!
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.ASTERISK]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.MUL]!!
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.GT]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.GT]!!
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.GE]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.GTEQ]!!
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.LT]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.LT]!!
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.LE]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.LTEQ]!!
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.PERC]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.PERC]!!
|
|
||||||
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.EQ]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.EQ]!!
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.PLUSEQ]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.PLUSEQ]!!
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.MINUSEQ]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.MINUSEQ]!!
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.ASTERISKEQ]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.MULTEQ]!!
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.DIVEQ]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.DIVEQ]!!
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.PERCEQ]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.PERCEQ]!!
|
|
||||||
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.AND]!!] = JKKtWordOperatorImpl("and")
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.OR]!!] = JKKtWordOperatorImpl("or")
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.XOR]!!] = JKKtWordOperatorImpl("xor")
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.GTGTGT]!!] = JKKtWordOperatorImpl("ushr")
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.GTGT]!!] = JKKtWordOperatorImpl("shr")
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.LTLT]!!] = JKKtWordOperatorImpl("shl")
|
|
||||||
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.OREQ]!!] = JKKtWordOperatorImpl("or")
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.ANDEQ]!!] = JKKtWordOperatorImpl("and")
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.XOREQ]!!] = JKKtWordOperatorImpl("xor")
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.GTGTGTEQ]!!] = JKKtWordOperatorImpl("ushr")
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.GTGTEQ]!!] = JKKtWordOperatorImpl("shr")
|
|
||||||
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.LTLTEQ]!!] = JKKtWordOperatorImpl("shl")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class JKKtWordOperatorImpl constructor(override val operatorText: String) : JKOperator, JKElementBase() {
|
class JKKtWordOperatorImpl constructor(override val operatorText: String) : JKOperator, JKElementBase() {
|
||||||
|
|||||||
@@ -11,13 +11,11 @@ import com.intellij.psi.PsiMethod
|
|||||||
import com.intellij.psi.PsiReference
|
import com.intellij.psi.PsiReference
|
||||||
import org.jetbrains.kotlin.j2k.JKSymbolProvider
|
import org.jetbrains.kotlin.j2k.JKSymbolProvider
|
||||||
import org.jetbrains.kotlin.j2k.conversions.parentOfType
|
import org.jetbrains.kotlin.j2k.conversions.parentOfType
|
||||||
import org.jetbrains.kotlin.j2k.tree.JKClass
|
import org.jetbrains.kotlin.j2k.tree.*
|
||||||
import org.jetbrains.kotlin.j2k.tree.JKField
|
|
||||||
import org.jetbrains.kotlin.j2k.tree.JKMethod
|
|
||||||
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
|
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
import org.jetbrains.kotlin.psi.KtProperty
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getValueParameterList
|
||||||
|
|
||||||
interface JKSymbol {
|
interface JKSymbol {
|
||||||
val target: Any
|
val target: Any
|
||||||
@@ -37,6 +35,9 @@ interface JKClassSymbol : JKNamedSymbol
|
|||||||
|
|
||||||
interface JKMethodSymbol : JKNamedSymbol {
|
interface JKMethodSymbol : JKNamedSymbol {
|
||||||
override val fqName: String
|
override val fqName: String
|
||||||
|
val recivierType: JKType?
|
||||||
|
val parameterTypes: List<JKType>
|
||||||
|
val returnType: JKType
|
||||||
}
|
}
|
||||||
|
|
||||||
interface JKFieldSymbol : JKNamedSymbol {
|
interface JKFieldSymbol : JKNamedSymbol {
|
||||||
@@ -75,6 +76,14 @@ class JKMultiverseKtClassSymbol(override val target: KtClassOrObject) : JKClassS
|
|||||||
}
|
}
|
||||||
|
|
||||||
class JKUniverseMethodSymbol(private val symbolProvider: JKSymbolProvider) : JKMethodSymbol, JKUniverseSymbol<JKMethod> {
|
class JKUniverseMethodSymbol(private val symbolProvider: JKSymbolProvider) : JKMethodSymbol, JKUniverseSymbol<JKMethod> {
|
||||||
|
override val recivierType: JKType?
|
||||||
|
get() = (target.parent as? JKClass)?.let {
|
||||||
|
JKClassTypeImpl(symbolProvider.provideUniverseSymbol(it), emptyList()/*TODO*/)
|
||||||
|
}
|
||||||
|
override val parameterTypes: List<JKType>
|
||||||
|
get() = target.parameters.map { it.type.type }
|
||||||
|
override val returnType: JKType
|
||||||
|
get() = target.returnType.type
|
||||||
override val name: String
|
override val name: String
|
||||||
get() = target.name.value
|
get() = target.name.value
|
||||||
override lateinit var target: JKMethod
|
override lateinit var target: JKMethod
|
||||||
@@ -85,6 +94,14 @@ class JKUniverseMethodSymbol(private val symbolProvider: JKSymbolProvider) : JKM
|
|||||||
}
|
}
|
||||||
|
|
||||||
class JKMultiverseMethodSymbol(override val target: PsiMethod, private val symbolProvider: JKSymbolProvider) : JKMethodSymbol {
|
class JKMultiverseMethodSymbol(override val target: PsiMethod, private val symbolProvider: JKSymbolProvider) : JKMethodSymbol {
|
||||||
|
override val recivierType: JKType?
|
||||||
|
get() = target.containingClass?.let {
|
||||||
|
JKClassTypeImpl(symbolProvider.provideDirectSymbol(it) as JKClassSymbol, emptyList()/*TODO*/)
|
||||||
|
}
|
||||||
|
override val parameterTypes: List<JKType>
|
||||||
|
get() = target.parameterList.parameters.map { it.type.toJK(symbolProvider) }
|
||||||
|
override val returnType: JKType
|
||||||
|
get() = target.returnType!!.toJK(symbolProvider)
|
||||||
override val name: String
|
override val name: String
|
||||||
get() = target.name
|
get() = target.name
|
||||||
override val declaredIn: JKSymbol?
|
override val declaredIn: JKSymbol?
|
||||||
@@ -93,7 +110,13 @@ class JKMultiverseMethodSymbol(override val target: PsiMethod, private val symbo
|
|||||||
get() = target.name // TODO("Fix this")
|
get() = target.name // TODO("Fix this")
|
||||||
}
|
}
|
||||||
|
|
||||||
class JKMultiverseFunctionSymbol(override val target: KtNamedFunction) : JKMethodSymbol {
|
class JKMultiverseFunctionSymbol(override val target: KtNamedFunction, private val symbolProvider: JKSymbolProvider) : JKMethodSymbol {
|
||||||
|
override val recivierType: JKType?
|
||||||
|
get() = target.receiverTypeReference?.typeElement?.toJK(symbolProvider)
|
||||||
|
override val parameterTypes: List<JKType>
|
||||||
|
get() = target.valueParameters.map { it.typeReference!!.typeElement!!.toJK(symbolProvider) }
|
||||||
|
override val returnType: JKType
|
||||||
|
get() = target.typeReference!!.typeElement!!.toJK(symbolProvider)
|
||||||
override val name: String
|
override val name: String
|
||||||
get() = target.name!!
|
get() = target.name!!
|
||||||
override val declaredIn: JKSymbol
|
override val declaredIn: JKSymbol
|
||||||
@@ -146,7 +169,12 @@ class JKUnresolvedMethod(override val target: String) : JKMethodSymbol {
|
|||||||
override val declaredIn: JKSymbol
|
override val declaredIn: JKSymbol
|
||||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||||
override val fqName: String = target
|
override val fqName: String = target
|
||||||
|
override val recivierType: JKType?
|
||||||
|
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||||
|
override val parameterTypes: List<JKType>
|
||||||
|
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||||
|
override val returnType: JKType
|
||||||
|
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||||
override val name: String
|
override val name: String
|
||||||
get() = target
|
get() = target
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,23 +5,22 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.j2k.tree
|
package org.jetbrains.kotlin.j2k.tree
|
||||||
|
|
||||||
import com.intellij.psi.PsiCatchSection
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.j2k.ConversionContext
|
import org.jetbrains.kotlin.j2k.ConversionContext
|
||||||
import org.jetbrains.kotlin.j2k.JKSymbolProvider
|
import org.jetbrains.kotlin.j2k.JKSymbolProvider
|
||||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||||
import org.jetbrains.kotlin.j2k.conversions.resolveFqName
|
import org.jetbrains.kotlin.j2k.conversions.resolveFqName
|
||||||
import org.jetbrains.kotlin.j2k.tree.impl.JKClassSymbol
|
import org.jetbrains.kotlin.j2k.tree.impl.*
|
||||||
import org.jetbrains.kotlin.j2k.tree.impl.JKClassTypeImpl
|
|
||||||
import org.jetbrains.kotlin.j2k.tree.impl.toJkType
|
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.psi.KtTypeElement
|
||||||
|
import org.jetbrains.kotlin.psi.KtUserType
|
||||||
|
|
||||||
|
|
||||||
fun JKExpression.type(context: ConversionContext): JKType =
|
fun JKExpression.type(context: ConversionContext): JKType =
|
||||||
when (this) {
|
when (this) {
|
||||||
is JKLiteralExpression -> this.type.toJkType(context.symbolProvider)
|
is JKLiteralExpression -> type.toJkType(context.symbolProvider)
|
||||||
else -> TODO(this.toString())
|
is JKBinaryExpression -> (operator as JKKtOperatorImpl).methodSymbol.returnType
|
||||||
|
else -> TODO(this::class.java.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ClassId.toKtClassType(
|
fun ClassId.toKtClassType(
|
||||||
@@ -33,3 +32,38 @@ fun ClassId.toKtClassType(
|
|||||||
return JKClassTypeImpl(typeSymbol, emptyList(), nullability)
|
return JKClassTypeImpl(typeSymbol, emptyList(), nullability)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun PsiType.toJK(symbolProvider: JKSymbolProvider, nullability: Nullability = Nullability.Default): JKType {
|
||||||
|
return when (this) {
|
||||||
|
is PsiClassType -> {
|
||||||
|
val target = resolve()
|
||||||
|
val parameters = parameters.map { it.toJK(symbolProvider, nullability) }
|
||||||
|
if (target != null) {
|
||||||
|
JKClassTypeImpl(
|
||||||
|
target.let { symbolProvider.provideDirectSymbol(it) as JKClassSymbol },
|
||||||
|
parameters,
|
||||||
|
nullability
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
JKUnresolvedClassType(this.rawType().canonicalText, parameters, nullability)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is PsiArrayType -> JKJavaArrayTypeImpl(componentType.toJK(symbolProvider, nullability), nullability)
|
||||||
|
is PsiPrimitiveType -> JKJavaPrimitiveTypeImpl.KEYWORD_TO_INSTANCE[presentableText]
|
||||||
|
?: error("Invalid primitive type $presentableText")
|
||||||
|
else -> throw Exception("Invalid PSI")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun KtTypeElement.toJK(symbolProvider: JKSymbolProvider): JKType =
|
||||||
|
when (this) {
|
||||||
|
is KtUserType -> {
|
||||||
|
val qualifiedName = qualifier?.text?.let { it + "." }.orEmpty() + referencedName
|
||||||
|
val typeParameters = typeArguments.map { it.typeReference!!.typeElement!!.toJK(symbolProvider) }
|
||||||
|
val symbol = symbolProvider.provideDirectSymbol(
|
||||||
|
resolveFqName(ClassId.fromString(qualifiedName), this)!!
|
||||||
|
) as JKClassSymbol
|
||||||
|
|
||||||
|
JKClassTypeImpl(symbol, typeParameters)
|
||||||
|
}
|
||||||
|
else -> TODO(this::class.java.toString())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user