aboutsummaryrefslogtreecommitdiff
path: root/crates/server/src/main_loop/handlers.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/server/src/main_loop/handlers.rs')
-rw-r--r--crates/server/src/main_loop/handlers.rs102
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};
8use libanalysis::{World, Query}; 8use libanalysis::{Query};
9use libeditor::{self, CursorPosition}; 9use libeditor::{self, CursorPosition};
10use libsyntax2::TextUnit; 10use libsyntax2::TextUnit;
11use serde_json::{to_value, from_value}; 11use serde_json::{to_value, from_value};
12 12
13use ::{ 13use ::{
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
19pub fn handle_syntax_tree( 19pub 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
29pub fn handle_extend_selection( 28pub 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
45pub fn handle_find_matching_brace( 43pub 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
64pub fn handle_document_symbol( 61pub 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
104pub fn handle_code_action( 100pub 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
129pub fn handle_workspace_symbol( 124pub 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
174pub fn handle_goto_definition( 168pub 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
194pub fn handle_execute_command( 187pub 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
267pub fn publish_diagnostics( 259pub 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
288pub fn publish_decorations( 279pub 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 {