@@ -107,9 +107,8 @@ module Regexp = struct
107
107
| Pipe_all (_ , _ , e ) -> recurse e
108
108
| Call lid ->
109
109
(* Use the Call node's own location, not the parent's location *)
110
- let call_loc = lid.loc in
111
- let ld = { txt = lid.txt; loc = call_loc } in
112
- if in_let then pexp_ident ~loc: call_loc ld else [% expr Re. group [% e pexp_ident ~loc: call_loc ld]]
110
+ let ld = { txt = lid.txt; loc = lid.loc } in
111
+ if in_let then pexp_ident ~loc: lid.loc ld else [% expr Re. group [% e pexp_ident ~loc: lid.loc ld]]
113
112
in
114
113
function { Location. txt = Capture_as (_ , _ , e ); _ } -> recurse e | e -> recurse e
115
114
@@ -143,51 +142,6 @@ module Regexp = struct
143
142
| Pipe_all (r , f , e' ) -> { e with txt = Pipe_all (r, f, squash_codes e') }
144
143
| Call _ -> e
145
144
146
- let relocate ~pos e =
147
- let open Location in
148
- let adjust_loc loc =
149
- if loc = Location. none then loc
150
- else
151
- {
152
- loc with
153
- loc_start =
154
- {
155
- pos_fname = pos.pos_fname;
156
- pos_lnum = pos.pos_lnum + loc.loc_start.pos_lnum - 1 ;
157
- (* -1 because parser starts at line 1 *)
158
- pos_cnum = pos.pos_cnum + loc.loc_start.pos_cnum;
159
- pos_bol = pos.pos_bol;
160
- };
161
- loc_end =
162
- {
163
- pos_fname = pos.pos_fname;
164
- pos_lnum = pos.pos_lnum + loc.loc_end.pos_lnum - 1 ;
165
- pos_cnum = pos.pos_cnum + loc.loc_end.pos_cnum;
166
- pos_bol = pos.pos_bol;
167
- };
168
- }
169
- in
170
-
171
- let rec recurse (node : _ Location.loc ) =
172
- let new_loc = adjust_loc node.loc in
173
- let new_txt =
174
- match node.txt with
175
- | Code s -> Code s
176
- | Seq es -> Seq (List. map recurse es)
177
- | Alt es -> Alt (List. map recurse es)
178
- | Opt e -> Opt (recurse e)
179
- | Repeat (range , e ) -> Repeat ({ range with loc = adjust_loc range.loc }, recurse e)
180
- | Nongreedy e -> Nongreedy (recurse e)
181
- | Caseless e -> Caseless (recurse e)
182
- | Capture e -> Capture (recurse e)
183
- | Capture_as (name , conv , e ) -> Capture_as ({ name with loc = adjust_loc name.loc }, conv, recurse e)
184
- | Pipe_all (name , func , e ) -> Pipe_all ({ name with loc = adjust_loc name.loc }, func, recurse e)
185
- | Call lid -> Call { lid with loc = adjust_loc lid.loc }
186
- in
187
- { txt = new_txt; loc = new_loc }
188
- in
189
- recurse e
190
-
191
145
let check_alternation_captures ~loc pattern =
192
146
let rec get_alt_captures = function
193
147
| { Location. txt = Regexp_types. Alt branches ; _ } -> Some (List. map get_branch_captures branches)
@@ -236,11 +190,23 @@ module Regexp = struct
236
190
end
237
191
238
192
module Parser = struct
193
+ let calculate_pattern_pos ~loc ~pattern_str =
194
+ let open Lexing in
195
+ match loc with
196
+ | { Location. loc_start; loc_end; _ } ->
197
+ let total_len = loc_end.pos_cnum - loc_start.pos_cnum in
198
+ let pattern_len = String. length pattern_str in
199
+
200
+ let delimiter_overhead = total_len - pattern_len in
201
+ let start_delimiter_size = delimiter_overhead / 2 in
202
+
203
+ { loc_start with pos_cnum = loc_start.pos_cnum + start_delimiter_size }
204
+
239
205
let get_parser ~mode ~target ~pos = match mode with `Pcre -> Regexp. parse_exn ~target ~pos | `Mik -> Regexp. parse_mik_exn ~target ~pos
240
206
241
- let run ~parser ~target ~pos s =
207
+ let run ~parser ~target ~pos : _ s =
242
208
let r, flags = parser s in
243
- let r = Regexp. (relocate ~pos @@ squash_codes r) in
209
+ let r = Regexp. squash_codes r in
244
210
let nG, bs = Regexp. bindings r in
245
211
let re = Regexp. to_re_expr ~in_let: (target = `Let ) r in
246
212
r, re, bs, nG, flags
@@ -311,11 +277,11 @@ let build_exec_match ~loc ~re_var ~continue_next ~on_match =
311
277
312
278
(* Transformations *)
313
279
314
- let transform_let ~mode vb =
280
+ let transform_let ~loc ~ mode vb =
315
281
let parser = Parser. get_parser ~mode ~target: `Let in
316
282
match vb.pvb_pat.ppat_desc, vb.pvb_expr.pexp_desc with
317
283
| Ppat_var { txt = _ ; _ } , Pexp_constant (Pconst_string (value , _ , _ )) ->
318
- let pos = vb.pvb_loc .loc_start in
284
+ let pos = loc. Location . loc_start in
319
285
let parsed, _flags = parser ~pos value in
320
286
let parsed = Regexp. squash_codes parsed in
321
287
let re_expr = Regexp. to_re_expr ~in_let: true parsed in
@@ -325,7 +291,7 @@ let transform_let ~mode vb =
325
291
326
292
let transform_destructuring_let ~mode ~loc pattern_str expr =
327
293
let target = `Match in
328
- let pos = loc.loc_start in
294
+ let pos = Parser. calculate_pattern_pos ~loc ~pattern_str in
329
295
let parser = Parser. get_parser ~mode ~target ~pos in
330
296
let r, re, bs, _, flags = Parser. run ~parser ~target ~pos pattern_str in
331
297
let capture_names = List. map (fun (name , _ , _ , _ ) -> name) (List. rev bs) in
@@ -389,9 +355,8 @@ let transform_cases ~mode ~loc cases =
389
355
in
390
356
391
357
let parse_pattern ~mode case =
392
- Ast_pattern. (parse (pstring __')) case.pc_lhs.ppat_loc case.pc_lhs (fun { txt = re_src ; loc = { loc_start; loc_end; _ } } ->
393
- let re_offset = (loc_end.pos_cnum - loc_start.pos_cnum - String. length re_src) / 2 in
394
- let pos = { loc_start with pos_cnum = loc_start.pos_cnum + re_offset } in
358
+ Ast_pattern. (parse (pstring __')) case.pc_lhs.ppat_loc case.pc_lhs (fun { txt = re_src ; loc } ->
359
+ let pos = Parser. calculate_pattern_pos ~loc ~pattern_str: re_src in
395
360
let parser = Parser. get_parser ~mode ~target ~pos in
396
361
let _, re, bs, nG, flags = Parser. run ~parser ~target ~pos re_src in
397
362
let re_str = Pprintast. string_of_expression re in
@@ -600,7 +565,7 @@ let transform_mixed_match ~loc ?matched_expr cases acc =
600
565
end
601
566
602
567
let transform_type ~mode ~loc rec_flag type_name pattern_str _td =
603
- let pos = loc. Location. loc_start in
568
+ let pos = Parser. calculate_pattern_pos ~loc ~pattern_str in
604
569
let parser = Parser. get_parser ~mode ~target: `Let ~pos in
605
570
let r, re, bs, _nG, flags = Parser. run ~parser ~target: `Let ~pos pattern_str in
606
571
0 commit comments