diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/JavaToJKTreeBuilder.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/JavaToJKTreeBuilder.kt index 4667117ff67..61f61f080fb 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/JavaToJKTreeBuilder.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/JavaToJKTreeBuilder.kt @@ -218,10 +218,8 @@ class JavaToJKTreeBuilder { JKNameIdentifierImpl(name!!), classKind ).also { - it.declarationList.apply { - declarations = psi.children.mapNotNull { - ElementVisitor(this@DeclarationMapper).apply { it.accept(this) }.resultElement as? JKUniverseDeclaration - } + it.declarationList = psi.children.mapNotNull { + ElementVisitor(this@DeclarationMapper).apply { it.accept(this) }.resultElement as? JKUniverseDeclaration } bindSymbol(this, it) diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/NewCodeBuilder.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/NewCodeBuilder.kt index cce76da088e..2434fed3743 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/NewCodeBuilder.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/NewCodeBuilder.kt @@ -45,10 +45,10 @@ class NewCodeBuilder { printer.print(classKindString(universeClass.classKind)) builder.append(" ") printer.print(universeClass.name.value) - if (universeClass.declarationList.declarations.isNotEmpty()) { + if (universeClass.declarationList.isNotEmpty()) { printer.println("{") printer.pushIndent() - universeClass.declarationList.declarations.forEach { it.accept(this, data) } + universeClass.declarationList.forEach { it.accept(this, data) } printer.popIndent() printer.println("}") } diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/JavaMethodToKotlinFunctionConversion.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/JavaMethodToKotlinFunctionConversion.kt index 4d1be1f7a73..13a4d859e33 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/JavaMethodToKotlinFunctionConversion.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/JavaMethodToKotlinFunctionConversion.kt @@ -32,7 +32,7 @@ class JavaMethodToKotlinFunctionConversion : TransformerBasedConversion() { override fun visitUniverseClass(universeClass: JKUniverseClass) { somethingChanged = true - universeClass.declarationList.declarations = universeClass.declarationList.declarations.map { + universeClass.declarationList = universeClass.declarationList.map { if (it is JKJavaMethod) JKKtFunctionImpl( JKJavaPrimitiveTypeImpl.BOOLEAN, it.name, diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/MatchBasedConversion.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/MatchBasedConversion.kt index 81563b6aa22..84caa4e0194 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/MatchBasedConversion.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/MatchBasedConversion.kt @@ -6,26 +6,55 @@ package org.jetbrains.kotlin.j2k.conversions import org.jetbrains.kotlin.j2k.tree.JKTreeElement -import org.jetbrains.kotlin.j2k.tree.impl.JKMutableBranchElement +import org.jetbrains.kotlin.j2k.tree.impl.JKBranchElementBase abstract class MatchBasedConversion : BaseConversion() { fun applyRecursive(element: JKTreeElement, func: (JKTreeElement) -> JKTreeElement): JKTreeElement { - if (element is JKMutableBranchElement) { + if (element is JKBranchElementBase) { val iter = element.children.listIterator() while (iter.hasNext()) { val child = iter.next() - val newChild = func(child) - if (child !== newChild) { - onElementChanged(newChild, child) - child.parent = null - newChild.parent = element - iter.set(newChild) + + if (child is List<*>) { + applyRecursiveToList(element, child as List, iter, func) + } else if (child is JKTreeElement) { + val newChild = func(child) + if (child !== newChild) { + child.detach(element) + iter.set(newChild) + newChild.attach(element) + onElementChanged(newChild, child) + } + } else { + error("unsupported child type: ${child::class}") } } } return element } + private inline fun applyRecursiveToList( + element: JKTreeElement, + child: List, + iter: MutableListIterator, + func: (JKTreeElement) -> JKTreeElement + ) { + + val newChild = child.map { + func(it) + } + + child.forEach { it.detach(element) } + iter.set(child) + newChild.forEach { it.attach(element) } + newChild.zip(child).forEach { (old, new) -> + if (old !== new) { + onElementChanged(new, old) + } + } + } + + abstract fun onElementChanged(new: JKTreeElement, old: JKTreeElement) } \ 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 9f6e664dca2..de1e27e2919 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/jk.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/jk.kt @@ -29,28 +29,28 @@ class JKChild(val value: Int) : ReadWriteProperty, value: T) { - (thisRef.children[this.value] as T).detach() - value.attach(thisRef) + (thisRef.children[this.value] as T).detach(thisRef) thisRef.children[this.value] = value + value.attach(thisRef) } } class JKListChild(val value: Int) : ReadWriteProperty> { override operator fun getValue(thisRef: JKBranchElementBase, property: KProperty<*>): List { - return thisRef.children.toList() as List + return thisRef.children[value] as List } override operator fun setValue(thisRef: JKBranchElementBase, property: KProperty<*>, value: List) { - (thisRef.children[this.value] as List).forEach { it.detach() } - value.forEach { it.attach(thisRef) } + (thisRef.children[this.value] as List).forEach { it.detach(thisRef) } thisRef.children[this.value] = value + value.forEach { it.attach(thisRef) } } } abstract class JKElementBase : JKTreeElement { override var parent: JKElement? = null - final override fun detach() { + final override fun detach(from: JKElement) { val prevParent = parent assert(prevParent != null) parent = null @@ -80,16 +80,18 @@ abstract class JKBranchElementBase : JKElementBase(), JKBranchElement { protected var childNum = 0 protected fun child(v: U): ReadWriteProperty { children.add(childNum, v) + v.attach(this) return JKChild(childNum++) } - protected inline fun child(): ReadWriteProperty> { - children[childNum] = listOf() + protected inline fun children(): ReadWriteProperty> { + children.add(childNum, listOf()) return JKListChild(childNum++) } - protected inline fun child(v: List): ReadWriteProperty> { - children[childNum] = v + protected inline fun children(v: List): ReadWriteProperty> { + children.add(childNum, v) + v.forEach { it.attach(this) } return JKListChild(childNum++) } @@ -113,7 +115,7 @@ class JKClassImpl(modifierList: JKModifierList, name: JKNameIdentifier, override override var modifierList by child(modifierList) override val valid: Boolean = true - override var declarationList by child() + override var declarationList by children() override fun accept(visitor: JKVisitor, data: D): R = visitor.visitUniverseClass(this, data) } @@ -122,7 +124,7 @@ class JKClassImpl(modifierList: JKModifierList, name: JKNameIdentifier, override class JKNameIdentifierImpl(override val value: String) : JKNameIdentifier, JKElementBase() {} class JKModifierListImpl(modifiers: List = emptyList()) : JKModifierList, JKBranchElementBase() { - override var modifiers: List by child(modifiers) + override var modifiers: List by children(modifiers) override fun accept(visitor: JKVisitor, data: D): R = visitor.visitModifierList(this, data) } @@ -132,7 +134,7 @@ class JKValueArgumentImpl(type: JKType, override val name: String) : JKValueArgu } class JKBlockImpl(statements: List = emptyList()) : JKBlock, JKBranchElementBase() { - override var statements by child(statements) + override var statements by children(statements) override fun accept(visitor: JKVisitor, data: D): R = visitor.visitBlock(this, data) } @@ -155,7 +157,7 @@ class JKPostfixExpressionImpl(expression: JKExpression, override var operator: J } class JKExpressionListImpl(expressions: List = emptyList()) : JKExpressionList, JKBranchElementBase() { - override var expressions by child(expressions) + override var expressions by children(expressions) override fun accept(visitor: JKVisitor, data: D): R = visitor.visitExpressionList(this, data) } diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/markers.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/markers.kt index 2a120b04a2e..85e5236a3da 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/markers.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/markers.kt @@ -23,7 +23,7 @@ interface JKQualifier interface JKElement { val parent: JKElement? - fun detach() + fun detach(from: JKElement) fun attach(to: JKElement) }