about summary refs log tree commit diff
path: root/src/libsyntax_pos
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo.net>2016-08-24 17:06:31 -0400
committerMichael Woerister <michaelwoerister@posteo.net>2016-09-01 09:43:44 -0400
commite355ec1c6a24f8a597a08809b9dad394498dc3dd (patch)
tree8ac8b42b5e30e3e63bbbfdc76d15faa3fb3b1fe5 /src/libsyntax_pos
parent8e4f4810dcc7cc21aec13d421d211a94f29e413f (diff)
downloadrust-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.rs64
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);
+    }
+}