src/Pure/PIDE/document.scala
changeset 73359 d8a0e996614b
parent 73344 f5c147654661
child 73361 ef8c9b3d5355
equal deleted inserted replaced
73358:78aa7846e91f 73359:d8a0e996614b
   244         : Iterator[(Command, Token.Pos)] =
   244         : Iterator[(Command, Token.Pos)] =
   245       {
   245       {
   246         var p = pos
   246         var p = pos
   247         for (command <- commands) yield {
   247         for (command <- commands) yield {
   248           val start = p
   248           val start = p
   249           p = (p /: command.span.content)(_.advance(_))
   249           p = command.span.content.foldLeft(p)(_.advance(_))
   250           (command, start)
   250           (command, start)
   251         }
   251         }
   252       }
   252       }
   253 
   253 
   254       private val block_size = 256
   254       private val block_size = 256
   383     }
   383     }
   384 
   384 
   385     def purge_suppressed: Option[Nodes] =
   385     def purge_suppressed: Option[Nodes] =
   386       graph.keys_iterator.filter(is_suppressed).toList match {
   386       graph.keys_iterator.filter(is_suppressed).toList match {
   387         case Nil => None
   387         case Nil => None
   388         case del => Some(new Nodes((graph /: del)(_.del_node(_))))
   388         case del => Some(new Nodes(del.foldLeft(graph)(_.del_node(_))))
   389       }
   389       }
   390 
   390 
   391     def + (entry: (Node.Name, Node)): Nodes =
   391     def + (entry: (Node.Name, Node)): Nodes =
   392     {
   392     {
   393       val (name, node) = entry
   393       val (name, node) = entry
   394       val imports = node.header.imports
   394       val imports = node.header.imports
   395       val graph1 =
   395       val graph1 =
   396         (graph.default_node(name, Node.empty) /: imports)((g, p) => g.default_node(p, Node.empty))
   396         imports.foldLeft(graph.default_node(name, Node.empty)) {
   397       val graph2 = (graph1 /: graph1.imm_preds(name))((g, dep) => g.del_edge(dep, name))
   397           case (g, p) => g.default_node(p, Node.empty)
   398       val graph3 = (graph2 /: imports)((g, dep) => g.add_edge(dep, name))
   398         }
       
   399       val graph2 =
       
   400         graph1.imm_preds(name).foldLeft(graph1) { case (g, dep) => g.del_edge(dep, name) }
       
   401       val graph3 = imports.foldLeft(graph2) { case (g, dep) => g.add_edge(dep, name) }
   399       new Nodes(graph3.map_node(name, _ => node))
   402       new Nodes(graph3.map_node(name, _ => node))
   400     }
   403     }
   401 
   404 
   402     def domain: Set[Node.Name] = graph.domain
   405     def domain: Set[Node.Name] = graph.domain
   403 
   406 
   447     }
   450     }
   448 
   451 
   449     def purge_suppressed(
   452     def purge_suppressed(
   450       versions: Map[Document_ID.Version, Version]): Map[Document_ID.Version, Version] =
   453       versions: Map[Document_ID.Version, Version]): Map[Document_ID.Version, Version] =
   451     {
   454     {
   452       (versions /:
   455       (for ((id, v) <- versions.iterator; v1 <- v.purge_suppressed) yield (id, v1)).
   453         (for ((id, v) <- versions.iterator; v1 <- v.purge_suppressed) yield (id, v1)))(_ + _)
   456         foldLeft(versions)(_ + _)
   454     }
   457     }
   455   }
   458   }
   456 
   459 
   457   final class Version private(
   460   final class Version private(
   458     val id: Document_ID.Version = Document_ID.none,
   461     val id: Document_ID.Version = Document_ID.none,
   565     def is_outdated: Boolean = edits.nonEmpty
   568     def is_outdated: Boolean = edits.nonEmpty
   566 
   569 
   567     private lazy val reverse_edits = edits.reverse
   570     private lazy val reverse_edits = edits.reverse
   568 
   571 
   569     def convert(offset: Text.Offset): Text.Offset =
   572     def convert(offset: Text.Offset): Text.Offset =
   570       (offset /: edits)((i, edit) => edit.convert(i))
   573       edits.foldLeft(offset) { case (i, edit) => edit.convert(i) }
   571     def revert(offset: Text.Offset): Text.Offset =
   574     def revert(offset: Text.Offset): Text.Offset =
   572       (offset /: reverse_edits)((i, edit) => edit.revert(i))
   575       reverse_edits.foldLeft(offset) { case (i, edit) => edit.revert(i) }
   573 
   576 
   574     def convert(range: Text.Range): Text.Range = range.map(convert)
   577     def convert(range: Text.Range): Text.Range = range.map(convert)
   575     def revert(range: Text.Range): Text.Range = range.map(revert)
   578     def revert(range: Text.Range): Text.Range = range.map(revert)
   576 
   579 
   577 
   580 
   681         val name = command.node_name.node
   684         val name = command.node_name.node
   682         val sources_iterator =
   685         val sources_iterator =
   683           node.commands.iterator.takeWhile(_ != command).map(_.source) ++
   686           node.commands.iterator.takeWhile(_ != command).map(_.source) ++
   684             (if (offset == 0) Iterator.empty
   687             (if (offset == 0) Iterator.empty
   685              else Iterator.single(command.source(Text.Range(0, command.chunk.decode(offset)))))
   688              else Iterator.single(command.source(Text.Range(0, command.chunk.decode(offset)))))
   686         val pos = (Line.Position.zero /: sources_iterator)(_.advance(_))
   689         val pos = sources_iterator.foldLeft(Line.Position.zero)(_.advance(_))
   687         Line.Node_Position(name, pos)
   690         Line.Node_Position(name, pos)
   688       }
   691       }
   689 
   692 
   690     def current_command(other_node_name: Node.Name, offset: Text.Offset): Option[Command] =
   693     def current_command(other_node_name: Node.Name, offset: Text.Offset): Option[Command] =
   691       if (other_node_name.is_theory) {
   694       if (other_node_name.is_theory) {
   840 
   843 
   841       def assign(update: Assign_Update): Assignment =
   844       def assign(update: Assign_Update): Assignment =
   842       {
   845       {
   843         require(!is_finished, "assignment already finished")
   846         require(!is_finished, "assignment already finished")
   844         val command_execs1 =
   847         val command_execs1 =
   845           (command_execs /: update) {
   848           update.foldLeft(command_execs) {
   846             case (res, (command_id, exec_ids)) =>
   849             case (res, (command_id, exec_ids)) =>
   847               if (exec_ids.isEmpty) res - command_id
   850               if (exec_ids.isEmpty) res - command_id
   848               else res + (command_id -> exec_ids)
   851               else res + (command_id -> exec_ids)
   849           }
   852           }
   850         new Assignment(command_execs1, true)
   853         new Assignment(command_execs1, true)
   926         if st.command.node_name == node_name
   929         if st.command.node_name == node_name
   927       } yield (Symbol.Text_Chunk.Id(st.command.id), st.command.chunk)
   930       } yield (Symbol.Text_Chunk.Id(st.command.id), st.command.chunk)
   928     }
   931     }
   929 
   932 
   930     private def redirection(st: Command.State): Graph[Document_ID.Command, Unit] =
   933     private def redirection(st: Command.State): Graph[Document_ID.Command, Unit] =
   931       (commands_redirection /: st.markups.redirection_iterator)({ case (graph, id) =>
   934       st.markups.redirection_iterator.foldLeft(commands_redirection) {
   932         graph.default_node(id, ()).default_node(st.command.id, ()).add_edge(id, st.command.id) })
   935         case (graph, id) =>
       
   936           graph.default_node(id, ()).default_node(st.command.id, ()).add_edge(id, st.command.id)
       
   937       }
   933 
   938 
   934     def accumulate(id: Document_ID.Generic, message: XML.Elem, cache: XML.Cache)
   939     def accumulate(id: Document_ID.Generic, message: XML.Elem, cache: XML.Cache)
   935       : (Command.State, State) =
   940       : (Command.State, State) =
   936     {
   941     {
   937       def update(st: Command.State): (Command.State, State) =
   942       def update(st: Command.State): (Command.State, State) =
  1020       def upd(exec_id: Document_ID.Exec, st: Command.State)
  1025       def upd(exec_id: Document_ID.Exec, st: Command.State)
  1021           : Option[(Document_ID.Exec, Command.State)] =
  1026           : Option[(Document_ID.Exec, Command.State)] =
  1022         if (execs.isDefinedAt(exec_id)) None else Some(exec_id -> st)
  1027         if (execs.isDefinedAt(exec_id)) None else Some(exec_id -> st)
  1023 
  1028 
  1024       val (changed_commands, new_execs) =
  1029       val (changed_commands, new_execs) =
  1025         ((Nil: List[Command], execs) /: update) {
  1030         update.foldLeft((Nil: List[Command], execs)) {
  1026           case ((commands1, execs1), (command_id, exec)) =>
  1031           case ((commands1, execs1), (command_id, exec)) =>
  1027             val st = the_static_state(command_id)
  1032             val st = the_static_state(command_id)
  1028             val command = st.command
  1033             val command = st.command
  1029             val commands2 = command :: commands1
  1034             val commands2 = command :: commands1
  1030             val execs2 =
  1035             val execs2 =
  1248           (name, edits) <- change.rev_edits
  1253           (name, edits) <- change.rev_edits
  1249           if name == node_name
  1254           if name == node_name
  1250         } yield edits
  1255         } yield edits
  1251 
  1256 
  1252       val edits =
  1257       val edits =
  1253         (pending_edits /: rev_pending_changes)({
  1258         rev_pending_changes.foldLeft(pending_edits) {
  1254           case (edits, Node.Edits(es)) => es ::: edits
  1259           case (edits, Node.Edits(es)) => es ::: edits
  1255           case (edits, _) => edits
  1260           case (edits, _) => edits
  1256         })
  1261         }
  1257 
  1262 
  1258       new Snapshot(this, version, node_name, edits, snippet_command)
  1263       new Snapshot(this, version, node_name, edits, snippet_command)
  1259     }
  1264     }
  1260 
  1265 
  1261     def snippet(command: Command): Snapshot =
  1266     def snippet(command: Command): Snapshot =