New J2K: Add from argument to detach
Support detach/attach/multilist in applyRecursive Clarify attach/detach/onElementChanged order
This commit is contained in:
committed by
Ilya Kirillov
parent
9b205c2825
commit
985e94fbf3
@@ -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)
|
||||
|
||||
@@ -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("}")
|
||||
}
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
@@ -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<JKTreeElement>, 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<JKTreeElement>,
|
||||
iter: MutableListIterator<Any>,
|
||||
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)
|
||||
}
|
||||
@@ -29,28 +29,28 @@ class JKChild<T : JKElement>(val value: Int) : ReadWriteProperty<JKBranchElement
|
||||
}
|
||||
|
||||
override operator fun setValue(thisRef: JKBranchElementBase, property: KProperty<*>, 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<T : JKElement>(val value: Int) : ReadWriteProperty<JKBranchElementBase, List<T>> {
|
||||
override operator fun getValue(thisRef: JKBranchElementBase, property: KProperty<*>): List<T> {
|
||||
return thisRef.children.toList() as List<T>
|
||||
return thisRef.children[value] as List<T>
|
||||
}
|
||||
|
||||
override operator fun setValue(thisRef: JKBranchElementBase, property: KProperty<*>, value: List<T>) {
|
||||
(thisRef.children[this.value] as List<T>).forEach { it.detach() }
|
||||
value.forEach { it.attach(thisRef) }
|
||||
(thisRef.children[this.value] as List<T>).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 <T : JKTreeElement, U : T> child(v: U): ReadWriteProperty<JKBranchElementBase, T> {
|
||||
children.add(childNum, v)
|
||||
v.attach(this)
|
||||
return JKChild(childNum++)
|
||||
}
|
||||
|
||||
protected inline fun <reified T : JKTreeElement> child(): ReadWriteProperty<JKBranchElementBase, List<T>> {
|
||||
children[childNum] = listOf<T>()
|
||||
protected inline fun <reified T : JKTreeElement> children(): ReadWriteProperty<JKBranchElementBase, List<T>> {
|
||||
children.add(childNum, listOf<T>())
|
||||
return JKListChild(childNum++)
|
||||
}
|
||||
|
||||
protected inline fun <reified T : JKTreeElement> child(v: List<T>): ReadWriteProperty<JKBranchElementBase, List<T>> {
|
||||
children[childNum] = v
|
||||
protected inline fun <reified T : JKTreeElement> children(v: List<T>): ReadWriteProperty<JKBranchElementBase, List<T>> {
|
||||
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<JKUniverseDeclaration>()
|
||||
override var declarationList by children<JKUniverseDeclaration>()
|
||||
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, 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<JKModifier> = emptyList()) : JKModifierList, JKBranchElementBase() {
|
||||
override var modifiers: List<JKModifier> by child(modifiers)
|
||||
override var modifiers: List<JKModifier> by children(modifiers)
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitModifierList(this, data)
|
||||
}
|
||||
|
||||
@@ -132,7 +134,7 @@ class JKValueArgumentImpl(type: JKType, override val name: String) : JKValueArgu
|
||||
}
|
||||
|
||||
class JKBlockImpl(statements: List<JKStatement> = emptyList()) : JKBlock, JKBranchElementBase() {
|
||||
override var statements by child(statements)
|
||||
override var statements by children(statements)
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitBlock(this, data)
|
||||
}
|
||||
|
||||
@@ -155,7 +157,7 @@ class JKPostfixExpressionImpl(expression: JKExpression, override var operator: J
|
||||
}
|
||||
|
||||
class JKExpressionListImpl(expressions: List<JKExpression> = emptyList()) : JKExpressionList, JKBranchElementBase() {
|
||||
override var expressions by child(expressions)
|
||||
override var expressions by children(expressions)
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitExpressionList(this, data)
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ interface JKQualifier
|
||||
interface JKElement {
|
||||
val parent: JKElement?
|
||||
|
||||
fun detach()
|
||||
fun detach(from: JKElement)
|
||||
|
||||
fun attach(to: JKElement)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user