aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_lsp_server')
-rw-r--r--crates/ra_lsp_server/src/caps.rs10
-rw-r--r--crates/ra_lsp_server/src/conv.rs3
-rw-r--r--crates/ra_lsp_server/src/lib.rs2
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs87
-rw-r--r--crates/ra_lsp_server/src/main_loop/mod.rs31
-rw-r--r--crates/ra_lsp_server/src/path_map.rs3
-rw-r--r--crates/ra_lsp_server/src/req.rs4
-rw-r--r--crates/ra_lsp_server/src/server_world.rs8
8 files changed, 74 insertions, 74 deletions
diff --git a/crates/ra_lsp_server/src/caps.rs b/crates/ra_lsp_server/src/caps.rs
index b6436b646..ac6aacfd3 100644
--- a/crates/ra_lsp_server/src/caps.rs
+++ b/crates/ra_lsp_server/src/caps.rs
@@ -1,8 +1,8 @@
1use languageserver_types::{ 1use languageserver_types::{
2 CodeActionProviderCapability, CompletionOptions, DocumentOnTypeFormattingOptions, 2 CodeActionProviderCapability, CompletionOptions, DocumentOnTypeFormattingOptions,
3 ExecuteCommandOptions, FoldingRangeProviderCapability, ServerCapabilities, 3 ExecuteCommandOptions, FoldingRangeProviderCapability, RenameOptions, RenameProviderCapability,
4 SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind, 4 ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind,
5 TextDocumentSyncOptions, RenameProviderCapability, RenameOptions 5 TextDocumentSyncOptions,
6}; 6};
7 7
8pub fn server_capabilities() -> ServerCapabilities { 8pub fn server_capabilities() -> ServerCapabilities {
@@ -40,8 +40,8 @@ pub fn server_capabilities() -> ServerCapabilities {
40 more_trigger_character: None, 40 more_trigger_character: None,
41 }), 41 }),
42 folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)), 42 folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)),
43 rename_provider: Some(RenameProviderCapability::Options(RenameOptions{ 43 rename_provider: Some(RenameProviderCapability::Options(RenameOptions {
44 prepare_provider: Some(true) 44 prepare_provider: Some(true),
45 })), 45 })),
46 color_provider: None, 46 color_provider: None,
47 execute_command_provider: Some(ExecuteCommandOptions { 47 execute_command_provider: Some(ExecuteCommandOptions {
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs
index bc0cf7c68..84ffac2da 100644
--- a/crates/ra_lsp_server/src/conv.rs
+++ b/crates/ra_lsp_server/src/conv.rs
@@ -192,7 +192,8 @@ impl TryConvWith for SourceChange {
192 .map(|it| it.edits.as_slice()) 192 .map(|it| it.edits.as_slice())
193 .unwrap_or(&[]); 193 .unwrap_or(&[]);
194 let line_col = translate_offset_with_edit(&*line_index, pos.offset, edits); 194 let line_col = translate_offset_with_edit(&*line_index, pos.offset, edits);
195 let position = Position::new(u64::from(line_col.line), u64::from(u32::from(line_col.col))); 195 let position =
196 Position::new(u64::from(line_col.line), u64::from(u32::from(line_col.col)));
196 Some(TextDocumentPositionParams { 197 Some(TextDocumentPositionParams {
197 text_document: TextDocumentIdentifier::new(pos.file_id.try_conv_with(world)?), 198 text_document: TextDocumentIdentifier::new(pos.file_id.try_conv_with(world)?),
198 position, 199 position,
diff --git a/crates/ra_lsp_server/src/lib.rs b/crates/ra_lsp_server/src/lib.rs
index ce77b2a33..f9481e04d 100644
--- a/crates/ra_lsp_server/src/lib.rs
+++ b/crates/ra_lsp_server/src/lib.rs
@@ -36,4 +36,4 @@ pub mod thread_watcher;
36mod vfs; 36mod vfs;
37 37
38pub type Result<T> = ::std::result::Result<T, ::failure::Error>; 38pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
39pub use crate::{caps::server_capabilities, main_loop::main_loop, main_loop::LspError}; \ No newline at end of file 39pub use crate::{caps::server_capabilities, main_loop::main_loop, main_loop::LspError};
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index 20cb5f772..c853ff653 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -1,15 +1,16 @@
1use std::collections::HashMap; 1use std::collections::HashMap;
2 2
3use rustc_hash::FxHashMap; 3use gen_lsp_server::ErrorCode;
4use languageserver_types::{ 4use languageserver_types::{
5 CodeActionResponse, Command, CompletionItem, CompletionItemKind, Diagnostic, 5 CodeActionResponse, Command, CompletionItem, CompletionItemKind, Diagnostic,
6 DiagnosticSeverity, DocumentSymbol, FoldingRange, FoldingRangeKind, FoldingRangeParams, 6 DiagnosticSeverity, DocumentSymbol, Documentation, FoldingRange, FoldingRangeKind,
7 InsertTextFormat, Location, Position, SymbolInformation, TextDocumentIdentifier, TextEdit, 7 FoldingRangeParams, InsertTextFormat, Location, MarkupContent, MarkupKind, Position,
8 RenameParams, WorkspaceEdit, PrepareRenameResponse, Documentation, MarkupContent, MarkupKind 8 PrepareRenameResponse, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit,
9 WorkspaceEdit,
9}; 10};
10use gen_lsp_server::ErrorCode;
11use ra_analysis::{FileId, FoldKind, Query, RunnableKind}; 11use ra_analysis::{FileId, FoldKind, Query, RunnableKind};
12use ra_syntax::text_utils::contains_offset_nonstrict; 12use ra_syntax::text_utils::contains_offset_nonstrict;
13use rustc_hash::FxHashMap;
13use serde_json::to_value; 14use serde_json::to_value;
14 15
15use crate::{ 16use crate::{
@@ -17,13 +18,10 @@ use crate::{
17 project_model::TargetKind, 18 project_model::TargetKind,
18 req::{self, Decoration}, 19 req::{self, Decoration},
19 server_world::ServerWorld, 20 server_world::ServerWorld,
20 Result, LspError 21 LspError, Result,
21}; 22};
22 23
23pub fn handle_syntax_tree( 24pub fn handle_syntax_tree(world: ServerWorld, params: req::SyntaxTreeParams) -> Result<String> {
24 world: ServerWorld,
25 params: req::SyntaxTreeParams,
26) -> Result<String> {
27 let id = params.text_document.try_conv_with(&world)?; 25 let id = params.text_document.try_conv_with(&world)?;
28 let res = world.analysis().syntax_tree(id); 26 let res = world.analysis().syntax_tree(id);
29 Ok(res) 27 Ok(res)
@@ -182,10 +180,7 @@ pub fn handle_workspace_symbol(
182 180
183 return Ok(Some(res)); 181 return Ok(Some(res));
184 182
185 fn exec_query( 183 fn exec_query(world: &ServerWorld, query: Query) -> Result<Vec<SymbolInformation>> {
186 world: &ServerWorld,
187 query: Query,
188 ) -> Result<Vec<SymbolInformation>> {
189 let mut res = Vec::new(); 184 let mut res = Vec::new();
190 for (file_id, symbol) in world.analysis().symbol_search(query)? { 185 for (file_id, symbol) in world.analysis().symbol_search(query)? {
191 let line_index = world.analysis().file_line_index(file_id); 186 let line_index = world.analysis().file_line_index(file_id);
@@ -290,7 +285,11 @@ pub fn handle_runnables(
290 }); 285 });
291 return Ok(res); 286 return Ok(res);
292 287
293 fn runnable_args(world: &ServerWorld, file_id: FileId, kind: &RunnableKind) -> Result<Vec<String>> { 288 fn runnable_args(
289 world: &ServerWorld,
290 file_id: FileId,
291 kind: &RunnableKind,
292 ) -> Result<Vec<String>> {
294 let spec = CargoTargetSpec::for_file(world, file_id)?; 293 let spec = CargoTargetSpec::for_file(world, file_id)?;
295 let mut res = Vec::new(); 294 let mut res = Vec::new();
296 match kind { 295 match kind {
@@ -327,18 +326,15 @@ pub fn handle_runnables(
327 }; 326 };
328 let file_id = world.analysis().crate_root(crate_id)?; 327 let file_id = world.analysis().crate_root(crate_id)?;
329 let path = world.path_map.get_path(file_id); 328 let path = world.path_map.get_path(file_id);
330 let res = world 329 let res = world.workspaces.iter().find_map(|ws| {
331 .workspaces 330 let tgt = ws.target_by_root(path)?;
332 .iter() 331 let res = CargoTargetSpec {
333 .find_map(|ws| { 332 package: tgt.package(ws).name(ws).to_string(),
334 let tgt = ws.target_by_root(path)?; 333 target: tgt.name(ws).to_string(),
335 let res = CargoTargetSpec { 334 target_kind: tgt.kind(ws),
336 package: tgt.package(ws).name(ws).to_string(), 335 };
337 target: tgt.name(ws).to_string(), 336 Some(res)
338 target_kind: tgt.kind(ws), 337 });
339 };
340 Some(res)
341 });
342 Ok(res) 338 Ok(res)
343 } 339 }
344 340
@@ -367,7 +363,6 @@ pub fn handle_runnables(
367 } 363 }
368 TargetKind::Other => (), 364 TargetKind::Other => (),
369 } 365 }
370
371 } 366 }
372 } 367 }
373} 368}
@@ -453,9 +448,7 @@ pub fn handle_signature_help(
453 let line_index = world.analysis().file_line_index(file_id); 448 let line_index = world.analysis().file_line_index(file_id);
454 let offset = params.position.conv_with(&line_index); 449 let offset = params.position.conv_with(&line_index);
455 450
456 if let Some((descriptor, active_param)) = 451 if let Some((descriptor, active_param)) = world.analysis().resolve_callable(file_id, offset)? {
457 world.analysis().resolve_callable(file_id, offset)?
458 {
459 let parameters: Vec<ParameterInformation> = descriptor 452 let parameters: Vec<ParameterInformation> = descriptor
460 .params 453 .params
461 .iter() 454 .iter()
@@ -468,7 +461,7 @@ pub fn handle_signature_help(
468 let documentation = if let Some(doc) = descriptor.doc { 461 let documentation = if let Some(doc) = descriptor.doc {
469 Some(Documentation::MarkupContent(MarkupContent { 462 Some(Documentation::MarkupContent(MarkupContent {
470 kind: MarkupKind::Markdown, 463 kind: MarkupKind::Markdown,
471 value: doc 464 value: doc,
472 })) 465 }))
473 } else { 466 } else {
474 None 467 None
@@ -511,16 +504,17 @@ pub fn handle_prepare_rename(
511 Ok(Some(PrepareRenameResponse::Range(loc.range))) 504 Ok(Some(PrepareRenameResponse::Range(loc.range)))
512} 505}
513 506
514pub fn handle_rename( 507pub fn handle_rename(world: ServerWorld, params: RenameParams) -> Result<Option<WorkspaceEdit>> {
515 world: ServerWorld,
516 params: RenameParams,
517) -> Result<Option<WorkspaceEdit>> {
518 let file_id = params.text_document.try_conv_with(&world)?; 508 let file_id = params.text_document.try_conv_with(&world)?;
519 let line_index = world.analysis().file_line_index(file_id); 509 let line_index = world.analysis().file_line_index(file_id);
520 let offset = params.position.conv_with(&line_index); 510 let offset = params.position.conv_with(&line_index);
521 511
522 if params.new_name.is_empty() { 512 if params.new_name.is_empty() {
523 return Err(LspError::new(ErrorCode::InvalidParams as i32, "New Name cannot be empty".into()).into()); 513 return Err(LspError::new(
514 ErrorCode::InvalidParams as i32,
515 "New Name cannot be empty".into(),
516 )
517 .into());
524 } 518 }
525 519
526 let refs = world.analysis().find_all_refs(file_id, offset)?; 520 let refs = world.analysis().find_all_refs(file_id, offset)?;
@@ -531,11 +525,10 @@ pub fn handle_rename(
531 let mut changes = HashMap::new(); 525 let mut changes = HashMap::new();
532 for r in refs { 526 for r in refs {
533 if let Ok(loc) = to_location(r.0, r.1, &world, &line_index) { 527 if let Ok(loc) = to_location(r.0, r.1, &world, &line_index) {
534 changes.entry(loc.uri).or_insert(Vec::new()).push( 528 changes.entry(loc.uri).or_insert(Vec::new()).push(TextEdit {
535 TextEdit { 529 range: loc.range,
536 range: loc.range, 530 new_text: params.new_name.clone(),
537 new_text: params.new_name.clone() 531 });
538 });
539 } 532 }
540 } 533 }
541 534
@@ -543,7 +536,7 @@ pub fn handle_rename(
543 changes: Some(changes), 536 changes: Some(changes),
544 537
545 // TODO: return this instead if client/server support it. See #144 538 // TODO: return this instead if client/server support it. See #144
546 document_changes : None, 539 document_changes: None,
547 })) 540 }))
548} 541}
549 542
@@ -557,9 +550,11 @@ pub fn handle_references(
557 550
558 let refs = world.analysis().find_all_refs(file_id, offset)?; 551 let refs = world.analysis().find_all_refs(file_id, offset)?;
559 552
560 Ok(Some(refs.into_iter() 553 Ok(Some(
561 .filter_map(|r| to_location(r.0, r.1, &world, &line_index).ok()) 554 refs.into_iter()
562 .collect())) 555 .filter_map(|r| to_location(r.0, r.1, &world, &line_index).ok())
556 .collect(),
557 ))
563} 558}
564 559
565pub fn handle_code_action( 560pub fn handle_code_action(
diff --git a/crates/ra_lsp_server/src/main_loop/mod.rs b/crates/ra_lsp_server/src/main_loop/mod.rs
index 9ddc3fd0b..c568706bd 100644
--- a/crates/ra_lsp_server/src/main_loop/mod.rs
+++ b/crates/ra_lsp_server/src/main_loop/mod.rs
@@ -24,7 +24,10 @@ use crate::{
24}; 24};
25 25
26#[derive(Debug, Fail)] 26#[derive(Debug, Fail)]
27#[fail(display = "Language Server request failed with {}. ({})", code, message)] 27#[fail(
28 display = "Language Server request failed with {}. ({})",
29 code, message
30)]
28pub struct LspError { 31pub struct LspError {
29 pub code: i32, 32 pub code: i32,
30 pub message: String, 33 pub message: String,
@@ -32,7 +35,7 @@ pub struct LspError {
32 35
33impl LspError { 36impl LspError {
34 pub fn new(code: i32, message: String) -> LspError { 37 pub fn new(code: i32, message: String) -> LspError {
35 LspError {code, message} 38 LspError { code, message }
36 } 39 }
37} 40}
38 41
@@ -214,11 +217,7 @@ fn main_loop_inner(
214 } 217 }
215} 218}
216 219
217fn on_task( 220fn on_task(task: Task, msg_sender: &Sender<RawMessage>, pending_requests: &mut FxHashSet<u64>) {
218 task: Task,
219 msg_sender: &Sender<RawMessage>,
220 pending_requests: &mut FxHashSet<u64>,
221) {
222 match task { 221 match task {
223 Task::Respond(response) => { 222 Task::Respond(response) => {
224 if pending_requests.remove(&response.id) { 223 if pending_requests.remove(&response.id) {
@@ -373,12 +372,16 @@ impl<'a> PoolDispatcher<'a> {
373 self.pool.spawn(move || { 372 self.pool.spawn(move || {
374 let resp = match f(world, params) { 373 let resp = match f(world, params) {
375 Ok(resp) => RawResponse::ok::<R>(id, &resp), 374 Ok(resp) => RawResponse::ok::<R>(id, &resp),
376 Err(e) => { 375 Err(e) => match e.downcast::<LspError>() {
377 match e.downcast::<LspError>() { 376 Ok(lsp_error) => {
378 Ok(lsp_error) => RawResponse::err(id, lsp_error.code, lsp_error.message), 377 RawResponse::err(id, lsp_error.code, lsp_error.message)
379 Err(e) => RawResponse::err(id, ErrorCode::InternalError as i32, format!("{}\n{}", e, e.backtrace()))
380 } 378 }
381 } 379 Err(e) => RawResponse::err(
380 id,
381 ErrorCode::InternalError as i32,
382 format!("{}\n{}", e, e.backtrace()),
383 ),
384 },
382 }; 385 };
383 let task = Task::Respond(resp); 386 let task = Task::Respond(resp);
384 sender.send(task); 387 sender.send(task);
@@ -412,7 +415,7 @@ fn update_file_notifications_on_threadpool(
412 if !is_canceled(&e) { 415 if !is_canceled(&e) {
413 error!("failed to compute diagnostics: {:?}", e); 416 error!("failed to compute diagnostics: {:?}", e);
414 } 417 }
415 }, 418 }
416 Ok(params) => { 419 Ok(params) => {
417 let not = RawNotification::new::<req::PublishDiagnostics>(&params); 420 let not = RawNotification::new::<req::PublishDiagnostics>(&params);
418 sender.send(Task::Notify(not)); 421 sender.send(Task::Notify(not));
@@ -423,7 +426,7 @@ fn update_file_notifications_on_threadpool(
423 if !is_canceled(&e) { 426 if !is_canceled(&e) {
424 error!("failed to compute decorations: {:?}", e); 427 error!("failed to compute decorations: {:?}", e);
425 } 428 }
426 }, 429 }
427 Ok(params) => { 430 Ok(params) => {
428 let not = RawNotification::new::<req::PublishDecorations>(&params); 431 let not = RawNotification::new::<req::PublishDecorations>(&params);
429 sender.send(Task::Notify(not)) 432 sender.send(Task::Notify(not))
diff --git a/crates/ra_lsp_server/src/path_map.rs b/crates/ra_lsp_server/src/path_map.rs
index d5957d673..dd09fa10a 100644
--- a/crates/ra_lsp_server/src/path_map.rs
+++ b/crates/ra_lsp_server/src/path_map.rs
@@ -33,7 +33,8 @@ impl PathMap {
33 } 33 }
34 pub fn get_or_insert(&mut self, path: PathBuf, root: Root) -> (bool, FileId) { 34 pub fn get_or_insert(&mut self, path: PathBuf, root: Root) -> (bool, FileId) {
35 let mut inserted = false; 35 let mut inserted = false;
36 let file_id = self.path2id 36 let file_id = self
37 .path2id
37 .get(path.as_path()) 38 .get(path.as_path())
38 .map(|&id| id) 39 .map(|&id| id)
39 .unwrap_or_else(|| { 40 .unwrap_or_else(|| {
diff --git a/crates/ra_lsp_server/src/req.rs b/crates/ra_lsp_server/src/req.rs
index 6cd04d84c..9d911912d 100644
--- a/crates/ra_lsp_server/src/req.rs
+++ b/crates/ra_lsp_server/src/req.rs
@@ -6,8 +6,8 @@ pub use languageserver_types::{
6 notification::*, request::*, ApplyWorkspaceEditParams, CodeActionParams, CompletionParams, 6 notification::*, request::*, ApplyWorkspaceEditParams, CodeActionParams, CompletionParams,
7 CompletionResponse, DocumentOnTypeFormattingParams, DocumentSymbolParams, 7 CompletionResponse, DocumentOnTypeFormattingParams, DocumentSymbolParams,
8 DocumentSymbolResponse, ExecuteCommandParams, Hover, InitializeResult, 8 DocumentSymbolResponse, ExecuteCommandParams, Hover, InitializeResult,
9 PublishDiagnosticsParams, SignatureHelp, TextDocumentEdit, TextDocumentPositionParams, 9 PublishDiagnosticsParams, ReferenceParams, SignatureHelp, TextDocumentEdit,
10 TextEdit, WorkspaceSymbolParams, ReferenceParams, 10 TextDocumentPositionParams, TextEdit, WorkspaceSymbolParams,
11}; 11};
12 12
13pub enum SyntaxTree {} 13pub enum SyntaxTree {}
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs
index 25986e230..3e76d2527 100644
--- a/crates/ra_lsp_server/src/server_world.rs
+++ b/crates/ra_lsp_server/src/server_world.rs
@@ -5,7 +5,9 @@ use std::{
5}; 5};
6 6
7use languageserver_types::Url; 7use languageserver_types::Url;
8use ra_analysis::{Analysis, AnalysisHost, AnalysisChange, CrateGraph, FileId, FileResolver, LibraryData}; 8use ra_analysis::{
9 Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, FileResolver, LibraryData,
10};
9use rustc_hash::FxHashMap; 11use rustc_hash::FxHashMap;
10 12
11use crate::{ 13use crate::{
@@ -65,9 +67,7 @@ impl ServerWorldState {
65 Some((file_id, text)) 67 Some((file_id, text))
66 } 68 }
67 }) 69 })
68 .for_each(|(file_id, text)| { 70 .for_each(|(file_id, text)| change.add_file(file_id, text));
69 change.add_file(file_id, text)
70 });
71 } 71 }
72 if inserted { 72 if inserted {
73 change.set_file_resolver(Arc::new(self.path_map.clone())) 73 change.set_file_resolver(Arc::new(self.path_map.clone()))