Skip to content
← Back

src/source/location_correspondence.ghul

1
namespace Source is
2
use Collections;
3
4
// The exact pre-edit -> post-edit location correspondence for one
5
// file's retained interface nodes, produced by an incremental EDIT's
6
// lockstep reconciliation walk (Syntax.Process.LOCATION_TRANSFER).
7
//
8
// Unlike a coordinate-delta model it carries the donor parse's actual
9
// locations, so it is correct however the interface around an edited
10
// body was reformatted — re-indented, blank lines or comments added or
11
// removed, a signature re-wrapped across a different number of lines.
12
//
13
// Keyed on the pre-edit location's packed (start, end) pair: a use /
14
// definition entry recorded at exactly a reconciled node's location
15
// translates; anything else (a body interior, re-recorded fresh by the
16
// re-walk) does not.
17
class LOCATION_CORRESPONDENCE is
18
_by_start: MAP[int, MAP[int, LOCATION]];
19
20
init() is
21
_by_start = MAP[int, MAP[int, LOCATION]]();
22
si
23
24
add(old_location: LOCATION, new_location: LOCATION) is
25
let by_end: MAP[int, LOCATION] mut;
26
27
if _by_start.contains_key(old_location.start) then
28
by_end = _by_start[old_location.start];
29
else
30
by_end = MAP[int, LOCATION]();
31
_by_start[old_location.start] = by_end;
32
fi
33
34
by_end[old_location.end] = new_location;
35
si
36
37
// The post-edit location for a retained interface entry, or null
38
// when `old_location` is not a reconciled interface node — the
39
// caller then treats it as a body / non-interface entry.
40
translate(old_location: LOCATION) -> LOCATION? is
41
let by_end: MAP[int, LOCATION] mut;
42
43
if !_by_start.try_get_value(old_location.start, by_end ref) then
44
return null;
45
fi
46
47
let result: LOCATION mut;
48
49
if by_end.try_get_value(old_location.end, result ref) then
50
return result;
51
fi
52
53
return null;
54
si
55
si
56
si