1 use rustc_data_structures::sync::Lrc;
2 use crate::source_map::SourceMap;
3 use crate::{BytePos, SourceFile};
11 file: Lrc<SourceFile>,
16 pub struct CachingSourceMapView<'cm> {
17 source_map: &'cm SourceMap,
18 line_cache: [CacheEntry; 3],
22 impl<'cm> CachingSourceMapView<'cm> {
23 pub fn new(source_map: &'cm SourceMap) -> CachingSourceMapView<'cm> {
24 let files = source_map.files();
25 let first_file = files[0].clone();
26 let entry = CacheEntry {
29 line_start: BytePos(0),
35 CachingSourceMapView {
37 line_cache: [entry.clone(), entry.clone(), entry],
42 pub fn byte_pos_to_line_and_col(&mut self,
44 -> Option<(Lrc<SourceFile>, usize, BytePos)> {
47 // Check if the position is in one of the cached lines
48 for cache_entry in self.line_cache.iter_mut() {
49 if pos >= cache_entry.line_start && pos < cache_entry.line_end {
50 cache_entry.time_stamp = self.time_stamp;
52 return Some((cache_entry.file.clone(),
53 cache_entry.line_number,
54 pos - cache_entry.line_start));
60 for index in 1 .. self.line_cache.len() {
61 if self.line_cache[index].time_stamp < self.line_cache[oldest].time_stamp {
66 let cache_entry = &mut self.line_cache[oldest];
68 // If the entry doesn't point to the correct file, fix it up
69 if pos < cache_entry.file.start_pos || pos >= cache_entry.file.end_pos {
71 if self.source_map.files().len() > 0 {
72 let file_index = self.source_map.lookup_source_file_idx(pos);
73 let file = self.source_map.files()[file_index].clone();
75 if pos >= file.start_pos && pos < file.end_pos {
76 cache_entry.file = file;
77 cache_entry.file_index = file_index;
91 let line_index = cache_entry.file.lookup_line(pos).unwrap();
92 let line_bounds = cache_entry.file.line_bounds(line_index);
94 cache_entry.line_number = line_index + 1;
95 cache_entry.line_start = line_bounds.0;
96 cache_entry.line_end = line_bounds.1;
97 cache_entry.time_stamp = self.time_stamp;
99 return Some((cache_entry.file.clone(),
100 cache_entry.line_number,
101 pos - cache_entry.line_start));