diff options
Diffstat (limited to 'crates/libanalysis')
-rw-r--r-- | crates/libanalysis/src/api.rs | 35 | ||||
-rw-r--r-- | crates/libanalysis/src/imp.rs | 58 | ||||
-rw-r--r-- | crates/libanalysis/src/lib.rs | 86 |
3 files changed, 92 insertions, 87 deletions
diff --git a/crates/libanalysis/src/api.rs b/crates/libanalysis/src/api.rs index 02eaf7b1c..ded88cd15 100644 --- a/crates/libanalysis/src/api.rs +++ b/crates/libanalysis/src/api.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use relative_path::RelativePathBuf; | 1 | use relative_path::{RelativePath, RelativePathBuf}; |
2 | use libsyntax2::{File, TextRange, TextUnit, AtomEdit}; | 2 | use libsyntax2::{File, TextRange, TextUnit, AtomEdit}; |
3 | use libeditor; | 3 | use libeditor; |
4 | use {imp::AnalysisImpl, FileId, Query}; | 4 | use {imp::{AnalysisImpl, AnalysisHostImpl}, Query}; |
5 | 5 | ||
6 | pub use libeditor::{ | 6 | pub use libeditor::{ |
7 | LocalEdit, StructureNode, LineIndex, FileSymbol, | 7 | LocalEdit, StructureNode, LineIndex, FileSymbol, |
@@ -109,3 +109,34 @@ impl Analysis { | |||
109 | self.imp.diagnostics(file_id) | 109 | self.imp.diagnostics(file_id) |
110 | } | 110 | } |
111 | } | 111 | } |
112 | |||
113 | pub trait FileResolver: Send + Sync + 'static { | ||
114 | fn file_stem(&self, id: FileId) -> String; | ||
115 | fn resolve(&self, id: FileId, path: &RelativePath) -> Option<FileId>; | ||
116 | } | ||
117 | |||
118 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
119 | pub struct FileId(pub u32); | ||
120 | |||
121 | #[derive(Debug)] | ||
122 | pub struct AnalysisHost { | ||
123 | pub(crate) imp: AnalysisHostImpl | ||
124 | } | ||
125 | |||
126 | impl AnalysisHost { | ||
127 | pub fn new() -> AnalysisHost { | ||
128 | AnalysisHost { imp: AnalysisHostImpl::new() } | ||
129 | } | ||
130 | |||
131 | pub fn analysis(&self, file_resolver: impl FileResolver) -> Analysis { | ||
132 | Analysis { imp: self.imp.analysis(file_resolver) } | ||
133 | } | ||
134 | |||
135 | pub fn change_file(&mut self, file_id: FileId, text: Option<String>) { | ||
136 | self.change_files(::std::iter::once((file_id, text))); | ||
137 | } | ||
138 | |||
139 | pub fn change_files(&mut self, changes: impl Iterator<Item=(FileId, Option<String>)>) { | ||
140 | self.imp.change_files(changes) | ||
141 | } | ||
142 | } | ||
diff --git a/crates/libanalysis/src/imp.rs b/crates/libanalysis/src/imp.rs index 5f451f53f..06bbc7cf2 100644 --- a/crates/libanalysis/src/imp.rs +++ b/crates/libanalysis/src/imp.rs | |||
@@ -22,9 +22,65 @@ use { | |||
22 | FileId, FileResolver, Query, Diagnostic, SourceChange, SourceFileEdit, Position, FileSystemEdit, | 22 | FileId, FileResolver, Query, Diagnostic, SourceChange, SourceFileEdit, Position, FileSystemEdit, |
23 | module_map::Problem, | 23 | module_map::Problem, |
24 | symbol_index::FileSymbols, | 24 | symbol_index::FileSymbols, |
25 | module_map::ModuleMap, | 25 | module_map::{ModuleMap, ChangeKind}, |
26 | }; | 26 | }; |
27 | 27 | ||
28 | #[derive(Debug)] | ||
29 | pub(crate) struct AnalysisHostImpl { | ||
30 | data: Arc<WorldData> | ||
31 | } | ||
32 | |||
33 | impl AnalysisHostImpl { | ||
34 | pub fn new() -> AnalysisHostImpl { | ||
35 | AnalysisHostImpl { | ||
36 | data: Arc::new(WorldData::default()), | ||
37 | } | ||
38 | } | ||
39 | |||
40 | pub fn analysis( | ||
41 | &self, | ||
42 | file_resolver: impl FileResolver, | ||
43 | ) -> AnalysisImpl { | ||
44 | AnalysisImpl { | ||
45 | needs_reindex: AtomicBool::new(false), | ||
46 | file_resolver: Arc::new(file_resolver), | ||
47 | data: self.data.clone() | ||
48 | } | ||
49 | } | ||
50 | |||
51 | pub fn change_files(&mut self, changes: impl Iterator<Item=(FileId, Option<String>)>) { | ||
52 | let data = self.data_mut(); | ||
53 | for (file_id, text) in changes { | ||
54 | let change_kind = if data.file_map.remove(&file_id).is_some() { | ||
55 | if text.is_some() { | ||
56 | ChangeKind::Update | ||
57 | } else { | ||
58 | ChangeKind::Delete | ||
59 | } | ||
60 | } else { | ||
61 | ChangeKind::Insert | ||
62 | }; | ||
63 | data.module_map.update_file(file_id, change_kind); | ||
64 | data.file_map.remove(&file_id); | ||
65 | if let Some(text) = text { | ||
66 | let file_data = FileData::new(text); | ||
67 | data.file_map.insert(file_id, Arc::new(file_data)); | ||
68 | } else { | ||
69 | data.file_map.remove(&file_id); | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | |||
74 | fn data_mut(&mut self) -> &mut WorldData { | ||
75 | if Arc::get_mut(&mut self.data).is_none() { | ||
76 | self.data = Arc::new(WorldData { | ||
77 | file_map: self.data.file_map.clone(), | ||
78 | module_map: self.data.module_map.clone(), | ||
79 | }); | ||
80 | } | ||
81 | Arc::get_mut(&mut self.data).unwrap() | ||
82 | } | ||
83 | } | ||
28 | 84 | ||
29 | pub(crate) struct AnalysisImpl { | 85 | pub(crate) struct AnalysisImpl { |
30 | pub(crate) needs_reindex: AtomicBool, | 86 | pub(crate) needs_reindex: AtomicBool, |
diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs index 027d7439b..a39141941 100644 --- a/crates/libanalysis/src/lib.rs +++ b/crates/libanalysis/src/lib.rs | |||
@@ -14,92 +14,10 @@ mod module_map; | |||
14 | mod api; | 14 | mod api; |
15 | mod imp; | 15 | mod imp; |
16 | 16 | ||
17 | use std::{ | ||
18 | sync::{ | ||
19 | Arc, | ||
20 | atomic::{AtomicBool}, | ||
21 | }, | ||
22 | }; | ||
23 | |||
24 | use relative_path::RelativePath; | ||
25 | |||
26 | use self::{ | ||
27 | module_map::{ChangeKind}, | ||
28 | imp::{WorldData, FileData}, | ||
29 | }; | ||
30 | pub use self::symbol_index::Query; | 17 | pub use self::symbol_index::Query; |
31 | pub use self::api::{ | 18 | pub use self::api::{ |
32 | Analysis, SourceChange, SourceFileEdit, FileSystemEdit, Position, Diagnostic, Runnable, RunnableKind | 19 | AnalysisHost, Analysis, SourceChange, SourceFileEdit, FileSystemEdit, Position, Diagnostic, Runnable, RunnableKind, |
20 | FileId, FileResolver, | ||
33 | }; | 21 | }; |
34 | 22 | ||
35 | pub type Result<T> = ::std::result::Result<T, ::failure::Error>; | 23 | pub type Result<T> = ::std::result::Result<T, ::failure::Error>; |
36 | |||
37 | pub trait FileResolver: Send + Sync + 'static { | ||
38 | fn file_stem(&self, id: FileId) -> String; | ||
39 | fn resolve(&self, id: FileId, path: &RelativePath) -> Option<FileId>; | ||
40 | } | ||
41 | |||
42 | #[derive(Debug)] | ||
43 | pub struct WorldState { | ||
44 | data: Arc<WorldData> | ||
45 | } | ||
46 | |||
47 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
48 | pub struct FileId(pub u32); | ||
49 | |||
50 | impl WorldState { | ||
51 | pub fn new() -> WorldState { | ||
52 | WorldState { | ||
53 | data: Arc::new(WorldData::default()), | ||
54 | } | ||
55 | } | ||
56 | |||
57 | pub fn analysis( | ||
58 | &self, | ||
59 | file_resolver: impl FileResolver, | ||
60 | ) -> Analysis { | ||
61 | let imp = imp::AnalysisImpl { | ||
62 | needs_reindex: AtomicBool::new(false), | ||
63 | file_resolver: Arc::new(file_resolver), | ||
64 | data: self.data.clone() | ||
65 | }; | ||
66 | Analysis { imp } | ||
67 | } | ||
68 | |||
69 | pub fn change_file(&mut self, file_id: FileId, text: Option<String>) { | ||
70 | self.change_files(::std::iter::once((file_id, text))); | ||
71 | } | ||
72 | |||
73 | pub fn change_files(&mut self, changes: impl Iterator<Item=(FileId, Option<String>)>) { | ||
74 | let data = self.data_mut(); | ||
75 | for (file_id, text) in changes { | ||
76 | let change_kind = if data.file_map.remove(&file_id).is_some() { | ||
77 | if text.is_some() { | ||
78 | ChangeKind::Update | ||
79 | } else { | ||
80 | ChangeKind::Delete | ||
81 | } | ||
82 | } else { | ||
83 | ChangeKind::Insert | ||
84 | }; | ||
85 | data.module_map.update_file(file_id, change_kind); | ||
86 | data.file_map.remove(&file_id); | ||
87 | if let Some(text) = text { | ||
88 | let file_data = FileData::new(text); | ||
89 | data.file_map.insert(file_id, Arc::new(file_data)); | ||
90 | } else { | ||
91 | data.file_map.remove(&file_id); | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | |||
96 | fn data_mut(&mut self) -> &mut WorldData { | ||
97 | if Arc::get_mut(&mut self.data).is_none() { | ||
98 | self.data = Arc::new(WorldData { | ||
99 | file_map: self.data.file_map.clone(), | ||
100 | module_map: self.data.module_map.clone(), | ||
101 | }); | ||
102 | } | ||
103 | Arc::get_mut(&mut self.data).unwrap() | ||
104 | } | ||
105 | } | ||