diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt index 598a753a00c..e2842bf11b9 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt @@ -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) diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/JKSymbolProvider.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/JKSymbolProvider.kt index afcce7a7426..1cb4c129c16 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/JKSymbolProvider.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/JKSymbolProvider.kt @@ -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()) } diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/JavaToJKTreeBuilder.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/JavaToJKTreeBuilder.kt index e776e5524f8..de22fe49ae9 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/JavaToJKTreeBuilder.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/JavaToJKTreeBuilder.kt @@ -167,7 +167,7 @@ class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) { fun PsiArrayInitializerExpression.toJK(): JKExpression { return JKJavaNewArrayImpl( initializers.map { it.toJK() }, - JKTypeElementImpl(type?.toJK().safeAs()?.type ?: JKContextType) + JKTypeElementImpl(type?.toJK(symbolProvider).safeAs()?.type ?: JKContextType) ) } @@ -190,7 +190,7 @@ class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) { } JKJavaNewEmptyArrayImpl( dimensions.map { it?.toJK() ?: JKStubExpressionImpl() }, - JKTypeElementImpl(generateSequence(type?.toJK()) { it.safeAs()?.type }.last()) + JKTypeElementImpl(generateSequence(type?.toJK(symbolProvider)) { it.safeAs()?.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() diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/AssignmentStatementOperatorConversion.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/AssignmentStatementOperatorConversion.kt index fefd2f5ab25..6844b600a5c 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/AssignmentStatementOperatorConversion.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/AssignmentStatementOperatorConversion.kt @@ -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) } } \ No newline at end of file diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/BinaryExpressionConversion.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/BinaryExpressionConversion.kt index 83be06c8ab2..6f294bfca01 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/BinaryExpressionConversion.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/BinaryExpressionConversion.kt @@ -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) } + } \ No newline at end of file diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/ForConversion.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/ForConversion.kt index a2bda5c5e94..5a7a9a44650 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/ForConversion.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/ForConversion.kt @@ -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( diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/jk.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/jk.kt index 1be530428cf..7effb9d0e89 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/jk.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/jk.kt @@ -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 accept(visitor: JKVisitor, data: D): R = visitor.visitFile(this, data) @@ -104,7 +109,7 @@ class JKBlockImpl(statements: List = 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 accept(visitor: JKVisitor, 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() + .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 accept(visitor: JKVisitor, data: D): R = visitor.visitPrefixExpression(this, data) @@ -236,19 +291,27 @@ class JKBooleanLiteral(val value: Boolean) : JKLiteralExpression, JKElementBase( override fun accept(visitor: JKVisitor, 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() { diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/k.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/k.kt index c6fd2ee1c46..03fddbc7425 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/k.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/k.kt @@ -83,56 +83,27 @@ class JKKtLiteralExpressionImpl( override fun accept(visitor: JKVisitor, 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() - - 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() { diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/symbols.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/symbols.kt index 72f16ee7477..76085553e82 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/symbols.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/symbols.kt @@ -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 + 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 { + override val recivierType: JKType? + get() = (target.parent as? JKClass)?.let { + JKClassTypeImpl(symbolProvider.provideUniverseSymbol(it), emptyList()/*TODO*/) + } + override val parameterTypes: List + 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 + 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 + 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 + 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 } diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/types.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/types.kt index 76b78dce044..b3da4852251 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/types.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/types.kt @@ -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()) + } \ No newline at end of file