1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 use syntax::codemap::CodeMap;
13 use syntax_pos::{BytePos, FileMap};
26 pub struct CachingCodemapView<'tcx> {
27 codemap: &'tcx CodeMap,
28 line_cache: [CacheEntry; 3],
32 impl<'gcx> CachingCodemapView<'gcx> {
33 pub fn new<'a, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> CachingCodemapView<'gcx> {
34 let codemap = tcx.sess.codemap();
35 let files = codemap.files();
36 let first_file = files[0].clone();
37 let entry = CacheEntry {
40 line_start: BytePos(0),
48 line_cache: [entry.clone(), entry.clone(), entry.clone()],
53 pub fn byte_pos_to_line_and_col(&mut self,
55 -> Option<(Rc<FileMap>, usize, BytePos)> {
58 // Check if the position is in one of the cached lines
59 for cache_entry in self.line_cache.iter_mut() {
60 if pos >= cache_entry.line_start && pos < cache_entry.line_end {
61 cache_entry.time_stamp = self.time_stamp;
63 return Some((cache_entry.file.clone(),
64 cache_entry.line_number,
65 pos - cache_entry.line_start));
71 for index in 1 .. self.line_cache.len() {
72 if self.line_cache[index].time_stamp < self.line_cache[oldest].time_stamp {
77 let cache_entry = &mut self.line_cache[oldest];
79 // If the entry doesn't point to the correct file, fix it up
80 if pos < cache_entry.file.start_pos || pos >= cache_entry.file.end_pos {
82 let files = self.codemap.files();
85 let file_index = self.codemap.lookup_filemap_idx(pos);
86 let file = files[file_index].clone();
88 if pos >= file.start_pos && pos < file.end_pos {
89 cache_entry.file = file;
90 cache_entry.file_index = file_index;
104 let line_index = cache_entry.file.lookup_line(pos).unwrap();
105 let line_bounds = cache_entry.file.line_bounds(line_index);
107 cache_entry.line_number = line_index + 1;
108 cache_entry.line_start = line_bounds.0;
109 cache_entry.line_end = line_bounds.1;
110 cache_entry.time_stamp = self.time_stamp;
112 return Some((cache_entry.file.clone(),
113 cache_entry.line_number,
114 pos - cache_entry.line_start));