(**************************************************************************)
(*                                                                        *)
(*                                 OCaml                                  *)
(*                                                                        *)
(*             Xavier Leroy, projet Cristal, INRIA Rocquencourt           *)
(*                                                                        *)
(*   Copyright 1996 Institut National de Recherche en Informatique et     *)
(*     en Automatique.                                                    *)
(*                                                                        *)
(*   All rights reserved.  This file is distributed under the terms of    *)
(*   the GNU Lesser General Public License version 2.1, with the          *)
(*   special exception on linking described in the file LICENSE.          *)
(*                                                                        *)
(**************************************************************************)

(** Long identifiers, used in parsetree.

  {b Warning:} this module is unstable and part of
  {{!Compiler_libs}compiler-libs}.

  To print a longident, see {!Pprintast.longident}, using
    {!Format.asprintf} to convert to a string.

*)

open Location

type t =
    Lident of string
  | Ldot of t loc * string loc
  | Lapply of t loc * t loc

(** [same t t'] compares the longidents [t] and [t'] without taking locations
    into account. *)
val same: t -> t -> bool

val flatten: t -> string list
val unflatten: string list -> t option
(** For a non-empty list [l], [unflatten l] is [Some lid] where [lid] is
    the long identifier created by concatenating the elements of [l]
    with [Ldot].
    [unflatten []] is [None].
*)

(** [head lid] returns the leftmost part of [lid], e.g., 
    given [String.Map.empty], returns [String].
    
    @raise Assert_failure if encounters [Lapply] *)
val head: t -> string
val last: t -> string
val parse: string -> t
  (* (* disabled in merlin. *)
[@@deprecated "this function may misparse its input,\n\
use \"Parse.longident\" or \"Longident.unflatten\""]
     *)
(**

   This function is broken on identifiers that are not just "Word.Word.word";
   for example, it returns incorrect results on infix operators
   and extended module paths.

   If you want to generate long identifiers that are a list of
   dot-separated identifiers, the function {!unflatten} is safer and faster.
   {!unflatten} is available since OCaml 4.06.0.

   If you want to parse any identifier correctly, use the long-identifiers
   functions from the {!Parse} module, in particular {!Parse.longident}.
   They are available since OCaml 4.11, and also provide proper
   input-location support.

*)

(* Merlin specific. *)

val keep_suffix : t -> t * bool
(** if [li', b = keep_suffix li] then:
    - the prefix of [li'] is a module path
    - [b = false] iff [li' = li].
    Corollary: [b = true] if [li] is a label access
               (i.e. [li = X.Y.z.Foo.Bar...]) *)
