aboutsummaryrefslogtreecommitdiff
path: root/crates/libanalysis/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/libanalysis/src/lib.rs')
-rw-r--r--crates/libanalysis/src/lib.rs70
1 files changed, 32 insertions, 38 deletions
diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs
index d01144627..fee0d10d6 100644
--- a/crates/libanalysis/src/lib.rs
+++ b/crates/libanalysis/src/lib.rs
@@ -17,7 +17,6 @@ use rayon::prelude::*;
17 17
18use std::{ 18use std::{
19 fmt, 19 fmt,
20 mem,
21 path::{Path}, 20 path::{Path},
22 sync::{ 21 sync::{
23 Arc, 22 Arc,
@@ -36,18 +35,16 @@ use libeditor::{LineIndex, FileSymbol, find_node};
36 35
37use self::{ 36use self::{
38 symbol_index::FileSymbols, 37 symbol_index::FileSymbols,
39 module_map::ModuleMap, 38 module_map::{ModuleMap, ChangeKind},
40}; 39};
41pub use self::symbol_index::Query; 40pub use self::symbol_index::Query;
42 41
43pub type Result<T> = ::std::result::Result<T, ::failure::Error>; 42pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
44const INDEXING_THRESHOLD: usize = 128;
45 43
46pub type FileResolver = dyn Fn(FileId, &Path) -> Option<FileId> + Send + Sync; 44pub type FileResolver = dyn Fn(FileId, &Path) -> Option<FileId> + Send + Sync;
47 45
48#[derive(Debug)] 46#[derive(Debug)]
49pub struct WorldState { 47pub struct WorldState {
50 updates: Vec<FileId>,
51 data: Arc<WorldData> 48 data: Arc<WorldData>
52} 49}
53 50
@@ -79,32 +76,16 @@ pub struct FileId(pub u32);
79impl WorldState { 76impl WorldState {
80 pub fn new() -> WorldState { 77 pub fn new() -> WorldState {
81 WorldState { 78 WorldState {
82 updates: Vec::new(),
83 data: Arc::new(WorldData::default()), 79 data: Arc::new(WorldData::default()),
84 } 80 }
85 } 81 }
86 82
87 pub fn snapshot( 83 pub fn snapshot(
88 &mut self, 84 &self,
89 file_resolver: impl Fn(FileId, &Path) -> Option<FileId> + 'static + Send + Sync, 85 file_resolver: impl Fn(FileId, &Path) -> Option<FileId> + 'static + Send + Sync,
90 ) -> World { 86 ) -> World {
91 let needs_reindex = self.updates.len() >= INDEXING_THRESHOLD;
92 if !self.updates.is_empty() {
93 let updates = mem::replace(&mut self.updates, Vec::new());
94 let data = self.data_mut();
95 for file_id in updates {
96 let syntax = data.file_map
97 .get(&file_id)
98 .map(|it| it.syntax());
99 data.module_map.update_file(
100 file_id,
101 syntax,
102 &file_resolver,
103 );
104 }
105 }
106 World { 87 World {
107 needs_reindex: AtomicBool::new(needs_reindex), 88 needs_reindex: AtomicBool::new(false),
108 file_resolver: Arc::new(file_resolver), 89 file_resolver: Arc::new(file_resolver),
109 data: self.data.clone() 90 data: self.data.clone()
110 } 91 }
@@ -115,21 +96,26 @@ impl WorldState {
115 } 96 }
116 97
117 pub fn change_files(&mut self, changes: impl Iterator<Item=(FileId, Option<String>)>) { 98 pub fn change_files(&mut self, changes: impl Iterator<Item=(FileId, Option<String>)>) {
118 let mut updates = Vec::new(); 99 let data = self.data_mut();
119 { 100 for (file_id, text) in changes {
120 let data = self.data_mut(); 101 let change_kind = if data.file_map.remove(&file_id).is_some() {
121 for (file_id, text) in changes { 102 if text.is_some() {
122 data.file_map.remove(&file_id); 103 ChangeKind::Update
123 if let Some(text) = text {
124 let file_data = FileData::new(text);
125 data.file_map.insert(file_id, Arc::new(file_data));
126 } else { 104 } else {
127 data.file_map.remove(&file_id); 105 ChangeKind::Delete
128 } 106 }
129 updates.push(file_id); 107 } else {
108 ChangeKind::Insert
109 };
110 data.module_map.update_file(file_id, change_kind);
111 data.file_map.remove(&file_id);
112 if let Some(text) = text {
113 let file_data = FileData::new(text);
114 data.file_map.insert(file_id, Arc::new(file_data));
115 } else {
116 data.file_map.remove(&file_id);
130 } 117 }
131 } 118 }
132 self.updates.extend(updates)
133 } 119 }
134 120
135 fn data_mut(&mut self) -> &mut WorldData { 121 fn data_mut(&mut self) -> &mut WorldData {
@@ -171,13 +157,17 @@ impl World {
171 let module_map = &self.data.module_map; 157 let module_map = &self.data.module_map;
172 let id = module_map.file2module(id); 158 let id = module_map.file2module(id);
173 module_map 159 module_map
174 .parent_modules(id) 160 .parent_modules(
161 id,
162 &*self.file_resolver,
163 &|file_id| self.file_syntax(file_id).unwrap(),
164 )
175 .into_iter() 165 .into_iter()
176 .map(|(id, m)| { 166 .map(|(id, name, node)| {
177 let id = module_map.module2file(id); 167 let id = module_map.module2file(id);
178 let sym = FileSymbol { 168 let sym = FileSymbol {
179 name: m.name().unwrap().text(), 169 name,
180 node_range: m.syntax().range(), 170 node_range: node.range(),
181 kind: MODULE, 171 kind: MODULE,
182 }; 172 };
183 (id, sym) 173 (id, sym)
@@ -235,7 +225,11 @@ impl World {
235 let module_map = &self.data.module_map; 225 let module_map = &self.data.module_map;
236 let id = module_map.file2module(id); 226 let id = module_map.file2module(id);
237 module_map 227 module_map
238 .child_module_by_name(id, name.as_str()) 228 .child_module_by_name(
229 id, name.as_str(),
230 &*self.file_resolver,
231 &|file_id| self.file_syntax(file_id).unwrap(),
232 )
239 .into_iter() 233 .into_iter()
240 .map(|id| module_map.module2file(id)) 234 .map(|id| module_map.module2file(id))
241 .collect() 235 .collect()