diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/JKSymbolProvider.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/JKSymbolProvider.kt index b9a753a89a2..78a396ba085 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/JKSymbolProvider.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/JKSymbolProvider.kt @@ -38,6 +38,7 @@ class JKSymbolProvider { is PsiField -> JKMultiverseFieldSymbol(psi, this) is KtNamedFunction -> JKMultiverseFunctionSymbol(psi, this) is KtProperty -> JKMultiversePropertySymbol(psi, this) + is PsiLocalVariable -> JKMultiverseFieldSymbol(psi, this) 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 dca7504124c..072ff7d67a4 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/JavaToJKTreeBuilder.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/JavaToJKTreeBuilder.kt @@ -309,19 +309,22 @@ class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) { fun Array.toJK(): List { return this.map { if (it is PsiLocalVariable) { - JKLocalVariableImpl( - with(modifierMapper) { it.modifierList.toJK() }, - with(expressionTreeMapper) { it.typeElement.toJK() }, - JKNameIdentifierImpl(it.name ?: TODO()), - with(expressionTreeMapper) { it.initializer.toJK() } - ).also { i -> - symbolProvider.provideUniverseSymbol(it, i) - i.psi = it - } + it.toJK() } else TODO() } } + fun PsiLocalVariable.toJK(): JKLocalVariable = + JKLocalVariableImpl( + with(modifierMapper) { modifierList.toJK() }, + with(expressionTreeMapper) { typeElement.toJK() }, + JKNameIdentifierImpl(this.name ?: TODO()), + with(expressionTreeMapper) { initializer.toJK() } + ).also { i -> + symbolProvider.provideUniverseSymbol(this, i) + i.psi = this + } + fun PsiStatement?.toJK(): JKStatement { return when (this) { null -> JKExpressionStatementImpl(JKStubExpressionImpl()) @@ -384,6 +387,7 @@ class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) { JKJavaThrowStatementImpl(with(expressionTreeMapper) { exception.toJK() }) is PsiTryStatement -> JKJavaTryStatementImpl( + resourceList?.toList()?.map { (it as PsiLocalVariable).toJK() }.orEmpty(), tryBlock?.toJK() ?: JKBodyStub, finallyBlock?.toJK() ?: JKBodyStub, catchSections.map { it.toJK() } diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/TryStatementConversion.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/TryStatementConversion.kt index e4c7672a247..4327a97607e 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/TryStatementConversion.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/TryStatementConversion.kt @@ -5,23 +5,65 @@ package org.jetbrains.kotlin.j2k.conversions -import org.jetbrains.kotlin.j2k.ConversionContext -import org.jetbrains.kotlin.j2k.copyTreeAndDetach +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.j2k.* import org.jetbrains.kotlin.j2k.tree.* import org.jetbrains.kotlin.j2k.tree.impl.* +import org.jetbrains.kotlin.name.ClassId +import java.util.* class TryStatementConversion(private val context: ConversionContext) : RecursiveApplicableConversionBase() { override fun applyToElement(element: JKTreeElement): JKTreeElement { if (element !is JKJavaTryStatement) return recurse(element) - val tryExpression = JKKtTryExpressionImpl( - element::tryBlock.detached(), - element::finallyBlock.detached(), - element.catchSections.flatMap(::convertCatchSection) - ) - return recurse(JKExpressionStatementImpl(tryExpression)) + return if (element.resourceDeclarations.isEmpty()) + recurse(convertNoResourcesTryStatement(element)) + else recurse(convertTryStatementWithResources(element)) } + private fun convertNoResourcesTryStatement(tryStatement: JKJavaTryStatement): JKStatement = + JKExpressionStatementImpl( + JKKtTryExpressionImpl( + tryStatement::tryBlock.detached(), + tryStatement::finallyBlock.detached(), + tryStatement.catchSections.flatMap(::convertCatchSection) + ) + ) + + private fun convertTryStatementWithResources(tryStatement: JKJavaTryStatement): JKStatement { + val body = + resourceDeclarationsToUseExpression( + tryStatement.resourceDeclarations, + JKBlockStatementImpl(tryStatement::tryBlock.detached()) + ) + return if (tryStatement.finallyBlock !is JKBodyStub || tryStatement.catchSections.isNotEmpty()) { + JKExpressionStatementImpl( + JKKtTryExpressionImpl( + JKBlockImpl(listOf(body)), + tryStatement::finallyBlock.detached(), + tryStatement.catchSections.flatMap(::convertCatchSection) + ) + ) + } else body + } + + private fun resourceDeclarationsToUseExpression( + resourceDeclarations: List, + innerStatement: JKStatement + ): JKStatement = + resourceDeclarations + .reversed() + .fold(innerStatement) { inner, variable -> + JKExpressionStatementImpl( + useExpression( + receiver = (variable as JKLocalVariable)::initializer.detached(), + variableIdentifier = variable::name.detached(), + body = inner, + symbolProvider = context.symbolProvider + ) + ) + } + private fun convertCatchSection(javaCatchSection: JKJavaTryCatchSection): List { javaCatchSection.block.detach(javaCatchSection) return javaCatchSection.parameter.type.type.let { diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/j.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/j.kt index e146b026118..a25b723d119 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/j.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/j.kt @@ -319,11 +319,13 @@ class JKJavaThrowStatementImpl(exception: JKExpression) : JKJavaThrowStatement, } class JKJavaTryStatementImpl( + resourceDeclarations: List, tryBlock: JKBlock, finallyBlock: JKBlock, catchSections: List ) : JKJavaTryStatement, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() { + override var resourceDeclarations: List by children(resourceDeclarations) override var tryBlock: JKBlock by child(tryBlock) override var finallyBlock: JKBlock by child(finallyBlock) override var catchSections: List by children(catchSections) 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 a6a5d4f9916..52f7239cbc2 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/symbols.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/symbols.kt @@ -5,10 +5,7 @@ package org.jetbrains.kotlin.j2k.tree.impl -import com.intellij.psi.PsiClass -import com.intellij.psi.PsiField -import com.intellij.psi.PsiMethod -import com.intellij.psi.PsiReference +import com.intellij.psi.* import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl import com.intellij.util.reverse import org.jetbrains.kotlin.j2k.JKSymbolProvider @@ -144,15 +141,15 @@ class JKUniverseFieldSymbol : JKFieldSymbol, JKUniverseSymbol { get() = target.name.value // TODO("Fix this") } -class JKMultiverseFieldSymbol(override val target: PsiField, private val symbolProvider: JKSymbolProvider) : JKFieldSymbol { +class JKMultiverseFieldSymbol(override val target: PsiVariable, private val symbolProvider: JKSymbolProvider) : JKFieldSymbol { override val fieldType: JKType get() = target.type.toJK(symbolProvider) override val name: String - get() = target.name + get() = target.name!! override val declaredIn: JKSymbol get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates. override val fqName: String - get() = target.name // TODO("Fix this") + get() = target.name!! // TODO("Fix this") } class JKMultiversePropertySymbol(override val target: KtProperty, private val symbolProvider: JKSymbolProvider) : JKFieldSymbol { diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/j.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/j.kt index 4e2532e20b8..80e01b66aef 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/j.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/j.kt @@ -93,6 +93,7 @@ interface JKJavaThrowStatement : JKStatement { } interface JKJavaTryStatement : JKStatement { + var resourceDeclarations: List var tryBlock: JKBlock var finallyBlock: JKBlock var catchSections: List