(** This module provides AST traversal classes, such as maps, iterations, folds,
    etc. on the {!Parsetree} types.

    {1 Link to the tutorial}

    For a detailed explanation on this module, refer to the {{!"ast-traversal"}
    relevant} part of the manual.

    {1 API} *)

open! Import

(** To use these classes, inherit from them and override the methods
    corresponding to the types from [Parsetree] you want to process. For
    instance to collect all the string constants in a structure:

    {[
      let string_constants_of =
        object
          inherit [string list] Ast_traverse.fold as super

          method! expression e acc =
            let acc = super#expression e acc in
            match e.pexp_desc with
            | Pexp_constant (Const_string (s, _)) -> s :: acc
            | _ -> acc

          method! pattern p acc =
            let acc = super#pattern p acc in
            match p.ppat_desc with
            | Ppat_constant (Const_string (s, _)) -> s :: acc
            | _ -> acc
        end

      let string_constants_of_structure = string_constants_of#structure
    ]} *)

class map :
  object
    inherit Ppxlib_traverse_builtins.map
    inherit Ast.map
  end

class iter :
  object
    inherit Ppxlib_traverse_builtins.iter
    inherit Ast.iter
  end

class ['acc] fold :
  object
    inherit ['acc] Ppxlib_traverse_builtins.fold
    inherit ['acc] Ast.fold
  end

class ['acc] fold_map :
  object
    inherit ['acc] Ppxlib_traverse_builtins.fold_map
    inherit ['acc] Ast.fold_map
  end

class ['ctx] map_with_context :
  object
    inherit ['ctx] Ppxlib_traverse_builtins.map_with_context
    inherit ['ctx] Ast.map_with_context
  end

class map_with_path : [string] map_with_context

val enter_value : (expression, string loc) Attribute.t
val enter_module : (module_expr, string loc) Attribute.t
val do_not_enter_value_binding : (value_binding, unit) Attribute.t
val do_not_enter_value_description : (value_description, unit) Attribute.t
val do_not_enter_module_binding : (module_binding, unit) Attribute.t
val do_not_enter_module_declaration : (module_declaration, unit) Attribute.t

val do_not_enter_module_type_declaration :
  (module_type_declaration, unit) Attribute.t

val do_not_enter_let_module : (expression, unit) Attribute.t

class virtual ['res] lift :
  object
    inherit ['res] Ppxlib_traverse_builtins.lift
    inherit ['res] Ast.lift
  end

class virtual ['ctx, 'res] lift_map_with_context :
  object
    inherit ['ctx, 'res] Ppxlib_traverse_builtins.lift_map_with_context
    inherit ['ctx, 'res] Ast.lift_map_with_context
  end

class map_with_expansion_context_and_errors :
  object
    inherit
      [Expansion_context.Base.t, Location.Error.t list] Ppxlib_traverse_builtins
                                                        .std_lift_mappers_with_context

    inherit
      [Expansion_context.Base.t, Location.Error.t list] Ast
                                                        .lift_map_with_context
  end

class sexp_of :
  object
    inherit [Sexp.t] Ppxlib_traverse_builtins.std_lifters
    inherit [Sexp.t] Ast.lift
  end

val sexp_of : sexp_of
