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.rs86
1 files changed, 2 insertions, 84 deletions
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;
14mod api; 14mod api;
15mod imp; 15mod imp;
16 16
17use std::{
18 sync::{
19 Arc,
20 atomic::{AtomicBool},
21 },
22};
23
24use relative_path::RelativePath;
25
26use self::{
27 module_map::{ChangeKind},
28 imp::{WorldData, FileData},
29};
30pub use self::symbol_index::Query; 17pub use self::symbol_index::Query;
31pub use self::api::{ 18pub 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
35pub type Result<T> = ::std::result::Result<T, ::failure::Error>; 23pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
36
37pub 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)]
43pub struct WorldState {
44 data: Arc<WorldData>
45}
46
47#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
48pub struct FileId(pub u32);
49
50impl 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}