aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/rust-analyzer/src/config.rs6
-rw-r--r--crates/rust-analyzer/src/handlers.rs10
-rw-r--r--crates/rust-analyzer/src/to_proto.rs8
-rw-r--r--crates/rust-analyzer/tests/rust-analyzer/main.rs43
4 files changed, 58 insertions, 9 deletions
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 8879a9161..3818160b7 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -44,6 +44,9 @@ config_data! {
44 /// Show function name and docs in parameter hints. 44 /// Show function name and docs in parameter hints.
45 callInfo_full: bool = "true", 45 callInfo_full: bool = "true",
46 46
47 /// Use semantic tokens for strings. Disable to support injected grammars
48 semanticStringTokens: bool = "true",
49
47 /// Automatically refresh project info via `cargo metadata` on 50 /// Automatically refresh project info via `cargo metadata` on
48 /// `Cargo.toml` changes. 51 /// `Cargo.toml` changes.
49 cargo_autoreload: bool = "true", 52 cargo_autoreload: bool = "true",
@@ -381,6 +384,9 @@ impl Config {
381 pub fn line_folding_only(&self) -> bool { 384 pub fn line_folding_only(&self) -> bool {
382 try_or!(self.caps.text_document.as_ref()?.folding_range.as_ref()?.line_folding_only?, false) 385 try_or!(self.caps.text_document.as_ref()?.folding_range.as_ref()?.line_folding_only?, false)
383 } 386 }
387 pub fn semantic_strings(&self) -> bool {
388 self.data.semanticStringTokens
389 }
384 pub fn hierarchical_symbols(&self) -> bool { 390 pub fn hierarchical_symbols(&self) -> bool {
385 try_or!( 391 try_or!(
386 self.caps 392 self.caps
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index f6e40f872..85dd73fca 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -1376,7 +1376,8 @@ pub(crate) fn handle_semantic_tokens_full(
1376 let line_index = snap.file_line_index(file_id)?; 1376 let line_index = snap.file_line_index(file_id)?;
1377 1377
1378 let highlights = snap.analysis.highlight(file_id)?; 1378 let highlights = snap.analysis.highlight(file_id)?;
1379 let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights); 1379 let semantic_strings = snap.config.semantic_strings();
1380 let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights, semantic_strings);
1380 1381
1381 // Unconditionally cache the tokens 1382 // Unconditionally cache the tokens
1382 snap.semantic_tokens_cache.lock().insert(params.text_document.uri, semantic_tokens.clone()); 1383 snap.semantic_tokens_cache.lock().insert(params.text_document.uri, semantic_tokens.clone());
@@ -1395,8 +1396,8 @@ pub(crate) fn handle_semantic_tokens_full_delta(
1395 let line_index = snap.file_line_index(file_id)?; 1396 let line_index = snap.file_line_index(file_id)?;
1396 1397
1397 let highlights = snap.analysis.highlight(file_id)?; 1398 let highlights = snap.analysis.highlight(file_id)?;
1398 1399 let semantic_strings = snap.config.semantic_strings();
1399 let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights); 1400 let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights, semantic_strings);
1400 1401
1401 let mut cache = snap.semantic_tokens_cache.lock(); 1402 let mut cache = snap.semantic_tokens_cache.lock();
1402 let cached_tokens = cache.entry(params.text_document.uri).or_default(); 1403 let cached_tokens = cache.entry(params.text_document.uri).or_default();
@@ -1425,7 +1426,8 @@ pub(crate) fn handle_semantic_tokens_range(
1425 let line_index = snap.file_line_index(frange.file_id)?; 1426 let line_index = snap.file_line_index(frange.file_id)?;
1426 1427
1427 let highlights = snap.analysis.highlight_range(frange)?; 1428 let highlights = snap.analysis.highlight_range(frange)?;
1428 let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights); 1429 let semantic_strings = snap.config.semantic_strings();
1430 let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights, semantic_strings);
1429 Ok(Some(semantic_tokens.into())) 1431 Ok(Some(semantic_tokens.into()))
1430} 1432}
1431 1433
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index ecf6fd12f..01ffe8db1 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -381,6 +381,7 @@ pub(crate) fn semantic_tokens(
381 text: &str, 381 text: &str,
382 line_index: &LineIndex, 382 line_index: &LineIndex,
383 highlights: Vec<HlRange>, 383 highlights: Vec<HlRange>,
384 include_strings: bool
384) -> lsp_types::SemanticTokens { 385) -> lsp_types::SemanticTokens {
385 let id = TOKEN_RESULT_COUNTER.fetch_add(1, Ordering::SeqCst).to_string(); 386 let id = TOKEN_RESULT_COUNTER.fetch_add(1, Ordering::SeqCst).to_string();
386 let mut builder = semantic_tokens::SemanticTokensBuilder::new(id); 387 let mut builder = semantic_tokens::SemanticTokensBuilder::new(id);
@@ -389,8 +390,11 @@ pub(crate) fn semantic_tokens(
389 if highlight_range.highlight.is_empty() { 390 if highlight_range.highlight.is_empty() {
390 continue; 391 continue;
391 } 392 }
392 let (type_, mods) = semantic_token_type_and_modifiers(highlight_range.highlight); 393 let (typ, mods) = semantic_token_type_and_modifiers(highlight_range.highlight);
393 let token_index = semantic_tokens::type_index(type_); 394 if !include_strings && typ == lsp_types::SemanticTokenType::STRING {
395 continue;
396 }
397 let token_index = semantic_tokens::type_index(typ);
394 let modifier_bitset = mods.0; 398 let modifier_bitset = mods.0;
395 399
396 for mut text_range in line_index.index.lines(highlight_range.range) { 400 for mut text_range in line_index.index.lines(highlight_range.range) {
diff --git a/crates/rust-analyzer/tests/rust-analyzer/main.rs b/crates/rust-analyzer/tests/rust-analyzer/main.rs
index 9e89209ea..62f34b643 100644
--- a/crates/rust-analyzer/tests/rust-analyzer/main.rs
+++ b/crates/rust-analyzer/tests/rust-analyzer/main.rs
@@ -18,15 +18,16 @@ use lsp_types::{
18 notification::DidOpenTextDocument, 18 notification::DidOpenTextDocument,
19 request::{ 19 request::{
20 CodeActionRequest, Completion, Formatting, GotoTypeDefinition, HoverRequest, 20 CodeActionRequest, Completion, Formatting, GotoTypeDefinition, HoverRequest,
21 WillRenameFiles, 21 SemanticTokensRangeRequest, WillRenameFiles
22 }, 22 },
23 CodeActionContext, CodeActionParams, CompletionParams, DidOpenTextDocumentParams, 23 CodeActionContext, CodeActionParams, CompletionParams, DidOpenTextDocumentParams,
24 DocumentFormattingParams, FileRename, FormattingOptions, GotoDefinitionParams, HoverParams, 24 DocumentFormattingParams, FileRename, FormattingOptions, GotoDefinitionParams, HoverParams,
25 PartialResultParams, Position, Range, RenameFilesParams, TextDocumentItem, 25 PartialResultParams, Position, Range, RenameFilesParams, SemanticTokensRangeParams, TextDocumentItem,
26 TextDocumentPositionParams, WorkDoneProgressParams, 26 TextDocumentPositionParams, WorkDoneProgressParams,
27 SemanticTokens
27}; 28};
28use rust_analyzer::lsp_ext::{OnEnter, Runnables, RunnablesParams}; 29use rust_analyzer::lsp_ext::{OnEnter, Runnables, RunnablesParams};
29use serde_json::json; 30use serde_json::{from_value, json};
30use test_utils::skip_slow_tests; 31use test_utils::skip_slow_tests;
31 32
32use crate::{ 33use crate::{
@@ -38,6 +39,42 @@ const PROFILE: &str = "";
38// const PROFILE: &'static str = "*@3>100"; 39// const PROFILE: &'static str = "*@3>100";
39 40
40#[test] 41#[test]
42fn can_disable_semantic_strings() {
43 if skip_slow_tests() {
44 return;
45 }
46
47 [true, false].iter().for_each(|semantic_strings| {
48 let server = Project::with_fixture(
49 r#"
50//- /Cargo.toml
51[package]
52name = "foo"
53version = "0.0.0"
54
55//- /src/lib.rs
56const foo: &'static str = "hi";
57"#,
58 )
59 .with_config(serde_json::json!({
60 "semanticStringTokens": semantic_strings
61 }))
62 .server().wait_until_workspace_is_loaded();
63
64 let res = server.send_request::<SemanticTokensRangeRequest>(SemanticTokensRangeParams {
65 text_document: server.doc_id("src/lib.rs"),
66 partial_result_params: PartialResultParams::default(),
67 work_done_progress_params: WorkDoneProgressParams::default(),
68 range: Range::new(Position::new(0, 26), Position::new(0, 30)),
69 });
70
71 let tok_res: SemanticTokens = from_value(res).expect("invalid server response");
72 assert!(tok_res.data.len() == *semantic_strings as usize);
73 });
74}
75
76
77#[test]
41fn completes_items_from_standard_library() { 78fn completes_items_from_standard_library() {
42 if skip_slow_tests() { 79 if skip_slow_tests() {
43 return; 80 return;