--- a/Admin/components/components.sha1 Thu Jan 15 15:04:51 2015 +0100
+++ b/Admin/components/components.sha1 Thu Jan 15 20:37:33 2015 +0100
@@ -93,6 +93,7 @@
14f20de82b25215a5e055631fb147356400625e6 scala-2.11.1.tar.gz
4fe9590d08e55760b86755d3fab750e90ac6c380 scala-2.11.2.tar.gz
27a296495b2167148de06314ed9a942f2dbe23fe scala-2.11.4.tar.gz
+4b24326541161ce65424293ca9da3e7c2c6ab452 scala-2.11.5.tar.gz
b447017e81600cc5e30dd61b5d4962f6da01aa80 scala-2.8.1.final.tar.gz
5659440f6b86db29f0c9c0de7249b7e24a647126 scala-2.9.2.tar.gz
43b5afbcad575ab6817d2289756ca22fd2ef43a9 spass-3.8ds.tar.gz
--- a/Admin/components/main Thu Jan 15 15:04:51 2015 +0100
+++ b/Admin/components/main Thu Jan 15 20:37:33 2015 +0100
@@ -10,7 +10,7 @@
jortho-1.0-2
kodkodi-1.5.2
polyml-5.5.2-1
-scala-2.11.4
+scala-2.11.5
spass-3.8ds
z3-4.3.2pre-1
xz-java-1.2-1
--- a/src/Pure/Concurrent/future.scala Thu Jan 15 15:04:51 2015 +0100
+++ b/src/Pure/Concurrent/future.scala Thu Jan 15 20:37:33 2015 +0100
@@ -47,6 +47,7 @@
trait Promise[A] extends Future[A]
{
+ def cancel: Unit
def fulfill_result(res: Exn.Result[A]): Unit
def fulfill(x: A): Unit
}
@@ -78,6 +79,10 @@
{
override def is_finished: Boolean = promise.isCompleted
+ def cancel: Unit =
+ try { fulfill_result(Exn.Exn(Exn.Interrupt())) }
+ catch { case _: IllegalStateException => }
+
def fulfill_result(res: Exn.Result[A]): Unit =
res match {
case Exn.Res(x) => promise.success(x)
--- a/src/Pure/General/path.ML Thu Jan 15 15:04:51 2015 +0100
+++ b/src/Pure/General/path.ML Thu Jan 15 20:37:33 2015 +0100
@@ -23,6 +23,7 @@
val make: string list -> T
val implode: T -> string
val explode: string -> T
+ val decode: T XML.Decode.T
val split: string -> T list
val pretty: T -> Pretty.T
val print: T -> string
@@ -161,6 +162,8 @@
space_explode ":" str
|> map_filter (fn s => if s = "" then NONE else SOME (explode_path s));
+val decode = XML.Decode.string #> explode_path;
+
(* print *)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Pure/PIDE/batch_session.scala Thu Jan 15 20:37:33 2015 +0100
@@ -0,0 +1,72 @@
+/* Title: Pure/Tools/batch_session.scala
+ Author: Makarius
+
+PIDE session in batch mode.
+*/
+
+package isabelle
+
+
+import isabelle._
+
+
+object Batch_Session
+{
+ def batch_session(
+ options: Options,
+ verbose: Boolean = false,
+ dirs: List[Path] = Nil,
+ session: String): Batch_Session =
+ {
+ val (_, session_tree) =
+ Build.find_sessions(options, dirs).selection(false, false, Nil, List(session))
+ val session_info = session_tree(session)
+ val parent_session =
+ session_info.parent getOrElse error("No parent session for " + quote(session))
+
+ if (Build.build(options, new Build.Console_Progress(verbose),
+ verbose = verbose, build_heap = true,
+ dirs = dirs, sessions = List(parent_session)) != 0)
+ new RuntimeException
+
+ val deps = Build.dependencies(Build.Ignore_Progress, false, verbose, false, session_tree)
+ val resources =
+ {
+ val content = deps(parent_session)
+ new Resources(content.loaded_theories, content.known_theories, content.syntax)
+ }
+
+ val progress = new Build.Console_Progress(verbose)
+
+ val prover_session = new Session(resources)
+ val batch_session = new Batch_Session(prover_session)
+
+ val handler = new Build.Handler(progress, session)
+
+ prover_session.phase_changed +=
+ Session.Consumer[Session.Phase](getClass.getName) {
+ case Session.Ready =>
+ prover_session.add_protocol_handler(handler)
+ val master_dir = session_info.dir
+ val theories = session_info.theories.map({ case (_, opts, thys) => (opts, thys) })
+ batch_session.build_theories_result =
+ Some(Build.build_theories(prover_session, master_dir, theories))
+ case Session.Inactive | Session.Failed =>
+ batch_session.session_result.fulfill_result(Exn.Exn(ERROR("Prover process terminated")))
+ case Session.Shutdown =>
+ batch_session.session_result.fulfill(())
+ case _ =>
+ }
+
+ prover_session.start("Isabelle", List("-r", "-q", parent_session))
+
+ batch_session
+ }
+}
+
+class Batch_Session private(val session: Session)
+{
+ val session_result = Future.promise[Unit]
+ @volatile var build_theories_result: Option[Promise[XML.Body]] = None
+}
+
--- a/src/Pure/PIDE/document.scala Thu Jan 15 15:04:51 2015 +0100
+++ b/src/Pure/PIDE/document.scala Thu Jan 15 20:37:33 2015 +0100
@@ -245,12 +245,14 @@
val get_blob: Option[Document.Blob] = None,
val header: Node.Header = Node.no_header,
val syntax: Option[Prover.Syntax] = None,
+ val text_perspective: Text.Perspective = Text.Perspective.empty,
val perspective: Node.Perspective_Command = Node.no_perspective_command,
_commands: Node.Commands = Node.Commands.empty)
{
def is_empty: Boolean =
get_blob.isEmpty &&
header == Node.no_header &&
+ text_perspective.is_empty &&
Node.is_no_perspective_command(perspective) &&
commands.isEmpty
@@ -262,22 +264,32 @@
def init_blob(blob: Document.Blob): Node = new Node(get_blob = Some(blob.unchanged))
def update_header(new_header: Node.Header): Node =
- new Node(get_blob, new_header, syntax, perspective, _commands)
+ new Node(get_blob, new_header, syntax, text_perspective, perspective, _commands)
def update_syntax(new_syntax: Option[Prover.Syntax]): Node =
- new Node(get_blob, header, new_syntax, perspective, _commands)
+ new Node(get_blob, header, new_syntax, text_perspective, perspective, _commands)
+
+ def update_perspective(
+ new_text_perspective: Text.Perspective,
+ new_perspective: Node.Perspective_Command): Node =
+ new Node(get_blob, header, syntax, new_text_perspective, new_perspective, _commands)
- def update_perspective(new_perspective: Node.Perspective_Command): Node =
- new Node(get_blob, header, syntax, new_perspective, _commands)
+ def edit_perspective: Node.Edit[Text.Edit, Text.Perspective] =
+ Node.Perspective(perspective.required, text_perspective, perspective.overlays)
- def same_perspective(other_perspective: Node.Perspective_Command): Boolean =
+ def same_perspective(
+ other_text_perspective: Text.Perspective,
+ other_perspective: Node.Perspective_Command): Boolean =
+ text_perspective == other_text_perspective &&
perspective.required == other_perspective.required &&
perspective.visible.same(other_perspective.visible) &&
perspective.overlays == other_perspective.overlays
def update_commands(new_commands: Linear_Set[Command]): Node =
if (new_commands eq _commands.commands) this
- else new Node(get_blob, header, syntax, perspective, Node.Commands(new_commands))
+ else
+ new Node(get_blob, header, syntax, text_perspective, perspective,
+ Node.Commands(new_commands))
def command_iterator(i: Text.Offset = 0): Iterator[(Command, Text.Offset)] =
_commands.iterator(i)
--- a/src/Pure/PIDE/markup.ML Thu Jan 15 15:04:51 2015 +0100
+++ b/src/Pure/PIDE/markup.ML Thu Jan 15 20:37:33 2015 +0100
@@ -186,7 +186,7 @@
val command_timing: Properties.entry
val loading_theory: string -> Properties.T
val dest_loading_theory: Properties.T -> string option
- val use_theories_result: string -> bool -> Properties.T
+ val build_theories_result: string -> Properties.T
val print_operationsN: string
val print_operations: Properties.T
val simp_trace_panelN: string
@@ -597,8 +597,7 @@
fun dest_loading_theory [("function", "loading_theory"), ("name", name)] = SOME name
| dest_loading_theory _ = NONE;
-fun use_theories_result id ok =
- [("function", "use_theories_result"), ("id", id), ("ok", print_bool ok)];
+fun build_theories_result id = [("function", "build_theories_result"), ("id", id)];
val print_operationsN = "print_operations";
val print_operations = [(functionN, print_operationsN)];
--- a/src/Pure/PIDE/markup.scala Thu Jan 15 15:04:51 2015 +0100
+++ b/src/Pure/PIDE/markup.scala Thu Jan 15 20:37:33 2015 +0100
@@ -458,21 +458,22 @@
}
}
+ val LOADING_THEORY = "loading_theory"
object Loading_Theory
{
def unapply(props: Properties.T): Option[String] =
props match {
- case List((FUNCTION, "loading_theory"), (NAME, name)) => Some(name)
+ case List((FUNCTION, LOADING_THEORY), (NAME, name)) => Some(name)
case _ => None
}
}
- object Use_Theories_Result
+ val BUILD_THEORIES_RESULT = "build_theories_result"
+ object Build_Theories_Result
{
- def unapply(props: Properties.T): Option[(String, Boolean)] =
+ def unapply(props: Properties.T): Option[String] =
props match {
- case List((FUNCTION, "use_theories_result"),
- ("id", id), ("ok", Properties.Value.Boolean(ok))) => Some((id, ok))
+ case List((FUNCTION, BUILD_THEORIES_RESULT), ("id", id)) => Some(id)
case _ => None
}
}
--- a/src/Pure/PIDE/protocol.ML Thu Jan 15 15:04:51 2015 +0100
+++ b/src/Pure/PIDE/protocol.ML Thu Jan 15 20:37:33 2015 +0100
@@ -53,45 +53,46 @@
val _ =
Isabelle_Process.protocol_command "Document.update"
- (fn [old_id_string, new_id_string, edits_yxml] => Document.change_state (fn state =>
- let
- val _ = Execution.discontinue ();
+ (Future.task_context "Document.update" (Future.new_group NONE)
+ (fn [old_id_string, new_id_string, edits_yxml] => Document.change_state (fn state =>
+ let
+ val _ = Execution.discontinue ();
- val old_id = Document_ID.parse old_id_string;
- val new_id = Document_ID.parse new_id_string;
- val edits =
- YXML.parse_body edits_yxml |>
- let open XML.Decode in
- list (pair string
- (variant
- [fn ([], a) => Document.Edits (list (pair (option int) (option int)) a),
- fn ([], a) =>
- let
- val (master, (name, (imports, (keywords, errors)))) =
- pair string (pair string (pair (list string)
- (pair (list (pair string
- (option (pair (pair string (list string)) (list string)))))
- (list string)))) a;
- val imports' = map (rpair Position.none) imports;
- val header = Thy_Header.make (name, Position.none) imports' keywords;
- in Document.Deps (master, header, errors) end,
- fn (a :: b, c) =>
- Document.Perspective (bool_atom a, map int_atom b,
- list (pair int (pair string (list string))) c)]))
- end;
+ val old_id = Document_ID.parse old_id_string;
+ val new_id = Document_ID.parse new_id_string;
+ val edits =
+ YXML.parse_body edits_yxml |>
+ let open XML.Decode in
+ list (pair string
+ (variant
+ [fn ([], a) => Document.Edits (list (pair (option int) (option int)) a),
+ fn ([], a) =>
+ let
+ val (master, (name, (imports, (keywords, errors)))) =
+ pair string (pair string (pair (list string)
+ (pair (list (pair string
+ (option (pair (pair string (list string)) (list string)))))
+ (list string)))) a;
+ val imports' = map (rpair Position.none) imports;
+ val header = Thy_Header.make (name, Position.none) imports' keywords;
+ in Document.Deps (master, header, errors) end,
+ fn (a :: b, c) =>
+ Document.Perspective (bool_atom a, map int_atom b,
+ list (pair int (pair string (list string))) c)]))
+ end;
- val (removed, assign_update, state') = Document.update old_id new_id edits state;
- val _ = List.app Execution.terminate removed;
- val _ = Execution.purge removed;
- val _ = List.app Isabelle_Process.reset_tracing removed;
+ val (removed, assign_update, state') = Document.update old_id new_id edits state;
+ val _ = List.app Execution.terminate removed;
+ val _ = Execution.purge removed;
+ val _ = List.app Isabelle_Process.reset_tracing removed;
- val _ =
- Output.protocol_message Markup.assign_update
- [(new_id, assign_update) |>
- let open XML.Encode
- in pair int (list (pair int (list int))) end
- |> YXML.string_of_body];
- in Document.start_execution state' end));
+ val _ =
+ Output.protocol_message Markup.assign_update
+ [(new_id, assign_update) |>
+ let open XML.Encode
+ in pair int (list (pair int (list int))) end
+ |> YXML.string_of_body];
+ in Document.start_execution state' end)));
val _ =
Isabelle_Process.protocol_command "Document.remove_versions"
@@ -111,21 +112,6 @@
handle exn => if Exn.is_interrupt exn then () (*sic!*) else reraise exn);
val _ =
- Isabelle_Process.protocol_command "use_theories"
- (fn id :: master_dir :: thys =>
- let
- val result =
- Exn.capture (fn () =>
- Thy_Info.use_theories
- {document = false, last_timing = K NONE, master_dir = Path.explode master_dir}
- (map (rpair Position.none) thys)) ();
- val ok =
- (case result of
- Exn.Res _ => true
- | Exn.Exn exn => (Runtime.exn_error_message exn; false));
- in Output.protocol_message (Markup.use_theories_result id ok) [] end);
-
-val _ =
Isabelle_Process.protocol_command "ML_System.share_common_data"
(fn [] => ML_System.share_common_data ());
--- a/src/Pure/PIDE/protocol.scala Thu Jan 15 15:04:51 2015 +0100
+++ b/src/Pure/PIDE/protocol.scala Thu Jan 15 20:37:33 2015 +0100
@@ -456,8 +456,8 @@
def remove_versions(versions: List[Document.Version])
{
val versions_yxml =
- { import XML.Encode._
- YXML.string_of_body(list(long)(versions.map(_.id))) }
+ { import XML.Encode._
+ YXML.string_of_body(list(long)(versions.map(_.id))) }
protocol_command("Document.remove_versions", versions_yxml)
}
@@ -468,8 +468,13 @@
protocol_command("Document.dialog_result", Properties.Value.Long(serial), result)
- /* use_theories */
+ /* build_theories */
- def use_theories(id: String, master_dir: Path, thys: List[Path]): Unit =
- protocol_command("use_theories", (id :: master_dir.implode :: thys.map(_.implode)): _*)
+ def build_theories(id: String, master_dir: Path, theories: List[(Options, List[Path])])
+ {
+ val theories_yxml =
+ { import XML.Encode._
+ YXML.string_of_body(list(pair(Options.encode, list(Path.encode)))(theories)) }
+ protocol_command("build_theories", id, master_dir.implode, theories_yxml)
+ }
}
--- a/src/Pure/PIDE/session.ML Thu Jan 15 15:04:51 2015 +0100
+++ b/src/Pure/PIDE/session.ML Thu Jan 15 20:37:33 2015 +0100
@@ -11,6 +11,7 @@
val get_keywords: unit -> Keyword.keywords
val init: bool -> bool -> Path.T -> string -> bool -> string -> (string * string) list ->
(Path.T * Path.T) list -> string -> string * string -> bool -> unit
+ val shutdown: unit -> unit
val finish: unit -> unit
val save: string -> unit
val protocol_handler: string -> unit
@@ -58,22 +59,23 @@
(* finish *)
+fun shutdown () =
+ (Execution.shutdown ();
+ Event_Timer.shutdown ();
+ Future.shutdown ());
+
fun finish () =
- (Execution.shutdown ();
+ (shutdown ();
Thy_Info.finish ();
Present.finish ();
- Future.shutdown ();
- Event_Timer.shutdown ();
- Future.shutdown ();
+ shutdown ();
keywords :=
fold (curry Keyword.merge_keywords o Thy_Header.get_keywords o Thy_Info.get_theory)
(Thy_Info.get_names ()) Keyword.empty_keywords;
session_finished := true);
fun save heap =
- (Execution.shutdown ();
- Event_Timer.shutdown ();
- Future.shutdown ();
+ (shutdown ();
ML_System.share_common_data ();
ML_System.save_state heap);
--- a/src/Pure/PIDE/session.scala Thu Jan 15 15:04:51 2015 +0100
+++ b/src/Pure/PIDE/session.scala Thu Jan 15 20:37:33 2015 +0100
@@ -63,6 +63,7 @@
case object Caret_Focus
case class Raw_Edits(doc_blobs: Document.Blobs, edits: List[Document.Edit_Text])
case class Dialog_Result(id: Document_ID.Generic, serial: Long, result: String)
+ case class Build_Theories(id: String, master_dir: Path, theories: List[(Options, List[Path])])
case class Commands_Changed(
assignment: Boolean, nodes: Set[Document.Node.Name], commands: Set[Command])
@@ -104,14 +105,20 @@
val functions: Map[String, (Prover, Prover.Protocol_Output) => Boolean]
}
- class Protocol_Handlers(
+ def bad_protocol_handler(exn: Throwable, name: String): Unit =
+ Output.error_message(
+ "Failed to initialize protocol handler: " + quote(name) + "\n" + Exn.message(exn))
+
+ private class Protocol_Handlers(
handlers: Map[String, Session.Protocol_Handler] = Map.empty,
functions: Map[String, Prover.Protocol_Output => Boolean] = Map.empty)
{
def get(name: String): Option[Protocol_Handler] = handlers.get(name)
- def add(prover: Prover, name: String): Protocol_Handlers =
+ def add(prover: Prover, handler: Protocol_Handler): Protocol_Handlers =
{
+ val name = handler.getClass.getName
+
val (handlers1, functions1) =
handlers.get(name) match {
case Some(old_handler) =>
@@ -123,22 +130,20 @@
val (handlers2, functions2) =
try {
- val new_handler = Class.forName(name).newInstance.asInstanceOf[Protocol_Handler]
- new_handler.start(prover)
+ handler.start(prover)
val new_functions =
- for ((a, f) <- new_handler.functions.toList) yield
+ for ((a, f) <- handler.functions.toList) yield
(a, (msg: Prover.Protocol_Output) => f(prover, msg))
val dups = for ((a, _) <- new_functions if functions1.isDefinedAt(a)) yield a
if (dups.nonEmpty) error("Duplicate protocol functions: " + commas_quote(dups))
- (handlers1 + (name -> new_handler), functions1 ++ new_functions)
+ (handlers1 + (name -> handler), functions1 ++ new_functions)
}
catch {
case exn: Throwable =>
- Output.error_message(
- "Failed to initialize protocol handler: " + quote(name) + "\n" + Exn.message(exn))
+ Session.bad_protocol_handler(exn, name)
(handlers1, functions1)
}
@@ -236,14 +241,6 @@
resources.base_syntax
- /* protocol handlers */
-
- @volatile private var _protocol_handlers = new Session.Protocol_Handlers()
-
- def protocol_handler(name: String): Option[Session.Protocol_Handler] =
- _protocol_handlers.get(name)
-
-
/* theory files */
def header_edit(name: Document.Node.Name, header: Document.Node.Header): Document.Edit_Text =
@@ -342,6 +339,17 @@
}
+ /* protocol handlers */
+
+ private val _protocol_handlers = Synchronized(new Session.Protocol_Handlers)
+
+ def get_protocol_handler(name: String): Option[Session.Protocol_Handler] =
+ _protocol_handlers.value.get(name)
+
+ def add_protocol_handler(handler: Session.Protocol_Handler): Unit =
+ _protocol_handlers.change(_.add(prover.get, handler))
+
+
/* manager thread */
private val delay_prune = Simple_Thread.delay_first(prune_delay) { manager.send(Prune_History) }
@@ -431,11 +439,16 @@
output match {
case msg: Prover.Protocol_Output =>
- val handled = _protocol_handlers.invoke(msg)
+ val handled = _protocol_handlers.value.invoke(msg)
if (!handled) {
msg.properties match {
case Markup.Protocol_Handler(name) if prover.defined =>
- _protocol_handlers = _protocol_handlers.add(prover.get, name)
+ try {
+ val handler =
+ Class.forName(name).newInstance.asInstanceOf[Session.Protocol_Handler]
+ add_protocol_handler(handler)
+ }
+ catch { case exn: Throwable => Session.bad_protocol_handler(exn, name) }
case Protocol.Command_Timing(state_id, timing) if prover.defined =>
val message = XML.elem(Markup.STATUS, List(XML.Elem(Markup.Timing(timing), Nil)))
@@ -524,7 +537,7 @@
case Stop =>
if (prover.defined && is_ready) {
- _protocol_handlers = _protocol_handlers.stop(prover.get)
+ _protocol_handlers.change(_.stop(prover.get))
global_state.change(_ => Document.State.init)
phase = Session.Shutdown
prover.get.terminate
@@ -553,6 +566,9 @@
prover.get.dialog_result(serial, result)
handle_output(new Prover.Output(Protocol.Dialog_Result(id, serial, result)))
+ case Session.Build_Theories(id, master_dir, theories) if prover.defined =>
+ prover.get.build_theories(id, master_dir, theories)
+
case Protocol_Command(name, args) if prover.defined =>
prover.get.protocol_command(name, args:_*)
@@ -615,4 +631,7 @@
def dialog_result(id: Document_ID.Generic, serial: Long, result: String)
{ manager.send(Session.Dialog_Result(id, serial, result)) }
+
+ def build_theories(id: String, master_dir: Path, theories: List[(Options, List[Path])])
+ { manager.send(Session.Build_Theories(id, master_dir, theories)) }
}
--- a/src/Pure/ROOT.ML Thu Jan 15 15:04:51 2015 +0100
+++ b/src/Pure/ROOT.ML Thu Jan 15 20:37:33 2015 +0100
@@ -65,6 +65,7 @@
use "General/linear_set.ML";
use "General/buffer.ML";
use "General/pretty.ML";
+use "PIDE/xml.ML";
use "General/path.ML";
use "General/url.ML";
use "General/file.ML";
@@ -78,7 +79,6 @@
if ML_System.is_polyml then use "General/sha1_polyml.ML" else ();
use "General/sha1_samples.ML";
-use "PIDE/xml.ML";
use "PIDE/yxml.ML";
use "PIDE/document_id.ML";
--- a/src/Pure/System/isabelle_process.ML Thu Jan 15 15:04:51 2015 +0100
+++ b/src/Pure/System/isabelle_process.ML Thu Jan 15 20:37:33 2015 +0100
@@ -162,9 +162,6 @@
System_Channel.input_line channel
|> Option.map (fn line => map (read_chunk channel) (space_explode "," line));
-fun task_context e =
- Future.task_context "Isabelle_Process.loop" (Future.new_group NONE) e ();
-
in
fun loop channel =
@@ -173,7 +170,7 @@
(case read_command channel of
NONE => false
| SOME [] => (Output.system_message "Isabelle process: no input"; true)
- | SOME (name :: args) => (task_context (fn () => run_command name args); true))
+ | SOME (name :: args) => (run_command name args; true))
handle exn => (Runtime.exn_system_message exn handle crash => recover crash; true);
in
if continue then loop channel
--- a/src/Pure/Thy/thy_syntax.scala Thu Jan 15 15:04:51 2015 +0100
+++ b/src/Pure/Thy/thy_syntax.scala Thu Jan 15 20:37:33 2015 +0100
@@ -288,11 +288,12 @@
val (visible, visible_overlay) = command_perspective(node, text_perspective, overlays)
val perspective: Document.Node.Perspective_Command =
Document.Node.Perspective(required, visible_overlay, overlays)
- if (node.same_perspective(perspective)) node
+ if (node.same_perspective(text_perspective, perspective)) node
else
- node.update_perspective(perspective).update_commands(
- consolidate_spans(resources, syntax, get_blob, reparse_limit,
- name, visible, node.commands))
+ node.update_perspective(text_perspective, perspective).
+ update_commands(
+ consolidate_spans(resources, syntax, get_blob, reparse_limit,
+ name, visible, node.commands))
}
}
@@ -341,13 +342,18 @@
else node
val node2 =
(node1 /: edits)(text_edit(resources, syntax, get_blob, reparse_limit, _, _))
-
- if (!(node.same_perspective(node2.perspective)))
- doc_edits += (name -> node2.perspective)
+ val node3 =
+ if (reparse_set.contains(name))
+ text_edit(resources, syntax, get_blob, reparse_limit,
+ node2, (name, node2.edit_perspective))
+ else node2
- doc_edits += (name -> Document.Node.Edits(diff_commands(commands, node2.commands)))
+ if (!(node.same_perspective(node3.text_perspective, node3.perspective)))
+ doc_edits += (name -> node3.perspective)
- nodes += (name -> node2)
+ doc_edits += (name -> Document.Node.Edits(diff_commands(commands, node3.commands)))
+
+ nodes += (name -> node3)
}
(doc_edits.toList.filterNot(_._2.is_void), Document.Version.make(nodes))
}
--- a/src/Pure/Tools/build.ML Thu Jan 15 15:04:51 2015 +0100
+++ b/src/Pure/Tools/build.ML Thu Jan 15 20:37:33 2015 +0100
@@ -97,33 +97,28 @@
(* build *)
-local
-
-fun use_theories last_timing options =
- Thy_Info.use_theories {
- document = Present.document_enabled (Options.string options "document"),
- last_timing = last_timing,
- master_dir = Path.current}
- |> Unsynchronized.setmp print_mode
- (space_explode "," (Options.string options "print_mode") @ print_mode_value ())
- |> Unsynchronized.setmp Goal.parallel_proofs (Options.int options "parallel_proofs")
- |> Unsynchronized.setmp Multithreading.trace (Options.int options "threads_trace")
- |> Multithreading.max_threads_setmp (Options.int options "threads")
- |> Unsynchronized.setmp Future.ML_statistics true;
-
-fun use_theories_condition last_timing (options, thys) =
- let val condition = space_explode "," (Options.string options "condition") in
- (case filter_out (can getenv_strict) condition of
- [] =>
- (Options.set_default options;
- use_theories last_timing options (map (rpair Position.none) thys))
- | conds =>
- Output.physical_stderr ("Skipping theories " ^ commas_quote thys ^
- " (undefined " ^ commas conds ^ ")\n"))
+fun build_theories last_timing master_dir (options, thys) =
+ let
+ val condition = space_explode "," (Options.string options "condition");
+ val conds = filter_out (can getenv_strict) condition;
+ in
+ if null conds then
+ (Options.set_default options;
+ (Thy_Info.use_theories {
+ document = Present.document_enabled (Options.string options "document"),
+ last_timing = last_timing,
+ master_dir = master_dir}
+ |> Unsynchronized.setmp print_mode
+ (space_explode "," (Options.string options "print_mode") @ print_mode_value ())
+ |> Unsynchronized.setmp Goal.parallel_proofs (Options.int options "parallel_proofs")
+ |> Multithreading.max_threads_setmp (Options.int options "threads")
+ |> Unsynchronized.setmp Multithreading.trace (Options.int options "threads_trace")
+ |> Unsynchronized.setmp Future.ML_statistics true) thys)
+ else
+ Output.physical_stderr ("Skipping theories " ^ commas_quote (map #1 thys) ^
+ " (undefined " ^ commas conds ^ ")\n")
end;
-in
-
fun build args_file = Command_Line.tool0 (fn () =>
let
val _ = SHA1_Samples.test ();
@@ -134,7 +129,7 @@
let open XML.Decode in
pair (list properties) (pair bool (pair Options.decode (pair bool (pair string
(pair (list (pair string string)) (pair string (pair string (pair string
- ((list (pair Options.decode (list string))))))))))))
+ ((list (pair Options.decode (list (string #> rpair Position.none)))))))))))))
end;
val _ = Options.set_default options;
@@ -156,7 +151,7 @@
val res1 =
theories |>
- (List.app (use_theories_condition last_timing)
+ (List.app (build_theories last_timing Path.current)
|> session_timing name verbose
|> Unsynchronized.setmp Output.protocol_message_fn protocol_message
|> Multithreading.max_threads_setmp (Options.int options "threads")
@@ -168,6 +163,25 @@
val _ = if do_output then () else exit 0;
in () end);
-end;
+
+(* PIDE protocol *)
+
+val _ =
+ Isabelle_Process.protocol_command "build_theories"
+ (fn [id, master_dir, theories_yxml] =>
+ let
+ val theories =
+ YXML.parse_body theories_yxml |>
+ let open XML.Decode
+ in list (pair Options.decode (list (string #> rpair Position.none))) end;
+ val res1 =
+ Exn.capture (fn () =>
+ theories |> List.app (build_theories (K NONE) (Path.explode master_dir))) ();
+ val res2 = Exn.capture Session.shutdown ();
+ val result =
+ (Par_Exn.release_all [res1, res2]; "") handle exn =>
+ (Runtime.exn_message exn handle _ (*sic!*) =>
+ "Exception raised, but failed to print details!");
+ in Output.protocol_message (Markup.build_theories_result id) [result] end);
end;
--- a/src/Pure/Tools/build.scala Thu Jan 15 15:04:51 2015 +0100
+++ b/src/Pure/Tools/build.scala Thu Jan 15 20:37:33 2015 +0100
@@ -1025,5 +1025,61 @@
}
}
}
+
+
+ /* PIDE protocol */
+
+ def build_theories(
+ session: Session, master_dir: Path, theories: List[(Options, List[Path])]): Promise[XML.Body] =
+ session.get_protocol_handler(classOf[Handler].getName) match {
+ case Some(handler: Handler) => handler.build_theories(session, master_dir, theories)
+ case _ => error("Cannot invoke build_theories: bad protocol handler")
+ }
+
+ class Handler(progress: Progress, session_name: String) extends Session.Protocol_Handler
+ {
+ private val pending = Synchronized(Map.empty[String, Promise[XML.Body]])
+
+ def build_theories(
+ session: Session, master_dir: Path, theories: List[(Options, List[Path])]): Promise[XML.Body] =
+ {
+ val promise = Future.promise[XML.Body]
+ val id = Document_ID.make().toString
+ pending.change(promises => promises + (id -> promise))
+ session.build_theories(id, master_dir, theories)
+ promise
+ }
+
+ private def loading_theory(prover: Prover, msg: Prover.Protocol_Output): Boolean =
+ msg.properties match {
+ case Markup.Loading_Theory(name) => progress.theory(session_name, name); true
+ case _ => false
+ }
+
+ private def build_theories_result(prover: Prover, msg: Prover.Protocol_Output): Boolean =
+ msg.properties match {
+ case Markup.Build_Theories_Result(id) =>
+ pending.change_result(promises =>
+ promises.get(id) match {
+ case Some(promise) =>
+ val error_message =
+ try { YXML.parse_body(Symbol.decode(msg.text)) }
+ catch { case exn: Throwable => List(XML.Text(Exn.message(exn))) }
+ promise.fulfill(error_message)
+ (true, promises - id)
+ case None =>
+ (false, promises)
+ })
+ case _ => false
+ }
+
+ override def stop(prover: Prover): Unit =
+ pending.change(promises => { for ((_, promise) <- promises) promise.cancel; Map.empty })
+
+ val functions =
+ Map(
+ Markup.BUILD_THEORIES_RESULT -> build_theories_result _,
+ Markup.LOADING_THEORY -> loading_theory _)
+ }
}
--- a/src/Pure/Tools/print_operation.scala Thu Jan 15 15:04:51 2015 +0100
+++ b/src/Pure/Tools/print_operation.scala Thu Jan 15 20:37:33 2015 +0100
@@ -10,7 +10,7 @@
object Print_Operation
{
def print_operations(session: Session): List[(String, String)] =
- session.protocol_handler("isabelle.Print_Operation$Handler") match {
+ session.get_protocol_handler("isabelle.Print_Operation$Handler") match {
case Some(handler: Handler) => handler.get
case _ => Nil
}
--- a/src/Pure/build-jars Thu Jan 15 15:04:51 2015 +0100
+++ b/src/Pure/build-jars Thu Jan 15 20:37:33 2015 +0100
@@ -55,6 +55,7 @@
Isar/parse.scala
Isar/token.scala
ML/ml_lex.scala
+ PIDE/batch_session.scala
PIDE/command.scala
PIDE/command_span.scala
PIDE/document.scala