diff options
| author | Michael Woerister <michaelwoerister@posteo.net> | 2016-08-24 17:06:31 -0400 |
|---|---|---|
| committer | Michael Woerister <michaelwoerister@posteo.net> | 2016-09-01 09:43:44 -0400 |
| commit | e355ec1c6a24f8a597a08809b9dad394498dc3dd (patch) | |
| tree | 8ac8b42b5e30e3e63bbbfdc76d15faa3fb3b1fe5 /src/libsyntax_pos | |
| parent | 8e4f4810dcc7cc21aec13d421d211a94f29e413f (diff) | |
| download | rust-e355ec1c6a24f8a597a08809b9dad394498dc3dd.tar.gz rust-e355ec1c6a24f8a597a08809b9dad394498dc3dd.zip | |
incr.comp.: Add stable hashing of HIR spans to ICH.
Diffstat (limited to 'src/libsyntax_pos')
| -rw-r--r-- | src/libsyntax_pos/lib.rs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index b11bbea84ab..d835f8058fa 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -507,6 +507,39 @@ impl FileMap { pub fn count_lines(&self) -> usize { self.lines.borrow().len() } + + /// Find the line containing the given position. The return value is the + /// index into the `lines` array of this FileMap, not the 1-based line + /// number. If the filemap is empty or the position is located before the + /// first line, None is returned. + pub fn lookup_line(&self, pos: BytePos) -> Option<usize> { + let lines = self.lines.borrow(); + if lines.len() == 0 { + return None; + } + + let line_index = lookup_line(&lines[..], pos); + assert!(line_index < lines.len() as isize); + if line_index >= 0 { + Some(line_index as usize) + } else { + None + } + } + + pub fn line_bounds(&self, line_index: usize) -> (BytePos, BytePos) { + if self.start_pos == self.end_pos { + return (self.start_pos, self.end_pos); + } + + let lines = self.lines.borrow(); + assert!(line_index < lines.len()); + if line_index == (lines.len() - 1) { + (lines[line_index], self.end_pos) + } else { + (lines[line_index], lines[line_index + 1]) + } + } } // _____________________________________________________________________________ @@ -688,3 +721,34 @@ pub struct MalformedCodemapPositions { pub end_pos: BytePos } +// Given a slice of line start positions and a position, returns the index of +// the line the position is on. Returns -1 if the position is located before +// the first line. +fn lookup_line(lines: &[BytePos], pos: BytePos) -> isize { + match lines.binary_search(&pos) { + Ok(line) => line as isize, + Err(line) => line as isize - 1 + } +} + +#[cfg(test)] +mod tests { + use super::{lookup_line, BytePos}; + + #[test] + fn test_lookup_line() { + + let lines = &[BytePos(3), BytePos(17), BytePos(28)]; + + assert_eq!(lookup_line(lines, BytePos(0)), -1); + assert_eq!(lookup_line(lines, BytePos(3)), 0); + assert_eq!(lookup_line(lines, BytePos(4)), 0); + + assert_eq!(lookup_line(lines, BytePos(16)), 0); + assert_eq!(lookup_line(lines, BytePos(17)), 1); + assert_eq!(lookup_line(lines, BytePos(18)), 1); + + assert_eq!(lookup_line(lines, BytePos(28)), 2); + assert_eq!(lookup_line(lines, BytePos(29)), 2); + } +} |
