diff options
author | Aleksey Kladov <[email protected]> | 2018-10-25 08:57:55 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-10-25 14:25:40 +0100 |
commit | ee4d904cfb1b604bc8627491e05980ac43cd59e3 (patch) | |
tree | 54d1b937de544b8f6a8f2821ad9599aa82192375 /crates/ra_lsp_server/src/server_world.rs | |
parent | 2cb2074c4b7219b32993abdcc7084637c0123d49 (diff) |
Store all the data in the Salsa Database
Diffstat (limited to 'crates/ra_lsp_server/src/server_world.rs')
-rw-r--r-- | crates/ra_lsp_server/src/server_world.rs | 70 |
1 files changed, 48 insertions, 22 deletions
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 | ||
7 | use languageserver_types::Url; | 8 | use languageserver_types::Url; |
8 | use ra_analysis::{Analysis, AnalysisHost, CrateGraph, CrateId, FileId, FileResolver, LibraryData}; | 9 | use ra_analysis::{Analysis, AnalysisHost, AnalysisChange, CrateGraph, CrateId, FileId, FileResolver, LibraryData}; |
9 | use rustc_hash::FxHashMap; | 10 | use rustc_hash::FxHashMap; |
10 | 11 | ||
11 | use crate::{ | 12 | use 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 { |