about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukas.wirth@ferrous-systems.com>2023-05-11 09:55:30 +0200
committerLukas Wirth <lukas.wirth@ferrous-systems.com>2023-05-11 10:01:38 +0200
commit91d5a689c770eb7f15087f55365ded717a736a2e (patch)
treedd36bb2a1f9af09f23245e4d6e5453e211fe30f3
parent4b42acf617d05005cc678bcdaec5123d8429cb63 (diff)
downloadrust-91d5a689c770eb7f15087f55365ded717a736a2e.tar.gz
rust-91d5a689c770eb7f15087f55365ded717a736a2e.zip
Add config for disabling non standard lsp highlight tokens
-rw-r--r--crates/rust-analyzer/src/config.rs6
-rw-r--r--crates/rust-analyzer/src/handlers/request.rs3
-rw-r--r--crates/rust-analyzer/src/semantic_tokens.rs58
-rw-r--r--crates/rust-analyzer/src/to_proto.rs13
-rw-r--r--docs/user/generated_config.adoc5
-rw-r--r--editors/code/package.json5
6 files changed, 70 insertions, 20 deletions
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index c88794e0cf2..e73a2d5c770 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -483,6 +483,8 @@ config_data! {
         /// When enabled, rust-analyzer will highlight rust source in doc comments as well as intra
         /// doc links.
         semanticHighlighting_doc_comment_inject_enable: bool = "true",
+        /// Whether the server is allowed to emit non-standard tokens and modifiers.
+        semanticHighlighting_nonStandardTokens: bool = "true",
         /// Use semantic tokens for operators.
         ///
         /// When disabled, rust-analyzer will emit semantic tokens only for operator tokens when
@@ -1464,6 +1466,10 @@ impl Config {
         }
     }
 
+    pub fn highlighting_non_standard_tokens(&self) -> bool {
+        self.data.semanticHighlighting_nonStandardTokens
+    }
+
     pub fn highlighting_config(&self) -> HighlightConfig {
         HighlightConfig {
             strings: self.data.semanticHighlighting_strings_enable,
diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs
index 4815f8e2305..e540b281e13 100644
--- a/crates/rust-analyzer/src/handlers/request.rs
+++ b/crates/rust-analyzer/src/handlers/request.rs
@@ -1477,6 +1477,7 @@ pub(crate) fn handle_semantic_tokens_full(
         &line_index,
         highlights,
         snap.config.semantics_tokens_augments_syntax_tokens(),
+        snap.config.highlighting_non_standard_tokens(),
     );
 
     // Unconditionally cache the tokens
@@ -1506,6 +1507,7 @@ pub(crate) fn handle_semantic_tokens_full_delta(
         &line_index,
         highlights,
         snap.config.semantics_tokens_augments_syntax_tokens(),
+        snap.config.highlighting_non_standard_tokens(),
     );
 
     let mut cache = snap.semantic_tokens_cache.lock();
@@ -1545,6 +1547,7 @@ pub(crate) fn handle_semantic_tokens_range(
         &line_index,
         highlights,
         snap.config.semantics_tokens_augments_syntax_tokens(),
+        snap.config.highlighting_non_standard_tokens(),
     );
     Ok(Some(semantic_tokens.into()))
 }
diff --git a/crates/rust-analyzer/src/semantic_tokens.rs b/crates/rust-analyzer/src/semantic_tokens.rs
index c2cc3f422d2..e5b43c5a10c 100644
--- a/crates/rust-analyzer/src/semantic_tokens.rs
+++ b/crates/rust-analyzer/src/semantic_tokens.rs
@@ -13,7 +13,7 @@ macro_rules! define_semantic_token_types {
             $($standard:ident),*$(,)?
         }
         custom {
-            $(($custom:ident, $string:literal)),*$(,)?
+            $(($custom:ident, $string:literal) $(=> $fallback:ident)?),*$(,)?
         }
 
     ) => {
@@ -24,6 +24,15 @@ macro_rules! define_semantic_token_types {
             $(SemanticTokenType::$standard,)*
             $($custom),*
         ];
+
+        pub(crate) fn standard_fallback_type(token: SemanticTokenType) -> Option<SemanticTokenType> {
+            $(
+                if token == $custom {
+                    None $(.or(Some(SemanticTokenType::$fallback)))?
+                } else
+            )*
+            { Some(token )}
+        }
     };
 }
 
@@ -51,42 +60,46 @@ define_semantic_token_types![
 
     custom {
         (ANGLE, "angle"),
-        (ARITHMETIC, "arithmetic"),
-        (ATTRIBUTE, "attribute"),
-        (ATTRIBUTE_BRACKET, "attributeBracket"),
-        (BITWISE, "bitwise"),
+        (ARITHMETIC, "arithmetic") => OPERATOR,
+        (ATTRIBUTE, "attribute") => DECORATOR,
+        (ATTRIBUTE_BRACKET, "attributeBracket") => DECORATOR,
+        (BITWISE, "bitwise") => OPERATOR,
         (BOOLEAN, "boolean"),
         (BRACE, "brace"),
         (BRACKET, "bracket"),
-        (BUILTIN_ATTRIBUTE, "builtinAttribute"),
+        (BUILTIN_ATTRIBUTE, "builtinAttribute") => DECORATOR,
         (BUILTIN_TYPE, "builtinType"),
-        (CHAR, "character"),
+        (CHAR, "character") => STRING,
         (COLON, "colon"),
         (COMMA, "comma"),
-        (COMPARISON, "comparison"),
+        (COMPARISON, "comparison") => OPERATOR,
         (CONST_PARAMETER, "constParameter"),
-        (DERIVE, "derive"),
-        (DERIVE_HELPER, "deriveHelper"),
+        (DERIVE, "derive") => DECORATOR,
+        (DERIVE_HELPER, "deriveHelper") => DECORATOR,
         (DOT, "dot"),
-        (ESCAPE_SEQUENCE, "escapeSequence"),
-        (FORMAT_SPECIFIER, "formatSpecifier"),
-        (GENERIC, "generic"),
+        (ESCAPE_SEQUENCE, "escapeSequence") => STRING,
+        (FORMAT_SPECIFIER, "formatSpecifier") => STRING,
+        (GENERIC, "generic") => TYPE_PARAMETER,
         (LABEL, "label"),
         (LIFETIME, "lifetime"),
-        (LOGICAL, "logical"),
-        (MACRO_BANG, "macroBang"),
+        (LOGICAL, "logical") => OPERATOR,
+        (MACRO_BANG, "macroBang") => MACRO,
         (PARENTHESIS, "parenthesis"),
         (PUNCTUATION, "punctuation"),
-        (SELF_KEYWORD, "selfKeyword"),
-        (SELF_TYPE_KEYWORD, "selfTypeKeyword"),
+        (SELF_KEYWORD, "selfKeyword") => KEYWORD,
+        (SELF_TYPE_KEYWORD, "selfTypeKeyword") => KEYWORD,
         (SEMICOLON, "semicolon"),
         (TYPE_ALIAS, "typeAlias"),
-        (TOOL_MODULE, "toolModule"),
+        (TOOL_MODULE, "toolModule") => DECORATOR,
         (UNION, "union"),
         (UNRESOLVED_REFERENCE, "unresolvedReference"),
     }
 ];
 
+macro_rules! count_tts {
+    () => {0usize};
+    ($_head:tt $($tail:tt)*) => {1usize + count_tts!($($tail)*)};
+}
 macro_rules! define_semantic_token_modifiers {
     (
         standard {
@@ -105,6 +118,8 @@ macro_rules! define_semantic_token_modifiers {
             $(SemanticTokenModifier::$standard,)*
             $($custom),*
         ];
+
+        const LAST_STANDARD_MOD: usize = count_tts!($($standard)*);
     };
 }
 
@@ -137,6 +152,13 @@ define_semantic_token_modifiers![
 #[derive(Default)]
 pub(crate) struct ModifierSet(pub(crate) u32);
 
+impl ModifierSet {
+    pub(crate) fn standard_fallback(&mut self) {
+        // Remove all non standard modifiers
+        self.0 = self.0 & !(!0u32 << LAST_STANDARD_MOD)
+    }
+}
+
 impl ops::BitOrAssign<SemanticTokenModifier> for ModifierSet {
     fn bitor_assign(&mut self, rhs: SemanticTokenModifier) {
         let idx = SUPPORTED_MODIFIERS.iter().position(|it| it == &rhs).unwrap();
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index acb6f0d04a7..616bdddd92b 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -24,7 +24,7 @@ use crate::{
     line_index::{LineEndings, LineIndex, PositionEncoding},
     lsp_ext,
     lsp_utils::invalid_params_error,
-    semantic_tokens,
+    semantic_tokens::{self, standard_fallback_type},
 };
 
 pub(crate) fn position(line_index: &LineIndex, offset: TextSize) -> lsp_types::Position {
@@ -587,6 +587,7 @@ pub(crate) fn semantic_tokens(
     line_index: &LineIndex,
     highlights: Vec<HlRange>,
     semantics_tokens_augments_syntax_tokens: bool,
+    non_standard_tokens: bool,
 ) -> lsp_types::SemanticTokens {
     let id = TOKEN_RESULT_COUNTER.fetch_add(1, Ordering::SeqCst).to_string();
     let mut builder = semantic_tokens::SemanticTokensBuilder::new(id);
@@ -616,7 +617,15 @@ pub(crate) fn semantic_tokens(
             }
         }
 
-        let (ty, mods) = semantic_token_type_and_modifiers(highlight_range.highlight);
+        let (mut ty, mut mods) = semantic_token_type_and_modifiers(highlight_range.highlight);
+
+        if !non_standard_tokens {
+            ty = match standard_fallback_type(ty) {
+                Some(ty) => ty,
+                None => continue,
+            };
+            mods.standard_fallback();
+        }
         let token_index = semantic_tokens::type_index(ty);
         let modifier_bitset = mods.0;
 
diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc
index 6a2da3d90e3..c2f8c6c754f 100644
--- a/docs/user/generated_config.adoc
+++ b/docs/user/generated_config.adoc
@@ -753,6 +753,11 @@ Inject additional highlighting into doc comments.
 When enabled, rust-analyzer will highlight rust source in doc comments as well as intra
 doc links.
 --
+[[rust-analyzer.semanticHighlighting.nonStandardTokens]]rust-analyzer.semanticHighlighting.nonStandardTokens (default: `true`)::
++
+--
+Whether the server is allowed to emit non-standard tokens and modifiers.
+--
 [[rust-analyzer.semanticHighlighting.operator.enable]]rust-analyzer.semanticHighlighting.operator.enable (default: `true`)::
 +
 --
diff --git a/editors/code/package.json b/editors/code/package.json
index 1ce6a1b2b00..b4620243c9f 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -1395,6 +1395,11 @@
                     "default": true,
                     "type": "boolean"
                 },
+                "rust-analyzer.semanticHighlighting.nonStandardTokens": {
+                    "markdownDescription": "Whether the server is allowed to emit non-standard tokens and modifiers.",
+                    "default": true,
+                    "type": "boolean"
+                },
                 "rust-analyzer.semanticHighlighting.operator.enable": {
                     "markdownDescription": "Use semantic tokens for operators.\n\nWhen disabled, rust-analyzer will emit semantic tokens only for operator tokens when\nthey are tagged with modifiers.",
                     "default": true,