(** Directories contents *)

(** This modules takes care of attaching source files of OCaml, C, Coq found in
    the source tree or generated by user rules to library, executables, tests
    and documentation stanzas to language specific collectors.

    It also helps handle [(include_subdirs ..)] as it handles the directory
    traversal. *)

open Import

type t

val dir : t -> Path.Build.t
val source_dir : t -> Source_tree.Dir.t option

(** Files in this directory. At the moment, this doesn't include all generated
    files, just the ones generated by [rule], [ocamllex], [ocamlyacc], [menhir]
    stanzas. *)
val text_files : t -> Filename.Set.t

(** C/C++ sources *)
val foreign_sources : t -> Foreign_sources.t Memo.t

val ocaml : t -> Ml_sources.t Memo.t
val melange : t -> Ml_sources.t Memo.t
val ml : t -> for_:Compilation_mode.t -> Ml_sources.t Memo.t

(** All mld files attached to this documentation stanza *)
val mlds : t -> stanza:Documentation.t -> Doc_sources.mld list Memo.t

val coq : t -> Coq_sources.t Memo.t
val rocq : t -> Rocq_sources.t Memo.t

(** Get the directory contents of the given directory. *)
val get : Super_context.t -> dir:Path.Build.t -> t Memo.t

val modules_of_lib
  :  Super_context.t
  -> Lib.t
  -> for_:Compilation_mode.t
  -> Modules.With_vlib.t option Memo.t

val modules_of_local_lib
  :  Super_context.t
  -> Lib.Local.t
  -> for_:Compilation_mode.t
  -> Modules.t Memo.t

(** All directories in this group if [t] is a group root or just [t] if it is
    not part of a group. *)
val dirs : t -> t list

module Standalone_or_root : sig
  type dir_contents := t
  type t

  val rules : t -> Rules.t Memo.t
  val root : t -> dir_contents Memo.t
  val subdirs : t -> dir_contents list Memo.t
end

type triage =
  | Standalone_or_root of Standalone_or_root.t
  | Group_part of Path.Build.t

(** In order to compute the directory contents, we need to interpret stanzas
    such as [rule] or [copy_files]. For such stanzas, computing the targets is
    very similar to interpreting the stanza and compiling it down to low-level
    rules.

    As a result, we proceed as follow: we interpret the stanza into rules and
    extract the targets of the computed rule. This function returns these rules.

    However, if the directory is part of a group, this function simply returns
    the root of the group. *)
val triage : Super_context.t -> dir:Path.Build.t -> triage Memo.t
