aboutsummaryrefslogtreecommitdiff
path: root/crates/libanalysis/src
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-09-10 10:57:40 +0100
committerAleksey Kladov <[email protected]>2018-09-10 10:57:40 +0100
commit505895a25f98423de07c3cec4793b66a19d098c7 (patch)
tree2df3f41f33b5db0b2bba1e2d2acd08f23fffbc2a /crates/libanalysis/src
parent4f647096665b2ca3725ba1f7415a21fbc46044bb (diff)
store file rsovler
Diffstat (limited to 'crates/libanalysis/src')
-rw-r--r--crates/libanalysis/src/imp.rs65
-rw-r--r--crates/libanalysis/src/lib.rs21
-rw-r--r--crates/libanalysis/src/module_map.rs41
-rw-r--r--crates/libanalysis/src/roots.rs7
4 files changed, 81 insertions, 53 deletions
diff --git a/crates/libanalysis/src/imp.rs b/crates/libanalysis/src/imp.rs
index 47b0d79ff..3e65ee14a 100644
--- a/crates/libanalysis/src/imp.rs
+++ b/crates/libanalysis/src/imp.rs
@@ -7,6 +7,7 @@ use std::{
7 collections::{HashSet, VecDeque}, 7 collections::{HashSet, VecDeque},
8}; 8};
9 9
10use relative_path::RelativePath;
10use libeditor::{self, FileSymbol, LineIndex, find_node_at_offset, LocalEdit}; 11use libeditor::{self, FileSymbol, LineIndex, find_node_at_offset, LocalEdit};
11use libsyntax2::{ 12use libsyntax2::{
12 TextUnit, TextRange, SmolStr, File, AstNode, 13 TextUnit, TextRange, SmolStr, File, AstNode,
@@ -21,6 +22,40 @@ use {
21 roots::{SourceRoot, ReadonlySourceRoot, WritableSourceRoot}, 22 roots::{SourceRoot, ReadonlySourceRoot, WritableSourceRoot},
22}; 23};
23 24
25
26#[derive(Clone, Debug)]
27pub(crate) struct FileResolverImp {
28 inner: Arc<FileResolver>
29}
30
31impl FileResolverImp {
32 pub(crate) fn new(inner: Arc<FileResolver>) -> FileResolverImp {
33 FileResolverImp { inner }
34 }
35 pub(crate) fn file_stem(&self, file_id: FileId) -> String {
36 self.inner.file_stem(file_id)
37 }
38 pub(crate) fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option<FileId> {
39 self.inner.resolve(file_id, path)
40 }
41}
42
43impl Default for FileResolverImp {
44 fn default() -> FileResolverImp {
45 #[derive(Debug)]
46 struct DummyResolver;
47 impl FileResolver for DummyResolver {
48 fn file_stem(&self, _file_: FileId) -> String {
49 panic!("file resolver not set")
50 }
51 fn resolve(&self, _file_id: FileId, _path: &::relative_path::RelativePath) -> Option<FileId> {
52 panic!("file resolver not set")
53 }
54 }
55 FileResolverImp { inner: Arc::new(DummyResolver) }
56 }
57}
58
24#[derive(Debug)] 59#[derive(Debug)]
25pub(crate) struct AnalysisHostImpl { 60pub(crate) struct AnalysisHostImpl {
26 data: Arc<WorldData> 61 data: Arc<WorldData>
@@ -32,13 +67,9 @@ impl AnalysisHostImpl {
32 data: Arc::new(WorldData::default()), 67 data: Arc::new(WorldData::default()),
33 } 68 }
34 } 69 }
35 pub fn analysis( 70 pub fn analysis(&self) -> AnalysisImpl {
36 &self,
37 file_resolver: Arc<dyn FileResolver>,
38 ) -> AnalysisImpl {
39 AnalysisImpl { 71 AnalysisImpl {
40 needs_reindex: AtomicBool::new(false), 72 needs_reindex: AtomicBool::new(false),
41 file_resolver,
42 data: self.data.clone(), 73 data: self.data.clone(),
43 } 74 }
44 } 75 }
@@ -48,6 +79,11 @@ impl AnalysisHostImpl {
48 data.root.update(file_id, text); 79 data.root.update(file_id, text);
49 } 80 }
50 } 81 }
82 pub fn set_file_resolver(&mut self, resolver: FileResolverImp) {
83 let data = self.data_mut();
84 data.file_resolver = resolver.clone();
85 data.root.set_file_resolver(resolver);
86 }
51 pub fn set_crate_graph(&mut self, graph: CrateGraph) { 87 pub fn set_crate_graph(&mut self, graph: CrateGraph) {
52 let mut visited = HashSet::new(); 88 let mut visited = HashSet::new();
53 for &file_id in graph.crate_roots.values() { 89 for &file_id in graph.crate_roots.values() {
@@ -67,7 +103,6 @@ impl AnalysisHostImpl {
67 103
68pub(crate) struct AnalysisImpl { 104pub(crate) struct AnalysisImpl {
69 needs_reindex: AtomicBool, 105 needs_reindex: AtomicBool,
70 file_resolver: Arc<dyn FileResolver>,
71 data: Arc<WorldData>, 106 data: Arc<WorldData>,
72} 107}
73 108
@@ -81,7 +116,6 @@ impl Clone for AnalysisImpl {
81 fn clone(&self) -> AnalysisImpl { 116 fn clone(&self) -> AnalysisImpl {
82 AnalysisImpl { 117 AnalysisImpl {
83 needs_reindex: AtomicBool::new(self.needs_reindex.load(SeqCst)), 118 needs_reindex: AtomicBool::new(self.needs_reindex.load(SeqCst)),
84 file_resolver: Arc::clone(&self.file_resolver),
85 data: Arc::clone(&self.data), 119 data: Arc::clone(&self.data),
86 } 120 }
87 } 121 }
@@ -117,11 +151,7 @@ impl AnalysisImpl {
117 let module_map = root.module_map(); 151 let module_map = root.module_map();
118 let id = module_map.file2module(file_id); 152 let id = module_map.file2module(file_id);
119 module_map 153 module_map
120 .parent_modules( 154 .parent_modules(id, &|file_id| root.syntax(file_id))
121 id,
122 &*self.file_resolver,
123 &|file_id| root.syntax(file_id),
124 )
125 .into_iter() 155 .into_iter()
126 .map(|(id, name, node)| { 156 .map(|(id, name, node)| {
127 let id = module_map.module2file(id); 157 let id = module_map.module2file(id);
@@ -149,11 +179,7 @@ impl AnalysisImpl {
149 } 179 }
150 let mid = module_map.file2module(id); 180 let mid = module_map.file2module(id);
151 let parents = module_map 181 let parents = module_map
152 .parent_module_ids( 182 .parent_module_ids(mid, &|file_id| self.file_syntax(file_id))
153 mid,
154 &*self.file_resolver,
155 &|file_id| self.file_syntax(file_id),
156 )
157 .into_iter() 183 .into_iter()
158 .map(|id| module_map.module2file(id)) 184 .map(|id| module_map.module2file(id))
159 .filter(|&id| visited.insert(id)); 185 .filter(|&id| visited.insert(id));
@@ -213,7 +239,6 @@ impl AnalysisImpl {
213 239
214 module_map.problems( 240 module_map.problems(
215 file_id, 241 file_id,
216 &*self.file_resolver,
217 &|file_id| self.file_syntax(file_id), 242 &|file_id| self.file_syntax(file_id),
218 |name_node, problem| { 243 |name_node, problem| {
219 let diag = match problem { 244 let diag = match problem {
@@ -291,7 +316,6 @@ impl AnalysisImpl {
291 module_map 316 module_map
292 .child_module_by_name( 317 .child_module_by_name(
293 id, name.as_str(), 318 id, name.as_str(),
294 &*self.file_resolver,
295 &|file_id| self.file_syntax(file_id), 319 &|file_id| self.file_syntax(file_id),
296 ) 320 )
297 .into_iter() 321 .into_iter()
@@ -306,8 +330,9 @@ impl AnalysisImpl {
306 } 330 }
307} 331}
308 332
309#[derive(Clone, Default, Debug)] 333#[derive(Default, Clone, Debug)]
310struct WorldData { 334struct WorldData {
335 file_resolver: FileResolverImp,
311 crate_graph: CrateGraph, 336 crate_graph: CrateGraph,
312 root: WritableSourceRoot, 337 root: WritableSourceRoot,
313 libs: Vec<Arc<ReadonlySourceRoot>>, 338 libs: Vec<Arc<ReadonlySourceRoot>>,
diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs
index ff4fc709b..80cde079f 100644
--- a/crates/libanalysis/src/lib.rs
+++ b/crates/libanalysis/src/lib.rs
@@ -19,11 +19,12 @@ mod roots;
19use std::{ 19use std::{
20 sync::Arc, 20 sync::Arc,
21 collections::HashMap, 21 collections::HashMap,
22 fmt::Debug,
22}; 23};
23 24
24use relative_path::{RelativePath, RelativePathBuf}; 25use relative_path::{RelativePath, RelativePathBuf};
25use libsyntax2::{File, TextRange, TextUnit, AtomEdit}; 26use libsyntax2::{File, TextRange, TextUnit, AtomEdit};
26use imp::{AnalysisImpl, AnalysisHostImpl}; 27use imp::{AnalysisImpl, AnalysisHostImpl, FileResolverImp};
27 28
28pub use libeditor::{ 29pub use libeditor::{
29 StructureNode, LineIndex, FileSymbol, 30 StructureNode, LineIndex, FileSymbol,
@@ -42,9 +43,9 @@ pub struct CrateGraph {
42 pub crate_roots: HashMap<CrateId, FileId>, 43 pub crate_roots: HashMap<CrateId, FileId>,
43} 44}
44 45
45pub trait FileResolver: Send + Sync + 'static { 46pub trait FileResolver: Debug + Send + Sync + 'static {
46 fn file_stem(&self, id: FileId) -> String; 47 fn file_stem(&self, file_id: FileId) -> String;
47 fn resolve(&self, id: FileId, path: &RelativePath) -> Option<FileId>; 48 fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option<FileId>;
48} 49}
49 50
50#[derive(Debug)] 51#[derive(Debug)]
@@ -56,8 +57,8 @@ impl AnalysisHost {
56 pub fn new() -> AnalysisHost { 57 pub fn new() -> AnalysisHost {
57 AnalysisHost { imp: AnalysisHostImpl::new() } 58 AnalysisHost { imp: AnalysisHostImpl::new() }
58 } 59 }
59 pub fn analysis(&self, file_resolver: impl FileResolver) -> Analysis { 60 pub fn analysis(&self) -> Analysis {
60 Analysis { imp: self.imp.analysis(Arc::new(file_resolver)) } 61 Analysis { imp: self.imp.analysis() }
61 } 62 }
62 pub fn change_file(&mut self, file_id: FileId, text: Option<String>) { 63 pub fn change_file(&mut self, file_id: FileId, text: Option<String>) {
63 self.change_files(::std::iter::once((file_id, text))); 64 self.change_files(::std::iter::once((file_id, text)));
@@ -65,6 +66,9 @@ impl AnalysisHost {
65 pub fn change_files(&mut self, mut changes: impl Iterator<Item=(FileId, Option<String>)>) { 66 pub fn change_files(&mut self, mut changes: impl Iterator<Item=(FileId, Option<String>)>) {
66 self.imp.change_files(&mut changes) 67 self.imp.change_files(&mut changes)
67 } 68 }
69 pub fn set_file_resolver(&mut self, resolver: Arc<FileResolver>) {
70 self.imp.set_file_resolver(FileResolverImp::new(resolver));
71 }
68 pub fn set_crate_graph(&mut self, graph: CrateGraph) { 72 pub fn set_crate_graph(&mut self, graph: CrateGraph) {
69 self.imp.set_crate_graph(graph) 73 self.imp.set_crate_graph(graph)
70 } 74 }
@@ -223,8 +227,9 @@ pub struct LibraryData {
223} 227}
224 228
225impl LibraryData { 229impl LibraryData {
226 pub fn prepare(files: Vec<(FileId, String)>) -> LibraryData { 230 pub fn prepare(files: Vec<(FileId, String)>, file_resolver: Arc<FileResolver>) -> LibraryData {
227 let root = roots::ReadonlySourceRoot::new(files); 231 let file_resolver = FileResolverImp::new(file_resolver);
232 let root = roots::ReadonlySourceRoot::new(files, file_resolver);
228 LibraryData { root } 233 LibraryData { root }
229 } 234 }
230} 235}
diff --git a/crates/libanalysis/src/module_map.rs b/crates/libanalysis/src/module_map.rs
index 1b225ecee..9acebd6e2 100644
--- a/crates/libanalysis/src/module_map.rs
+++ b/crates/libanalysis/src/module_map.rs
@@ -1,12 +1,11 @@
1use relative_path::RelativePathBuf; 1use relative_path::RelativePathBuf;
2
3use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard}; 2use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard};
4use libsyntax2::{ 3use libsyntax2::{
5 File, 4 File,
6 ast::{self, AstNode, NameOwner}, 5 ast::{self, AstNode, NameOwner},
7 SyntaxNode, SmolStr, 6 SyntaxNode, SmolStr,
8}; 7};
9use {FileId, FileResolver}; 8use {FileId, imp::FileResolverImp};
10 9
11type SyntaxProvider<'a> = dyn Fn(FileId) -> &'a File + 'a; 10type SyntaxProvider<'a> = dyn Fn(FileId) -> &'a File + 'a;
12 11
@@ -32,6 +31,7 @@ impl Clone for ModuleMap {
32 31
33#[derive(Clone, Debug, Default)] 32#[derive(Clone, Debug, Default)]
34struct State { 33struct State {
34 file_resolver: FileResolverImp,
35 changes: Vec<(FileId, ChangeKind)>, 35 changes: Vec<(FileId, ChangeKind)>,
36 links: Vec<Link>, 36 links: Vec<Link>,
37} 37}
@@ -59,27 +59,25 @@ impl ModuleMap {
59 pub fn new() -> ModuleMap { 59 pub fn new() -> ModuleMap {
60 Default::default() 60 Default::default()
61 } 61 }
62 62 pub fn update_file(&mut self, file_id: FileId, change_kind: ChangeKind) {
63 pub fn update_file(&mut self, file: FileId, change_kind: ChangeKind) { 63 self.state.get_mut().changes.push((file_id, change_kind));
64 self.state.get_mut().changes.push((file, change_kind)); 64 }
65 pub(crate) fn set_file_resolver(&mut self, file_resolver: FileResolverImp) {
66 self.state.get_mut().file_resolver = file_resolver;
65 } 67 }
66
67 pub fn module2file(&self, m: ModuleId) -> FileId { 68 pub fn module2file(&self, m: ModuleId) -> FileId {
68 m.0 69 m.0
69 } 70 }
70
71 pub fn file2module(&self, file_id: FileId) -> ModuleId { 71 pub fn file2module(&self, file_id: FileId) -> ModuleId {
72 ModuleId(file_id) 72 ModuleId(file_id)
73 } 73 }
74
75 pub fn child_module_by_name<'a>( 74 pub fn child_module_by_name<'a>(
76 &self, 75 &self,
77 parent_mod: ModuleId, 76 parent_mod: ModuleId,
78 child_mod: &str, 77 child_mod: &str,
79 file_resolver: &FileResolver,
80 syntax_provider: &SyntaxProvider, 78 syntax_provider: &SyntaxProvider,
81 ) -> Vec<ModuleId> { 79 ) -> Vec<ModuleId> {
82 self.links(file_resolver, syntax_provider) 80 self.links(syntax_provider)
83 .links 81 .links
84 .iter() 82 .iter()
85 .filter(|link| link.owner == parent_mod) 83 .filter(|link| link.owner == parent_mod)
@@ -92,11 +90,10 @@ impl ModuleMap {
92 pub fn parent_modules( 90 pub fn parent_modules(
93 &self, 91 &self,
94 m: ModuleId, 92 m: ModuleId,
95 file_resolver: &FileResolver,
96 syntax_provider: &SyntaxProvider, 93 syntax_provider: &SyntaxProvider,
97 ) -> Vec<(ModuleId, SmolStr, SyntaxNode)> { 94 ) -> Vec<(ModuleId, SmolStr, SyntaxNode)> {
98 let mut res = Vec::new(); 95 let mut res = Vec::new();
99 self.for_each_parent_link(m, file_resolver, syntax_provider, |link| { 96 self.for_each_parent_link(m, syntax_provider, |link| {
100 res.push( 97 res.push(
101 (link.owner, link.name().clone(), link.syntax.clone()) 98 (link.owner, link.name().clone(), link.syntax.clone())
102 ) 99 )
@@ -107,22 +104,20 @@ impl ModuleMap {
107 pub fn parent_module_ids( 104 pub fn parent_module_ids(
108 &self, 105 &self,
109 m: ModuleId, 106 m: ModuleId,
110 file_resolver: &FileResolver,
111 syntax_provider: &SyntaxProvider, 107 syntax_provider: &SyntaxProvider,
112 ) -> Vec<ModuleId> { 108 ) -> Vec<ModuleId> {
113 let mut res = Vec::new(); 109 let mut res = Vec::new();
114 self.for_each_parent_link(m, file_resolver, syntax_provider, |link| res.push(link.owner)); 110 self.for_each_parent_link(m, syntax_provider, |link| res.push(link.owner));
115 res 111 res
116 } 112 }
117 113
118 fn for_each_parent_link( 114 fn for_each_parent_link(
119 &self, 115 &self,
120 m: ModuleId, 116 m: ModuleId,
121 file_resolver: &FileResolver,
122 syntax_provider: &SyntaxProvider, 117 syntax_provider: &SyntaxProvider,
123 f: impl FnMut(&Link) 118 f: impl FnMut(&Link)
124 ) { 119 ) {
125 self.links(file_resolver, syntax_provider) 120 self.links(syntax_provider)
126 .links 121 .links
127 .iter() 122 .iter()
128 .filter(move |link| link.points_to.iter().any(|&it| it == m)) 123 .filter(move |link| link.points_to.iter().any(|&it| it == m))
@@ -132,12 +127,11 @@ impl ModuleMap {
132 pub fn problems( 127 pub fn problems(
133 &self, 128 &self,
134 file: FileId, 129 file: FileId,
135 file_resolver: &FileResolver,
136 syntax_provider: &SyntaxProvider, 130 syntax_provider: &SyntaxProvider,
137 mut cb: impl FnMut(ast::Name, &Problem), 131 mut cb: impl FnMut(ast::Name, &Problem),
138 ) { 132 ) {
139 let module = self.file2module(file); 133 let module = self.file2module(file);
140 let links = self.links(file_resolver, syntax_provider); 134 let links = self.links(syntax_provider);
141 links 135 links
142 .links 136 .links
143 .iter() 137 .iter()
@@ -151,7 +145,6 @@ impl ModuleMap {
151 145
152 fn links( 146 fn links(
153 &self, 147 &self,
154 file_resolver: &FileResolver,
155 syntax_provider: &SyntaxProvider, 148 syntax_provider: &SyntaxProvider,
156 ) -> RwLockReadGuard<State> { 149 ) -> RwLockReadGuard<State> {
157 { 150 {
@@ -162,7 +155,7 @@ impl ModuleMap {
162 } 155 }
163 let mut guard = self.state.write(); 156 let mut guard = self.state.write();
164 if !guard.changes.is_empty() { 157 if !guard.changes.is_empty() {
165 guard.apply_changes(file_resolver, syntax_provider); 158 guard.apply_changes(syntax_provider);
166 } 159 }
167 assert!(guard.changes.is_empty()); 160 assert!(guard.changes.is_empty());
168 RwLockWriteGuard::downgrade(guard) 161 RwLockWriteGuard::downgrade(guard)
@@ -172,7 +165,6 @@ impl ModuleMap {
172impl State { 165impl State {
173 pub fn apply_changes( 166 pub fn apply_changes(
174 &mut self, 167 &mut self,
175 file_resolver: &FileResolver,
176 syntax_provider: &SyntaxProvider, 168 syntax_provider: &SyntaxProvider,
177 ) { 169 ) {
178 let mut reresolve = false; 170 let mut reresolve = false;
@@ -197,13 +189,14 @@ impl State {
197 } 189 }
198 ChangeKind::Update => { 190 ChangeKind::Update => {
199 let file = syntax_provider(file_id); 191 let file = syntax_provider(file_id);
192 let resolver = &self.file_resolver;
200 self.links.extend( 193 self.links.extend(
201 file 194 file
202 .ast() 195 .ast()
203 .modules() 196 .modules()
204 .filter_map(|it| Link::new(mod_id, it)) 197 .filter_map(|it| Link::new(mod_id, it))
205 .map(|mut link| { 198 .map(|mut link| {
206 link.resolve(file_resolver); 199 link.resolve(resolver);
207 link 200 link
208 }) 201 })
209 ); 202 );
@@ -212,7 +205,7 @@ impl State {
212 } 205 }
213 if reresolve { 206 if reresolve {
214 for link in self.links.iter_mut() { 207 for link in self.links.iter_mut() {
215 link.resolve(file_resolver) 208 link.resolve(&self.file_resolver)
216 } 209 }
217 } 210 }
218 } 211 }
@@ -245,7 +238,7 @@ impl Link {
245 .unwrap() 238 .unwrap()
246 } 239 }
247 240
248 fn resolve(&mut self, file_resolver: &FileResolver) { 241 fn resolve(&mut self, file_resolver: &FileResolverImp) {
249 if !self.ast().has_semi() { 242 if !self.ast().has_semi() {
250 self.problem = None; 243 self.problem = None;
251 self.points_to = Vec::new(); 244 self.points_to = Vec::new();
diff --git a/crates/libanalysis/src/roots.rs b/crates/libanalysis/src/roots.rs
index 6d1375f88..629a697c5 100644
--- a/crates/libanalysis/src/roots.rs
+++ b/crates/libanalysis/src/roots.rs
@@ -12,6 +12,7 @@ use libsyntax2::File;
12 12
13use { 13use {
14 FileId, 14 FileId,
15 imp::FileResolverImp,
15 module_map::{ModuleMap, ChangeKind}, 16 module_map::{ModuleMap, ChangeKind},
16 symbol_index::SymbolIndex, 17 symbol_index::SymbolIndex,
17}; 18};
@@ -48,6 +49,9 @@ impl WritableSourceRoot {
48 self.file_map.insert(file_id, Arc::new((file_data, Default::default()))); 49 self.file_map.insert(file_id, Arc::new((file_data, Default::default())));
49 } 50 }
50 } 51 }
52 pub fn set_file_resolver(&mut self, file_resolver: FileResolverImp) {
53 self.module_map.set_file_resolver(file_resolver)
54 }
51 pub fn reindex(&self) { 55 pub fn reindex(&self) {
52 let now = Instant::now(); 56 let now = Instant::now();
53 self.file_map 57 self.file_map
@@ -136,8 +140,9 @@ pub(crate) struct ReadonlySourceRoot {
136} 140}
137 141
138impl ReadonlySourceRoot { 142impl ReadonlySourceRoot {
139 pub fn new(files: Vec<(FileId, String)>) -> ReadonlySourceRoot { 143 pub(crate) fn new(files: Vec<(FileId, String)>, file_resolver: FileResolverImp) -> ReadonlySourceRoot {
140 let mut module_map = ModuleMap::new(); 144 let mut module_map = ModuleMap::new();
145 module_map.set_file_resolver(file_resolver);
141 let symbol_index = SymbolIndex::for_files( 146 let symbol_index = SymbolIndex::for_files(
142 files.par_iter().map(|(file_id, text)| { 147 files.par_iter().map(|(file_id, text)| {
143 (*file_id, File::parse(text)) 148 (*file_id, File::parse(text))