diff options
author | Kitson Kelly <me@kitsonkelly.com> | 2020-12-30 15:17:17 +1100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-30 15:17:17 +1100 |
commit | 8011eced141e7bf0e1eac334daf326bd49504748 (patch) | |
tree | 3d2bdd36cc4f19285ba5292b9946cdabf466d25b /cli/lsp/language_server.rs | |
parent | e8a81724bb3b3767edaddbe78edc52108ae78b5f (diff) |
feat(lsp): add cache command (#8911)
Diffstat (limited to 'cli/lsp/language_server.rs')
-rw-r--r-- | cli/lsp/language_server.rs | 97 |
1 files changed, 68 insertions, 29 deletions
diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index e70c0198d..08ece2b62 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -9,9 +9,8 @@ use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::ModuleSpecifier; use dprint_plugin_typescript as dprint; -use lspower::jsonrpc::Error as LSPError; -use lspower::jsonrpc::ErrorCode as LSPErrorCode; -use lspower::jsonrpc::Result as LSPResult; +use lspower::jsonrpc::Error as LspError; +use lspower::jsonrpc::Result as LspResult; use lspower::lsp_types::*; use lspower::Client; use std::collections::HashMap; @@ -33,6 +32,7 @@ use super::diagnostics; use super::diagnostics::DiagnosticCollection; use super::diagnostics::DiagnosticSource; use super::memory_cache::MemoryCache; +use super::sources; use super::sources::Sources; use super::text; use super::text::apply_content_changes; @@ -361,7 +361,7 @@ impl lspower::LanguageServer for LanguageServer { async fn initialize( &self, params: InitializeParams, - ) -> LSPResult<InitializeResult> { + ) -> LspResult<InitializeResult> { info!("Starting Deno language server..."); let capabilities = capabilities::server_capabilities(¶ms.capabilities); @@ -439,7 +439,7 @@ impl lspower::LanguageServer for LanguageServer { info!("Server ready."); } - async fn shutdown(&self) -> LSPResult<()> { + async fn shutdown(&self) -> LspResult<()> { Ok(()) } @@ -586,7 +586,7 @@ impl lspower::LanguageServer for LanguageServer { async fn formatting( &self, params: DocumentFormattingParams, - ) -> LSPResult<Option<Vec<TextEdit>>> { + ) -> LspResult<Option<Vec<TextEdit>>> { let specifier = utils::normalize_url(params.text_document.uri.clone()); let file_text = { let file_cache = self.file_cache.read().unwrap(); @@ -631,7 +631,7 @@ impl lspower::LanguageServer for LanguageServer { } } - async fn hover(&self, params: HoverParams) -> LSPResult<Option<Hover>> { + async fn hover(&self, params: HoverParams) -> LspResult<Option<Hover>> { if !self.enabled() { return Ok(None); } @@ -662,7 +662,7 @@ impl lspower::LanguageServer for LanguageServer { async fn document_highlight( &self, params: DocumentHighlightParams, - ) -> LSPResult<Option<Vec<DocumentHighlight>>> { + ) -> LspResult<Option<Vec<DocumentHighlight>>> { if !self.enabled() { return Ok(None); } @@ -702,7 +702,7 @@ impl lspower::LanguageServer for LanguageServer { async fn references( &self, params: ReferenceParams, - ) -> LSPResult<Option<Vec<Location>>> { + ) -> LspResult<Option<Vec<Location>>> { if !self.enabled() { return Ok(None); } @@ -743,7 +743,7 @@ impl lspower::LanguageServer for LanguageServer { async fn goto_definition( &self, params: GotoDefinitionParams, - ) -> LSPResult<Option<GotoDefinitionResponse>> { + ) -> LspResult<Option<GotoDefinitionResponse>> { if !self.enabled() { return Ok(None); } @@ -779,7 +779,7 @@ impl lspower::LanguageServer for LanguageServer { async fn completion( &self, params: CompletionParams, - ) -> LSPResult<Option<CompletionResponse>> { + ) -> LspResult<Option<CompletionResponse>> { if !self.enabled() { return Ok(None); } @@ -812,7 +812,7 @@ impl lspower::LanguageServer for LanguageServer { async fn rename( &self, params: RenameParams, - ) -> LSPResult<Option<WorkspaceEdit>> { + ) -> LspResult<Option<WorkspaceEdit>> { if !self.enabled() { return Ok(None); } @@ -827,7 +827,7 @@ impl lspower::LanguageServer for LanguageServer { .await .map_err(|err| { error!("Failed to get line_index {:#?}", err); - LSPError::internal_error() + LspError::internal_error() })?; let req = tsc::RequestMethod::FindRenameLocations(( @@ -844,7 +844,7 @@ impl lspower::LanguageServer for LanguageServer { .await .map_err(|err| { error!("Failed to request to tsserver {:#?}", err); - LSPError::invalid_request() + LspError::invalid_request() })?; let maybe_locations = serde_json::from_value::< @@ -855,7 +855,7 @@ impl lspower::LanguageServer for LanguageServer { "Failed to deserialize tsserver response to Vec<RenameLocation> {:#?}", err ); - LSPError::internal_error() + LspError::internal_error() })?; match maybe_locations { @@ -873,7 +873,7 @@ impl lspower::LanguageServer for LanguageServer { "Failed to convert tsc::RenameLocations to WorkspaceEdit {:#?}", err ); - LSPError::internal_error() + LspError::internal_error() })?; Ok(Some(workpace_edits)) } @@ -885,8 +885,18 @@ impl lspower::LanguageServer for LanguageServer { &self, method: &str, params: Option<Value>, - ) -> LSPResult<Option<Value>> { + ) -> LspResult<Option<Value>> { match method { + "deno/cache" => match params.map(serde_json::from_value) { + Some(Ok(params)) => Ok(Some( + serde_json::to_value(self.cache(params).await?).map_err(|err| { + error!("Failed to serialize cache response: {:#?}", err); + LspError::internal_error() + })?, + )), + Some(Err(err)) => Err(LspError::invalid_params(err.to_string())), + None => Err(LspError::invalid_params("Missing parameters")), + }, "deno/virtualTextDocument" => match params.map(serde_json::from_value) { Some(Ok(params)) => Ok(Some( serde_json::to_value(self.virtual_text_document(params).await?) @@ -895,25 +905,60 @@ impl lspower::LanguageServer for LanguageServer { "Failed to serialize virtual_text_document response: {:#?}", err ); - LSPError::internal_error() + LspError::internal_error() })?, )), - Some(Err(err)) => Err(LSPError::invalid_params(err.to_string())), - None => Err(LSPError::invalid_params("Missing parameters")), + Some(Err(err)) => Err(LspError::invalid_params(err.to_string())), + None => Err(LspError::invalid_params("Missing parameters")), }, _ => { error!("Got a {} request, but no handler is defined", method); - Err(LSPError::method_not_found()) + Err(LspError::method_not_found()) } } } } +#[derive(Debug, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct CacheParams { + pub text_document: TextDocumentIdentifier, +} + +#[derive(Debug, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct VirtualTextDocumentParams { + pub text_document: TextDocumentIdentifier, +} + impl LanguageServer { + async fn cache(&self, params: CacheParams) -> LspResult<bool> { + let specifier = utils::normalize_url(params.text_document.uri); + let maybe_import_map = self.maybe_import_map.read().unwrap().clone(); + sources::cache(specifier.clone(), maybe_import_map) + .await + .map_err(|err| { + error!("{}", err); + LspError::internal_error() + })?; + { + let file_cache = self.file_cache.read().unwrap(); + if let Some(file_id) = file_cache.lookup(&specifier) { + let mut diagnostics_collection = self.diagnostics.write().unwrap(); + diagnostics_collection.invalidate(&file_id); + } + } + self.prepare_diagnostics().await.map_err(|err| { + error!("{}", err); + LspError::internal_error() + })?; + Ok(true) + } + async fn virtual_text_document( &self, params: VirtualTextDocumentParams, - ) -> LSPResult<Option<String>> { + ) -> LspResult<Option<String>> { let specifier = utils::normalize_url(params.text_document.uri); let url = specifier.as_url(); let contents = if url.as_str() == "deno:/status.md" { @@ -933,7 +978,7 @@ impl LanguageServer { if let Some(text) = tsc::get_asset(&specifier, &self.ts_server, &state_snapshot) .await - .map_err(|_| LSPError::new(LSPErrorCode::InternalError))? + .map_err(|_| LspError::internal_error())? { Some(text) } else { @@ -1009,12 +1054,6 @@ impl DocumentData { } } -#[derive(Debug, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct VirtualTextDocumentParams { - pub text_document: TextDocumentIdentifier, -} - #[cfg(test)] mod tests { use super::*; |