diff options
Diffstat (limited to 'crates/server/src/main_loop/handlers.rs')
-rw-r--r-- | crates/server/src/main_loop/handlers.rs | 102 |
1 files changed, 46 insertions, 56 deletions
diff --git a/crates/server/src/main_loop/handlers.rs b/crates/server/src/main_loop/handlers.rs index f25c64c97..675f69bec 100644 --- a/crates/server/src/main_loop/handlers.rs +++ b/crates/server/src/main_loop/handlers.rs | |||
@@ -5,35 +5,33 @@ use languageserver_types::{ | |||
5 | Command, TextDocumentIdentifier, WorkspaceEdit, | 5 | Command, TextDocumentIdentifier, WorkspaceEdit, |
6 | SymbolInformation, Position, | 6 | SymbolInformation, Position, |
7 | }; | 7 | }; |
8 | use libanalysis::{World, Query}; | 8 | use libanalysis::{Query}; |
9 | use libeditor::{self, CursorPosition}; | 9 | use libeditor::{self, CursorPosition}; |
10 | use libsyntax2::TextUnit; | 10 | use libsyntax2::TextUnit; |
11 | use serde_json::{to_value, from_value}; | 11 | use serde_json::{to_value, from_value}; |
12 | 12 | ||
13 | use ::{ | 13 | use ::{ |
14 | PathMap, | ||
15 | req::{self, Decoration}, Result, | 14 | req::{self, Decoration}, Result, |
16 | conv::{Conv, ConvWith, TryConvWith, MapConvWith, to_location}, | 15 | conv::{Conv, ConvWith, TryConvWith, MapConvWith, to_location}, |
16 | server_world::ServerWorld, | ||
17 | }; | 17 | }; |
18 | 18 | ||
19 | pub fn handle_syntax_tree( | 19 | pub fn handle_syntax_tree( |
20 | world: World, | 20 | world: ServerWorld, |
21 | path_map: PathMap, | ||
22 | params: req::SyntaxTreeParams, | 21 | params: req::SyntaxTreeParams, |
23 | ) -> Result<String> { | 22 | ) -> Result<String> { |
24 | let id = params.text_document.try_conv_with(&path_map)?; | 23 | let id = params.text_document.try_conv_with(&world)?; |
25 | let file = world.file_syntax(id)?; | 24 | let file = world.analysis().file_syntax(id)?; |
26 | Ok(libeditor::syntax_tree(&file)) | 25 | Ok(libeditor::syntax_tree(&file)) |
27 | } | 26 | } |
28 | 27 | ||
29 | pub fn handle_extend_selection( | 28 | pub fn handle_extend_selection( |
30 | world: World, | 29 | world: ServerWorld, |
31 | path_map: PathMap, | ||
32 | params: req::ExtendSelectionParams, | 30 | params: req::ExtendSelectionParams, |
33 | ) -> Result<req::ExtendSelectionResult> { | 31 | ) -> Result<req::ExtendSelectionResult> { |
34 | let file_id = params.text_document.try_conv_with(&path_map)?; | 32 | let file_id = params.text_document.try_conv_with(&world)?; |
35 | let file = world.file_syntax(file_id)?; | 33 | let file = world.analysis().file_syntax(file_id)?; |
36 | let line_index = world.file_line_index(file_id)?; | 34 | let line_index = world.analysis().file_line_index(file_id)?; |
37 | let selections = params.selections.into_iter() | 35 | let selections = params.selections.into_iter() |
38 | .map_conv_with(&line_index) | 36 | .map_conv_with(&line_index) |
39 | .map(|r| libeditor::extend_selection(&file, r).unwrap_or(r)) | 37 | .map(|r| libeditor::extend_selection(&file, r).unwrap_or(r)) |
@@ -43,13 +41,12 @@ pub fn handle_extend_selection( | |||
43 | } | 41 | } |
44 | 42 | ||
45 | pub fn handle_find_matching_brace( | 43 | pub fn handle_find_matching_brace( |
46 | world: World, | 44 | world: ServerWorld, |
47 | path_map: PathMap, | ||
48 | params: req::FindMatchingBraceParams, | 45 | params: req::FindMatchingBraceParams, |
49 | ) -> Result<Vec<Position>> { | 46 | ) -> Result<Vec<Position>> { |
50 | let file_id = params.text_document.try_conv_with(&path_map)?; | 47 | let file_id = params.text_document.try_conv_with(&world)?; |
51 | let file = world.file_syntax(file_id)?; | 48 | let file = world.analysis().file_syntax(file_id)?; |
52 | let line_index = world.file_line_index(file_id)?; | 49 | let line_index = world.analysis().file_line_index(file_id)?; |
53 | let res = params.offsets | 50 | let res = params.offsets |
54 | .into_iter() | 51 | .into_iter() |
55 | .map_conv_with(&line_index) | 52 | .map_conv_with(&line_index) |
@@ -62,13 +59,12 @@ pub fn handle_find_matching_brace( | |||
62 | } | 59 | } |
63 | 60 | ||
64 | pub fn handle_document_symbol( | 61 | pub fn handle_document_symbol( |
65 | world: World, | 62 | world: ServerWorld, |
66 | path_map: PathMap, | ||
67 | params: req::DocumentSymbolParams, | 63 | params: req::DocumentSymbolParams, |
68 | ) -> Result<Option<req::DocumentSymbolResponse>> { | 64 | ) -> Result<Option<req::DocumentSymbolResponse>> { |
69 | let file_id = params.text_document.try_conv_with(&path_map)?; | 65 | let file_id = params.text_document.try_conv_with(&world)?; |
70 | let file = world.file_syntax(file_id)?; | 66 | let file = world.analysis().file_syntax(file_id)?; |
71 | let line_index = world.file_line_index(file_id)?; | 67 | let line_index = world.analysis().file_line_index(file_id)?; |
72 | 68 | ||
73 | let mut parents: Vec<(DocumentSymbol, Option<usize>)> = Vec::new(); | 69 | let mut parents: Vec<(DocumentSymbol, Option<usize>)> = Vec::new(); |
74 | 70 | ||
@@ -102,13 +98,12 @@ pub fn handle_document_symbol( | |||
102 | } | 98 | } |
103 | 99 | ||
104 | pub fn handle_code_action( | 100 | pub fn handle_code_action( |
105 | world: World, | 101 | world: ServerWorld, |
106 | path_map: PathMap, | ||
107 | params: req::CodeActionParams, | 102 | params: req::CodeActionParams, |
108 | ) -> Result<Option<Vec<Command>>> { | 103 | ) -> Result<Option<Vec<Command>>> { |
109 | let file_id = params.text_document.try_conv_with(&path_map)?; | 104 | let file_id = params.text_document.try_conv_with(&world)?; |
110 | let file = world.file_syntax(file_id)?; | 105 | let file = world.analysis().file_syntax(file_id)?; |
111 | let line_index = world.file_line_index(file_id)?; | 106 | let line_index = world.analysis().file_line_index(file_id)?; |
112 | let offset = params.range.conv_with(&line_index).start(); | 107 | let offset = params.range.conv_with(&line_index).start(); |
113 | let mut ret = Vec::new(); | 108 | let mut ret = Vec::new(); |
114 | 109 | ||
@@ -127,8 +122,7 @@ pub fn handle_code_action( | |||
127 | } | 122 | } |
128 | 123 | ||
129 | pub fn handle_workspace_symbol( | 124 | pub fn handle_workspace_symbol( |
130 | world: World, | 125 | world: ServerWorld, |
131 | path_map: PathMap, | ||
132 | params: req::WorkspaceSymbolParams, | 126 | params: req::WorkspaceSymbolParams, |
133 | ) -> Result<Option<Vec<SymbolInformation>>> { | 127 | ) -> Result<Option<Vec<SymbolInformation>>> { |
134 | let all_symbols = params.query.contains("#"); | 128 | let all_symbols = params.query.contains("#"); |
@@ -143,25 +137,25 @@ pub fn handle_workspace_symbol( | |||
143 | q.limit(128); | 137 | q.limit(128); |
144 | q | 138 | q |
145 | }; | 139 | }; |
146 | let mut res = exec_query(&world, &path_map, query)?; | 140 | let mut res = exec_query(&world, query)?; |
147 | if res.is_empty() && !all_symbols { | 141 | if res.is_empty() && !all_symbols { |
148 | let mut query = Query::new(params.query); | 142 | let mut query = Query::new(params.query); |
149 | query.limit(128); | 143 | query.limit(128); |
150 | res = exec_query(&world, &path_map, query)?; | 144 | res = exec_query(&world, query)?; |
151 | } | 145 | } |
152 | 146 | ||
153 | return Ok(Some(res)); | 147 | return Ok(Some(res)); |
154 | 148 | ||
155 | fn exec_query(world: &World, path_map: &PathMap, query: Query) -> Result<Vec<SymbolInformation>> { | 149 | fn exec_query(world: &ServerWorld, query: Query) -> Result<Vec<SymbolInformation>> { |
156 | let mut res = Vec::new(); | 150 | let mut res = Vec::new(); |
157 | for (file_id, symbol) in world.world_symbols(query) { | 151 | for (file_id, symbol) in world.analysis().world_symbols(query) { |
158 | let line_index = world.file_line_index(file_id)?; | 152 | let line_index = world.analysis().file_line_index(file_id)?; |
159 | let info = SymbolInformation { | 153 | let info = SymbolInformation { |
160 | name: symbol.name.to_string(), | 154 | name: symbol.name.to_string(), |
161 | kind: symbol.kind.conv(), | 155 | kind: symbol.kind.conv(), |
162 | location: to_location( | 156 | location: to_location( |
163 | file_id, symbol.node_range, | 157 | file_id, symbol.node_range, |
164 | path_map, &line_index | 158 | world, &line_index |
165 | )?, | 159 | )?, |
166 | container_name: None, | 160 | container_name: None, |
167 | }; | 161 | }; |
@@ -172,19 +166,18 @@ pub fn handle_workspace_symbol( | |||
172 | } | 166 | } |
173 | 167 | ||
174 | pub fn handle_goto_definition( | 168 | pub fn handle_goto_definition( |
175 | world: World, | 169 | world: ServerWorld, |
176 | path_map: PathMap, | ||
177 | params: req::TextDocumentPositionParams, | 170 | params: req::TextDocumentPositionParams, |
178 | ) -> Result<Option<req::GotoDefinitionResponse>> { | 171 | ) -> Result<Option<req::GotoDefinitionResponse>> { |
179 | let file_id = params.text_document.try_conv_with(&path_map)?; | 172 | let file_id = params.text_document.try_conv_with(&world)?; |
180 | let line_index = world.file_line_index(file_id)?; | 173 | let line_index = world.analysis().file_line_index(file_id)?; |
181 | let offset = params.position.conv_with(&line_index); | 174 | let offset = params.position.conv_with(&line_index); |
182 | let mut res = Vec::new(); | 175 | let mut res = Vec::new(); |
183 | for (file_id, symbol) in world.approximately_resolve_symbol(file_id, offset)? { | 176 | for (file_id, symbol) in world.analysis().approximately_resolve_symbol(file_id, offset)? { |
184 | let line_index = world.file_line_index(file_id)?; | 177 | let line_index = world.analysis().file_line_index(file_id)?; |
185 | let location = to_location( | 178 | let location = to_location( |
186 | file_id, symbol.node_range, | 179 | file_id, symbol.node_range, |
187 | &path_map, &line_index, | 180 | &world, &line_index, |
188 | )?; | 181 | )?; |
189 | res.push(location) | 182 | res.push(location) |
190 | } | 183 | } |
@@ -192,8 +185,7 @@ pub fn handle_goto_definition( | |||
192 | } | 185 | } |
193 | 186 | ||
194 | pub fn handle_execute_command( | 187 | pub fn handle_execute_command( |
195 | world: World, | 188 | world: ServerWorld, |
196 | path_map: PathMap, | ||
197 | mut params: req::ExecuteCommandParams, | 189 | mut params: req::ExecuteCommandParams, |
198 | ) -> Result<(req::ApplyWorkspaceEditParams, Option<Position>)> { | 190 | ) -> Result<(req::ApplyWorkspaceEditParams, Option<Position>)> { |
199 | if params.command.as_str() != "apply_code_action" { | 191 | if params.command.as_str() != "apply_code_action" { |
@@ -204,13 +196,13 @@ pub fn handle_execute_command( | |||
204 | } | 196 | } |
205 | let arg = params.arguments.pop().unwrap(); | 197 | let arg = params.arguments.pop().unwrap(); |
206 | let arg: ActionRequest = from_value(arg)?; | 198 | let arg: ActionRequest = from_value(arg)?; |
207 | let file_id = arg.text_document.try_conv_with(&path_map)?; | 199 | let file_id = arg.text_document.try_conv_with(&world)?; |
208 | let file = world.file_syntax(file_id)?; | 200 | let file = world.analysis().file_syntax(file_id)?; |
209 | let action_result = match arg.id { | 201 | let action_result = match arg.id { |
210 | ActionId::FlipComma => libeditor::flip_comma(&file, arg.offset).map(|f| f()), | 202 | ActionId::FlipComma => libeditor::flip_comma(&file, arg.offset).map(|f| f()), |
211 | ActionId::AddDerive => libeditor::add_derive(&file, arg.offset).map(|f| f()), | 203 | ActionId::AddDerive => libeditor::add_derive(&file, arg.offset).map(|f| f()), |
212 | }.ok_or_else(|| format_err!("command not applicable"))?; | 204 | }.ok_or_else(|| format_err!("command not applicable"))?; |
213 | let line_index = world.file_line_index(file_id)?; | 205 | let line_index = world.analysis().file_line_index(file_id)?; |
214 | let mut changes = HashMap::new(); | 206 | let mut changes = HashMap::new(); |
215 | changes.insert( | 207 | changes.insert( |
216 | arg.text_document.uri, | 208 | arg.text_document.uri, |
@@ -265,13 +257,12 @@ impl ActionId { | |||
265 | } | 257 | } |
266 | 258 | ||
267 | pub fn publish_diagnostics( | 259 | pub fn publish_diagnostics( |
268 | world: World, | 260 | world: ServerWorld, |
269 | path_map: PathMap, | ||
270 | uri: Url | 261 | uri: Url |
271 | ) -> Result<req::PublishDiagnosticsParams> { | 262 | ) -> Result<req::PublishDiagnosticsParams> { |
272 | let file_id = uri.try_conv_with(&path_map)?; | 263 | let file_id = world.uri_to_file_id(&uri)?; |
273 | let file = world.file_syntax(file_id)?; | 264 | let file = world.analysis().file_syntax(file_id)?; |
274 | let line_index = world.file_line_index(file_id)?; | 265 | let line_index = world.analysis().file_line_index(file_id)?; |
275 | let diagnostics = libeditor::diagnostics(&file) | 266 | let diagnostics = libeditor::diagnostics(&file) |
276 | .into_iter() | 267 | .into_iter() |
277 | .map(|d| Diagnostic { | 268 | .map(|d| Diagnostic { |
@@ -286,13 +277,12 @@ pub fn publish_diagnostics( | |||
286 | } | 277 | } |
287 | 278 | ||
288 | pub fn publish_decorations( | 279 | pub fn publish_decorations( |
289 | world: World, | 280 | world: ServerWorld, |
290 | path_map: PathMap, | ||
291 | uri: Url | 281 | uri: Url |
292 | ) -> Result<req::PublishDecorationsParams> { | 282 | ) -> Result<req::PublishDecorationsParams> { |
293 | let file_id = uri.try_conv_with(&path_map)?; | 283 | let file_id = world.uri_to_file_id(&uri)?; |
294 | let file = world.file_syntax(file_id)?; | 284 | let file = world.analysis().file_syntax(file_id)?; |
295 | let line_index = world.file_line_index(file_id)?; | 285 | let line_index = world.analysis().file_line_index(file_id)?; |
296 | let decorations = libeditor::highlight(&file) | 286 | let decorations = libeditor::highlight(&file) |
297 | .into_iter() | 287 | .into_iter() |
298 | .map(|h| Decoration { | 288 | .map(|h| Decoration { |