From 0d83afd93973cf4051aa73a0a05a78b451763d33 Mon Sep 17 00:00:00 2001 From: Kitson Kelly Date: Thu, 19 Aug 2021 13:19:12 +1000 Subject: [PATCH] fix(lsp): better handling of languageId (#11755) Fixes #11521 Fixes #11742 --- cli/lsp/README.md | 19 +++++++++++++++ cli/lsp/documents.rs | 48 ++++++++++++++++++++++++++++++++++---- cli/lsp/language_server.rs | 22 +++++++++++------ 3 files changed, 78 insertions(+), 11 deletions(-) diff --git a/cli/lsp/README.md b/cli/lsp/README.md index 53e35e8cce..8b0135f250 100644 --- a/cli/lsp/README.md +++ b/cli/lsp/README.md @@ -22,6 +22,7 @@ There are several settings that the language server supports for a workspace: - `deno.cache` - `deno.config` - `deno.importMap` +- `deno.internalDebug` - `deno.codeLens.implementations` - `deno.codeLens.references` - `deno.codeLens.referencesAllFunctions` @@ -159,3 +160,21 @@ client: suggestions: boolean; } ``` + +## Language IDs + +The language server supports diagnostics and formatting for the following +[text document language IDs](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentItem): + +- `"javascript"` +- `"javascriptreact"` +- `"jsx"` _non standard, same as `javascriptreact`_ +- `"typescript"` +- `"typescriptreact"` +- `"tsx"` _non standard, same as `typescriptreact`_ + +The language server supports only formatting for the following language IDs: + +- `"json"` +- `"jsonc"` +- `"markdown"` diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs index c2b207e14d..4f961715df 100644 --- a/cli/lsp/documents.rs +++ b/cli/lsp/documents.rs @@ -6,7 +6,6 @@ use super::tsc; use crate::media_type::MediaType; -use deno_core::error::anyhow; use deno_core::error::custom_error; use deno_core::error::AnyError; use deno_core::error::Context; @@ -28,21 +27,24 @@ pub enum LanguageId { Json, JsonC, Markdown, + Unknown, } impl FromStr for LanguageId { type Err = AnyError; - fn from_str(s: &str) -> Result { + fn from_str(s: &str) -> Result { match s { "javascript" => Ok(Self::JavaScript), "javascriptreact" => Ok(Self::Jsx), + "jsx" => Ok(Self::Jsx), "typescript" => Ok(Self::TypeScript), "typescriptreact" => Ok(Self::Tsx), + "tsx" => Ok(Self::Tsx), "json" => Ok(Self::Json), "jsonc" => Ok(Self::JsonC), "markdown" => Ok(Self::Markdown), - _ => Err(anyhow!("Unsupported language id: {}", s)), + _ => Ok(Self::Unknown), } } } @@ -57,6 +59,7 @@ impl<'a> From<&'a LanguageId> for MediaType { LanguageId::Markdown => MediaType::Unknown, LanguageId::Tsx => MediaType::Tsx, LanguageId::TypeScript => MediaType::TypeScript, + LanguageId::Unknown => MediaType::Unknown, } } } @@ -448,6 +451,35 @@ mod tests { use deno_core::resolve_url; use lspower::lsp; + #[test] + fn test_language_id() { + assert_eq!( + "javascript".parse::().unwrap(), + LanguageId::JavaScript + ); + assert_eq!( + "javascriptreact".parse::().unwrap(), + LanguageId::Jsx + ); + assert_eq!("jsx".parse::().unwrap(), LanguageId::Jsx); + assert_eq!( + "typescript".parse::().unwrap(), + LanguageId::TypeScript + ); + assert_eq!( + "typescriptreact".parse::().unwrap(), + LanguageId::Tsx + ); + assert_eq!("tsx".parse::().unwrap(), LanguageId::Tsx); + assert_eq!("json".parse::().unwrap(), LanguageId::Json); + assert_eq!("jsonc".parse::().unwrap(), LanguageId::JsonC); + assert_eq!( + "markdown".parse::().unwrap(), + LanguageId::Markdown + ); + assert_eq!("rust".parse::().unwrap(), LanguageId::Unknown); + } + #[test] fn test_document_cache_contains() { let mut document_cache = DocumentCache::default(); @@ -543,10 +575,18 @@ mod tests { document_cache.open( specifier.clone(), 1, - LanguageId::TypeScript, + "typescript".parse().unwrap(), "console.log(\"hello world\");\n", ); assert!(document_cache.is_diagnosable(&specifier)); + let specifier = resolve_url("file:///a/file.rs").unwrap(); + document_cache.open( + specifier.clone(), + 1, + "rust".parse().unwrap(), + "pub mod a;", + ); + assert!(!document_cache.is_diagnosable(&specifier)); let specifier = resolve_url("asset:///lib.es2015.symbol.wellknown.d.ts").unwrap(); assert!(document_cache.is_diagnosable(&specifier)); diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index 9fbe6be5d8..9926ac0e4d 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -772,13 +772,21 @@ impl Inner { // already managed by the language service return; } - let language_id = match params.text_document.language_id.parse() { - Ok(language_id) => language_id, - Err(err) => { - error!("{}", err); - LanguageId::TypeScript - } - }; + let language_id = + params + .text_document + .language_id + .parse() + .unwrap_or_else(|err| { + error!("{}", err); + LanguageId::Unknown + }); + if language_id == LanguageId::Unknown { + warn!( + "Unsupported language id \"{}\" received for document \"{}\".", + params.text_document.language_id, params.text_document.uri + ); + } let media_type = MediaType::from(&language_id); self.documents.open( specifier.clone(),