Permalink
Browse files

Extracting zipper to hole map conversion methods into a trait.

  • Loading branch information...
ncreep committed Dec 13, 2011
1 parent bddf6e9 commit 2b38bcd8ae494e17c1fbe56dd13f1df3c9d3dd64
@@ -1,14 +1,15 @@
package com.codecommit.antixml
import Zipper._
+import ZipperHoleMapper._
import util.VectorCase
import collection.immutable.IndexedSeq
/** Provides unselection support for zipper. */
-private[antixml] trait ZipperUnselection { self: Zipper[Node] =>
+private[antixml] trait ZipperUnselection extends ZipperHoleMapper { self: Zipper[Node] =>
/** Applies the node updates to the context parent and returns the result. */
- private def unselect(context: Context, mergeStrategy: ZipperMergeStrategy) = {
+ def unselect(context: Context, mergeStrategy: ZipperMergeStrategy) = {
val topLevelHoleInfo = toHoleInfo(context)
pullBackGroup(context.parent, topLevelHoleInfo, mergeStrategy)._1.asInstanceOf[Zipper[Node]]
}
@@ -123,9 +123,9 @@ import CanBuildFromWithZipper._
trait Zipper[+A <: Node] extends Group[A]
with IndexedSeqLike[A, Zipper[A]]
with ZipperGroupOverrides[A]
+ with ZipperUnselection
with ZipperHoleShifting
- with ZipperAxes
- with ZipperUnselection { self =>
+ with ZipperAxes { self =>
/**
* Returns the original group that was selected upon when the Zipper was created. A value of `None` indicates that
@@ -153,61 +153,6 @@ trait Zipper[+A <: Node] extends Group[A]
val ctx = context.getOrElse(sys.error("Zipper does not have a valid context"))
unselect(ctx, zms)
}
-
- /** Each hole is associated with a list of node/time pairs as well as a master update time */
- private[antixml] type HoleInfo = ZipperHoleMap[(VectorCase[(Node,Time)],Time)]
-
- /** Converts the given context object into a hole info instance. */
- private[antixml] def toHoleInfo(context: Context) = new HoleMapper(context).holeInfo
-
- /** A utility class to convert the contents of the zipper into a hole map. */
- private[this] class HoleMapper(context: Context) {
- private val initHoleInfoItem:(VectorCase[(Node,Time)],Time) = (util.Vector0,0)
-
- type HoleMapGet[A] = A => (ZipperPath, Time, GenTraversableOnce[Node])
-
- /** Adding items to the hole info object using the given getter function to transform the items
- * into the appropriate format. */
- private def addToHoleInfo[A](items: Seq[A], h: HoleInfo, get: HoleMapGet[A]) = {
- (h /: items) { (hi, item) =>
- val (path, time, nodes) = get(item)
- val (oldNodes, oldTime) = hi.getDeep(path).getOrElse(initHoleInfoItem)
- val newItems = (oldNodes /: nodes) { case(old, node) => old :+ (node, time) }
- val newTime = math.max(oldTime, time)
- hi.updatedDeep(path, (newItems, newTime))
- }
- }
-
- val holeInfo: HoleInfo = {
- val Context(_, _, metas, additionalHoles, hiddenNodes) = context
-
- /* Getters for the different parts of the zipper. */
-
- val indicesGet = (i: Int) => {
- val (path, time) = metas(i)
- val items = util.Vector1(self(i))
- (path, time, items)
- }
-
- val hiddenGet = (ewc: ElemsWithContextHidden) => {
- val ElemsWithContextHidden(path, time, items) = ewc
- (path, time, items)
- }
-
- val additonalGet = (pt: (ZipperPath, Time)) => {
- val (path, time) = pt
- (path, time, util.Vector0)
- }
-
- case class ItemsGet[A](items: Seq[A], get: HoleMapGet[A])
- val itemsGetters = List(ItemsGet(indices, indicesGet), ItemsGet(hiddenNodes, hiddenGet), ItemsGet(additionalHoles, additonalGet))
-
- val holeInit: HoleInfo = ZipperHoleMap.empty
- (holeInit /: itemsGetters) { case (hi, ItemsGet(items, get)) =>
- addToHoleInfo(items, hi, get)
- }
- }
- }
}
object Zipper {
@@ -0,0 +1,68 @@
+package com.codecommit.antixml
+
+import Zipper._
+import ZipperHoleMapper._
+import util.VectorCase
+import scala.collection.GenTraversableOnce
+import CanBuildFromWithZipper._
+
+/** Converts a zipper into a hole map. */
+private[antixml] trait ZipperHoleMapper { self: Zipper[Node] =>
+
+ private val initHoleInfoItem: (VectorCase[(Node, Time)], Time) = (util.Vector0, 0)
+
+ private type HoleMapGet[A] = A => (ZipperPath, Time, GenTraversableOnce[Node])
+
+ /** Adding items to the hole info object using the given getter function to transform the items
+ * into the appropriate format.
+ */
+ private def addToHoleInfo[A](items: Seq[A], h: HoleInfo, get: HoleMapGet[A]) = {
+ (h /: items) { (hi, item) =>
+ val (path, time, nodes) = get(item)
+ val (oldNodes, oldTime) = hi.getDeep(path).getOrElse(initHoleInfoItem)
+ val newItems = (oldNodes /: nodes) { case (old, node) => old :+ (node, time) }
+ val newTime = math.max(oldTime, time)
+ hi.updatedDeep(path, (newItems, newTime))
+ }
+ }
+
+ /** Using the given context to convert self to a hole map. */
+ def toHoleInfo(context: Context): HoleInfo = {
+ val Context(_, _, metas, additionalHoles, hiddenNodes) = context
+
+ /* Getters for the different parts of the zipper. */
+
+ val indicesGet = (i: Int) => {
+ val (path, time) = metas(i)
+ val items = util.Vector1(self(i))
+ (path, time, items)
+ }
+
+ val hiddenGet = (ewc: ElemsWithContextHidden) => {
+ val ElemsWithContextHidden(path, time, items) = ewc
+ (path, time, items)
+ }
+
+ val additonalGet = (pt: (ZipperPath, Time)) => {
+ val (path, time) = pt
+ (path, time, util.Vector0)
+ }
+
+ case class ItemsGet[A](items: Seq[A], get: HoleMapGet[A])
+ val itemsGetters = List(
+ ItemsGet(indices, indicesGet),
+ ItemsGet(hiddenNodes, hiddenGet),
+ ItemsGet(additionalHoles, additonalGet))
+
+ val holeInit: HoleInfo = ZipperHoleMap.empty
+ (holeInit /: itemsGetters) {
+ case (hi, ItemsGet(items, get)) =>
+ addToHoleInfo(items, hi, get)
+ }
+ }
+}
+
+object ZipperHoleMapper {
+ /** Each hole is associated with a list of node/time pairs as well as a master update time */
+ private[antixml] type HoleInfo = ZipperHoleMap[(VectorCase[(Node,Time)],Time)]
+}
@@ -7,7 +7,7 @@ import scala.collection.immutable.SortedSet
import CanBuildFromWithZipper._
/** Responsible for zipper hole shifting support. */
-private[antixml] trait ZipperHoleShifting { self: Zipper[Node] =>
+private[antixml] trait ZipperHoleShifting extends ZipperHoleMapper { self: Zipper[Node] =>
/** Shifts the focus of the zipper to another set of holes.
*

0 comments on commit 2b38bcd

Please sign in to comment.