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.
11 use rustc_data_structures::sync::Lrc;
12 use syntax::source_map::SourceMap;
13 use syntax_pos::{BytePos, SourceFile};
21 file: Lrc<SourceFile>,
26 pub struct CachingSourceMapView<'cm> {
27 source_map: &'cm SourceMap,
28 line_cache: [CacheEntry; 3],
32 impl<'cm> CachingSourceMapView<'cm> {
33 pub fn new(source_map: &'cm SourceMap) -> CachingSourceMapView<'cm> {
34 let files = source_map.files();
35 let first_file = files[0].clone();
36 let entry = CacheEntry {
39 line_start: BytePos(0),
45 CachingSourceMapView {
47 line_cache: [entry.clone(), entry.clone(), entry],
52 pub fn byte_pos_to_line_and_col(&mut self,
54 -> Option<(Lrc<SourceFile>, usize, BytePos)> {
57 // Check if the position is in one of the cached lines
58 for cache_entry in self.line_cache.iter_mut() {
59 if pos >= cache_entry.line_start && pos < cache_entry.line_end {
60 cache_entry.time_stamp = self.time_stamp;
62 return Some((cache_entry.file.clone(),
63 cache_entry.line_number,
64 pos - cache_entry.line_start));
70 for index in 1 .. self.line_cache.len() {
71 if self.line_cache[index].time_stamp < self.line_cache[oldest].time_stamp {
76 let cache_entry = &mut self.line_cache[oldest];
78 // If the entry doesn't point to the correct file, fix it up
79 if pos < cache_entry.file.start_pos || pos >= cache_entry.file.end_pos {
81 if self.source_map.files().len() > 0 {
82 let file_index = self.source_map.lookup_source_file_idx(pos);
83 let file = self.source_map.files()[file_index].clone();
85 if pos >= file.start_pos && pos < file.end_pos {
86 cache_entry.file = file;
87 cache_entry.file_index = file_index;
101 let line_index = cache_entry.file.lookup_line(pos).unwrap();
102 let line_bounds = cache_entry.file.line_bounds(line_index);
104 cache_entry.line_number = line_index + 1;
105 cache_entry.line_start = line_bounds.0;
106 cache_entry.line_end = line_bounds.1;
107 cache_entry.time_stamp = self.time_stamp;
109 return Some((cache_entry.file.clone(),
110 cache_entry.line_number,
111 pos - cache_entry.line_start));