diff -r ce3eed2b16f7 -r 4e4d3ea3725a src/Pure/PIDE/markup_tree.scala --- a/src/Pure/PIDE/markup_tree.scala Sun Aug 22 16:43:20 2010 +0200 +++ b/src/Pure/PIDE/markup_tree.scala Sun Aug 22 18:46:16 2010 +0200 @@ -17,31 +17,24 @@ object Markup_Tree { - case class Node[A](val range: Text.Range, val info: A) - { - def contains[B](that: Node[B]): Boolean = this.range contains that.range - def restrict(r: Text.Range): Node[A] = Node(range.restrict(r), info) - } - - /* branches sorted by quasi-order -- overlapping ranges appear as equivalent */ object Branches { - type Entry = (Node[Any], Markup_Tree) - type T = SortedMap[Node[Any], Entry] + type Entry = (Text.Info[Any], Markup_Tree) + type T = SortedMap[Text.Info[Any], Entry] - val empty = SortedMap.empty[Node[Any], Entry](new scala.math.Ordering[Node[Any]] + val empty = SortedMap.empty[Text.Info[Any], Entry](new scala.math.Ordering[Text.Info[Any]] { - def compare(x: Node[Any], y: Node[Any]): Int = x.range compare y.range + def compare(x: Text.Info[Any], y: Text.Info[Any]): Int = x.range compare y.range }) def update(branches: T, entry: Entry): T = branches + (entry._1 -> entry) def overlapping(range: Text.Range, branches: T): T = { - val start = Node[Any](Text.Range(range.start), Nil) - val stop = Node[Any](Text.Range(range.stop), Nil) + val start = Text.Info[Any](Text.Range(range.start), Nil) + val stop = Text.Info[Any](Text.Range(range.stop), Nil) branches.get(stop) match { case Some(end) if range overlaps end._1.range => update(branches.range(start, stop), end) @@ -64,49 +57,50 @@ case list => list.mkString("Tree(", ",", ")") } - def + (new_node: Node[Any]): Markup_Tree = + def + (new_info: Text.Info[Any]): Markup_Tree = { - branches.get(new_node) match { + branches.get(new_info) match { case None => - new Markup_Tree(Branches.update(branches, new_node -> empty)) - case Some((node, subtree)) => - if (node.range != new_node.range && node.contains(new_node)) - new Markup_Tree(Branches.update(branches, node -> (subtree + new_node))) - else if (new_node.contains(branches.head._1) && new_node.contains(branches.last._1)) - new Markup_Tree(Branches.update(Branches.empty, (new_node -> this))) + new Markup_Tree(Branches.update(branches, new_info -> empty)) + case Some((info, subtree)) => + if (info.range != new_info.range && info.contains(new_info)) + new Markup_Tree(Branches.update(branches, info -> (subtree + new_info))) + else if (new_info.contains(branches.head._1) && new_info.contains(branches.last._1)) + new Markup_Tree(Branches.update(Branches.empty, (new_info -> this))) else { - val body = Branches.overlapping(new_node.range, branches) - if (body.forall(e => new_node.contains(e._1))) { + val body = Branches.overlapping(new_info.range, branches) + if (body.forall(e => new_info.contains(e._1))) { val rest = (branches /: body) { case (bs, (e, _)) => bs - e } - new Markup_Tree(Branches.update(rest, new_node -> new Markup_Tree(body))) + new Markup_Tree(Branches.update(rest, new_info -> new Markup_Tree(body))) } else { // FIXME split markup!? - System.err.println("Ignored overlapping markup: " + new_node) + System.err.println("Ignored overlapping markup information: " + new_info) this } } } } - def select[A](root: Node[A])(sel: PartialFunction[Any, A]): Stream[Node[A]] = + def select[A](root: Text.Info[A])(sel: PartialFunction[Text.Info[Any], A]): Stream[Text.Info[A]] = { - def stream(parent: Node[A], bs: Branches.T): Stream[Node[A]] = + def stream(parent: Text.Info[A], bs: Branches.T): Stream[Text.Info[A]] = { val substream = - (for ((_, (node, subtree)) <- Branches.overlapping(parent.range, bs).toStream) yield { - if (sel.isDefinedAt(node.info)) { - val current = Node(node.range.restrict(parent.range), sel(node.info)) + (for ((_, (info, subtree)) <- Branches.overlapping(parent.range, bs).toStream) yield { + if (sel.isDefinedAt(info)) { + val current = Text.Info(info.range.restrict(parent.range), sel(info)) stream(current, subtree.branches) } - else stream(parent.restrict(node.range), subtree.branches) + else stream(parent.restrict(info.range), subtree.branches) }).flatten - def padding(last: Text.Offset, s: Stream[Node[A]]): Stream[Node[A]] = + def padding(last: Text.Offset, s: Stream[Text.Info[A]]): Stream[Text.Info[A]] = s match { - case (node @ Node(Text.Range(start, stop), _)) #:: rest => + case info #:: rest => + val Text.Range(start, stop) = info.range if (last < start) - parent.restrict(Text.Range(last, start)) #:: node #:: padding(stop, rest) - else node #:: padding(stop, rest) + parent.restrict(Text.Range(last, start)) #:: info #:: padding(stop, rest) + else info #:: padding(stop, rest) case Stream.Empty => if (last < parent.range.stop) Stream(parent.restrict(Text.Range(last, parent.range.stop))) @@ -118,10 +112,11 @@ stream(root, branches) } - def swing_tree(parent: DefaultMutableTreeNode)(swing_node: Node[Any] => DefaultMutableTreeNode) + def swing_tree(parent: DefaultMutableTreeNode) + (swing_node: Text.Info[Any] => DefaultMutableTreeNode) { - for ((_, (node, subtree)) <- branches) { - val current = swing_node(node) + for ((_, (info, subtree)) <- branches) { + val current = swing_node(info) subtree.swing_tree(current)(swing_node) parent.add(current) }