From 1facbe68fa73a36917ea0e16a85201219a5418d1 Mon Sep 17 00:00:00 2001 From: Xanonymous Date: Mon, 29 Jul 2024 00:24:01 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20implement=20child=20remo?= =?UTF-8?q?val=20function=20for=20tree?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/tw/xcc/gumtree/model/BasicTree.kt | 2 +- .../kotlin/tw/xcc/gumtree/model/GumTree.kt | 22 +++++++++++++++++++ .../tw/xcc/gumtree/model/GumTreeView.kt | 8 +++++++ core/src/test/kotlin/GumTreeTest.kt | 16 ++++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/core/src/main/kotlin/tw/xcc/gumtree/model/BasicTree.kt b/core/src/main/kotlin/tw/xcc/gumtree/model/BasicTree.kt index 13db19f..acbcd5c 100644 --- a/core/src/main/kotlin/tw/xcc/gumtree/model/BasicTree.kt +++ b/core/src/main/kotlin/tw/xcc/gumtree/model/BasicTree.kt @@ -68,7 +68,7 @@ abstract class BasicTree : Tree, Traversable where T : BasicTree { } } - fun addChild(child: T) { + open fun addChild(child: T) { synchronized(this) { val newChildrenMap = childrenMap.get() newChildrenMap[newChildrenMap.size] = child.also { it.setParentTo(self) } diff --git a/core/src/main/kotlin/tw/xcc/gumtree/model/GumTree.kt b/core/src/main/kotlin/tw/xcc/gumtree/model/GumTree.kt index ff0b801..6cdfea6 100644 --- a/core/src/main/kotlin/tw/xcc/gumtree/model/GumTree.kt +++ b/core/src/main/kotlin/tw/xcc/gumtree/model/GumTree.kt @@ -76,6 +76,23 @@ open class GumTree( child: GumTree ) = insertChildAtImpl(pos, child) + open fun tryRemoveChild(child: GumTree): Boolean = + synchronized(this) { + val pos = child.positionOfParent + if (pos == -1) { + return false + } + + val children = childrenMap.get() + val removedChild = children.remove(pos) ?: return false + + removedChild.setParentTo(null) + removedChild._positionOfParent.set(-1) + childrenMap.set(children) + + return true + } + open fun toNewFrozen(): GumTreeView = synchronized(this) { val children = childrenMap.get() @@ -88,6 +105,11 @@ open class GumTree( infix fun hasSameLabelAs(other: GumTree): Boolean = label == other.label + override fun addChild(child: GumTree) { + super.addChild(child) + child._positionOfParent.set(childCount() - 1) + } + final override infix fun isIsomorphicTo(other: GumTree): Boolean = isIsomorphicTo(this, other) final override infix fun isIsoStructuralTo(other: GumTree): Boolean = isIsoStructuralTo(this, other) diff --git a/core/src/main/kotlin/tw/xcc/gumtree/model/GumTreeView.kt b/core/src/main/kotlin/tw/xcc/gumtree/model/GumTreeView.kt index 5eb8faa..3bc3230 100644 --- a/core/src/main/kotlin/tw/xcc/gumtree/model/GumTreeView.kt +++ b/core/src/main/kotlin/tw/xcc/gumtree/model/GumTreeView.kt @@ -41,6 +41,14 @@ class GumTreeView private constructor(target: GumTree) : GumTree(target) { throw NoSuchMethodException("calling this method in GumTreeView is not allowed") } + override fun addChild(child: GumTree) { + throw NoSuchMethodException("calling this method in GumTreeView is not allowed") + } + + override fun tryRemoveChild(child: GumTree): Boolean { + throw NoSuchMethodException("calling this method in GumTreeView is not allowed") + } + override fun inOrdered(): List = throw NotImplementedError() companion object { diff --git a/core/src/test/kotlin/GumTreeTest.kt b/core/src/test/kotlin/GumTreeTest.kt index 4f850fb..97734b3 100644 --- a/core/src/test/kotlin/GumTreeTest.kt +++ b/core/src/test/kotlin/GumTreeTest.kt @@ -142,4 +142,20 @@ internal class GumTreeTest { assertEquals(child.id, frozen.childAt(0)?.id) assertTrue(child !== frozen.childAt(0)) } + + @Test + fun `test tryRemoveChild`() { + val child = GumTree(TreeType.empty(), "child") + givenTree.addChild(child) + val actualResult = givenTree.tryRemoveChild(child) + assertTrue(actualResult) + assertEquals(0, givenTree.childCount()) + } + + @Test + fun `test tryRemoveChild with non-child`() { + val child = GumTree(TreeType.empty(), "child") + val actualResult = givenTree.tryRemoveChild(child) + assertFalse(actualResult) + } } \ No newline at end of file