From 2fa0b20ce05a1d6b8f9bf0f0d9f1dfb15b84fb9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Tue, 16 Jun 2020 21:28:57 +0300 Subject: Remove debugging code for incremental sync --- crates/rust-analyzer/src/main_loop.rs | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) (limited to 'crates') diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index cc9bb1726..887253d5b 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -669,14 +669,11 @@ fn apply_document_changes( mut line_index: Cow<'_, LineIndex>, content_changes: Vec, ) { - // Remove when https://github.com/rust-analyzer/rust-analyzer/issues/4263 is fixed. - let backup_text = old_text.clone(); - let backup_changes = content_changes.clone(); - // The changes we got must be applied sequentially, but can cross lines so we // have to keep our line index updated. // Some clients (e.g. Code) sort the ranges in reverse. As an optimization, we // remember the last valid line in the index and only rebuild it if needed. + // The VFS will normalize the end of lines to `\n`. enum IndexValid { All, UpToLineExclusive(u64), @@ -700,19 +697,7 @@ fn apply_document_changes( } index_valid = IndexValid::UpToLineExclusive(range.start.line); let range = from_proto::text_range(&line_index, range); - let mut text = old_text.to_owned(); - match std::panic::catch_unwind(move || { - text.replace_range(Range::::from(range), &change.text); - text - }) { - Ok(t) => *old_text = t, - Err(e) => { - eprintln!("Bug in incremental text synchronization. Please report the following output on https://github.com/rust-analyzer/rust-analyzer/issues/4263"); - dbg!(&backup_text); - dbg!(&backup_changes); - std::panic::resume_unwind(e); - } - } + old_text.replace_range(Range::::from(range), &change.text); } None => { *old_text = change.text; -- cgit v1.2.3 From 8ff91cf6b649ea241e886726df91d9bcb6b6c7cb Mon Sep 17 00:00:00 2001 From: Leander Tentrup Date: Tue, 16 Jun 2020 23:03:59 +0200 Subject: Inspect markdown code fences to determine whether to apply syntax highlighting --- crates/ra_ide/src/snapshots/highlight_doctest.html | 6 +++++- crates/ra_ide/src/syntax_highlighting/injection.rs | 14 ++++++++++++-- crates/ra_ide/src/syntax_highlighting/tests.rs | 6 +++++- 3 files changed, 22 insertions(+), 4 deletions(-) (limited to 'crates') diff --git a/crates/ra_ide/src/snapshots/highlight_doctest.html b/crates/ra_ide/src/snapshots/highlight_doctest.html index 5228df267..13a5d1b12 100644 --- a/crates/ra_ide/src/snapshots/highlight_doctest.html +++ b/crates/ra_ide/src/snapshots/highlight_doctest.html @@ -73,9 +73,13 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd /// /// ``` /// - /// ``` + /// ```rust,no_run /// let foobar = Foo::new().bar(); /// ``` + /// + /// ```sh + /// echo 1 + /// ``` pub fn foo(&self) -> bool { true } diff --git a/crates/ra_ide/src/syntax_highlighting/injection.rs b/crates/ra_ide/src/syntax_highlighting/injection.rs index a02ffe59e..929a5cc5c 100644 --- a/crates/ra_ide/src/syntax_highlighting/injection.rs +++ b/crates/ra_ide/src/syntax_highlighting/injection.rs @@ -53,6 +53,10 @@ pub(super) fn highlight_injection( /// Mapping from extracted documentation code to original code type RangesMap = BTreeMap; +const RUSTDOC_FENCE: &'static str = "```"; +const RUSTDOC_FENCE_TOKENS: &[&'static str] = + &["", "rust", "should_panic", "ignore", "no_run", "compile_fail", "edition2015", "edition2018"]; + /// Extracts Rust code from documentation comments as well as a mapping from /// the extracted source code back to the original source ranges. /// Lastly, a vector of new comment highlight ranges (spanning only the @@ -67,6 +71,7 @@ pub(super) fn extract_doc_comments( // Mapping from extracted documentation code to original code let mut range_mapping: RangesMap = BTreeMap::new(); let mut line_start = TextSize::try_from(prefix.len()).unwrap(); + let mut is_codeblock = false; let mut is_doctest = false; // Replace the original, line-spanning comment ranges by new, only comment-prefix // spanning comment ranges. @@ -76,8 +81,13 @@ pub(super) fn extract_doc_comments( .filter_map(|el| el.into_token().and_then(ast::Comment::cast)) .filter(|comment| comment.kind().doc.is_some()) .filter(|comment| { - if comment.text().contains("```") { - is_doctest = !is_doctest; + if let Some(idx) = comment.text().find(RUSTDOC_FENCE) { + is_codeblock = !is_codeblock; + // Check whether code is rust by inspecting fence guards + let guards = &comment.text()[idx + RUSTDOC_FENCE.len()..]; + let is_rust = + guards.split(',').all(|sub| RUSTDOC_FENCE_TOKENS.contains(&sub.trim())); + is_doctest = is_codeblock && is_rust; false } else { is_doctest diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs index 062b3ff4a..ebf5b50ac 100644 --- a/crates/ra_ide/src/syntax_highlighting/tests.rs +++ b/crates/ra_ide/src/syntax_highlighting/tests.rs @@ -329,9 +329,13 @@ impl Foo { /// /// ``` /// - /// ``` + /// ```rust,no_run /// let foobar = Foo::new().bar(); /// ``` + /// + /// ```sh + /// echo 1 + /// ``` pub fn foo(&self) -> bool { true } -- cgit v1.2.3 From 656e95211edf26bd82bd66f53ca3bcdfb7296e81 Mon Sep 17 00:00:00 2001 From: Gabriel Valfridsson Date: Tue, 16 Jun 2020 22:26:33 +0200 Subject: Warnings as hint or info --- crates/rust-analyzer/src/config.rs | 5 + crates/rust-analyzer/src/diagnostics.rs | 6 + ..._tests__snap_rustc_unused_variable_as_hint.snap | 86 +++++++++ ..._tests__snap_rustc_unused_variable_as_info.snap | 86 +++++++++ crates/rust-analyzer/src/diagnostics/to_proto.rs | 213 +++++++++++++++++++-- crates/rust-analyzer/src/main_loop.rs | 1 + 6 files changed, 384 insertions(+), 13 deletions(-) create mode 100644 crates/rust-analyzer/src/diagnostics/snapshots/rust_analyzer__diagnostics__to_proto__tests__snap_rustc_unused_variable_as_hint.snap create mode 100644 crates/rust-analyzer/src/diagnostics/snapshots/rust_analyzer__diagnostics__to_proto__tests__snap_rustc_unused_variable_as_info.snap (limited to 'crates') diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 0e7a937a0..0df7427cb 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -9,6 +9,7 @@ use std::{ffi::OsString, path::PathBuf}; +use crate::diagnostics::DiagnosticsConfig; use lsp_types::ClientCapabilities; use ra_flycheck::FlycheckConfig; use ra_ide::{AssistConfig, CompletionConfig, HoverConfig, InlayHintsConfig}; @@ -20,6 +21,7 @@ pub struct Config { pub client_caps: ClientCapsConfig, pub publish_diagnostics: bool, + pub diagnostics: DiagnosticsConfig, pub lru_capacity: Option, pub proc_macro_srv: Option<(PathBuf, Vec)>, pub files: FilesConfig, @@ -136,6 +138,7 @@ impl Default for Config { with_sysroot: true, publish_diagnostics: true, + diagnostics: DiagnosticsConfig::default(), lru_capacity: None, proc_macro_srv: None, files: FilesConfig { watcher: FilesWatcher::Notify, exclude: Vec::new() }, @@ -184,6 +187,8 @@ impl Config { set(value, "/withSysroot", &mut self.with_sysroot); set(value, "/diagnostics/enable", &mut self.publish_diagnostics); + set(value, "/diagnostics/warningsAsInfo", &mut self.diagnostics.warnings_as_info); + set(value, "/diagnostics/warningsAsHint", &mut self.diagnostics.warnings_as_hint); set(value, "/lruCapacity", &mut self.lru_capacity); self.files.watcher = match get(value, "/files/watcher") { Some("client") => FilesWatcher::Client, diff --git a/crates/rust-analyzer/src/diagnostics.rs b/crates/rust-analyzer/src/diagnostics.rs index 25856c543..290609e7f 100644 --- a/crates/rust-analyzer/src/diagnostics.rs +++ b/crates/rust-analyzer/src/diagnostics.rs @@ -10,6 +10,12 @@ use crate::lsp_ext; pub type CheckFixes = Arc>>; +#[derive(Debug, Default, Clone)] +pub struct DiagnosticsConfig { + pub warnings_as_info: Vec, + pub warnings_as_hint: Vec, +} + #[derive(Debug, Default, Clone)] pub struct DiagnosticCollection { pub native: HashMap>, diff --git a/crates/rust-analyzer/src/diagnostics/snapshots/rust_analyzer__diagnostics__to_proto__tests__snap_rustc_unused_variable_as_hint.snap b/crates/rust-analyzer/src/diagnostics/snapshots/rust_analyzer__diagnostics__to_proto__tests__snap_rustc_unused_variable_as_hint.snap new file mode 100644 index 000000000..f0273315e --- /dev/null +++ b/crates/rust-analyzer/src/diagnostics/snapshots/rust_analyzer__diagnostics__to_proto__tests__snap_rustc_unused_variable_as_hint.snap @@ -0,0 +1,86 @@ +--- +source: crates/rust-analyzer/src/diagnostics/to_proto.rs +expression: diag +--- +[ + MappedRustDiagnostic { + location: Location { + uri: "file:///test/driver/subcommand/repl.rs", + range: Range { + start: Position { + line: 290, + character: 8, + }, + end: Position { + line: 290, + character: 11, + }, + }, + }, + diagnostic: Diagnostic { + range: Range { + start: Position { + line: 290, + character: 8, + }, + end: Position { + line: 290, + character: 11, + }, + }, + severity: Some( + Hint, + ), + code: Some( + String( + "unused_variables", + ), + ), + source: Some( + "rustc", + ), + message: "unused variable: `foo`\n#[warn(unused_variables)] on by default", + related_information: None, + tags: Some( + [ + Unnecessary, + ], + ), + }, + fixes: [ + CodeAction { + title: "consider prefixing with an underscore", + id: None, + group: None, + kind: Some( + "quickfix", + ), + command: None, + edit: Some( + SnippetWorkspaceEdit { + changes: Some( + { + "file:///test/driver/subcommand/repl.rs": [ + TextEdit { + range: Range { + start: Position { + line: 290, + character: 8, + }, + end: Position { + line: 290, + character: 11, + }, + }, + new_text: "_foo", + }, + ], + }, + ), + document_changes: None, + }, + ), + }, + ], + }, +] diff --git a/crates/rust-analyzer/src/diagnostics/snapshots/rust_analyzer__diagnostics__to_proto__tests__snap_rustc_unused_variable_as_info.snap b/crates/rust-analyzer/src/diagnostics/snapshots/rust_analyzer__diagnostics__to_proto__tests__snap_rustc_unused_variable_as_info.snap new file mode 100644 index 000000000..85fd050fd --- /dev/null +++ b/crates/rust-analyzer/src/diagnostics/snapshots/rust_analyzer__diagnostics__to_proto__tests__snap_rustc_unused_variable_as_info.snap @@ -0,0 +1,86 @@ +--- +source: crates/rust-analyzer/src/diagnostics/to_proto.rs +expression: diag +--- +[ + MappedRustDiagnostic { + location: Location { + uri: "file:///test/driver/subcommand/repl.rs", + range: Range { + start: Position { + line: 290, + character: 8, + }, + end: Position { + line: 290, + character: 11, + }, + }, + }, + diagnostic: Diagnostic { + range: Range { + start: Position { + line: 290, + character: 8, + }, + end: Position { + line: 290, + character: 11, + }, + }, + severity: Some( + Information, + ), + code: Some( + String( + "unused_variables", + ), + ), + source: Some( + "rustc", + ), + message: "unused variable: `foo`\n#[warn(unused_variables)] on by default", + related_information: None, + tags: Some( + [ + Unnecessary, + ], + ), + }, + fixes: [ + CodeAction { + title: "consider prefixing with an underscore", + id: None, + group: None, + kind: Some( + "quickfix", + ), + command: None, + edit: Some( + SnippetWorkspaceEdit { + changes: Some( + { + "file:///test/driver/subcommand/repl.rs": [ + TextEdit { + range: Range { + start: Position { + line: 290, + character: 8, + }, + end: Position { + line: 290, + character: 11, + }, + }, + new_text: "_foo", + }, + ], + }, + ), + document_changes: None, + }, + ), + }, + ], + }, +] diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs index 24ff9b280..ba74f15f3 100644 --- a/crates/rust-analyzer/src/diagnostics/to_proto.rs +++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs @@ -9,14 +9,24 @@ use lsp_types::{ use ra_flycheck::{Applicability, DiagnosticLevel, DiagnosticSpan, DiagnosticSpanMacroExpansion}; use stdx::format_to; +use super::DiagnosticsConfig; use crate::{lsp_ext, to_proto::url_from_abs_path}; -/// Converts a Rust level string to a LSP severity -fn map_level_to_severity(val: DiagnosticLevel) -> Option { - let res = match val { +/// Determines the LSP severity from a diagnostic +fn map_diagnostic_to_severity( + config: &DiagnosticsConfig, + val: &ra_flycheck::Diagnostic, +) -> Option { + let res = match val.level { DiagnosticLevel::Ice => DiagnosticSeverity::Error, DiagnosticLevel::Error => DiagnosticSeverity::Error, - DiagnosticLevel::Warning => DiagnosticSeverity::Warning, + DiagnosticLevel::Warning => match &val.code { + Some(code) if config.warnings_as_hint.contains(&code.code) => DiagnosticSeverity::Hint, + Some(code) if config.warnings_as_info.contains(&code.code) => { + DiagnosticSeverity::Information + } + _ => DiagnosticSeverity::Warning, + }, DiagnosticLevel::Note => DiagnosticSeverity::Information, DiagnosticLevel::Help => DiagnosticSeverity::Hint, DiagnosticLevel::Unknown => return None, @@ -172,6 +182,7 @@ pub(crate) struct MappedRustDiagnostic { /// /// If the diagnostic has no primary span this will return `None` pub(crate) fn map_rust_diagnostic_to_lsp( + config: &DiagnosticsConfig, rd: &ra_flycheck::Diagnostic, workspace_root: &Path, ) -> Vec { @@ -180,7 +191,7 @@ pub(crate) fn map_rust_diagnostic_to_lsp( return Vec::new(); } - let severity = map_level_to_severity(rd.level); + let severity = map_diagnostic_to_severity(config, rd); let mut source = String::from("rustc"); let mut code = rd.code.as_ref().map(|c| c.code.clone()); @@ -328,7 +339,7 @@ mod tests { ); let workspace_root = Path::new("/test/"); - let diag = map_rust_diagnostic_to_lsp(&diag, workspace_root); + let diag = map_rust_diagnostic_to_lsp(&DiagnosticsConfig::default(), &diag, workspace_root); insta::assert_debug_snapshot!(diag); } @@ -410,7 +421,183 @@ mod tests { ); let workspace_root = Path::new("/test/"); - let diag = map_rust_diagnostic_to_lsp(&diag, workspace_root); + let diag = map_rust_diagnostic_to_lsp(&DiagnosticsConfig::default(), &diag, workspace_root); + insta::assert_debug_snapshot!(diag); + } + + #[test] + #[cfg(not(windows))] + fn snap_rustc_unused_variable_as_info() { + let diag = parse_diagnostic( + r##"{ + "message": "unused variable: `foo`", + "code": { + "code": "unused_variables", + "explanation": null + }, + "level": "warning", + "spans": [ + { + "file_name": "driver/subcommand/repl.rs", + "byte_start": 9228, + "byte_end": 9231, + "line_start": 291, + "line_end": 291, + "column_start": 9, + "column_end": 12, + "is_primary": true, + "text": [ + { + "text": " let foo = 42;", + "highlight_start": 9, + "highlight_end": 12 + } + ], + "label": null, + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + } + ], + "children": [ + { + "message": "#[warn(unused_variables)] on by default", + "code": null, + "level": "note", + "spans": [], + "children": [], + "rendered": null + }, + { + "message": "consider prefixing with an underscore", + "code": null, + "level": "help", + "spans": [ + { + "file_name": "driver/subcommand/repl.rs", + "byte_start": 9228, + "byte_end": 9231, + "line_start": 291, + "line_end": 291, + "column_start": 9, + "column_end": 12, + "is_primary": true, + "text": [ + { + "text": " let foo = 42;", + "highlight_start": 9, + "highlight_end": 12 + } + ], + "label": null, + "suggested_replacement": "_foo", + "suggestion_applicability": "MachineApplicable", + "expansion": null + } + ], + "children": [], + "rendered": null + } + ], + "rendered": "warning: unused variable: `foo`\n --> driver/subcommand/repl.rs:291:9\n |\n291 | let foo = 42;\n | ^^^ help: consider prefixing with an underscore: `_foo`\n |\n = note: #[warn(unused_variables)] on by default\n\n" + }"##, + ); + + let config = DiagnosticsConfig { + warnings_as_info: vec!["unused_variables".to_string()], + ..DiagnosticsConfig::default() + }; + + let workspace_root = Path::new("/test/"); + let diag = map_rust_diagnostic_to_lsp(&config, &diag, workspace_root); + insta::assert_debug_snapshot!(diag); + } + + #[test] + #[cfg(not(windows))] + fn snap_rustc_unused_variable_as_hint() { + let diag = parse_diagnostic( + r##"{ + "message": "unused variable: `foo`", + "code": { + "code": "unused_variables", + "explanation": null + }, + "level": "warning", + "spans": [ + { + "file_name": "driver/subcommand/repl.rs", + "byte_start": 9228, + "byte_end": 9231, + "line_start": 291, + "line_end": 291, + "column_start": 9, + "column_end": 12, + "is_primary": true, + "text": [ + { + "text": " let foo = 42;", + "highlight_start": 9, + "highlight_end": 12 + } + ], + "label": null, + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + } + ], + "children": [ + { + "message": "#[warn(unused_variables)] on by default", + "code": null, + "level": "note", + "spans": [], + "children": [], + "rendered": null + }, + { + "message": "consider prefixing with an underscore", + "code": null, + "level": "help", + "spans": [ + { + "file_name": "driver/subcommand/repl.rs", + "byte_start": 9228, + "byte_end": 9231, + "line_start": 291, + "line_end": 291, + "column_start": 9, + "column_end": 12, + "is_primary": true, + "text": [ + { + "text": " let foo = 42;", + "highlight_start": 9, + "highlight_end": 12 + } + ], + "label": null, + "suggested_replacement": "_foo", + "suggestion_applicability": "MachineApplicable", + "expansion": null + } + ], + "children": [], + "rendered": null + } + ], + "rendered": "warning: unused variable: `foo`\n --> driver/subcommand/repl.rs:291:9\n |\n291 | let foo = 42;\n | ^^^ help: consider prefixing with an underscore: `_foo`\n |\n = note: #[warn(unused_variables)] on by default\n\n" + }"##, + ); + + let config = DiagnosticsConfig { + warnings_as_hint: vec!["unused_variables".to_string()], + ..DiagnosticsConfig::default() + }; + + let workspace_root = Path::new("/test/"); + let diag = map_rust_diagnostic_to_lsp(&config, &diag, workspace_root); insta::assert_debug_snapshot!(diag); } @@ -534,7 +721,7 @@ mod tests { ); let workspace_root = Path::new("/test/"); - let diag = map_rust_diagnostic_to_lsp(&diag, workspace_root); + let diag = map_rust_diagnostic_to_lsp(&DiagnosticsConfig::default(), &diag, workspace_root); insta::assert_debug_snapshot!(diag); } @@ -654,7 +841,7 @@ mod tests { ); let workspace_root = Path::new("/test/"); - let diag = map_rust_diagnostic_to_lsp(&diag, workspace_root); + let diag = map_rust_diagnostic_to_lsp(&DiagnosticsConfig::default(), &diag, workspace_root); insta::assert_debug_snapshot!(diag); } @@ -697,7 +884,7 @@ mod tests { ); let workspace_root = Path::new("/test/"); - let diag = map_rust_diagnostic_to_lsp(&diag, workspace_root); + let diag = map_rust_diagnostic_to_lsp(&DiagnosticsConfig::default(), &diag, workspace_root); insta::assert_debug_snapshot!(diag); } @@ -968,7 +1155,7 @@ mod tests { ); let workspace_root = Path::new("/test/"); - let diag = map_rust_diagnostic_to_lsp(&diag, workspace_root); + let diag = map_rust_diagnostic_to_lsp(&DiagnosticsConfig::default(), &diag, workspace_root); insta::assert_debug_snapshot!(diag); } @@ -1197,7 +1384,7 @@ mod tests { ); let workspace_root = Path::new("/test/"); - let diag = map_rust_diagnostic_to_lsp(&diag, workspace_root); + let diag = map_rust_diagnostic_to_lsp(&DiagnosticsConfig::default(), &diag, workspace_root); insta::assert_debug_snapshot!(diag); } @@ -1330,7 +1517,7 @@ mod tests { ); let workspace_root = Path::new("/test/"); - let diag = map_rust_diagnostic_to_lsp(&diag, workspace_root); + let diag = map_rust_diagnostic_to_lsp(&DiagnosticsConfig::default(), &diag, workspace_root); insta::assert_debug_snapshot!(diag); } } diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index cc9bb1726..534d9f223 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -734,6 +734,7 @@ fn on_check_task( CheckTask::AddDiagnostic { workspace_root, diagnostic } => { let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp( + &global_state.config.diagnostics, &diagnostic, &workspace_root, ); -- cgit v1.2.3