Commit 074b7318 authored by POTTIER Francois's avatar POTTIER Francois

Movement.

parent 88a680e0
......@@ -15,6 +15,75 @@ type tyvars = tyvar list
(* -------------------------------------------------------------------------- *)
(* Testing whether an identifier is valid. *)
(* We use OCaml's lexer to analyze the string and check if it is a valid
identifier. This method is slightly unorthodox, as the lexer can have
undesired side effects, such as raising an [Error] exception or printing
warnings. We do our best to hide these effects. The strength of this
approach is to give us (at little cost) a correct criterion for deciding if
an identifier is valid. *)
type classification =
| LIDENT
| UIDENT
| OTHER
let classify (s : string) : classification =
let lexbuf = Lexing.from_string s in
let backup = !Location.formatter_for_warnings in
let null = Format.formatter_of_buffer (Buffer.create 0) in
Location.formatter_for_warnings := null;
let result = try
let token1 = Lexer.token lexbuf in
let token2 = Lexer.token lexbuf in
match token1, token2 with
| Parser.LIDENT _, Parser.EOF ->
LIDENT
| Parser.UIDENT _, Parser.EOF ->
UIDENT
| _, _ ->
OTHER
with Lexer.Error _ ->
OTHER
in
Location.formatter_for_warnings := backup;
result
(* -------------------------------------------------------------------------- *)
(* Testing if a string is a valid [mod_longident], i.e., a possibly-qualified
module identifier. *)
(* We might wish to use OCaml's parser for this purpose, but [mod_longident] is
not declared as a start symbol. Furthermore, that would be perhaps slightly
too lenient, e.g., allowing whitespace and comments inside. Our solution is
to split at the dots using [Longident.parse], then check that every piece
is a valid module name. *)
let is_valid_mod_longident (m : string) : bool =
String.length m > 0 &&
let ms = Longident.flatten (Longident.parse m) in
List.for_all (fun m -> classify m = UIDENT) ms
(* -------------------------------------------------------------------------- *)
(* Testing if a string is a valid [class_longident], i.e., a possibly-qualified
class identifier. *)
let is_valid_class_longident (m : string) : bool =
String.length m > 0 &&
match Longident.parse m with
| Lident c ->
classify c = LIDENT
| Ldot (m, c) ->
List.for_all (fun m -> classify m = UIDENT) (Longident.flatten m) &&
classify c = LIDENT
| Lapply _ ->
assert false (* this cannot happen *)
(* -------------------------------------------------------------------------- *)
(* Testing for the presence of attributes. *)
(* We use [ppx_deriving] to extract a specific attribute from an attribute
......@@ -144,75 +213,6 @@ let is_local (decls : type_declaration list) (tycon : Longident.t)
(* -------------------------------------------------------------------------- *)
(* Testing whether an identifier is valid. *)
(* We use OCaml's lexer to analyze the string and check if it is a valid
identifier. This method is slightly unorthodox, as the lexer can have
undesired side effects, such as raising an [Error] exception or printing
warnings. We do our best to hide these effects. The strength of this
approach is to give us (at little cost) a correct criterion for deciding if
an identifier is valid. *)
type classification =
| LIDENT
| UIDENT
| OTHER
let classify (s : string) : classification =
let lexbuf = Lexing.from_string s in
let backup = !Location.formatter_for_warnings in
let null = Format.formatter_of_buffer (Buffer.create 0) in
Location.formatter_for_warnings := null;
let result = try
let token1 = Lexer.token lexbuf in
let token2 = Lexer.token lexbuf in
match token1, token2 with
| Parser.LIDENT _, Parser.EOF ->
LIDENT
| Parser.UIDENT _, Parser.EOF ->
UIDENT
| _, _ ->
OTHER
with Lexer.Error _ ->
OTHER
in
Location.formatter_for_warnings := backup;
result
(* -------------------------------------------------------------------------- *)
(* Testing if a string is a valid [mod_longident], i.e., a possibly-qualified
module identifier. *)
(* We might wish to use OCaml's parser for this purpose, but [mod_longident] is
not declared as a start symbol. Furthermore, that would be perhaps slightly
too lenient, e.g., allowing whitespace and comments inside. Our solution is
to split at the dots using [Longident.parse], then check that every piece
is a valid module name. *)
let is_valid_mod_longident (m : string) : bool =
String.length m > 0 &&
let ms = Longident.flatten (Longident.parse m) in
List.for_all (fun m -> classify m = UIDENT) ms
(* -------------------------------------------------------------------------- *)
(* Testing if a string is a valid [class_longident], i.e., a possibly-qualified
class identifier. *)
let is_valid_class_longident (m : string) : bool =
String.length m > 0 &&
match Longident.parse m with
| Lident c ->
classify c = LIDENT
| Ldot (m, c) ->
List.for_all (fun m -> classify m = UIDENT) (Longident.flatten m) &&
classify c = LIDENT
| Lapply _ ->
assert false (* this cannot happen *)
(* -------------------------------------------------------------------------- *)
(* [occurs_type alpha ty] tests whether the type variable [alpha] occurs in
the type [ty]. This function goes down into all OCaml types, even those
that are not supported by [visitors]. *)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment