src/Pure/Thy/sessions.scala
changeset 72600 2fa4f25d9d07
parent 72574 d892f6d66402
child 72603 9576d0faf8f9
equal deleted inserted replaced
72599:76550282267f 72600:2fa4f25d9d07
    51     pos: Position.T = Position.none,
    51     pos: Position.T = Position.none,
    52     doc_names: List[String] = Nil,
    52     doc_names: List[String] = Nil,
    53     session_directories: Map[JFile, String] = Map.empty,
    53     session_directories: Map[JFile, String] = Map.empty,
    54     global_theories: Map[String, String] = Map.empty,
    54     global_theories: Map[String, String] = Map.empty,
    55     session_theories: List[Document.Node.Name] = Nil,
    55     session_theories: List[Document.Node.Name] = Nil,
       
    56     document_theories: List[Document.Node.Name] = Nil,
    56     loaded_theories: Graph[String, Outer_Syntax] = Graph.string,
    57     loaded_theories: Graph[String, Outer_Syntax] = Graph.string,
    57     used_theories: List[(Document.Node.Name, Options)] = Nil,
    58     used_theories: List[(Document.Node.Name, Options)] = Nil,
    58     known_theories: Map[String, Document.Node.Entry] = Map.empty,
    59     known_theories: Map[String, Document.Node.Entry] = Map.empty,
    59     known_loaded_files: Map[String, List[Path]] = Map.empty,
    60     known_loaded_files: Map[String, List[Path]] = Map.empty,
    60     overall_syntax: Outer_Syntax = Outer_Syntax.empty,
    61     overall_syntax: Outer_Syntax = Outer_Syntax.empty,
   246                 qualifier = deps_base.theory_qualifier(name)
   247                 qualifier = deps_base.theory_qualifier(name)
   247                 if !known_sessions(qualifier)
   248                 if !known_sessions(qualifier)
   248               } yield "Bad import of theory " + quote(name.toString) +
   249               } yield "Bad import of theory " + quote(name.toString) +
   249                 ": need to include sessions " + quote(qualifier) + " in ROOT"
   250                 ": need to include sessions " + quote(qualifier) + " in ROOT"
   250             }
   251             }
       
   252 
       
   253             val document_errors =
       
   254               info.document_theories.flatMap(
       
   255               {
       
   256                 case (thy, pos) =>
       
   257                   val ancestors = sessions_structure.build_requirements(List(session_name))
       
   258                   val qualifier = deps_base.theory_qualifier(session_name)
       
   259 
       
   260                   def err(msg: String): Option[String] =
       
   261                     Some(msg + " " + quote(thy) + Position.here(pos))
       
   262 
       
   263                   known_theories.get(thy) match {
       
   264                     case None => err("Unknown document theory")
       
   265                     case Some(entry) =>
       
   266                       if (session_theories.contains(entry.name)) {
       
   267                         err("Redundant document theory from this session:")
       
   268                       }
       
   269                       else if (ancestors.contains(qualifier)) None
       
   270                       else if (dependencies.theories.contains(entry.name)) None
       
   271                       else err("Document theory from other session not imported properly:")
       
   272                   }
       
   273               })
       
   274             val document_theories =
       
   275               info.document_theories.map({ case (thy, _) => known_theories(thy).name })
   251 
   276 
   252             val dir_errors =
   277             val dir_errors =
   253             {
   278             {
   254               val ok = info.dirs.map(_.canonical_file).toSet
   279               val ok = info.dirs.map(_.canonical_file).toSet
   255               val bad =
   280               val bad =
   295                 pos = info.pos,
   320                 pos = info.pos,
   296                 doc_names = doc_names,
   321                 doc_names = doc_names,
   297                 session_directories = sessions_structure.session_directories,
   322                 session_directories = sessions_structure.session_directories,
   298                 global_theories = sessions_structure.global_theories,
   323                 global_theories = sessions_structure.global_theories,
   299                 session_theories = session_theories,
   324                 session_theories = session_theories,
       
   325                 document_theories = document_theories,
   300                 loaded_theories = dependencies.loaded_theories,
   326                 loaded_theories = dependencies.loaded_theories,
   301                 used_theories = dependencies.theories_adjunct,
   327                 used_theories = dependencies.theories_adjunct,
   302                 known_theories = known_theories,
   328                 known_theories = known_theories,
   303                 known_loaded_files = known_loaded_files,
   329                 known_loaded_files = known_loaded_files,
   304                 overall_syntax = overall_syntax,
   330                 overall_syntax = overall_syntax,
   305                 imported_sources = check_sources(imported_files),
   331                 imported_sources = check_sources(imported_files),
   306                 sources = check_sources(session_files),
   332                 sources = check_sources(session_files),
   307                 session_graph_display = session_graph_display,
   333                 session_graph_display = session_graph_display,
   308                 errors = dependencies.errors ::: loaded_files_errors ::: import_errors :::
   334                 errors = dependencies.errors ::: loaded_files_errors ::: import_errors :::
   309                   dir_errors ::: sources_errors ::: path_errors ::: bibtex_errors)
   335                   document_errors ::: dir_errors ::: sources_errors ::: path_errors :::
       
   336                   bibtex_errors)
   310 
   337 
   311             session_bases + (info.name -> base)
   338             session_bases + (info.name -> base)
   312           }
   339           }
   313           catch {
   340           catch {
   314             case ERROR(msg) =>
   341             case ERROR(msg) =>
   389                   description = "Required theory imports from other sessions",
   416                   description = "Required theory imports from other sessions",
   390                   options = Nil,
   417                   options = Nil,
   391                   imports = info.deps,
   418                   imports = info.deps,
   392                   directories = Nil,
   419                   directories = Nil,
   393                   theories = List((Nil, required_theories.map(thy => ((thy, Position.none), false)))),
   420                   theories = List((Nil, required_theories.map(thy => ((thy, Position.none), false)))),
       
   421                   document_theories = Nil,
   394                   document_files = Nil,
   422                   document_files = Nil,
   395                   export_files = Nil))))
   423                   export_files = Nil))))
   396         }
   424         }
   397       }
   425       }
   398       else (session, Nil)
   426       else (session, Nil)
   424     directories: List[Path],
   452     directories: List[Path],
   425     options: Options,
   453     options: Options,
   426     imports: List[String],
   454     imports: List[String],
   427     theories: List[(Options, List[(String, Position.T)])],
   455     theories: List[(Options, List[(String, Position.T)])],
   428     global_theories: List[String],
   456     global_theories: List[String],
       
   457     document_theories: List[(String, Position.T)],
   429     document_files: List[(Path, Path)],
   458     document_files: List[(Path, Path)],
   430     export_files: List[(Path, Int, List[String])],
   459     export_files: List[(Path, Int, List[String])],
   431     meta_digest: SHA1.Digest)
   460     meta_digest: SHA1.Digest)
   432   {
   461   {
   433     def deps: List[String] = parent.toList ::: imports
   462     def deps: List[String] = parent.toList ::: imports
   537 
   566 
   538       val export_files =
   567       val export_files =
   539         entry.export_files.map({ case (dir, prune, pats) => (Path.explode(dir), prune, pats) })
   568         entry.export_files.map({ case (dir, prune, pats) => (Path.explode(dir), prune, pats) })
   540 
   569 
   541       val meta_digest =
   570       val meta_digest =
   542         SHA1.digest((name, chapter, entry.parent, entry.directories, entry.options, entry.imports,
   571         SHA1.digest(
   543           entry.theories_no_position, conditions, entry.document_files).toString)
   572           (name, chapter, entry.parent, entry.directories, entry.options, entry.imports,
       
   573             entry.theories_no_position, conditions, entry.document_theories, entry.document_files)
       
   574           .toString)
   544 
   575 
   545       Info(name, chapter, dir_selected, entry.pos, entry.groups, session_path,
   576       Info(name, chapter, dir_selected, entry.pos, entry.groups, session_path,
   546         entry.parent, entry.description, directories, session_options,
   577         entry.parent, entry.description, directories, session_options,
   547         entry.imports, theories, global_theories, document_files, export_files, meta_digest)
   578         entry.imports, theories, global_theories, entry.document_theories, document_files,
       
   579         export_files, meta_digest)
   548     }
   580     }
   549     catch {
   581     catch {
   550       case ERROR(msg) =>
   582       case ERROR(msg) =>
   551         error(msg + "\nThe error(s) above occurred in session entry " +
   583         error(msg + "\nThe error(s) above occurred in session entry " +
   552           quote(entry.name) + Position.here(entry.pos))
   584           quote(entry.name) + Position.here(entry.pos))
   789   private val DIRECTORIES = "directories"
   821   private val DIRECTORIES = "directories"
   790   private val OPTIONS = "options"
   822   private val OPTIONS = "options"
   791   private val SESSIONS = "sessions"
   823   private val SESSIONS = "sessions"
   792   private val THEORIES = "theories"
   824   private val THEORIES = "theories"
   793   private val GLOBAL = "global"
   825   private val GLOBAL = "global"
       
   826   private val DOCUMENT_THEORIES = "document_theories"
   794   private val DOCUMENT_FILES = "document_files"
   827   private val DOCUMENT_FILES = "document_files"
   795   private val EXPORT_FILES = "export_files"
   828   private val EXPORT_FILES = "export_files"
   796 
   829 
   797   val root_syntax: Outer_Syntax =
   830   val root_syntax: Outer_Syntax =
   798     Outer_Syntax.empty + "(" + ")" + "+" + "," + "=" + "[" + "]" +
   831     Outer_Syntax.empty + "(" + ")" + "+" + "," + "=" + "[" + "]" +
   802       (DESCRIPTION, Keyword.QUASI_COMMAND) +
   835       (DESCRIPTION, Keyword.QUASI_COMMAND) +
   803       (DIRECTORIES, Keyword.QUASI_COMMAND) +
   836       (DIRECTORIES, Keyword.QUASI_COMMAND) +
   804       (OPTIONS, Keyword.QUASI_COMMAND) +
   837       (OPTIONS, Keyword.QUASI_COMMAND) +
   805       (SESSIONS, Keyword.QUASI_COMMAND) +
   838       (SESSIONS, Keyword.QUASI_COMMAND) +
   806       (THEORIES, Keyword.QUASI_COMMAND) +
   839       (THEORIES, Keyword.QUASI_COMMAND) +
       
   840       (DOCUMENT_THEORIES, Keyword.QUASI_COMMAND) +
   807       (DOCUMENT_FILES, Keyword.QUASI_COMMAND) +
   841       (DOCUMENT_FILES, Keyword.QUASI_COMMAND) +
   808       (EXPORT_FILES, Keyword.QUASI_COMMAND)
   842       (EXPORT_FILES, Keyword.QUASI_COMMAND)
   809 
   843 
   810   abstract class Entry
   844   abstract class Entry
   811   sealed case class Chapter(name: String) extends Entry
   845   sealed case class Chapter(name: String) extends Entry
   818     description: String,
   852     description: String,
   819     options: List[Options.Spec],
   853     options: List[Options.Spec],
   820     imports: List[String],
   854     imports: List[String],
   821     directories: List[String],
   855     directories: List[String],
   822     theories: List[(List[Options.Spec], List[((String, Position.T), Boolean)])],
   856     theories: List[(List[Options.Spec], List[((String, Position.T), Boolean)])],
       
   857     document_theories: List[(String, Position.T)],
   823     document_files: List[(String, String)],
   858     document_files: List[(String, String)],
   824     export_files: List[(String, Int, List[String])]) extends Entry
   859     export_files: List[(String, Int, List[String])]) extends Entry
   825   {
   860   {
   826     def theories_no_position: List[(List[Options.Spec], List[(String, Boolean)])] =
   861     def theories_no_position: List[(List[Options.Spec], List[(String, Boolean)])] =
   827       theories.map({ case (a, b) => (a, b.map({ case ((c, _), d) => (c, d) })) })
   862       theories.map({ case (a, b) => (a, b.map({ case ((c, _), d) => (c, d) })) })
   850         $$$(THEORIES) ~!
   885         $$$(THEORIES) ~!
   851           ((options | success(Nil)) ~ rep1(theory_entry)) ^^
   886           ((options | success(Nil)) ~ rep1(theory_entry)) ^^
   852           { case _ ~ (x ~ y) => (x, y) }
   887           { case _ ~ (x ~ y) => (x, y) }
   853 
   888 
   854       val in_path = $$$("(") ~! ($$$(IN) ~ path ~ $$$(")")) ^^ { case _ ~ (_ ~ x ~ _) => x }
   889       val in_path = $$$("(") ~! ($$$(IN) ~ path ~ $$$(")")) ^^ { case _ ~ (_ ~ x ~ _) => x }
       
   890 
       
   891       val document_theories =
       
   892         $$$(DOCUMENT_THEORIES) ~! rep1(position(name)) ^^ { case _ ~ x => x }
   855 
   893 
   856       val document_files =
   894       val document_files =
   857         $$$(DOCUMENT_FILES) ~!
   895         $$$(DOCUMENT_FILES) ~!
   858           ((in_path | success("document")) ~ rep1(path)) ^^ { case _ ~ (x ~ y) => y.map((x, _)) }
   896           ((in_path | success("document")) ~ rep1(path)) ^^ { case _ ~ (x ~ y) => y.map((x, _)) }
   859 
   897 
   872               (($$$(DESCRIPTION) ~! text ^^ { case _ ~ x => x }) | success("")) ~
   910               (($$$(DESCRIPTION) ~! text ^^ { case _ ~ x => x }) | success("")) ~
   873               (($$$(OPTIONS) ~! options ^^ { case _ ~ x => x }) | success(Nil)) ~
   911               (($$$(OPTIONS) ~! options ^^ { case _ ~ x => x }) | success(Nil)) ~
   874               (($$$(SESSIONS) ~! rep1(session_name)  ^^ { case _ ~ x => x }) | success(Nil)) ~
   912               (($$$(SESSIONS) ~! rep1(session_name)  ^^ { case _ ~ x => x }) | success(Nil)) ~
   875               (($$$(DIRECTORIES) ~! rep1(path) ^^ { case _ ~ x => x }) | success(Nil)) ~
   913               (($$$(DIRECTORIES) ~! rep1(path) ^^ { case _ ~ x => x }) | success(Nil)) ~
   876               rep(theories) ~
   914               rep(theories) ~
       
   915               (opt(document_theories) ^^ (x => x.getOrElse(Nil))) ~
   877               (rep(document_files) ^^ (x => x.flatten)) ~
   916               (rep(document_files) ^^ (x => x.flatten)) ~
   878               (rep(export_files))))) ^^
   917               rep(export_files)))) ^^
   879         { case _ ~ ((a, pos) ~ b ~ c ~ (_ ~ (d ~ e ~ f ~ g ~ h ~ i ~ j ~ k))) =>
   918         { case _ ~ ((a, pos) ~ b ~ c ~ (_ ~ (d ~ e ~ f ~ g ~ h ~ i ~ j ~ k ~ l))) =>
   880             Session_Entry(pos, a, b, c, d, e, f, g, h, i, j, k) }
   919             Session_Entry(pos, a, b, c, d, e, f, g, h, i, j, k, l) }
   881     }
   920     }
   882 
   921 
   883     def parse_root(path: Path): List[Entry] =
   922     def parse_root(path: Path): List[Entry] =
   884     {
   923     {
   885       val toks = Token.explode(root_syntax.keywords, File.read(path))
   924       val toks = Token.explode(root_syntax.keywords, File.read(path))