From 19c569e8e21cbff9ee25589fa063353f57de5f94 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Thu, 4 Oct 2018 15:35:46 +0300 Subject: [PATCH] New J2K: Add conversion of Java `instanceof` expression to Kotlin `is` expression --- .../jetbrains/kotlin/j2k/ConversionsRunner.kt | 1 + .../jetbrains/kotlin/j2k/NewCodeBuilder.kt | 9 ++++ .../j2k/conversions/InstanceofConversion.kt | 45 +++++++++++++++++++ .../org/jetbrains/kotlin/j2k/tree/impl/jk.kt | 1 + .../org/jetbrains/kotlin/j2k/tree/impl/k.kt | 8 ++++ j2k/newSrc/org/jetbrains/kotlin/j2k/tree/k.kt | 5 +++ .../org/jetbrains/kotlin/j2k/tree/markers.kt | 5 +++ .../kotlin/j2k/tree/visitors/JKVisitor.kt | 1 + .../kotlin/j2k/tree/visitors/JKVisitorVoid.kt | 2 + 9 files changed, 77 insertions(+) create mode 100644 j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/InstanceofConversion.kt diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt index 70989138a77..1881c02023d 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt @@ -48,6 +48,7 @@ object ConversionsRunner { +PolyadicExpressionConversion() +BinaryExpressionConversion() +SwitchStatementConversion(context) + +InstanceofConversion() } fun doApply(trees: List, context: ConversionContext) { diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/NewCodeBuilder.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/NewCodeBuilder.kt index a8f8fc7424c..e9a23160d98 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/NewCodeBuilder.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/NewCodeBuilder.kt @@ -173,6 +173,13 @@ class NewCodeBuilder { printer.printlnWithNoIndent() } + override fun visitKtIsExpression(ktIsExpression: JKKtIsExpression) { + ktIsExpression.expression.accept(this) + printer.printWithNoIndent(" is ") + ktIsExpression.type.accept(this) + } + + override fun visitParameter(parameter: JKParameter) { printer.printWithNoIndent(parameter.name.value, ": ") parameter.type.accept(this) @@ -339,6 +346,8 @@ class NewCodeBuilder { is JKClassType -> type.classReference.fqName?.let { printer.printWithNoIndent(FqName(it).shortName().asString()) } is JKUnresolvedClassType -> printer.printWithNoIndent(type.name) is JKContextType -> return + is JKStarProjectionType -> + printer.printWithNoIndent("*") else -> printer.printWithNoIndent("Unit /* TODO: ${type::class} */") } if (type is JKParametrizedType && type.parameters.isNotEmpty()) { diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/InstanceofConversion.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/InstanceofConversion.kt new file mode 100644 index 00000000000..ca3cf322b6a --- /dev/null +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/InstanceofConversion.kt @@ -0,0 +1,45 @@ +/* + * 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 com.intellij.psi.PsiClass +import org.jetbrains.kotlin.j2k.tree.JKBinaryExpression +import org.jetbrains.kotlin.j2k.tree.JKClassType +import org.jetbrains.kotlin.j2k.tree.JKJavaInstanceOfExpression +import org.jetbrains.kotlin.j2k.tree.JKTreeElement +import org.jetbrains.kotlin.j2k.tree.impl.* +import org.jetbrains.kotlin.psi.KtClass + + +class InstanceofConversion : RecursiveApplicableConversionBase() { + override fun applyToElement(element: JKTreeElement): JKTreeElement { + if (element is JKJavaInstanceOfExpression) { + val checkingType = element.type.type + val type = + when (checkingType) { + is JKClassType -> { + if (checkingType.parameters.isEmpty()) { + val resolvedClass = checkingType.classReference?.target + val parametersCount = + when (resolvedClass) { + is PsiClass -> resolvedClass.typeParameters.size + is KtClass -> resolvedClass.typeParameters.size + else -> 0 + } + val typeParameters = List(parametersCount) { JKStarProjectionTypeImpl() } + JKClassTypeImpl(checkingType.classReference as JKClassSymbol, + typeParameters, + checkingType.nullability) + + } else checkingType + } + else -> checkingType + } + return recurse(JKKtIsExpressionImpl(element.expression.also { it.detach(it.parent!!) }, JKTypeElementImpl(type))) + } + return recurse(element) + } +} \ No newline at end of file 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 2d18ad9266b..93244c7ccf6 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/jk.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/jk.kt @@ -187,6 +187,7 @@ class JKClassTypeImpl( override val nullability: Nullability = Nullability.Default ) : JKClassType +class JKStarProjectionTypeImpl : JKStarProjectionType class JKUnresolvedClassType( val name: String, 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 e002aa70c1e..93169a51ff5 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/k.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/k.kt @@ -245,3 +245,11 @@ class JKKtValueWhenLabelImpl(expression: JKExpression) : JKKtValueWhenLabel, JKB override var expression: JKExpression by child(expression) override fun accept(visitor: JKVisitor, data: D): R = visitor.visitKtValueWhenLabel(this, data) } + + +class JKKtIsExpressionImpl(expression: JKExpression, type: JKTypeElement) : JKKtIsExpression, JKBranchElementBase() { + override var type by child(type) + override var expression by child(expression) + + override fun accept(visitor: JKVisitor, data: D): R = visitor.visitKtIsExpression(this, data) +} \ No newline at end of file diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/k.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/k.kt index 364caad75f2..63fea84abcf 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/k.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/k.kt @@ -74,4 +74,9 @@ interface JKKtElseWhenLabel : JKKtWhenLabel interface JKKtValueWhenLabel : JKKtWhenLabel { var expression: JKExpression +} + +interface JKKtIsExpression : JKExpression { + var expression: JKExpression + var type: JKTypeElement } \ No newline at end of file diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/markers.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/markers.kt index b3694dc3f5f..71136104a8d 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/markers.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/markers.kt @@ -68,6 +68,11 @@ interface JKJavaArrayType : JKType { val type: JKType } +interface JKStarProjectionType : JKType { + override val nullability: Nullability + get() = Nullability.NotNull +} + inline fun JKElement.getParentOfType(): T? { var p = parent while (true) { diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/visitors/JKVisitor.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/visitors/JKVisitor.kt index 37e9adceb13..0e5358b0f04 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/visitors/JKVisitor.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/visitors/JKVisitor.kt @@ -88,4 +88,5 @@ interface JKVisitor { fun visitKtWhenLabel(ktWhenLabel: JKKtWhenLabel, data: D): R = visitTreeElement(ktWhenLabel, data) fun visitKtElseWhenLabel(ktElseWhenLabel: JKKtElseWhenLabel, data: D): R = visitKtWhenLabel(ktElseWhenLabel, data) fun visitKtValueWhenLabel(ktValueWhenLabel: JKKtValueWhenLabel, data: D): R = visitKtWhenLabel(ktValueWhenLabel, data) + fun visitKtIsExpression(ktIsExpression: JKKtIsExpression, data: D): R = visitExpression(ktIsExpression, data) } diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/visitors/JKVisitorVoid.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/visitors/JKVisitorVoid.kt index 983ee3fe23f..7cc8ad7afc2 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/visitors/JKVisitorVoid.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/visitors/JKVisitorVoid.kt @@ -173,4 +173,6 @@ interface JKVisitorVoid : JKVisitor { override fun visitKtElseWhenLabel(ktElseWhenLabel: JKKtElseWhenLabel, data: Nothing?) = visitKtElseWhenLabel(ktElseWhenLabel) fun visitKtValueWhenLabel(ktValueWhenLabel: JKKtValueWhenLabel) = visitKtWhenLabel(ktValueWhenLabel, null) override fun visitKtValueWhenLabel(ktValueWhenLabel: JKKtValueWhenLabel, data: Nothing?) = visitKtValueWhenLabel(ktValueWhenLabel) + fun visitKtIsExpression(ktIsExpression: JKKtIsExpression) = visitExpression(ktIsExpression, null) + override fun visitKtIsExpression(ktIsExpression: JKKtIsExpression, data: Nothing?) = visitKtIsExpression(ktIsExpression) }