aboutsummaryrefslogtreecommitdiff
path: root/crates/libanalysis/src/imp.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-09-02 18:08:58 +0100
committerAleksey Kladov <[email protected]>2018-09-02 20:51:59 +0100
commit440dc41dd8f53876d0949272e76b1f560e10ec69 (patch)
tree55daf3b6e687be992e84845e813151daaec64267 /crates/libanalysis/src/imp.rs
parente98d8cd255ab5c2fee873a58af6c2c3ad561dab4 (diff)
Add source root
Diffstat (limited to 'crates/libanalysis/src/imp.rs')
-rw-r--r--crates/libanalysis/src/imp.rs121
1 files changed, 16 insertions, 105 deletions
diff --git a/crates/libanalysis/src/imp.rs b/crates/libanalysis/src/imp.rs
index b80ce1ab5..73a6f4306 100644
--- a/crates/libanalysis/src/imp.rs
+++ b/crates/libanalysis/src/imp.rs
@@ -4,13 +4,9 @@ use std::{
4 atomic::{AtomicBool, Ordering::SeqCst}, 4 atomic::{AtomicBool, Ordering::SeqCst},
5 }, 5 },
6 fmt, 6 fmt,
7 time::Instant, 7 collections::{HashSet, VecDeque},
8 collections::{HashMap, HashSet, VecDeque},
9 panic,
10}; 8};
11 9
12use rayon::prelude::*;
13use once_cell::sync::OnceCell;
14use libeditor::{self, FileSymbol, LineIndex, find_node_at_offset, LocalEdit}; 10use libeditor::{self, FileSymbol, LineIndex, find_node_at_offset, LocalEdit};
15use libsyntax2::{ 11use libsyntax2::{
16 TextUnit, TextRange, SmolStr, File, AstNode, 12 TextUnit, TextRange, SmolStr, File, AstNode,
@@ -20,10 +16,9 @@ use libsyntax2::{
20 16
21use { 17use {
22 FileId, FileResolver, Query, Diagnostic, SourceChange, SourceFileEdit, Position, FileSystemEdit, 18 FileId, FileResolver, Query, Diagnostic, SourceChange, SourceFileEdit, Position, FileSystemEdit,
23 module_map::Problem,
24 symbol_index::FileSymbols,
25 module_map::{ModuleMap, ChangeKind},
26 JobToken, CrateGraph, CrateId, 19 JobToken, CrateGraph, CrateId,
20 module_map::Problem,
21 roots::SourceRoot,
27}; 22};
28 23
29#[derive(Debug)] 24#[derive(Debug)]
@@ -50,23 +45,7 @@ impl AnalysisHostImpl {
50 pub fn change_files(&mut self, changes: &mut dyn Iterator<Item=(FileId, Option<String>)>) { 45 pub fn change_files(&mut self, changes: &mut dyn Iterator<Item=(FileId, Option<String>)>) {
51 let data = self.data_mut(); 46 let data = self.data_mut();
52 for (file_id, text) in changes { 47 for (file_id, text) in changes {
53 let change_kind = if data.file_map.remove(&file_id).is_some() { 48 data.root.update(file_id, text);
54 if text.is_some() {
55 ChangeKind::Update
56 } else {
57 ChangeKind::Delete
58 }
59 } else {
60 ChangeKind::Insert
61 };
62 data.module_map.update_file(file_id, change_kind);
63 data.file_map.remove(&file_id);
64 if let Some(text) = text {
65 let file_data = FileData::new(text);
66 data.file_map.insert(file_id, Arc::new(file_data));
67 } else {
68 data.file_map.remove(&file_id);
69 }
70 } 49 }
71 } 50 }
72 pub fn set_crate_graph(&mut self, graph: CrateGraph) { 51 pub fn set_crate_graph(&mut self, graph: CrateGraph) {
@@ -106,31 +85,18 @@ impl Clone for AnalysisImpl {
106} 85}
107 86
108impl AnalysisImpl { 87impl AnalysisImpl {
109 pub fn file_syntax(&self, file_id: FileId) -> File { 88 pub fn file_syntax(&self, file_id: FileId) -> &File {
110 self.file_data(file_id).syntax().clone() 89 self.data.root.syntax(file_id)
111 } 90 }
112 91 pub fn file_line_index(&self, file_id: FileId) -> &LineIndex {
113 pub fn file_line_index(&self, id: FileId) -> LineIndex { 92 self.data.root.lines(file_id)
114 let data = self.file_data(id);
115 data
116 .lines
117 .get_or_init(|| LineIndex::new(&data.text))
118 .clone()
119 } 93 }
120 94 pub fn world_symbols(&self, query: Query, token: &JobToken) -> Vec<(FileId, FileSymbol)> {
121 pub fn world_symbols(&self, mut query: Query, token: &JobToken) -> Vec<(FileId, FileSymbol)> {
122 self.reindex(); 95 self.reindex();
123 self.data.file_map.iter() 96 query.search(&self.data.root.symbols(), token)
124 .take_while(move |_| !token.is_canceled())
125 .flat_map(move |(id, data)| {
126 let symbols = data.symbols();
127 query.process(symbols).into_iter().map(move |s| (*id, s))
128 })
129 .collect()
130 } 97 }
131
132 pub fn parent_module(&self, id: FileId) -> Vec<(FileId, FileSymbol)> { 98 pub fn parent_module(&self, id: FileId) -> Vec<(FileId, FileSymbol)> {
133 let module_map = &self.data.module_map; 99 let module_map = self.data.root.module_map();
134 let id = module_map.file2module(id); 100 let id = module_map.file2module(id);
135 module_map 101 module_map
136 .parent_modules( 102 .parent_modules(
@@ -152,7 +118,7 @@ impl AnalysisImpl {
152 } 118 }
153 119
154 pub fn crate_for(&self, id: FileId) -> Vec<CrateId> { 120 pub fn crate_for(&self, id: FileId) -> Vec<CrateId> {
155 let module_map = &self.data.module_map; 121 let module_map = self.data.root.module_map();
156 let crate_graph = &self.data.crate_graph; 122 let crate_graph = &self.data.crate_graph;
157 let mut res = Vec::new(); 123 let mut res = Vec::new();
158 let mut work = VecDeque::new(); 124 let mut work = VecDeque::new();
@@ -222,7 +188,7 @@ impl AnalysisImpl {
222 .map(|d| Diagnostic { range: d.range, message: d.msg, fix: None }) 188 .map(|d| Diagnostic { range: d.range, message: d.msg, fix: None })
223 .collect::<Vec<_>>(); 189 .collect::<Vec<_>>();
224 190
225 self.data.module_map.problems( 191 self.data.root.module_map().problems(
226 file_id, 192 file_id,
227 &*self.file_resolver, 193 &*self.file_resolver,
228 &|file_id| self.file_syntax(file_id), 194 &|file_id| self.file_syntax(file_id),
@@ -296,7 +262,7 @@ impl AnalysisImpl {
296 Some(name) => name.text(), 262 Some(name) => name.text(),
297 None => return Vec::new(), 263 None => return Vec::new(),
298 }; 264 };
299 let module_map = &self.data.module_map; 265 let module_map = self.data.root.module_map();
300 let id = module_map.file2module(id); 266 let id = module_map.file2module(id);
301 module_map 267 module_map
302 .child_module_by_name( 268 .child_module_by_name(
@@ -311,19 +277,7 @@ impl AnalysisImpl {
311 277
312 fn reindex(&self) { 278 fn reindex(&self) {
313 if self.needs_reindex.compare_and_swap(true, false, SeqCst) { 279 if self.needs_reindex.compare_and_swap(true, false, SeqCst) {
314 let now = Instant::now(); 280 self.data.root.reindex();
315 let data = &*self.data;
316 data.file_map
317 .par_iter()
318 .for_each(|(_, data)| drop(data.symbols()));
319 info!("parallel indexing took {:?}", now.elapsed());
320 }
321 }
322
323 fn file_data(&self, file_id: FileId) -> Arc<FileData> {
324 match self.data.file_map.get(&file_id) {
325 Some(data) => data.clone(),
326 None => panic!("unknown file: {:?}", file_id),
327 } 281 }
328 } 282 }
329} 283}
@@ -331,50 +285,7 @@ impl AnalysisImpl {
331#[derive(Clone, Default, Debug)] 285#[derive(Clone, Default, Debug)]
332struct WorldData { 286struct WorldData {
333 crate_graph: CrateGraph, 287 crate_graph: CrateGraph,
334 file_map: HashMap<FileId, Arc<FileData>>, 288 root: SourceRoot,
335 module_map: ModuleMap,
336}
337
338#[derive(Debug)]
339struct FileData {
340 text: String,
341 symbols: OnceCell<FileSymbols>,
342 syntax: OnceCell<File>,
343 lines: OnceCell<LineIndex>,
344}
345
346impl FileData {
347 fn new(text: String) -> FileData {
348 FileData {
349 text,
350 symbols: OnceCell::new(),
351 syntax: OnceCell::new(),
352 lines: OnceCell::new(),
353 }
354 }
355
356 fn syntax(&self) -> &File {
357 let text = &self.text;
358 let syntax = &self.syntax;
359 match panic::catch_unwind(panic::AssertUnwindSafe(|| syntax.get_or_init(|| File::parse(text)))) {
360 Ok(file) => file,
361 Err(err) => {
362 error!("Parser paniced on:\n------\n{}\n------\n", &self.text);
363 panic::resume_unwind(err)
364 }
365 }
366 }
367
368 fn syntax_transient(&self) -> File {
369 self.syntax.get().map(|s| s.clone())
370 .unwrap_or_else(|| File::parse(&self.text))
371 }
372
373 fn symbols(&self) -> &FileSymbols {
374 let syntax = self.syntax_transient();
375 self.symbols
376 .get_or_init(|| FileSymbols::new(&syntax))
377 }
378} 289}
379 290
380impl SourceChange { 291impl SourceChange {