(**
 * Copyright (c) 2013-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *)

module type S = sig
  module L: Loc_sig.S

  type scope = int
  type use = L.t
  type uses = L.LSet.t
  module Def: sig
    type t = {
      locs: L.t Nel.t;
      name: int;
      actual_name: string;
    }
    val compare: t -> t -> int
  end
  module DefMap: MyMap_sig.S with type key = Def.t
  type use_def_map = Def.t L.LMap.t
  module Scope: sig
    type t = {
      lexical: bool;
      parent: int option;
      defs: Def.t SMap.t;
      locals: use_def_map;
      globals: SSet.t;
      loc: L.t;
    }
  end
  type info = {
    max_distinct: int;
    scopes: Scope.t IMap.t;
  }

  val scope: info -> scope -> Scope.t

  (* List of scopes associated with a loc. The returned list order should be
     based on the scope depth (some nodes such as functions have two scopes
     associated, one for the name and one for the params/body). *)
  val scope_of_loc: info -> L.t -> scope list

  val all_uses: info -> uses
  val defs_of_all_uses: info -> use_def_map
  val uses_of_all_defs: info -> uses DefMap.t
  val def_of_use: info -> use -> Def.t
  val use_is_def: info -> use -> bool
  val uses_of_def: info -> ?exclude_def:bool -> Def.t -> uses
  val uses_of_use: info -> ?exclude_def:bool -> use -> uses
  val def_is_unused: info -> Def.t -> bool
  val is_local_use: info -> use -> bool
  val fold_scope_chain: info -> (scope -> Scope.t -> 'a -> 'a) -> scope -> 'a -> 'a

  val build_scope_tree: info -> Scope.t Tree.t
  val compute_free_and_bound_variables: Scope.t Tree.t -> (Def.t SMap.t * SSet.t * SSet.t) Tree.t

  val toplevel_names: info -> SSet.t
end
