228 .transitive_closure |
228 .transitive_closure |
229 .restrict(required_sessions.toSet) |
229 .restrict(required_sessions.toSet) |
230 .transitive_reduction_acyclic |
230 .transitive_reduction_acyclic |
231 |
231 |
232 val graph0 = |
232 val graph0 = |
233 (Graph_Display.empty_graph /: required_subgraph.topological_order)( |
233 required_subgraph.topological_order.foldLeft(Graph_Display.empty_graph) { |
234 { case (g, session) => |
234 case (g, session) => |
235 val a = session_node(session) |
235 val a = session_node(session) |
236 val bs = required_subgraph.imm_preds(session).toList.map(session_node) |
236 val bs = required_subgraph.imm_preds(session).toList.map(session_node) |
237 ((g /: (a :: bs))(_.default_node(_, Nil)) /: bs)(_.add_edge(_, a)) }) |
237 bs.foldLeft((a :: bs).foldLeft(g)(_.default_node(_, Nil)))(_.add_edge(_, a)) |
238 |
238 } |
239 (graph0 /: dependencies.entries)( |
239 |
240 { case (g, entry) => |
240 dependencies.entries.foldLeft(graph0) { |
241 val a = node(entry.name) |
241 case (g, entry) => |
242 val bs = entry.header.imports.map(node).filterNot(_ == a) |
242 val a = node(entry.name) |
243 ((g /: (a :: bs))(_.default_node(_, Nil)) /: bs)(_.add_edge(_, a)) }) |
243 val bs = entry.header.imports.map(node).filterNot(_ == a) |
|
244 bs.foldLeft((a :: bs).foldLeft(g)(_.default_node(_, Nil)))(_.add_edge(_, a)) |
|
245 } |
244 } |
246 } |
245 |
247 |
246 val known_theories = |
248 val known_theories = |
247 (deps_base.known_theories /: |
249 dependencies.entries.iterator.map(entry => entry.name.theory -> entry). |
248 dependencies.entries.iterator.map(entry => entry.name.theory -> entry))(_ + _) |
250 foldLeft(deps_base.known_theories)(_ + _) |
249 |
251 |
250 val known_loaded_files = deps_base.known_loaded_files ++ loaded_files |
252 val known_loaded_files = deps_base.known_loaded_files ++ loaded_files |
251 |
253 |
252 val import_errors = |
254 val import_errors = |
253 { |
255 { |
487 { |
489 { |
488 val parent_base = session_bases(parent.getOrElse("")) |
490 val parent_base = session_bases(parent.getOrElse("")) |
489 val imports_bases = imports.map(session_bases) |
491 val imports_bases = imports.map(session_bases) |
490 parent_base.copy( |
492 parent_base.copy( |
491 known_theories = |
493 known_theories = |
492 (parent_base.known_theories /: |
494 (for { |
493 (for { |
495 base <- imports_bases.iterator |
494 base <- imports_bases.iterator |
496 (_, entry) <- base.known_theories.iterator |
495 (_, entry) <- base.known_theories.iterator |
497 } yield (entry.name.theory -> entry)).foldLeft(parent_base.known_theories)(_ + _), |
496 } yield (entry.name.theory -> entry)))(_ + _), |
|
497 known_loaded_files = |
498 known_loaded_files = |
498 (parent_base.known_loaded_files /: |
499 imports_bases.iterator.map(_.known_loaded_files). |
499 imports_bases.iterator.map(_.known_loaded_files))(_ ++ _)) |
500 foldLeft(parent_base.known_loaded_files)(_ ++ _)) |
500 } |
501 } |
501 |
502 |
502 def dirs: List[Path] = dir :: directories |
503 def dirs: List[Path] = dir :: directories |
503 |
504 |
504 def timeout: Time = Time.seconds(options.real("timeout") * options.real("timeout_scale")) |
505 def timeout: Time = Time.seconds(options.real("timeout") * options.real("timeout_scale")) |
659 error(cat_lines(exn.cycles.map(cycle => |
660 error(cat_lines(exn.cycles.map(cycle => |
660 "Cyclic session dependency of " + |
661 "Cyclic session dependency of " + |
661 cycle.map(c => quote(c.toString)).mkString(" via "))) + Position.here(pos)) |
662 cycle.map(c => quote(c.toString)).mkString(" via "))) + Position.here(pos)) |
662 } |
663 } |
663 } |
664 } |
664 (graph /: graph.iterator) { |
665 graph.iterator.foldLeft(graph) { |
665 case (g, (name, (info, _))) => (g /: edges(info))(add_edge(info.pos, name, _, _)) |
666 case (g, (name, (info, _))) => |
|
667 edges(info).foldLeft(g)(add_edge(info.pos, name, _, _)) |
666 } |
668 } |
667 } |
669 } |
668 |
670 |
669 val info_graph = |
671 val info_graph = |
670 (Graph.string[Info] /: infos) { |
672 infos.foldLeft(Graph.string[Info]) { |
671 case (graph, info) => |
673 case (graph, info) => |
672 if (graph.defined(info.name)) |
674 if (graph.defined(info.name)) |
673 error("Duplicate session " + quote(info.name) + Position.here(info.pos) + |
675 error("Duplicate session " + quote(info.name) + Position.here(info.pos) + |
674 Position.here(graph.get_node(info.name).pos)) |
676 Position.here(graph.get_node(info.name).pos)) |
675 else graph.new_node(info.name, info) |
677 else graph.new_node(info.name, info) |
679 |
681 |
680 val session_positions: List[(String, Position.T)] = |
682 val session_positions: List[(String, Position.T)] = |
681 (for ((name, (info, _)) <- info_graph.iterator) yield (name, info.pos)).toList |
683 (for ((name, (info, _)) <- info_graph.iterator) yield (name, info.pos)).toList |
682 |
684 |
683 val session_directories: Map[JFile, String] = |
685 val session_directories: Map[JFile, String] = |
684 (Map.empty[JFile, String] /: |
686 (for { |
685 (for { |
687 session <- imports_graph.topological_order.iterator |
686 session <- imports_graph.topological_order.iterator |
688 info = info_graph.get_node(session) |
687 info = info_graph.get_node(session) |
689 dir <- info.dirs.iterator |
688 dir <- info.dirs.iterator |
690 } yield (info, dir)).foldLeft(Map.empty[JFile, String]) { |
689 } yield (info, dir)))({ case (dirs, (info, dir)) => |
691 case (dirs, (info, dir)) => |
690 val session = info.name |
692 val session = info.name |
691 val canonical_dir = dir.canonical_file |
693 val canonical_dir = dir.canonical_file |
692 dirs.get(canonical_dir) match { |
694 dirs.get(canonical_dir) match { |
693 case Some(session1) => |
695 case Some(session1) => |
694 val info1 = info_graph.get_node(session1) |
696 val info1 = info_graph.get_node(session1) |
695 error("Duplicate use of directory " + dir + |
697 error("Duplicate use of directory " + dir + |
696 "\n for session " + quote(session1) + Position.here(info1.pos) + |
698 "\n for session " + quote(session1) + Position.here(info1.pos) + |
697 "\n vs. session " + quote(session) + Position.here(info.pos)) |
699 "\n vs. session " + quote(session) + Position.here(info.pos)) |
698 case None => dirs + (canonical_dir -> session) |
700 case None => dirs + (canonical_dir -> session) |
699 } |
701 } |
700 }) |
702 } |
701 |
703 |
702 val global_theories: Map[String, String] = |
704 val global_theories: Map[String, String] = |
703 (Thy_Header.bootstrap_global_theories.toMap /: |
705 (for { |
704 (for { |
706 session <- imports_graph.topological_order.iterator |
705 session <- imports_graph.topological_order.iterator |
707 info = info_graph.get_node(session) |
706 info = info_graph.get_node(session) |
708 thy <- info.global_theories.iterator } |
707 thy <- info.global_theories.iterator } |
709 yield (info, thy)).foldLeft(Thy_Header.bootstrap_global_theories.toMap) { |
708 yield (info, thy)))({ case (global, (info, thy)) => |
710 case (global, (info, thy)) => |
709 val qualifier = info.name |
711 val qualifier = info.name |
710 global.get(thy) match { |
712 global.get(thy) match { |
711 case Some(qualifier1) if qualifier != qualifier1 => |
713 case Some(qualifier1) if qualifier != qualifier1 => |
712 error("Duplicate global theory " + quote(thy) + Position.here(info.pos)) |
714 error("Duplicate global theory " + quote(thy) + Position.here(info.pos)) |
713 case _ => global + (thy -> qualifier) |
715 case _ => global + (thy -> qualifier) |
714 } |
716 } |
715 }) |
717 } |
716 |
718 |
717 new Structure( |
719 new Structure( |
718 session_positions, session_directories, global_theories, build_graph, imports_graph) |
720 session_positions, session_directories, global_theories, build_graph, imports_graph) |
719 } |
721 } |
720 } |
722 } |
737 def dest_session_directories: List[(String, String)] = |
739 def dest_session_directories: List[(String, String)] = |
738 for ((file, session) <- session_directories.toList) |
740 for ((file, session) <- session_directories.toList) |
739 yield (File.standard_path(file), session) |
741 yield (File.standard_path(file), session) |
740 |
742 |
741 lazy val chapters: SortedMap[String, List[Info]] = |
743 lazy val chapters: SortedMap[String, List[Info]] = |
742 (SortedMap.empty[String, List[Info]] /: build_graph.iterator)( |
744 build_graph.iterator.foldLeft(SortedMap.empty[String, List[Info]]) { |
743 { case (chs, (_, (info, _))) => |
745 case (chs, (_, (info, _))) => |
744 chs + (info.chapter -> (info :: chs.getOrElse(info.chapter, Nil))) }) |
746 chs + (info.chapter -> (info :: chs.getOrElse(info.chapter, Nil))) |
|
747 } |
745 |
748 |
746 def build_graph_display: Graph_Display.Graph = Graph_Display.make_graph(build_graph) |
749 def build_graph_display: Graph_Display.Graph = Graph_Display.make_graph(build_graph) |
747 def imports_graph_display: Graph_Display.Graph = Graph_Display.make_graph(imports_graph) |
750 def imports_graph_display: Graph_Display.Graph = Graph_Display.make_graph(imports_graph) |
748 |
751 |
749 def defined(name: String): Boolean = imports_graph.defined(name) |
752 def defined(name: String): Boolean = imports_graph.defined(name) |
1059 (select, dir) <- directories(dirs, select_dirs) |
1062 (select, dir) <- directories(dirs, select_dirs) |
1060 res <- load_dir(select, check_session_dir(dir)) |
1063 res <- load_dir(select, check_session_dir(dir)) |
1061 } yield res |
1064 } yield res |
1062 |
1065 |
1063 val unique_roots = |
1066 val unique_roots = |
1064 ((Map.empty[JFile, (Boolean, Path)] /: roots) { case (m, (select, path)) => |
1067 roots.foldLeft(Map.empty[JFile, (Boolean, Path)]) { |
1065 val file = path.canonical_file |
1068 case (m, (select, path)) => |
1066 m.get(file) match { |
1069 val file = path.canonical_file |
1067 case None => m + (file -> (select, path)) |
1070 m.get(file) match { |
1068 case Some((select1, path1)) => m + (file -> (select1 || select, path1)) |
1071 case None => m + (file -> (select, path)) |
1069 } |
1072 case Some((select1, path1)) => m + (file -> (select1 || select, path1)) |
1070 }).toList.map(_._2) |
1073 } |
|
1074 }.toList.map(_._2) |
1071 |
1075 |
1072 Structure.make(unique_roots.flatMap(p => read_root(options, p._1, p._2)) ::: infos) |
1076 Structure.make(unique_roots.flatMap(p => read_root(options, p._1, p._2)) ::: infos) |
1073 } |
1077 } |
1074 |
1078 |
1075 |
1079 |