aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_lsp_server/src')
-rw-r--r--crates/ra_lsp_server/src/path_map.rs13
-rw-r--r--crates/ra_lsp_server/src/server_world.rs70
2 files changed, 56 insertions, 27 deletions
diff --git a/crates/ra_lsp_server/src/path_map.rs b/crates/ra_lsp_server/src/path_map.rs
index d32829382..b3d1dc3db 100644
--- a/crates/ra_lsp_server/src/path_map.rs
+++ b/crates/ra_lsp_server/src/path_map.rs
@@ -22,15 +22,18 @@ impl PathMap {
22 pub fn new() -> PathMap { 22 pub fn new() -> PathMap {
23 Default::default() 23 Default::default()
24 } 24 }
25 pub fn get_or_insert(&mut self, path: PathBuf, root: Root) -> FileId { 25 pub fn get_or_insert(&mut self, path: PathBuf, root: Root) -> (bool, FileId) {
26 self.path2id 26 let mut inserted = false;
27 let file_id = self.path2id
27 .get(path.as_path()) 28 .get(path.as_path())
28 .map(|&id| id) 29 .map(|&id| id)
29 .unwrap_or_else(|| { 30 .unwrap_or_else(|| {
31 inserted = true;
30 let id = self.new_file_id(); 32 let id = self.new_file_id();
31 self.insert(path, id, root); 33 self.insert(path, id, root);
32 id 34 id
33 }) 35 });
36 (inserted, file_id)
34 } 37 }
35 pub fn get_id(&self, path: &Path) -> Option<FileId> { 38 pub fn get_id(&self, path: &Path) -> Option<FileId> {
36 self.path2id.get(path).map(|&id| id) 39 self.path2id.get(path).map(|&id| id)
@@ -105,8 +108,8 @@ mod test {
105 #[test] 108 #[test]
106 fn test_resolve() { 109 fn test_resolve() {
107 let mut m = PathMap::new(); 110 let mut m = PathMap::new();
108 let id1 = m.get_or_insert(PathBuf::from("/foo"), Root::Workspace); 111 let (_, id1) = m.get_or_insert(PathBuf::from("/foo"), Root::Workspace);
109 let id2 = m.get_or_insert(PathBuf::from("/foo/bar.rs"), Root::Workspace); 112 let (_, id2) = m.get_or_insert(PathBuf::from("/foo/bar.rs"), Root::Workspace);
110 assert_eq!(m.resolve(id1, &RelativePath::new("bar.rs")), Some(id2),) 113 assert_eq!(m.resolve(id1, &RelativePath::new("bar.rs")), Some(id2),)
111 } 114 }
112} 115}
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs
index 69b2a1cd1..555de66ff 100644
--- a/crates/ra_lsp_server/src/server_world.rs
+++ b/crates/ra_lsp_server/src/server_world.rs
@@ -2,10 +2,11 @@ use std::{
2 fs, 2 fs,
3 path::{Path, PathBuf}, 3 path::{Path, PathBuf},
4 sync::Arc, 4 sync::Arc,
5 collections::BTreeMap,
5}; 6};
6 7
7use languageserver_types::Url; 8use languageserver_types::Url;
8use ra_analysis::{Analysis, AnalysisHost, CrateGraph, CrateId, FileId, FileResolver, LibraryData}; 9use ra_analysis::{Analysis, AnalysisHost, AnalysisChange, CrateGraph, CrateId, FileId, FileResolver, LibraryData};
9use rustc_hash::FxHashMap; 10use rustc_hash::FxHashMap;
10 11
11use crate::{ 12use crate::{
@@ -39,30 +40,40 @@ impl ServerWorldState {
39 } 40 }
40 } 41 }
41 pub fn apply_fs_changes(&mut self, events: Vec<FileEvent>) { 42 pub fn apply_fs_changes(&mut self, events: Vec<FileEvent>) {
43 let mut change = AnalysisChange::new();
44 let mut inserted = false;
42 { 45 {
43 let pm = &mut self.path_map; 46 let pm = &mut self.path_map;
44 let mm = &mut self.mem_map; 47 let mm = &mut self.mem_map;
45 let changes = events 48 events
46 .into_iter() 49 .into_iter()
47 .map(|event| { 50 .map(|event| {
48 let text = match event.kind { 51 let text = match event.kind {
49 FileEventKind::Add(text) => Some(text), 52 FileEventKind::Add(text) => text,
50 }; 53 };
51 (event.path, text) 54 (event.path, text)
52 }) 55 })
53 .map(|(path, text)| (pm.get_or_insert(path, Root::Workspace), text)) 56 .map(|(path, text)| {
54 .filter_map(|(id, text)| { 57 let (ins, file_id) = pm.get_or_insert(path, Root::Workspace);
55 if mm.contains_key(&id) { 58 inserted |= ins;
56 mm.insert(id, text); 59 (file_id, text)
60 })
61 .filter_map(|(file_id, text)| {
62 if mm.contains_key(&file_id) {
63 mm.insert(file_id, Some(text));
57 None 64 None
58 } else { 65 } else {
59 Some((id, text)) 66 Some((file_id, text))
60 } 67 }
68 })
69 .for_each(|(file_id, text)| {
70 change.add_file(file_id, text)
61 }); 71 });
62 self.analysis_host.change_files(changes);
63 } 72 }
64 self.analysis_host 73 if inserted {
65 .set_file_resolver(Arc::new(self.path_map.clone())); 74 change.set_file_resolver(Arc::new(self.path_map.clone()))
75 }
76 self.analysis_host.apply_change(change);
66 } 77 }
67 pub fn events_to_files( 78 pub fn events_to_files(
68 &mut self, 79 &mut self,
@@ -76,24 +87,31 @@ impl ServerWorldState {
76 let FileEventKind::Add(text) = event.kind; 87 let FileEventKind::Add(text) = event.kind;
77 (event.path, text) 88 (event.path, text)
78 }) 89 })
79 .map(|(path, text)| (pm.get_or_insert(path, Root::Lib), text)) 90 .map(|(path, text)| (pm.get_or_insert(path, Root::Lib).1, text))
80 .collect() 91 .collect()
81 }; 92 };
82 let resolver = Arc::new(self.path_map.clone()); 93 let resolver = Arc::new(self.path_map.clone());
83 (files, resolver) 94 (files, resolver)
84 } 95 }
85 pub fn add_lib(&mut self, data: LibraryData) { 96 pub fn add_lib(&mut self, data: LibraryData) {
86 self.analysis_host.add_library(data); 97 let mut change = AnalysisChange::new();
98 change.add_library(data);
99 self.analysis_host.apply_change(change);
87 } 100 }
88 101
89 pub fn add_mem_file(&mut self, path: PathBuf, text: String) -> FileId { 102 pub fn add_mem_file(&mut self, path: PathBuf, text: String) -> FileId {
90 let file_id = self.path_map.get_or_insert(path, Root::Workspace); 103 let (inserted, file_id) = self.path_map.get_or_insert(path, Root::Workspace);
91 self.analysis_host
92 .set_file_resolver(Arc::new(self.path_map.clone()));
93 self.mem_map.insert(file_id, None);
94 if self.path_map.get_root(file_id) != Root::Lib { 104 if self.path_map.get_root(file_id) != Root::Lib {
95 self.analysis_host.change_file(file_id, Some(text)); 105 let mut change = AnalysisChange::new();
106 if inserted {
107 change.add_file(file_id, text);
108 change.set_file_resolver(Arc::new(self.path_map.clone()));
109 } else {
110 change.change_file(file_id, text);
111 }
112 self.analysis_host.apply_change(change);
96 } 113 }
114 self.mem_map.insert(file_id, None);
97 file_id 115 file_id
98 } 116 }
99 117
@@ -103,7 +121,9 @@ impl ServerWorldState {
103 .get_id(path) 121 .get_id(path)
104 .ok_or_else(|| format_err!("change to unknown file: {}", path.display()))?; 122 .ok_or_else(|| format_err!("change to unknown file: {}", path.display()))?;
105 if self.path_map.get_root(file_id) != Root::Lib { 123 if self.path_map.get_root(file_id) != Root::Lib {
106 self.analysis_host.change_file(file_id, Some(text)); 124 let mut change = AnalysisChange::new();
125 change.change_file(file_id, text);
126 self.analysis_host.apply_change(change);
107 } 127 }
108 Ok(()) 128 Ok(())
109 } 129 }
@@ -120,12 +140,16 @@ impl ServerWorldState {
120 // Do this via file watcher ideally. 140 // Do this via file watcher ideally.
121 let text = fs::read_to_string(path).ok(); 141 let text = fs::read_to_string(path).ok();
122 if self.path_map.get_root(file_id) != Root::Lib { 142 if self.path_map.get_root(file_id) != Root::Lib {
123 self.analysis_host.change_file(file_id, text); 143 let mut change = AnalysisChange::new();
144 if let Some(text) = text {
145 change.change_file(file_id, text);
146 }
147 self.analysis_host.apply_change(change);
124 } 148 }
125 Ok(file_id) 149 Ok(file_id)
126 } 150 }
127 pub fn set_workspaces(&mut self, ws: Vec<CargoWorkspace>) { 151 pub fn set_workspaces(&mut self, ws: Vec<CargoWorkspace>) {
128 let mut crate_roots = FxHashMap::default(); 152 let mut crate_roots = BTreeMap::default();
129 ws.iter() 153 ws.iter()
130 .flat_map(|ws| { 154 .flat_map(|ws| {
131 ws.packages() 155 ws.packages()
@@ -140,7 +164,9 @@ impl ServerWorldState {
140 }); 164 });
141 let crate_graph = CrateGraph { crate_roots }; 165 let crate_graph = CrateGraph { crate_roots };
142 self.workspaces = Arc::new(ws); 166 self.workspaces = Arc::new(ws);
143 self.analysis_host.set_crate_graph(crate_graph); 167 let mut change = AnalysisChange::new();
168 change.set_crate_graph(crate_graph);
169 self.analysis_host.apply_change(change);
144 } 170 }
145 pub fn snapshot(&self) -> ServerWorld { 171 pub fn snapshot(&self) -> ServerWorld {
146 ServerWorld { 172 ServerWorld {