474 groups: List[String], |
474 groups: List[String], |
475 description: String, |
475 description: String, |
476 sessions: List[String] |
476 sessions: List[String] |
477 ) |
477 ) |
478 |
478 |
|
479 object Info { |
|
480 def make( |
|
481 chapter_defs: Chapter_Defs, |
|
482 options: Options, |
|
483 dir_selected: Boolean, |
|
484 dir: Path, |
|
485 chapter: String, |
|
486 entry: Session_Entry |
|
487 ): Info = { |
|
488 try { |
|
489 val name = entry.name |
|
490 |
|
491 if (illegal_session(name)) error("Illegal session name " + quote(name)) |
|
492 if (is_pure(name) && entry.parent.isDefined) error("Illegal parent session") |
|
493 if (!is_pure(name) && !entry.parent.isDefined) error("Missing parent session") |
|
494 |
|
495 val session_path = dir + Path.explode(entry.path) |
|
496 val directories = entry.directories.map(dir => session_path + Path.explode(dir)) |
|
497 |
|
498 val session_options = options ++ entry.options |
|
499 |
|
500 val theories = |
|
501 entry.theories.map({ case (opts, thys) => |
|
502 (session_options ++ opts, |
|
503 thys.map({ case ((thy, pos), _) => |
|
504 val thy_name = Thy_Header.import_name(thy) |
|
505 if (illegal_theory(thy_name)) { |
|
506 error("Illegal theory name " + quote(thy_name) + Position.here(pos)) |
|
507 } |
|
508 else (thy, pos) })) }) |
|
509 |
|
510 val global_theories = |
|
511 for { (_, thys) <- entry.theories; ((thy, pos), global) <- thys if global } |
|
512 yield { |
|
513 val thy_name = Path.explode(thy).file_name |
|
514 if (Long_Name.is_qualified(thy_name)) { |
|
515 error("Bad qualified name for global theory " + |
|
516 quote(thy_name) + Position.here(pos)) |
|
517 } |
|
518 else thy_name |
|
519 } |
|
520 |
|
521 val conditions = |
|
522 theories.flatMap(thys => space_explode(',', thys._1.string("condition"))).distinct.sorted. |
|
523 map(x => (x, Isabelle_System.getenv(x) != "")) |
|
524 |
|
525 val document_files = |
|
526 entry.document_files.map({ case (s1, s2) => (Path.explode(s1), Path.explode(s2)) }) |
|
527 |
|
528 val export_files = |
|
529 entry.export_files.map({ case (dir, prune, pats) => (Path.explode(dir), prune, pats) }) |
|
530 |
|
531 val meta_digest = |
|
532 SHA1.digest( |
|
533 (name, chapter, entry.parent, entry.directories, entry.options, entry.imports, |
|
534 entry.theories_no_position, conditions, entry.document_theories_no_position, |
|
535 entry.document_files) |
|
536 .toString) |
|
537 |
|
538 val chapter_groups = chapter_defs(chapter).groups |
|
539 val groups = chapter_groups ::: entry.groups.filterNot(chapter_groups.contains) |
|
540 |
|
541 Info(name, chapter, dir_selected, entry.pos, groups, session_path, |
|
542 entry.parent, entry.description, directories, session_options, |
|
543 entry.imports, theories, global_theories, entry.document_theories, document_files, |
|
544 export_files, entry.export_classpath, meta_digest) |
|
545 } |
|
546 catch { |
|
547 case ERROR(msg) => |
|
548 error(msg + "\nThe error(s) above occurred in session entry " + |
|
549 quote(entry.name) + Position.here(entry.pos)) |
|
550 } |
|
551 } |
|
552 } |
|
553 |
479 sealed case class Info( |
554 sealed case class Info( |
480 name: String, |
555 name: String, |
481 chapter: String, |
556 chapter: String, |
482 dir_selected: Boolean, |
557 dir_selected: Boolean, |
483 pos: Position.T, |
558 pos: Position.T, |
566 |
641 |
567 def is_afp: Boolean = chapter == AFP.chapter |
642 def is_afp: Boolean = chapter == AFP.chapter |
568 def is_afp_bulky: Boolean = is_afp && groups.exists(AFP.groups_bulky.contains) |
643 def is_afp_bulky: Boolean = is_afp && groups.exists(AFP.groups_bulky.contains) |
569 } |
644 } |
570 |
645 |
571 def make_info( |
|
572 chapter_defs: Chapter_Defs, |
|
573 options: Options, |
|
574 dir_selected: Boolean, |
|
575 dir: Path, |
|
576 chapter: String, |
|
577 entry: Session_Entry |
|
578 ): Info = { |
|
579 try { |
|
580 val name = entry.name |
|
581 |
|
582 if (illegal_session(name)) error("Illegal session name " + quote(name)) |
|
583 if (is_pure(name) && entry.parent.isDefined) error("Illegal parent session") |
|
584 if (!is_pure(name) && !entry.parent.isDefined) error("Missing parent session") |
|
585 |
|
586 val session_path = dir + Path.explode(entry.path) |
|
587 val directories = entry.directories.map(dir => session_path + Path.explode(dir)) |
|
588 |
|
589 val session_options = options ++ entry.options |
|
590 |
|
591 val theories = |
|
592 entry.theories.map({ case (opts, thys) => |
|
593 (session_options ++ opts, |
|
594 thys.map({ case ((thy, pos), _) => |
|
595 val thy_name = Thy_Header.import_name(thy) |
|
596 if (illegal_theory(thy_name)) { |
|
597 error("Illegal theory name " + quote(thy_name) + Position.here(pos)) |
|
598 } |
|
599 else (thy, pos) })) }) |
|
600 |
|
601 val global_theories = |
|
602 for { (_, thys) <- entry.theories; ((thy, pos), global) <- thys if global } |
|
603 yield { |
|
604 val thy_name = Path.explode(thy).file_name |
|
605 if (Long_Name.is_qualified(thy_name)) { |
|
606 error("Bad qualified name for global theory " + |
|
607 quote(thy_name) + Position.here(pos)) |
|
608 } |
|
609 else thy_name |
|
610 } |
|
611 |
|
612 val conditions = |
|
613 theories.flatMap(thys => space_explode(',', thys._1.string("condition"))).distinct.sorted. |
|
614 map(x => (x, Isabelle_System.getenv(x) != "")) |
|
615 |
|
616 val document_files = |
|
617 entry.document_files.map({ case (s1, s2) => (Path.explode(s1), Path.explode(s2)) }) |
|
618 |
|
619 val export_files = |
|
620 entry.export_files.map({ case (dir, prune, pats) => (Path.explode(dir), prune, pats) }) |
|
621 |
|
622 val meta_digest = |
|
623 SHA1.digest( |
|
624 (name, chapter, entry.parent, entry.directories, entry.options, entry.imports, |
|
625 entry.theories_no_position, conditions, entry.document_theories_no_position, |
|
626 entry.document_files) |
|
627 .toString) |
|
628 |
|
629 val chapter_groups = chapter_defs(chapter).groups |
|
630 val groups = chapter_groups ::: entry.groups.filterNot(chapter_groups.contains) |
|
631 |
|
632 Info(name, chapter, dir_selected, entry.pos, groups, session_path, |
|
633 entry.parent, entry.description, directories, session_options, |
|
634 entry.imports, theories, global_theories, entry.document_theories, document_files, |
|
635 export_files, entry.export_classpath, meta_digest) |
|
636 } |
|
637 catch { |
|
638 case ERROR(msg) => |
|
639 error(msg + "\nThe error(s) above occurred in session entry " + |
|
640 quote(entry.name) + Position.here(entry.pos)) |
|
641 } |
|
642 } |
|
643 |
|
644 object Selection { |
646 object Selection { |
645 val empty: Selection = Selection() |
647 val empty: Selection = Selection() |
646 val all: Selection = Selection(all_sessions = true) |
648 val all: Selection = Selection(all_sessions = true) |
647 def session(session: String): Selection = Selection(sessions = List(session)) |
649 def session(session: String): Selection = Selection(sessions = List(session)) |
648 } |
650 } |
689 val info_roots = new mutable.ListBuffer[Info] |
691 val info_roots = new mutable.ListBuffer[Info] |
690 for (root <- roots) { |
692 for (root <- roots) { |
691 root.entries.foreach { |
693 root.entries.foreach { |
692 case entry: Chapter_Entry => chapter = entry.name |
694 case entry: Chapter_Entry => chapter = entry.name |
693 case entry: Session_Entry => |
695 case entry: Session_Entry => |
694 info_roots += make_info(chapter_defs, options, root.select, root.dir, chapter, entry) |
696 info_roots += Info.make(chapter_defs, options, root.select, root.dir, chapter, entry) |
695 case _ => |
697 case _ => |
696 } |
698 } |
697 chapter = UNSORTED |
699 chapter = UNSORTED |
698 } |
700 } |
699 info_roots.toList |
701 info_roots.toList |