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) =
|
||||
batchPipe {
|
||||
+BinaryExpressionConversion(context)
|
||||
+ArrayInitializerConversion(context)
|
||||
+ModalityConversion(context)
|
||||
+ImplicitInitializerConversion()
|
||||
@@ -47,7 +48,6 @@ object ConversionsRunner {
|
||||
+StaticsToCompanionExtractConversion()
|
||||
+ClassToObjectPromotionConversion()
|
||||
+PolyadicExpressionConversion()
|
||||
+BinaryExpressionConversion()
|
||||
+SwitchStatementConversion(context)
|
||||
+InstanceofConversion()
|
||||
+ForConversion(context)
|
||||
|
||||
@@ -36,7 +36,7 @@ class JKSymbolProvider {
|
||||
is KtClassOrObject -> JKMultiverseKtClassSymbol(psi)
|
||||
is PsiMethod -> JKMultiverseMethodSymbol(psi, this)
|
||||
is PsiField -> JKMultiverseFieldSymbol(psi)
|
||||
is KtNamedFunction -> JKMultiverseFunctionSymbol(psi)
|
||||
is KtNamedFunction -> JKMultiverseFunctionSymbol(psi, this)
|
||||
is KtProperty -> JKMultiversePropertySymbol(psi)
|
||||
else -> TODO(psi::class.toString())
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) {
|
||||
fun PsiArrayInitializerExpression.toJK(): JKExpression {
|
||||
return JKJavaNewArrayImpl(
|
||||
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(
|
||||
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 {
|
||||
return JKTypeElementImpl(type.toJK()).also {
|
||||
return JKTypeElementImpl(type.toJK(symbolProvider)).also {
|
||||
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) {
|
||||
@@ -264,7 +242,7 @@ class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) {
|
||||
}
|
||||
|
||||
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 extTypes = this.extendsList?.mapTypes().orEmpty()
|
||||
|
||||
+11
-10
@@ -16,16 +16,17 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
||||
|
||||
class AssignmentStatementOperatorConversion : RecursiveApplicableConversionBase() {
|
||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||
if (element !is JKKtAssignmentStatement) return recurse(element)
|
||||
val newOperator = JKKtOperatorImpl.javaToKotlinOperator[element.operator] ?: return recurse(element)
|
||||
if (newOperator is JKKtWordOperatorImpl) {
|
||||
element.operator = JKKtOperatorImpl.tokenToOperator[KtTokens.EQ] ?: return recurse(element)
|
||||
val expr = element.expression
|
||||
element.expression = JKStubExpressionImpl()
|
||||
element.expression = JKBinaryExpressionImpl(element.field.copyTree(), expr, newOperator)
|
||||
} else {
|
||||
element.operator = newOperator
|
||||
}
|
||||
//todo fix
|
||||
// if (element !is JKKtAssignmentStatement) return recurse(element)
|
||||
// val newOperator = JKKtOperatorImpl.javaToKotlinOperator[element.operator] ?: return recurse(element)
|
||||
// if (newOperator is JKKtWordOperatorImpl) {
|
||||
// element.operator = JKKtOperatorImpl.tokenToOperator[KtTokens.EQ] ?: return recurse(element)
|
||||
// val expr = element.expression
|
||||
// element.expression = JKStubExpressionImpl()
|
||||
// element.expression = JKBinaryExpressionImpl(element.field.copyTree(), expr, newOperator)
|
||||
// } else {
|
||||
// element.operator = newOperator
|
||||
// }
|
||||
return recurse(element)
|
||||
}
|
||||
}
|
||||
@@ -5,15 +5,25 @@
|
||||
|
||||
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.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 {
|
||||
if (element is JKBinaryExpression)
|
||||
element.operator = JKKtOperatorImpl.javaToKotlinOperator[element.operator] ?: element.operator
|
||||
return recurse(element)
|
||||
if (element !is JKBinaryExpression) return recurse(element)
|
||||
val ktOperator = (element.operator as? JKJavaOperatorImpl)?.toKtToken() ?: 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,
|
||||
psiContext
|
||||
)
|
||||
else -> JKBinaryExpressionImpl(
|
||||
else -> JKBinaryExpressionImpl.createKotlinBinaryExpression(
|
||||
start,
|
||||
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
|
||||
return JKBinaryExpressionImpl(
|
||||
return JKBinaryExpressionImpl.createKotlinBinaryExpression(
|
||||
bound,
|
||||
JKKtLiteralExpressionImpl(Math.abs(correction).toString(), JKLiteralExpression.LiteralType.INT),
|
||||
JKKtOperatorImpl.tokenToOperator[sign]!!
|
||||
)
|
||||
sign,
|
||||
context)!!
|
||||
}
|
||||
|
||||
private fun indicesIterationRange(
|
||||
|
||||
@@ -18,16 +18,21 @@ package org.jetbrains.kotlin.j2k.tree.impl
|
||||
|
||||
import com.intellij.psi.PsiClass
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.j2k.ConversionContext
|
||||
import org.jetbrains.kotlin.j2k.JKSymbolProvider
|
||||
import org.jetbrains.kotlin.j2k.ast.Mutability
|
||||
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.JKLiteralExpression.LiteralType
|
||||
import org.jetbrains.kotlin.j2k.tree.JKLiteralExpression.LiteralType.BOOLEAN
|
||||
import org.jetbrains.kotlin.j2k.tree.JKLiteralExpression.LiteralType.NULL
|
||||
import org.jetbrains.kotlin.j2k.tree.visitors.JKVisitor
|
||||
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
|
||||
class JKFileImpl : JKFile, JKBranchElementBase() {
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
//todo split to java and kt sbinary expression
|
||||
class JKBinaryExpressionImpl(
|
||||
left: JKExpression,
|
||||
right: JKExpression,
|
||||
@@ -112,11 +117,61 @@ class JKBinaryExpressionImpl(
|
||||
) : JKBinaryExpression,
|
||||
JKBranchElementBase() {
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitBinaryExpression(this, data)
|
||||
|
||||
override var right by child(right)
|
||||
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() {
|
||||
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)
|
||||
}
|
||||
|
||||
fun JKLiteralExpression.LiteralType.toJkType(symbolProvider: JKSymbolProvider): JKType =
|
||||
when (this) {
|
||||
JKLiteralExpression.LiteralType.CHAR -> JKJavaPrimitiveTypeImpl.CHAR
|
||||
JKLiteralExpression.LiteralType.BOOLEAN -> JKJavaPrimitiveTypeImpl.BOOLEAN
|
||||
JKLiteralExpression.LiteralType.INT -> JKJavaPrimitiveTypeImpl.INT
|
||||
JKLiteralExpression.LiteralType.LONG -> JKJavaPrimitiveTypeImpl.LONG
|
||||
JKLiteralExpression.LiteralType.FLOAT -> JKJavaPrimitiveTypeImpl.FLOAT
|
||||
JKLiteralExpression.LiteralType.DOUBLE -> JKJavaPrimitiveTypeImpl.DOUBLE
|
||||
fun JKLiteralExpression.LiteralType.toJkType(symbolProvider: JKSymbolProvider): JKType {
|
||||
fun defaultTypeByName(name: String) =
|
||||
JKClassTypeImpl(
|
||||
symbolProvider.provideDirectSymbol(
|
||||
resolveFqName(ClassId.fromString("kotlin.$name"), symbolProvider.symbolsByPsi.keys.first())!!
|
||||
) as JKClassSymbol, emptyList(), Nullability.NotNull
|
||||
)
|
||||
|
||||
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 ->
|
||||
ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.unit.toSafe()).toKtClassType(symbolProvider)
|
||||
JKLiteralExpression.LiteralType.STRING ->
|
||||
ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.string.toSafe()).toKtClassType(symbolProvider)
|
||||
}
|
||||
}
|
||||
|
||||
class JKLocalVariableImpl(modifierList: JKModifierList, type: JKTypeElement, name: JKNameIdentifier, initializer: JKExpression) :
|
||||
JKLocalVariable, JKBranchElementBase() {
|
||||
|
||||
@@ -83,56 +83,27 @@ class JKKtLiteralExpressionImpl(
|
||||
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
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
override val operatorText: String
|
||||
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() {
|
||||
|
||||
@@ -11,13 +11,11 @@ import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiReference
|
||||
import org.jetbrains.kotlin.j2k.JKSymbolProvider
|
||||
import org.jetbrains.kotlin.j2k.conversions.parentOfType
|
||||
import org.jetbrains.kotlin.j2k.tree.JKClass
|
||||
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.j2k.tree.*
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getValueParameterList
|
||||
|
||||
interface JKSymbol {
|
||||
val target: Any
|
||||
@@ -37,6 +35,9 @@ interface JKClassSymbol : JKNamedSymbol
|
||||
|
||||
interface JKMethodSymbol : JKNamedSymbol {
|
||||
override val fqName: String
|
||||
val recivierType: JKType?
|
||||
val parameterTypes: List<JKType>
|
||||
val returnType: JKType
|
||||
}
|
||||
|
||||
interface JKFieldSymbol : JKNamedSymbol {
|
||||
@@ -75,6 +76,14 @@ class JKMultiverseKtClassSymbol(override val target: KtClassOrObject) : JKClassS
|
||||
}
|
||||
|
||||
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
|
||||
get() = target.name.value
|
||||
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 {
|
||||
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
|
||||
get() = target.name
|
||||
override val declaredIn: JKSymbol?
|
||||
@@ -93,7 +110,13 @@ class JKMultiverseMethodSymbol(override val target: PsiMethod, private val symbo
|
||||
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
|
||||
get() = target.name!!
|
||||
override val declaredIn: JKSymbol
|
||||
@@ -146,7 +169,12 @@ class JKUnresolvedMethod(override val target: String) : JKMethodSymbol {
|
||||
override val declaredIn: JKSymbol
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
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
|
||||
get() = target
|
||||
}
|
||||
|
||||
@@ -5,23 +5,22 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
import com.intellij.psi.PsiCatchSection
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.j2k.ConversionContext
|
||||
import org.jetbrains.kotlin.j2k.JKSymbolProvider
|
||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||
import org.jetbrains.kotlin.j2k.conversions.resolveFqName
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.JKClassSymbol
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.JKClassTypeImpl
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.toJkType
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.psi.KtTypeElement
|
||||
import org.jetbrains.kotlin.psi.KtUserType
|
||||
|
||||
|
||||
fun JKExpression.type(context: ConversionContext): JKType =
|
||||
when (this) {
|
||||
is JKLiteralExpression -> this.type.toJkType(context.symbolProvider)
|
||||
else -> TODO(this.toString())
|
||||
is JKLiteralExpression -> type.toJkType(context.symbolProvider)
|
||||
is JKBinaryExpression -> (operator as JKKtOperatorImpl).methodSymbol.returnType
|
||||
else -> TODO(this::class.java.toString())
|
||||
}
|
||||
|
||||
fun ClassId.toKtClassType(
|
||||
@@ -33,3 +32,38 @@ fun ClassId.toKtClassType(
|
||||
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