Skip to content

Commit 9dbce34

Browse files
authored
Stricter AST checks (#2557)
* Normalize docstrings using the extended AST This use the extended AST normalization for docstrings within the std AST. This ensures that repl phrases are handled correctly and removes some code. * Stricter AST checks The AST check was previously trigerring if both the std AST and the extended AST were different. The std AST is intended to be the most trustworthy and is intended to catch changes in the code that the extended AST couldn't.
1 parent ca77ba9 commit 9dbce34

File tree

4 files changed

+16
-53
lines changed

4 files changed

+16
-53
lines changed

lib/Normalize_extended_ast.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ let normalize_cmt (conf : Conf.t) =
174174
normalize_code ~normalize_cmt conf mapper c
175175
end
176176

177+
let normalize_code (conf : Conf.t) code =
178+
let n = normalize_cmt conf in
179+
n#code code
180+
177181
let ast fragment ~ignore_doc_comments c =
178182
let normalize_cmt = normalize_cmt c in
179183
map fragment

lib/Normalize_extended_ast.mli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,6 @@ val equal : 'a t -> ignore_doc_comments:bool -> Conf.t -> 'a -> 'a -> bool
2020
val diff_cmts :
2121
Conf.t -> Cmt.t list -> Cmt.t list -> (unit, Cmt.error list) Result.t
2222
(** Difference between two lists of comments. *)
23+
24+
val normalize_code : Conf.t -> string -> string
25+
(** Normalize a code block in docstrings. *)

lib/Normalize_std_ast.ml

Lines changed: 6 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -18,49 +18,10 @@ let is_doc = function
1818
| {attr_name= {Location.txt= "ocaml.doc" | "ocaml.text"; _}; _} -> true
1919
| _ -> false
2020

21-
let dedup_cmts fragment ast comments =
22-
let of_ast ast =
23-
let docs = ref (Set.empty (module Cmt)) in
24-
let attribute m atr =
25-
match atr with
26-
| { attr_payload=
27-
PStr
28-
[ { pstr_desc=
29-
Pstr_eval
30-
( { pexp_desc=
31-
Pexp_constant (Pconst_string (doc, _, None))
32-
; pexp_loc
33-
; _ }
34-
, [] )
35-
; _ } ]
36-
; _ }
37-
when is_doc atr ->
38-
docs := Set.add !docs (Cmt.create_docstring doc pexp_loc) ;
39-
atr
40-
| _ -> Ast_mapper.default_mapper.attribute m atr
41-
in
42-
map fragment {Ast_mapper.default_mapper with attribute} ast |> ignore ;
43-
!docs
44-
in
45-
Set.(to_list (diff (of_list (module Cmt) comments) (of_ast ast)))
46-
47-
let normalize_code conf (m : Ast_mapper.mapper) txt =
48-
let input_name = "<output>" in
49-
match
50-
Parse_with_comments.parse Parse.ast Structure conf ~input_name
51-
~source:txt
52-
with
53-
| {ast; comments; _} ->
54-
let comments = dedup_cmts Structure ast comments in
55-
let print_comments fmt (l : Cmt.t list) =
56-
List.sort l ~compare:(fun a b ->
57-
Migrate_ast.Location.compare (Cmt.loc a) (Cmt.loc b) )
58-
|> List.iter ~f:(fun cmt -> Format.fprintf fmt "%s," (Cmt.txt cmt))
59-
in
60-
let ast = m.structure m ast in
61-
Format.asprintf "AST,%a,COMMENTS,[%a]" Printast.implementation ast
62-
print_comments comments
63-
| exception _ -> txt
21+
let normalize_code conf txt =
22+
(* Normalize code blocks in docstrings using the extended AST. This
23+
correctly handles repl phrases. *)
24+
Normalize_extended_ast.normalize_code conf txt
6425

6526
let docstring (c : Conf.t) =
6627
Docstring.normalize ~parse_docstrings:c.fmt_opts.parse_docstrings.v
@@ -83,7 +44,7 @@ let make_mapper conf ~ignore_doc_comments =
8344
, [] )
8445
; _ } as pstr ) ]
8546
when is_doc attr ->
86-
let normalize_code = normalize_code conf m in
47+
let normalize_code = normalize_code conf in
8748
let doc' = docstring conf ~normalize_code doc in
8849
Ast_mapper.default_mapper.attribute m
8950
{ attr with
@@ -239,8 +200,7 @@ let docstrings (type a) (fragment : a t) s =
239200
!docstrings
240201

241202
let docstring conf =
242-
let mapper = make_mapper conf ~ignore_doc_comments:false in
243-
let normalize_code = normalize_code conf mapper in
203+
let normalize_code = normalize_code conf in
244204
docstring conf ~normalize_code
245205

246206
let moved_docstrings fragment c s1 s2 =

lib/Translation_unit.ml

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -322,13 +322,9 @@ let format (type ext std) (ext_fg : ext Extended_ast.t)
322322
in
323323
(* Ast not preserved ? *)
324324
( if
325-
(not
326-
(Normalize_std_ast.equal std_fg conf std_t.ast std_t_new.ast
327-
~ignore_doc_comments:(not conf.opr_opts.comment_check.v) ) )
328-
&& not
329-
(Normalize_extended_ast.equal ext_fg conf ext_t.ast
330-
ext_t_new.ast
331-
~ignore_doc_comments:(not conf.opr_opts.comment_check.v) )
325+
not
326+
(Normalize_std_ast.equal std_fg conf std_t.ast std_t_new.ast
327+
~ignore_doc_comments:(not conf.opr_opts.comment_check.v) )
332328
then
333329
let old_ast =
334330
dump_ast std_fg ~suffix:".old"

0 commit comments

Comments
 (0)