Skip to content

Commit 6199fd9

Browse files
authored
Attach location to constants (ocaml-ppx#1749)
1 parent 3bafa21 commit 6199fd9

22 files changed

+450
-198
lines changed

lib/Ast.ml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ module Exp = struct
278278

279279
let rec is_trivial c exp =
280280
match exp.pexp_desc with
281-
| Pexp_constant (Pconst_string (_, _, None)) -> true
281+
| Pexp_constant {pconst_desc= Pconst_string (_, _, None); _} -> true
282282
| Pexp_constant _ | Pexp_field _ | Pexp_ident _ | Pexp_send _ -> true
283283
| Pexp_construct (_, exp) -> Option.for_all exp ~f:(is_trivial c)
284284
| Pexp_apply (e0, [(_, e1)]) when is_prefix e0 -> is_trivial c e1
@@ -345,7 +345,8 @@ let doc_atrs ?(acc = []) atrs =
345345
[ { pstr_desc=
346346
Pstr_eval
347347
( { pexp_desc=
348-
Pexp_constant (Pconst_string (doc, _, None))
348+
Pexp_constant
349+
{pconst_desc= Pconst_string (doc, _, None); _}
349350
; pexp_loc= loc
350351
; pexp_attributes= []
351352
; _ }
@@ -1735,7 +1736,8 @@ end = struct
17351736
({txt= Lident "::"; _}, Some {pexp_desc= Pexp_tuple _; _}) ->
17361737
Some ColonColon
17371738
| Pexp_construct (_, Some _) -> Some Apply
1738-
| Pexp_constant (Pconst_integer (i, _) | Pconst_float (i, _)) -> (
1739+
| Pexp_constant
1740+
{pconst_desc= Pconst_integer (i, _) | Pconst_float (i, _); _} -> (
17391741
match i.[0] with '-' | '+' -> Some UMinus | _ -> Some Atomic )
17401742
| Pexp_apply ({pexp_desc= Pexp_ident {txt= Lident i; loc; _}; _}, [_])
17411743
-> (
@@ -2276,7 +2278,8 @@ end = struct
22762278
(* Integers without suffixes must be parenthesised on the lhs of an
22772279
indexing operator *)
22782280
| ( Exp {pexp_desc= Pexp_apply (op, (Nolabel, left) :: _); _}
2279-
, {pexp_desc= Pexp_constant (Pconst_integer (_, None)); _} )
2281+
, { pexp_desc= Pexp_constant {pconst_desc= Pconst_integer (_, None); _}
2282+
; _ } )
22802283
when exp == left && Exp.is_index_op op ->
22812284
true
22822285
| Exp {pexp_desc= Pexp_field (e, _); _}, {pexp_desc= Pexp_construct _; _}

lib/Cmts.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ let relocate_ext_cmts (t : t) src ((_pre : string Location.loc), pld)
304304
| PStr
305305
[ { pstr_desc=
306306
Pstr_eval
307-
( { pexp_desc= Pexp_constant (Pconst_string _)
307+
( { pexp_desc= Pexp_constant {pconst_desc= Pconst_string _; _}
308308
; pexp_loc= _
309309
; pexp_loc_stack= _
310310
; pexp_attributes= _ }
@@ -349,7 +349,7 @@ let init fragment ~debug source asts comments_n_docstrings =
349349
in
350350
let comments = Normalize.dedup_cmts fragment asts comments_n_docstrings in
351351
if not (List.is_empty comments) then (
352-
let loc_tree, locs = Loc_tree.of_ast fragment asts source in
352+
let loc_tree, locs = Loc_tree.of_ast fragment asts in
353353
if debug then
354354
List.iter locs ~f:(fun loc ->
355355
if not (Location.compare loc Location.none = 0) then

lib/Conf.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2249,7 +2249,9 @@ let update ?(quiet = false) c {attr_name= {txt; loc}; attr_payload; _} =
22492249
| PStr
22502250
[ { pstr_desc=
22512251
Pstr_eval
2252-
( { pexp_desc= Pexp_constant (Pconst_string (str, _, None))
2252+
( { pexp_desc=
2253+
Pexp_constant
2254+
{pconst_desc= Pconst_string (str, _, None); _}
22532255
; pexp_attributes= []
22542256
; _ }
22552257
, [] )

lib/Fmt_ast.ml

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,10 @@ let fmt_str_loc c ?pre {txt; loc} = Cmts.fmt c loc (fmt_opt pre $ str txt)
239239
let fmt_str_loc_opt c ?pre ?(default = "_") {txt; loc} =
240240
Cmts.fmt c loc (fmt_opt pre $ str (Option.value ~default txt))
241241

242-
let fmt_constant c ~loc ?epi const =
242+
let fmt_constant c ?epi {pconst_desc; pconst_loc= loc} =
243243
Cmts.fmt c loc
244244
@@
245-
match const with
245+
match pconst_desc with
246246
| Pconst_integer (lit, suf) | Pconst_float (lit, suf) ->
247247
str lit $ opt suf char
248248
| Pconst_char _ -> wrap "'" "'" @@ str (Source.char_literal c.source loc)
@@ -502,7 +502,9 @@ let rec fmt_extension c ctx key (ext, pld) =
502502
, PStr
503503
[ { pstr_desc=
504504
Pstr_eval
505-
( { pexp_desc= Pexp_constant (Pconst_string (str, loc, delim))
505+
( { pexp_desc=
506+
Pexp_constant
507+
{pconst_desc= Pconst_string (str, loc, delim); _}
506508
; pexp_loc
507509
; pexp_loc_stack= _
508510
; pexp_attributes= [] }
@@ -543,7 +545,9 @@ and fmt_attribute c ~key {attr_name; attr_payload; attr_loc} =
543545
, PStr
544546
[ { pstr_desc=
545547
Pstr_eval
546-
( { pexp_desc= Pexp_constant (Pconst_string (doc, _, None))
548+
( { pexp_desc=
549+
Pexp_constant
550+
{pconst_desc= Pconst_string (doc, _, None); _}
547551
; pexp_attributes= []
548552
; _ }
549553
, [] )
@@ -952,11 +956,8 @@ and fmt_pattern ?ext c ?pro ?parens ?(box = false)
952956
$ fmt "@ as@ "
953957
$ Cmts.fmt c loc
954958
(wrap_if (String_id.is_symbol txt) "( " " )" (str txt)) ) )
955-
| Ppat_constant const ->
956-
fmt_constant c ~loc:(Source.loc_of_pat_constant c.source pat) const
957-
| Ppat_interval (l, u) ->
958-
let loc1, loc2 = Source.locs_of_interval c.source ppat_loc in
959-
fmt_constant ~loc:loc1 c l $ str " .. " $ fmt_constant ~loc:loc2 c u
959+
| Ppat_constant const -> fmt_constant c const
960+
| Ppat_interval (l, u) -> fmt_constant c l $ str " .. " $ fmt_constant c u
960961
| Ppat_tuple pats ->
961962
let parens = parens || Poly.(c.conf.parens_tuple_patterns = `Always) in
962963
hvbox 0
@@ -1069,7 +1070,9 @@ and fmt_pattern ?ext c ?pro ?parens ?(box = false)
10691070
let xpats = Sugar.or_pat c.cmts xpat in
10701071
let space p =
10711072
match p.ppat_desc with
1072-
| Ppat_constant (Pconst_integer (i, _) | Pconst_float (i, _)) -> (
1073+
| Ppat_constant
1074+
{pconst_desc= Pconst_integer (i, _) | Pconst_float (i, _); _}
1075+
-> (
10731076
match i.[0] with '-' | '+' -> true | _ -> false )
10741077
| _ -> false
10751078
in
@@ -1966,11 +1969,10 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0)
19661969
$ fmt_if_k paren_body (closing_paren c)
19671970
$ fmt_atrs ) ) )
19681971
| Pexp_constant const ->
1969-
let loc = Source.loc_of_expr_constant c.source exp in
19701972
Params.parens_if
19711973
(parens || not (List.is_empty pexp_attributes))
19721974
c.conf
1973-
(fmt_constant c ~loc ?epi const $ fmt_atrs)
1975+
(fmt_constant c ?epi const $ fmt_atrs)
19741976
| Pexp_constraint
19751977
( {pexp_desc= Pexp_pack me; pexp_attributes= []; pexp_loc; _}
19761978
, {ptyp_desc= Ptyp_package (id, cnstrs); ptyp_attributes= []; _} ) ->

lib/Indent.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ module Valid_ast = struct
5252
| Unequal_lengths ->
5353
impossible "Cannot match pre-post formatting locations."
5454

55-
let indent_range fragment ~unformatted:(ast, src, txt_src)
55+
let indent_range fragment ~unformatted:(ast, txt_src)
5656
~formatted:(fmted_ast, fmted_src) ~lines ~range:(low, high) =
57-
let loctree, locs = Loc_tree.of_ast fragment ast src in
58-
let _, locs' = Loc_tree.of_ast fragment fmted_ast fmted_src in
57+
let loctree, locs = Loc_tree.of_ast fragment ast in
58+
let _, locs' = Loc_tree.of_ast fragment fmted_ast in
5959
let indent_line i =
6060
match loc_of_line loctree locs i with
6161
| Some loc -> (

lib/Indent.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
module Valid_ast : sig
1313
val indent_range :
1414
'a Extended_ast.t
15-
-> unformatted:'a * Source.t * string
15+
-> unformatted:'a * string
1616
-> formatted:'a * Source.t
1717
-> lines:string list
1818
-> range:int * int

lib/Loc_tree.ml

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ open Extended_ast
1414
include Non_overlapping_interval_tree.Make (Location)
1515

1616
(** Use Ast_mapper to collect all locs in ast, and create tree of them. *)
17-
let of_ast fragment ast src =
17+
let of_ast fragment ast =
1818
let attribute (m : Ast_mapper.mapper) attr =
1919
(* ignore location of docstrings *)
2020
if Ast.Attr.is_doc attr then attr
@@ -25,20 +25,6 @@ let of_ast fragment ast src =
2525
locs := loc :: !locs ;
2626
loc
2727
in
28-
let pat m p =
29-
( match p.ppat_desc with
30-
| Ppat_constant _ -> locs := Source.loc_of_pat_constant src p :: !locs
31-
| _ -> () ) ;
32-
Ast_mapper.default_mapper.pat m p
33-
in
34-
let expr m e =
35-
( match e.pexp_desc with
36-
| Pexp_constant _ -> locs := Source.loc_of_expr_constant src e :: !locs
37-
| _ -> () ) ;
38-
Ast_mapper.default_mapper.expr m e
39-
in
40-
let mapper =
41-
Ast_mapper.{default_mapper with location; pat; attribute; expr}
42-
in
28+
let mapper = Ast_mapper.{default_mapper with location; attribute} in
4329
map fragment mapper ast |> ignore ;
4430
(of_list !locs, !locs)

lib/Loc_tree.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@
1111

1212
include Non_overlapping_interval_tree.S with type itv = Location.t
1313

14-
val of_ast : 'a Extended_ast.t -> 'a -> Source.t -> t * Location.t list
14+
val of_ast : 'a Extended_ast.t -> 'a -> t * Location.t list
1515
(** Use Ast_mapper to collect all locs in ast, and create a tree of them. *)

lib/Normalize.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ let dedup_cmts fragment ast comments =
3131
[ { pstr_desc=
3232
Pstr_eval
3333
( { pexp_desc=
34-
Pexp_constant (Pconst_string (doc, _, None))
34+
Pexp_constant
35+
{pconst_desc= Pconst_string (doc, _, None); _}
3536
; pexp_loc
3637
; _ }
3738
, [] )

lib/Source.ml

Lines changed: 6 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -146,53 +146,13 @@ let is_long_pmty_functor t {pmty_desc; pmty_loc= from; _} =
146146
| Pmty_functor (fp, _) -> is_long_functor_syntax t ~from fp
147147
| _ -> false
148148

149-
let string_literal t mode (l : Location.t) =
150-
(* the location of a [string] might include surrounding comments and
151-
attributes because of [reloc_{exp,pat}] and a [string] can be found in
152-
attributes payloads. {[ f ((* comments *) "c" [@attributes]) ]} *)
153-
let toks =
154-
tokens_at t
155-
~filter:(function
156-
| Parser.STRING (_, _, None) -> true
157-
| Parser.LBRACKETAT | Parser.LBRACKETATAT | Parser.LBRACKETATATAT ->
158-
true
159-
| _ -> false )
160-
l
161-
in
162-
match toks with
163-
| [(Parser.STRING (_, _, None), loc)]
164-
|(Parser.STRING (_, _, None), loc)
165-
:: ( Parser.LBRACKETATATAT, _
166-
| Parser.LBRACKETATAT, _
167-
| Parser.LBRACKETAT, _ )
168-
:: _ ->
169-
Option.value_exn ~message:"Parse error while reading string literal"
170-
(Literal_lexer.string mode (string_at t loc))
171-
| _ -> impossible "Pconst_string is only produced by string literals"
149+
let string_literal t mode loc =
150+
Option.value_exn ~message:"Parse error while reading string literal"
151+
(Literal_lexer.string mode (string_at t loc))
172152

173-
let char_literal t (l : Location.t) =
174-
(* the location of a [char] might include surrounding comments and
175-
attributes because of [reloc_{exp,pat}] and a [char] can be found in
176-
attributes payloads. {[ f ((* comments *) 'c' [@attributes]) ]} *)
177-
let toks =
178-
tokens_at t
179-
~filter:(function
180-
| Parser.CHAR _ -> true
181-
| Parser.LBRACKETAT | Parser.LBRACKETATAT | Parser.LBRACKETATATAT ->
182-
true
183-
| _ -> false )
184-
l
185-
in
186-
match toks with
187-
| [(Parser.CHAR _, loc)]
188-
|(Parser.CHAR _, loc)
189-
:: ( Parser.LBRACKETATATAT, _
190-
| Parser.LBRACKETATAT, _
191-
| Parser.LBRACKETAT, _ )
192-
:: _ ->
193-
(Option.value_exn ~message:"Parse error while reading char literal")
194-
(Literal_lexer.char (string_at t loc))
195-
| _ -> impossible "Pconst_char is only produced by char literals"
153+
let char_literal t loc =
154+
Option.value_exn ~message:"Parse error while reading char literal"
155+
(Literal_lexer.char (string_at t loc))
196156

197157
let begins_line ?(ignore_spaces = true) t (l : Location.t) =
198158
if not ignore_spaces then Position.column l.loc_start = 0
@@ -227,44 +187,6 @@ let extension_using_sugar ~(name : string Location.loc)
227187
let type_constraint_is_first typ loc =
228188
Location.compare_start typ.ptyp_loc loc < 0
229189

230-
let locs_of_interval source loc =
231-
let toks =
232-
tokens_at source loc ~filter:(function
233-
| CHAR _ | DOTDOT | INT _ | STRING _ | FLOAT _ -> true
234-
| _ -> false )
235-
in
236-
match toks with
237-
| [ ((CHAR _ | INT _ | STRING _ | FLOAT _), loc1)
238-
; (DOTDOT, _)
239-
; ((CHAR _ | INT _ | STRING _ | FLOAT _), loc2) ] ->
240-
(loc1, loc2)
241-
| _ ->
242-
impossible
243-
"Ppat_interval is only produced by the sequence of 3 tokens: \
244-
CONSTANT-DOTDOT-CONSTANT "
245-
246-
let loc_of_constant t loc (cst : constant) =
247-
let filter : Parser.token -> bool =
248-
match cst with
249-
| Pconst_string _ -> ( function STRING _ -> true | _ -> false )
250-
| Pconst_char _ -> ( function CHAR _ -> true | _ -> false )
251-
| Pconst_integer _ -> ( function INT _ -> true | _ -> false )
252-
| Pconst_float _ -> ( function FLOAT _ -> true | _ -> false )
253-
in
254-
match tokens_at t loc ~filter with [(_, loc)] -> loc | _ -> loc
255-
256-
let loc_of_pat_constant t (p : pattern) =
257-
match p.ppat_desc with
258-
| Ppat_constant cst ->
259-
loc_of_constant t (Location.smallest p.ppat_loc p.ppat_loc_stack) cst
260-
| _ -> impossible "loc_of_pat_constant is only called on constants"
261-
262-
let loc_of_expr_constant t (e : expression) =
263-
match e.pexp_desc with
264-
| Pexp_constant cst ->
265-
loc_of_constant t (Location.smallest e.pexp_loc e.pexp_loc_stack) cst
266-
| _ -> impossible "loc_of_expr_constant is only called on constants"
267-
268190
let is_quoted_string t loc =
269191
let toks =
270192
tokens_at t loc ~filter:(function

0 commit comments

Comments
 (0)