src/Pure/Thy/sessions.scala
changeset 70672 e4bba654d085
parent 70671 cb1776c8e216
child 70673 b0172698d0d3
equal deleted inserted replaced
70671:cb1776c8e216 70672:e4bba654d085
   536     export_files: List[(Path, Int, List[String])],
   536     export_files: List[(Path, Int, List[String])],
   537     meta_digest: SHA1.Digest)
   537     meta_digest: SHA1.Digest)
   538   {
   538   {
   539     def deps: List[String] = parent.toList ::: imports
   539     def deps: List[String] = parent.toList ::: imports
   540 
   540 
   541     def dirs: List[Path] = dir :: directories.map(_._1)
   541     def dirs: List[(Path, Boolean)] = (dir, false) :: directories
   542     def dirs_strict: List[Path] = dir :: (for { (d, false) <- directories } yield d)
       
   543 
   542 
   544     def timeout: Time = Time.seconds(options.real("timeout") * options.real("timeout_scale"))
   543     def timeout: Time = Time.seconds(options.real("timeout") * options.real("timeout_scale"))
   545 
   544 
   546     def bibtex_entries: List[Text.Info[String]] =
   545     def bibtex_entries: List[Text.Info[String]] =
   547       (for {
   546       (for {
   559 
   558 
   560       if (exclude_session(name)) error("Bad session name")
   559       if (exclude_session(name)) error("Bad session name")
   561       if (is_pure(name) && entry.parent.isDefined) error("Illegal parent session")
   560       if (is_pure(name) && entry.parent.isDefined) error("Illegal parent session")
   562       if (!is_pure(name) && !entry.parent.isDefined) error("Missing parent session")
   561       if (!is_pure(name) && !entry.parent.isDefined) error("Missing parent session")
   563 
   562 
       
   563       val session_path = dir + Path.explode(entry.path)
   564       val directories =
   564       val directories =
   565         for { (d, b) <- entry.directories }
   565         for { (dir, overlapping) <- entry.directories }
   566         yield (dir + Path.explode(d), b)
   566         yield (session_path + Path.explode(dir), overlapping)
   567 
   567 
   568       val session_options = options ++ entry.options
   568       val session_options = options ++ entry.options
   569 
   569 
   570       val theories =
   570       val theories =
   571         entry.theories.map({ case (opts, thys) =>
   571         entry.theories.map({ case (opts, thys) =>
   597 
   597 
   598       val meta_digest =
   598       val meta_digest =
   599         SHA1.digest((name, chapter, entry.parent, entry.directories, entry.options, entry.imports,
   599         SHA1.digest((name, chapter, entry.parent, entry.directories, entry.options, entry.imports,
   600           entry.theories_no_position, conditions, entry.document_files).toString)
   600           entry.theories_no_position, conditions, entry.document_files).toString)
   601 
   601 
   602       Info(name, chapter, dir_selected, entry.pos, entry.groups, dir + Path.explode(entry.path),
   602       Info(name, chapter, dir_selected, entry.pos, entry.groups, session_path,
   603         entry.parent, entry.description, directories, session_options,
   603         entry.parent, entry.description, directories, session_options,
   604         entry.imports, theories, global_theories, document_files, export_files, meta_digest)
   604         entry.imports, theories, global_theories, document_files, export_files, meta_digest)
   605     }
   605     }
   606     catch {
   606     catch {
   607       case ERROR(msg) =>
   607       case ERROR(msg) =>
   669           else graph.new_node(info.name, info)
   669           else graph.new_node(info.name, info)
   670       }
   670       }
   671     val build_graph = add_edges(info_graph, "parent", _.parent)
   671     val build_graph = add_edges(info_graph, "parent", _.parent)
   672     val imports_graph = add_edges(build_graph, "imports", _.imports)
   672     val imports_graph = add_edges(build_graph, "imports", _.imports)
   673 
   673 
   674     val strict_directories: Map[JFile, String] =
   674     val session_directories: Map[JFile, (String, Boolean)] =
   675       (Map.empty[JFile, String] /:
   675       (Map.empty[JFile, (String, Boolean)] /:
   676         (for {
   676         (for {
   677           session <- imports_graph.topological_order.iterator
   677           session <- imports_graph.topological_order.iterator
   678           info = info_graph.get_node(session)
   678           info = info_graph.get_node(session)
   679           dir <- info.dirs_strict.iterator
   679           dir_overlapping <- info.dirs.iterator
   680         } yield (info, dir)))({ case (dirs, (info, dir)) =>
   680         } yield (info, dir_overlapping)))({ case (dirs, (info, (dir, overlapping))) =>
   681             val session = info.name
   681             val session = info.name
   682             val canonical_dir = dir.canonical_file
   682             val canonical_dir = dir.canonical_file
       
   683             def update(over: Boolean) = dirs + (canonical_dir -> (session -> over))
   683             dirs.get(canonical_dir) match {
   684             dirs.get(canonical_dir) match {
   684               case Some(session1) if session != session1 =>
   685               case Some((session1, overlapping1)) =>
   685                 val info1 = info_graph.get_node(session1)
   686                 if (session == session1) update(overlapping || overlapping1)
   686                 error("Duplicate use of directory " + dir +
   687                 else if (overlapping && !overlapping1) dirs
   687                   "\n  for session " + quote(session1) + Position.here(info1.pos) +
   688                 else if (!overlapping && overlapping1) update(overlapping)
   688                   "\n  vs. session " + quote(session) + Position.here(info.pos))
   689                 else {
   689               case _ => dirs + (canonical_dir -> session)
   690                   val info1 = info_graph.get_node(session1)
       
   691                   error("Duplicate use of directory " + dir +
       
   692                     "\n  for session " + quote(session1) + Position.here(info1.pos) +
       
   693                     "\n  vs. session " + quote(session) + Position.here(info.pos))
       
   694                 }
       
   695               case None => update(overlapping)
   690             }
   696             }
   691           })
   697           })
   692 
   698 
   693     val global_theories: Map[String, String] =
   699     val global_theories: Map[String, String] =
   694       (Thy_Header.bootstrap_global_theories.toMap /:
   700       (Thy_Header.bootstrap_global_theories.toMap /:
   703                 error("Duplicate global theory " + quote(thy) + Position.here(info.pos))
   709                 error("Duplicate global theory " + quote(thy) + Position.here(info.pos))
   704               case _ => global + (thy -> qualifier)
   710               case _ => global + (thy -> qualifier)
   705             }
   711             }
   706           })
   712           })
   707 
   713 
   708     new Structure(strict_directories, global_theories, build_graph, imports_graph)
   714     new Structure(session_directories, global_theories, build_graph, imports_graph)
   709   }
   715   }
   710 
   716 
   711   final class Structure private[Sessions](
   717   final class Structure private[Sessions](
   712       val strict_directories: Map[JFile, String],
   718       val session_directories: Map[JFile, (String, Boolean)],
   713       val global_theories: Map[String, String],
   719       val global_theories: Map[String, String],
   714       val build_graph: Graph[String, Info],
   720       val build_graph: Graph[String, Info],
   715       val imports_graph: Graph[String, Info])
   721       val imports_graph: Graph[String, Info])
   716   {
   722   {
   717     sessions_structure =>
   723     sessions_structure =>
   779         val sessions = graph.all_preds(selected(graph, sel)).filterNot(excluded)
   785         val sessions = graph.all_preds(selected(graph, sel)).filterNot(excluded)
   780         graph.restrict(graph.all_preds(sessions).toSet)
   786         graph.restrict(graph.all_preds(sessions).toSet)
   781       }
   787       }
   782 
   788 
   783       new Structure(
   789       new Structure(
   784         strict_directories, global_theories, restrict(build_graph), restrict(imports_graph))
   790         session_directories, global_theories, restrict(build_graph), restrict(imports_graph))
   785     }
   791     }
   786 
   792 
   787     def selection_deps(
   793     def selection_deps(
   788       options: Options,
   794       options: Options,
   789       selection: Selection,
   795       selection: Selection,