Skip to content

Commit ddaf752

Browse files
authored
flambda-backend: Set location on topmost Jane Syntax attribute (#1696)
* Demonstrate _none_ Location * Fix bug and demonstrate via tests
1 parent 5205836 commit ddaf752

File tree

3 files changed

+131
-2
lines changed

3 files changed

+131
-2
lines changed

parsing/jane_syntax_parsing.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -800,8 +800,8 @@ module Make_ast (AST : AST_internal) : AST with type ast = AST.ast = struct
800800

801801
let make_entire_jane_syntax ~loc feature ast =
802802
AST.with_location
803-
(make_jane_syntax feature []
804-
(Ast_helper.with_default_loc { loc with loc_ghost = true } ast))
803+
(Ast_helper.with_default_loc { loc with loc_ghost = true } (fun () ->
804+
make_jane_syntax feature [] (ast ())))
805805
loc
806806

807807
(** Generically lift our custom ASTs for our novel syntax from OCaml ASTs. *)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
(* TEST
2+
include ocamlcommon *)
3+
4+
let () = Language_extension.enable Comprehensions ();;
5+
6+
module Location_map = struct
7+
include Map.Make (struct
8+
type t = Location.t
9+
let compare = compare
10+
end)
11+
12+
let add_multi key data t =
13+
update key (function
14+
| None -> Some [data]
15+
| Some x -> Some (data :: x))
16+
t
17+
end
18+
19+
let gather_attributes_by_location program_text =
20+
let program_text_buf = Lexing.from_string program_text in
21+
Lexing.set_filename program_text_buf "<no filename in test>";
22+
let parsed = Parse.expression program_text_buf in
23+
let attrs_by_location = ref Location_map.empty in
24+
let record_attribute { Parsetree.attr_name; attr_loc } =
25+
attrs_by_location :=
26+
Location_map.add_multi attr_loc attr_name.txt !attrs_by_location
27+
in
28+
(* We can't use an [attribute] iterator because Jane Syntax attributes are
29+
skipped by the default iterator. To undo this behavior, we instead override
30+
the expression iterator to look at attributes literally.
31+
*)
32+
let expr iterator (x : Parsetree.expression) =
33+
List.iter record_attribute x.pexp_attributes;
34+
Ast_iterator.default_iterator.expr iterator { x with pexp_attributes = [] }
35+
in
36+
let iterator = { Ast_iterator.default_iterator with expr } in
37+
iterator.expr iterator parsed;
38+
!attrs_by_location
39+
;;
40+
41+
let run_test program_text ~summary =
42+
print_endline "---";
43+
Printf.printf "Test: %s\n" summary;
44+
print_endline "Program text:";
45+
print_endline program_text;
46+
print_endline "Attributes and their locations:";
47+
let attributes_by_location = gather_attributes_by_location program_text in
48+
Location_map.iter
49+
(fun loc at_loc ->
50+
let printf fmt = Format.fprintf Format.std_formatter fmt in
51+
printf "\tAt location %a:\n" Location.print_loc loc;
52+
List.iter (printf "\t\t%s\n") at_loc)
53+
attributes_by_location
54+
;;
55+
56+
let () =
57+
run_test ~summary:"single Jane Syntax construct"
58+
"[ x for x in [ 1; 2; 3 ]]"
59+
;;
60+
61+
let () =
62+
run_test ~summary:"multiple Jane Syntax constructs"
63+
"let x1 = [ x for x in [ 1; 2; 3 ]] in\n\
64+
let x2 = [ y for y = 1 to 100 ] in\n\
65+
let x3 = [ y for y = 1 to 100 ] in\n\
66+
let x4 = [ y for y = 100 downto 1 ] in\n\
67+
let x6 = [| y for y = 100 downto 1 |] in\n\
68+
let x7 = [ y for y = 1 to 100 when y = 50 ] in\n\
69+
()"
70+
;;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
Test: single Jane Syntax construct
3+
Program text:
4+
[ x for x in [ 1; 2; 3 ]]
5+
Attributes and their locations:
6+
At location File "<no filename in test>", line 1, characters 0-25:
7+
jane.non_erasable.comprehensions.body
8+
jane.non_erasable.comprehensions.for.in
9+
jane.non_erasable.comprehensions.for
10+
jane.non_erasable.comprehensions.list
11+
jane.non_erasable.comprehensions
12+
---
13+
Test: multiple Jane Syntax constructs
14+
Program text:
15+
let x1 = [ x for x in [ 1; 2; 3 ]] in
16+
let x2 = [ y for y = 1 to 100 ] in
17+
let x3 = [ y for y = 1 to 100 ] in
18+
let x4 = [ y for y = 100 downto 1 ] in
19+
let x6 = [| y for y = 100 downto 1 |] in
20+
let x7 = [ y for y = 1 to 100 when y = 50 ] in
21+
()
22+
Attributes and their locations:
23+
At location File "<no filename in test>", line 1, characters 9-34:
24+
jane.non_erasable.comprehensions.body
25+
jane.non_erasable.comprehensions.for.in
26+
jane.non_erasable.comprehensions.for
27+
jane.non_erasable.comprehensions.list
28+
jane.non_erasable.comprehensions
29+
At location File "<no filename in test>", line 2, characters 9-31:
30+
jane.non_erasable.comprehensions.body
31+
jane.non_erasable.comprehensions.for.range.upto
32+
jane.non_erasable.comprehensions.for
33+
jane.non_erasable.comprehensions.list
34+
jane.non_erasable.comprehensions
35+
At location File "<no filename in test>", line 3, characters 9-31:
36+
jane.non_erasable.comprehensions.body
37+
jane.non_erasable.comprehensions.for.range.upto
38+
jane.non_erasable.comprehensions.for
39+
jane.non_erasable.comprehensions.list
40+
jane.non_erasable.comprehensions
41+
At location File "<no filename in test>", line 4, characters 9-35:
42+
jane.non_erasable.comprehensions.body
43+
jane.non_erasable.comprehensions.for.range.downto
44+
jane.non_erasable.comprehensions.for
45+
jane.non_erasable.comprehensions.list
46+
jane.non_erasable.comprehensions
47+
At location File "<no filename in test>", line 5, characters 9-37:
48+
jane.non_erasable.comprehensions.body
49+
jane.non_erasable.comprehensions.for.range.downto
50+
jane.non_erasable.comprehensions.for
51+
jane.non_erasable.comprehensions.array.mutable
52+
jane.non_erasable.comprehensions
53+
At location File "<no filename in test>", line 6, characters 9-43:
54+
jane.non_erasable.comprehensions.body
55+
jane.non_erasable.comprehensions.when
56+
jane.non_erasable.comprehensions.for.range.upto
57+
jane.non_erasable.comprehensions.for
58+
jane.non_erasable.comprehensions.list
59+
jane.non_erasable.comprehensions

0 commit comments

Comments
 (0)