Skip to content

Commit 9dcb674

Browse files
kevinagraydon
authored andcommitted
Add function to get a code snippet from a span,
and also to get the byte offset within a string from a span chpos.
1 parent e127bf6 commit 9dcb674

File tree

1 file changed

+40
-3
lines changed

1 file changed

+40
-3
lines changed

src/comp/syntax/codemap.rs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ fn next_line(file: filemap, chpos: uint, byte_pos: uint) {
3434

3535
type lookup_fn = fn@(file_pos) -> uint;
3636

37-
fn lookup_pos(map: codemap, pos: uint, lookup: lookup_fn) -> loc {
37+
fn lookup_line(map: codemap, pos: uint, lookup: lookup_fn)
38+
-> option::t<{fm: filemap, line: uint}>
39+
{
3840
let len = vec::len(map.files);
3941
let a = 0u;
4042
let b = len;
@@ -43,7 +45,7 @@ fn lookup_pos(map: codemap, pos: uint, lookup: lookup_fn) -> loc {
4345
if lookup(map.files[m].start_pos) > pos { b = m; } else { a = m; }
4446
}
4547
if (a >= len) {
46-
ret { filename: "-", line: 0u, col: 0u };
48+
ret none;
4749
}
4850
let f = map.files[a];
4951
a = 0u;
@@ -52,7 +54,18 @@ fn lookup_pos(map: codemap, pos: uint, lookup: lookup_fn) -> loc {
5254
let m = (a + b) / 2u;
5355
if lookup(f.lines[m]) > pos { b = m; } else { a = m; }
5456
}
55-
ret {filename: f.name, line: a + 1u, col: pos - lookup(f.lines[a])};
57+
ret some({fm: f, line: a});
58+
}
59+
60+
fn lookup_pos(map: codemap, pos: uint, lookup: lookup_fn) -> loc {
61+
alt lookup_line(map, pos, lookup) {
62+
some({fm: f, line: a}) {
63+
{filename: f.name, line: a + 1u, col: pos - lookup(f.lines[a])}
64+
}
65+
none {
66+
{ filename: "-", line: 0u, col: 0u }
67+
}
68+
}
5669
}
5770

5871
fn lookup_char_pos(map: codemap, pos: uint) -> loc {
@@ -125,6 +138,30 @@ fn get_line(fm: filemap, line: int) -> str unsafe {
125138
ret str::unsafe::slice_bytes(*fm.src, begin, end);
126139
}
127140

141+
fn lookup_byte_offset(cm: codemap::codemap, chpos: uint)
142+
-> {fm: filemap, pos: uint}
143+
{
144+
fn lookup(pos: file_pos) -> uint { ret pos.ch; }
145+
let {fm,line} = option::get(lookup_line(cm,chpos,lookup));
146+
let line_offset = fm.lines[line].byte;
147+
let col = chpos - fm.lines[line].ch;
148+
let col_offset = str::byte_len_range(*fm.src, line_offset, col);
149+
ret {fm: fm, pos: line_offset + col_offset};
150+
}
151+
152+
fn span_to_snippet(sp: span, cm: codemap::codemap) -> str {
153+
let begin = lookup_byte_offset(cm,sp.lo);
154+
let end = lookup_byte_offset(cm,sp.hi);
155+
assert begin.fm == end.fm;
156+
ret str::slice(*begin.fm.src, begin.pos, end.pos);
157+
}
158+
159+
fn get_snippet(cm: codemap::codemap, fidx: uint, lo: uint, hi: uint) -> str
160+
{
161+
let fm = cm.files[fidx];
162+
ret str::slice(*fm.src, lo, hi)
163+
}
164+
128165
fn get_filemap(cm: codemap, filename: str) -> filemap {
129166
for fm: filemap in cm.files { if fm.name == filename { ret fm; } }
130167
//XXjdm the following triggers a mismatched type bug

0 commit comments

Comments
 (0)