New J2K: Extract base from concrete implementations

This commit is contained in:
Simon Ogorodnik
2018-05-28 17:40:28 +03:00
committed by Ilya Kirillov
parent bfb0f4a369
commit 7c278bfbab
2 changed files with 98 additions and 86 deletions
@@ -0,0 +1,98 @@
/*
* 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.tree.impl
import org.jetbrains.kotlin.j2k.tree.JKBranchElement
import org.jetbrains.kotlin.j2k.tree.JKElement
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
import org.jetbrains.kotlin.j2k.tree.visitors.JKVisitor
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
private class JKChild<T : JKElement>(val value: Int) : ReadWriteProperty<JKBranchElementBase, T> {
override operator fun getValue(thisRef: JKBranchElementBase, property: KProperty<*>): T {
return thisRef.children[value] as T
}
override operator fun setValue(thisRef: JKBranchElementBase, property: KProperty<*>, value: T) {
(thisRef.children[this.value] as T).detach(thisRef)
thisRef.children[this.value] = value
value.attach(thisRef)
}
}
private class JKListChild<T : JKElement>(val value: Int) : ReadWriteProperty<JKBranchElementBase, List<T>> {
override operator fun getValue(thisRef: JKBranchElementBase, property: KProperty<*>): 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(thisRef) }
thisRef.children[this.value] = value
value.forEach { it.attach(thisRef) }
}
}
abstract class JKElementBase : JKTreeElement {
override var parent: JKElement? = null
final override fun detach(from: JKElement) {
val prevParent = parent
assert(prevParent != null)
parent = null
onDetach(prevParent!!)
}
open fun onDetach(from: JKElement) {
}
final override fun attach(to: JKElement) {
assert(parent == null)
parent = to
onAttach()
}
open fun onAttach() {
}
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitTreeElement(this, data)
override fun <D> acceptChildren(visitor: JKVisitor<Unit, D>, data: D) {}
}
abstract class JKBranchElementBase : JKElementBase(), JKBranchElement {
private 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> children(): ReadWriteProperty<JKBranchElementBase, List<T>> {
return children(emptyList())
}
protected fun <T : JKTreeElement> children(v: List<T>): ReadWriteProperty<JKBranchElementBase, List<T>> {
children.add(childNum, v)
v.forEach { it.attach(this) }
return JKListChild(childNum++)
}
override fun <D> acceptChildren(visitor: JKVisitor<Unit, D>, data: D) {
children.forEach {
if (it is JKTreeElement)
it.accept(visitor, data)
else
(it as? List<JKTreeElement>)?.forEach { it.accept(visitor, data) }
}
}
override val children: MutableList<Any> = mutableListOf()
}
@@ -19,92 +19,6 @@ package org.jetbrains.kotlin.j2k.tree.impl
import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.j2k.tree.*
import org.jetbrains.kotlin.j2k.tree.visitors.JKVisitor
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class JKChild<T : JKElement>(val value: Int) : ReadWriteProperty<JKBranchElementBase, T> {
override operator fun getValue(thisRef: JKBranchElementBase, property: KProperty<*>): T {
return thisRef.children[value] as T
}
override operator fun setValue(thisRef: JKBranchElementBase, property: KProperty<*>, value: T) {
(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[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(thisRef) }
thisRef.children[this.value] = value
value.forEach { it.attach(thisRef) }
}
}
abstract class JKElementBase : JKTreeElement {
override var parent: JKElement? = null
final override fun detach(from: JKElement) {
val prevParent = parent
assert(prevParent != null)
parent = null
onDetach(prevParent!!)
}
open fun onDetach(from: JKElement) {
}
final override fun attach(to: JKElement) {
assert(parent == null)
parent = to
onAttach()
}
open fun onAttach() {
}
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitTreeElement(this, data)
override fun <D> acceptChildren(visitor: JKVisitor<Unit, D>, data: D) {}
}
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> children(): ReadWriteProperty<JKBranchElementBase, List<T>> {
children.add(childNum, listOf<T>())
return JKListChild(childNum++)
}
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++)
}
override fun <D> acceptChildren(visitor: JKVisitor<Unit, D>, data: D) {
children.forEach {
if (it is JKTreeElement)
it.accept(visitor, data)
else
(it as? List<JKTreeElement>)?.forEach { it.accept(visitor, data) }
}
}
override val children: MutableList<Any> = mutableListOf()
}
class JKClassImpl(modifierList: JKModifierList, name: JKNameIdentifier, override var classKind: JKClass.ClassKind) :
JKClass,