diff -r f9dd4c9ed812 -r 8e83800a35c8 lib/jedit/plugin/isabelle_plugin.scala --- a/lib/jedit/plugin/isabelle_plugin.scala Sun Aug 24 21:15:46 2008 +0200 +++ b/lib/jedit/plugin/isabelle_plugin.scala Sun Aug 24 21:15:48 2008 +0200 @@ -20,11 +20,22 @@ import scala.io.Source -/* Global state */ + +/** global state **/ object IsabellePlugin { - // unique ids - private var id_count = 0 + + /* Isabelle process */ + + var isabelle: IsabelleProcess = null + + def result_content(result: IsabelleProcess.Result) = + XML.content(isabelle.decode_result(result)).mkString("") + + + /* unique ids */ + + private var id_count: BigInt = 0 def id() : String = synchronized { id_count += 1; "jedit:" + id_count } @@ -37,109 +48,103 @@ def id_properties() : Properties = { id_properties(id()) } - // the error source - var errors: DefaultErrorSource = null - - // the Isabelle process - var isabelle: IsabelleProcess = null - + /* result consumers */ - // result content - def result_content(result: IsabelleProcess.Result) = - XML.content(isabelle.result_tree(result)).mkString("") - + type Consumer = IsabelleProcess.Result => Boolean + private var consumers = new ListBuffer[Consumer] - // result consumers - type consumer = IsabelleProcess.Result => Boolean - private var consumers = new ListBuffer[consumer] - - def add_consumer(consumer: consumer) = synchronized { consumers += consumer } + def add_consumer(consumer: Consumer) = synchronized { consumers += consumer } def add_permanent_consumer(consumer: IsabelleProcess.Result => Unit) = { add_consumer(result => { consumer(result); false }) } - def del_consumer(consumer: consumer) = synchronized { consumers -= consumer } + def del_consumer(consumer: Consumer) = synchronized { consumers -= consumer } - def consume(result: IsabelleProcess.Result) : Unit = { + private def consume(result: IsabelleProcess.Result) = { synchronized { consumers.elements.toList } foreach (consumer => { + if (result != null && result.is_control) Log.log(Log.DEBUG, result, null) val finished = try { consumer(result) } - catch { case e: Throwable => Log.log(Log.ERROR, this, e); true } - if (finished || result == null) - del_consumer(consumer) + catch { case e: Throwable => Log.log(Log.ERROR, result, e); true } + if (finished || result == null) del_consumer(consumer) }) } + + class ConsumerThread extends Thread { + override def run = { + var finished = false + while (!finished) { + val result = + try { IsabellePlugin.isabelle.get_result() } + catch { case _: NullPointerException => null } + + if (result != null) { + consume(result) + if (result.kind == IsabelleProcess.Kind.EXIT) { + consume(null) + finished = true + } + } + else finished = true + } + } + } + } /* Main plugin setup */ class IsabellePlugin extends EditPlugin { - private var thread: Thread = null + + import IsabellePlugin._ + + val errors = new DefaultErrorSource("isabelle") + val consumer_thread = new ConsumerThread + override def start = { - // error source - IsabellePlugin.errors = new DefaultErrorSource("isabelle") - ErrorSource.registerErrorSource(IsabellePlugin.errors) + + /* error source */ - IsabellePlugin.add_permanent_consumer (result => - if (result != null && result.props != null && + ErrorSource.registerErrorSource(errors) + + add_permanent_consumer (result => + if (result != null && (result.kind == IsabelleProcess.Kind.WARNING || result.kind == IsabelleProcess.Kind.ERROR)) { - val typ = - if (result.kind == IsabelleProcess.Kind.WARNING) ErrorSource.WARNING - else ErrorSource.ERROR (Position.line_of(result.props), Position.file_of(result.props)) match { case (Some(line), Some(file)) => - val content = IsabellePlugin.result_content(result) + val typ = + if (result.kind == IsabelleProcess.Kind.WARNING) ErrorSource.WARNING + else ErrorSource.ERROR + val content = result_content(result) if (content.length > 0) { val lines = Source.fromString(content).getLines - val err = new DefaultErrorSource.DefaultError(IsabellePlugin.errors, + val err = new DefaultErrorSource.DefaultError(errors, typ, file, line - 1, 0, 0, lines.next) for (msg <- lines) err.addExtraMessage(msg) - IsabellePlugin.errors.addError(err) + errors.addError(err) } case _ => } }) - // Isabelle process - IsabellePlugin.isabelle = - new IsabelleProcess("-mno_brackets", "-mno_type_brackets", "-mxsymbols") - thread = new Thread (new Runnable { - def run = { - var result: IsabelleProcess.Result = null - do { - try { - result = IsabellePlugin.isabelle.results.take - } - catch { - case _: NullPointerException => result = null - case _: InterruptedException => result = null - } - if (result != null) { - System.err.println(result) // FIXME - IsabellePlugin.consume(result) - } - if (result.kind == IsabelleProcess.Kind.EXIT) { - result = null - IsabellePlugin.consume(null) - } - } while (result != null) - } - }) - thread.start + /* Isabelle process */ + + isabelle = new IsabelleProcess("-mno_brackets", "-mno_type_brackets", "-mxsymbols") + consumer_thread.start + } - override def stop = { - IsabellePlugin.isabelle.kill - thread.interrupt; thread.join; thread = null - IsabellePlugin.isabelle = null - ErrorSource.unregisterErrorSource(IsabellePlugin.errors) - IsabellePlugin.errors = null + override def stop = { + isabelle.kill + consumer_thread.join + ErrorSource.unregisterErrorSource(errors) } + }