diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt index dcdf322d8b8..5b6ebf244db 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt @@ -37,6 +37,7 @@ object ConversionsRunner { LiteralConversion(), InnerClassConversion(), ModifiersConversion(context), + StaticsToCompanionExtractConversion(), PolyadicExpressionConversion(), BinaryExpressionConversion() ) diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/NewCodeBuilder.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/NewCodeBuilder.kt index 9cc5b9fe8d3..62cf3519c37 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/NewCodeBuilder.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/NewCodeBuilder.kt @@ -37,6 +37,8 @@ class NewCodeBuilder { JKClass.ClassKind.CLASS -> "class" JKClass.ClassKind.ENUM -> "enum class" JKClass.ClassKind.INTERFACE -> "interface" + JKClass.ClassKind.OBJECT -> "object" + JKClass.ClassKind.COMPANION -> "companion object" } inner class Visitor : JKVisitorVoid { diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/StaticsToCompanionExtractConversion.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/StaticsToCompanionExtractConversion.kt new file mode 100644 index 00000000000..be34e393abf --- /dev/null +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/StaticsToCompanionExtractConversion.kt @@ -0,0 +1,54 @@ +/* + * 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 org.jetbrains.kotlin.j2k.tree.* +import org.jetbrains.kotlin.j2k.tree.impl.* + +class StaticsToCompanionExtractConversion : RecursiveApplicableConversionBase() { + override fun applyToElement(element: JKTreeElement): JKTreeElement { + if (element !is JKClass) return recurse(element) + if (element.classKind == JKClass.ClassKind.COMPANION || element.classKind == JKClass.ClassKind.OBJECT) return element + val statics = element.declarationList.filter { declaration -> + declaration is JKModifierListOwner && + declaration.modifierList.modifiers.any { it is JKJavaModifier && it.type == JKJavaModifier.JavaModifierType.STATIC } + } + + if (statics.isEmpty()) return recurse(element) + val companion = findOrCreateCompanion(element) + + + element.declarationList -= statics + companion.declarationList += statics.onEach { declaration -> + (declaration as JKModifierListOwner) + declaration.modifierList.modifiers = + declaration.modifierList.modifiers.filterNot { it is JKJavaModifier && it.type == JKJavaModifier.JavaModifierType.STATIC } + } + + return recurse(element) + } + + fun findOrCreateCompanion(element: JKClass): JKClass { + val companion = element.declarationList + .asSequence() + .filterIsInstance() + .firstOrNull { it.classKind == JKClass.ClassKind.COMPANION } + + if (companion != null) return companion + + return JKClassImpl( + JKModifierListImpl( + listOf( + JKAccessModifierImpl(JKAccessModifier.Visibility.PUBLIC), + JKModalityModifierImpl(JKModalityModifier.Modality.FINAL) + ) + ), + JKNameIdentifierImpl(""), + JKInheritanceInfoImpl(emptyList()), + JKClass.ClassKind.COMPANION + ).also { element.declarationList += it } + } +} diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/jk.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/jk.kt index 96d90fc4fd8..59ae2624225 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/jk.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/jk.kt @@ -47,7 +47,7 @@ interface JKClass : JKDeclaration, JKModifierListOwner { var classKind: ClassKind enum class ClassKind { - ABSTRACT, ANNOTATION, CLASS, ENUM, INTERFACE + ABSTRACT, ANNOTATION, CLASS, ENUM, INTERFACE, OBJECT, COMPANION } }