]> git.proxmox.com Git - rustc.git/blame - src/librustc/ich/caching_codemap_view.rs
New upstream version 1.31.0~beta.4+dfsg1
[rustc.git] / src / librustc / ich / caching_codemap_view.rs
CommitLineData
9e0c209e
SL
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.
4//
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.
10
0531ce1d 11use rustc_data_structures::sync::Lrc;
b7449926
XL
12use syntax::source_map::SourceMap;
13use syntax_pos::{BytePos, SourceFile};
9e0c209e
SL
14
15#[derive(Clone)]
16struct CacheEntry {
17 time_stamp: usize,
18 line_number: usize,
19 line_start: BytePos,
20 line_end: BytePos,
b7449926 21 file: Lrc<SourceFile>,
7cac9316 22 file_index: usize,
9e0c209e
SL
23}
24
ea8adc8c 25#[derive(Clone)]
b7449926
XL
26pub struct CachingSourceMapView<'cm> {
27 source_map: &'cm SourceMap,
9e0c209e
SL
28 line_cache: [CacheEntry; 3],
29 time_stamp: usize,
30}
31
b7449926
XL
32impl<'cm> CachingSourceMapView<'cm> {
33 pub fn new(source_map: &'cm SourceMap) -> CachingSourceMapView<'cm> {
34 let files = source_map.files();
7cac9316 35 let first_file = files[0].clone();
9e0c209e
SL
36 let entry = CacheEntry {
37 time_stamp: 0,
38 line_number: 0,
39 line_start: BytePos(0),
40 line_end: BytePos(0),
41 file: first_file,
7cac9316 42 file_index: 0,
9e0c209e
SL
43 };
44
b7449926
XL
45 CachingSourceMapView {
46 source_map,
0bf4aa26 47 line_cache: [entry.clone(), entry.clone(), entry],
9e0c209e
SL
48 time_stamp: 0,
49 }
50 }
51
9e0c209e
SL
52 pub fn byte_pos_to_line_and_col(&mut self,
53 pos: BytePos)
b7449926 54 -> Option<(Lrc<SourceFile>, usize, BytePos)> {
9e0c209e
SL
55 self.time_stamp += 1;
56
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;
7cac9316 61
9e0c209e
SL
62 return Some((cache_entry.file.clone(),
63 cache_entry.line_number,
64 pos - cache_entry.line_start));
65 }
66 }
67
68 // No cache hit ...
69 let mut oldest = 0;
70 for index in 1 .. self.line_cache.len() {
71 if self.line_cache[index].time_stamp < self.line_cache[oldest].time_stamp {
72 oldest = index;
73 }
74 }
75
76 let cache_entry = &mut self.line_cache[oldest];
77
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 {
80 let file_valid;
b7449926
XL
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();
9e0c209e
SL
84
85 if pos >= file.start_pos && pos < file.end_pos {
86 cache_entry.file = file;
7cac9316 87 cache_entry.file_index = file_index;
9e0c209e
SL
88 file_valid = true;
89 } else {
90 file_valid = false;
91 }
92 } else {
93 file_valid = false;
94 }
95
96 if !file_valid {
97 return None;
98 }
99 }
100
101 let line_index = cache_entry.file.lookup_line(pos).unwrap();
102 let line_bounds = cache_entry.file.line_bounds(line_index);
103
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;
108
109 return Some((cache_entry.file.clone(),
110 cache_entry.line_number,
111 pos - cache_entry.line_start));
112 }
113}