|
| 1 | +open Std |
| 2 | + |
| 3 | +let qual_or_unqual_path mode leftmost_ident path p = |
| 4 | + let rec aux acc (p : Path.t) = |
| 5 | + match p with |
| 6 | + | Pident ident -> |
| 7 | + Ident.name ident :: acc |
| 8 | + | Pdot (path', s) when |
| 9 | + mode = `Unqualify && Path.same path path' -> |
| 10 | + s :: acc |
| 11 | + | Pdot (path', s) when |
| 12 | + mode = `Qualify && s = leftmost_ident -> |
| 13 | + s :: acc |
| 14 | + | Pdot (path', s) -> |
| 15 | + aux (s :: acc) path' |
| 16 | + | _ -> raise Not_found |
| 17 | + in |
| 18 | + aux [] p |> String.concat ~sep:"." |
| 19 | + |
| 20 | +(* checks if the (un)qualified longident has a different length, i.e., has changed |
| 21 | +
|
| 22 | + XXX(Ulugbek): computes longident length using [loc_start] and [loc_end], hence |
| 23 | + it doesn't work for multiline longidents because we can't compute their length *) |
| 24 | +let same_longident new_lident { Location. loc_start; loc_end; _ } = |
| 25 | + let old_longident_len = Lexing.column loc_end - Lexing.column loc_start in |
| 26 | + loc_start.Lexing.pos_lnum = loc_end.Lexing.pos_lnum && |
| 27 | + String.length new_lident = old_longident_len |
| 28 | + |
| 29 | + |
| 30 | +let get_rewrites ~mode typer pos = |
| 31 | + match Mbrowse.select_open_node (Mtyper.node_at typer pos) with |
| 32 | + | None | Some (_, _, []) -> [] |
| 33 | + | Some (orig_path, longident, ((_, node) :: _)) -> |
| 34 | + let paths = |
| 35 | + Browse_tree.all_occurrences_of_prefix ~strict_prefix:true orig_path node |
| 36 | + in |
| 37 | + let paths = List.concat_map ~f:snd paths in |
| 38 | + let leftmost_ident = Longident.flatten longident |> List.hd in |
| 39 | + List.filter_map paths ~f:(fun {Location. txt = path; loc} -> |
| 40 | + if loc.Location.loc_ghost || Location_aux.compare_pos pos loc > 0 then |
| 41 | + None |
| 42 | + else |
| 43 | + match qual_or_unqual_path mode leftmost_ident orig_path path with |
| 44 | + | s when same_longident s loc -> None |
| 45 | + | s -> Some (s, loc) |
| 46 | + | exception Not_found -> None |
| 47 | + ) |
| 48 | + |> List.sort_uniq ~cmp:(fun (_,l1) (_,l2) -> Location_aux.compare l1 l2) |
0 commit comments