diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-08-18 17:40:12 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-08-18 17:40:12 +0100 |
commit | aa2def023e6b0aa8a68f4992423f566d435e55c6 (patch) | |
tree | 769fbd88c0845367795e1273333245d2cadfc475 /crates/ide/src | |
parent | f7a8ce35256e6a79dbe641787007e18a74e52b16 (diff) | |
parent | 8146669542dfc887956901b54a453c9a97fee7e3 (diff) |
Merge #5804
5804: Add type safety to diagnostic codes
r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ide/src')
-rw-r--r-- | crates/ide/src/diagnostics.rs | 76 |
1 files changed, 17 insertions, 59 deletions
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index 3c36c0e15..92b5adaa2 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs | |||
@@ -25,7 +25,7 @@ use self::fixes::DiagnosticWithFix; | |||
25 | 25 | ||
26 | #[derive(Debug)] | 26 | #[derive(Debug)] |
27 | pub struct Diagnostic { | 27 | pub struct Diagnostic { |
28 | pub name: Option<String>, | 28 | // pub name: Option<String>, |
29 | pub message: String, | 29 | pub message: String, |
30 | pub range: TextRange, | 30 | pub range: TextRange, |
31 | pub severity: Severity, | 31 | pub severity: Severity, |
@@ -71,7 +71,7 @@ pub(crate) fn diagnostics( | |||
71 | 71 | ||
72 | // [#34344] Only take first 128 errors to prevent slowing down editor/ide, the number 128 is chosen arbitrarily. | 72 | // [#34344] Only take first 128 errors to prevent slowing down editor/ide, the number 128 is chosen arbitrarily. |
73 | res.extend(parse.errors().iter().take(128).map(|err| Diagnostic { | 73 | res.extend(parse.errors().iter().take(128).map(|err| Diagnostic { |
74 | name: None, | 74 | // name: None, |
75 | range: err.range(), | 75 | range: err.range(), |
76 | message: format!("Syntax Error: {}", err), | 76 | message: format!("Syntax Error: {}", err), |
77 | severity: Severity::Error, | 77 | severity: Severity::Error, |
@@ -98,14 +98,14 @@ pub(crate) fn diagnostics( | |||
98 | }) | 98 | }) |
99 | // Only collect experimental diagnostics when they're enabled. | 99 | // Only collect experimental diagnostics when they're enabled. |
100 | .filter(|diag| !(diag.is_experimental() && config.disable_experimental)) | 100 | .filter(|diag| !(diag.is_experimental() && config.disable_experimental)) |
101 | .filter(|diag| !config.disabled.contains(diag.name())); | 101 | .filter(|diag| !config.disabled.contains(diag.code().as_str())); |
102 | 102 | ||
103 | // Finalize the `DiagnosticSink` building process. | 103 | // Finalize the `DiagnosticSink` building process. |
104 | let mut sink = sink_builder | 104 | let mut sink = sink_builder |
105 | // Diagnostics not handled above get no fix and default treatment. | 105 | // Diagnostics not handled above get no fix and default treatment. |
106 | .build(|d| { | 106 | .build(|d| { |
107 | res.borrow_mut().push(Diagnostic { | 107 | res.borrow_mut().push(Diagnostic { |
108 | name: Some(d.name().into()), | 108 | // name: Some(d.name().into()), |
109 | message: d.message(), | 109 | message: d.message(), |
110 | range: sema.diagnostics_display_range(d).range, | 110 | range: sema.diagnostics_display_range(d).range, |
111 | severity: Severity::Error, | 111 | severity: Severity::Error, |
@@ -122,7 +122,7 @@ pub(crate) fn diagnostics( | |||
122 | 122 | ||
123 | fn diagnostic_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabase>) -> Diagnostic { | 123 | fn diagnostic_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabase>) -> Diagnostic { |
124 | Diagnostic { | 124 | Diagnostic { |
125 | name: Some(d.name().into()), | 125 | // name: Some(d.name().into()), |
126 | range: sema.diagnostics_display_range(d).range, | 126 | range: sema.diagnostics_display_range(d).range, |
127 | message: d.message(), | 127 | message: d.message(), |
128 | severity: Severity::Error, | 128 | severity: Severity::Error, |
@@ -149,7 +149,7 @@ fn check_unnecessary_braces_in_use_statement( | |||
149 | }); | 149 | }); |
150 | 150 | ||
151 | acc.push(Diagnostic { | 151 | acc.push(Diagnostic { |
152 | name: None, | 152 | // name: None, |
153 | range: use_range, | 153 | range: use_range, |
154 | message: "Unnecessary braces in use statement".to_string(), | 154 | message: "Unnecessary braces in use statement".to_string(), |
155 | severity: Severity::WeakWarning, | 155 | severity: Severity::WeakWarning, |
@@ -196,7 +196,7 @@ fn check_struct_shorthand_initialization( | |||
196 | 196 | ||
197 | let field_range = record_field.syntax().text_range(); | 197 | let field_range = record_field.syntax().text_range(); |
198 | acc.push(Diagnostic { | 198 | acc.push(Diagnostic { |
199 | name: None, | 199 | // name: None, |
200 | range: field_range, | 200 | range: field_range, |
201 | message: "Shorthand struct initialization".to_string(), | 201 | message: "Shorthand struct initialization".to_string(), |
202 | severity: Severity::WeakWarning, | 202 | severity: Severity::WeakWarning, |
@@ -294,54 +294,6 @@ mod tests { | |||
294 | assert_eq!(diagnostics.len(), 0, "unexpected diagnostics:\n{:#?}", diagnostics); | 294 | assert_eq!(diagnostics.len(), 0, "unexpected diagnostics:\n{:#?}", diagnostics); |
295 | } | 295 | } |
296 | 296 | ||
297 | /// Takes a multi-file input fixture with annotated cursor position and the list of disabled diagnostics, | ||
298 | /// and checks that provided diagnostics aren't spawned during analysis. | ||
299 | fn check_disabled_diagnostics(ra_fixture: &str, disabled_diagnostics: &[&'static str]) { | ||
300 | let mut config = DiagnosticsConfig::default(); | ||
301 | config.disabled = disabled_diagnostics.into_iter().map(|diag| diag.to_string()).collect(); | ||
302 | |||
303 | let mock = MockAnalysis::with_files(ra_fixture); | ||
304 | let files = mock.files().map(|(it, _)| it).collect::<Vec<_>>(); | ||
305 | let analysis = mock.analysis(); | ||
306 | |||
307 | let diagnostics = files | ||
308 | .clone() | ||
309 | .into_iter() | ||
310 | .flat_map(|file_id| analysis.diagnostics(&config, file_id).unwrap()) | ||
311 | .collect::<Vec<_>>(); | ||
312 | |||
313 | // First, we have to check that diagnostic is not emitted when it's added to the disabled diagnostics list. | ||
314 | for diagnostic in diagnostics { | ||
315 | if let Some(name) = diagnostic.name { | ||
316 | assert!( | ||
317 | !disabled_diagnostics.contains(&name.as_str()), | ||
318 | "Diagnostic {} is disabled", | ||
319 | name | ||
320 | ); | ||
321 | } | ||
322 | } | ||
323 | |||
324 | // Then, we must reset the config and repeat the check, so that we'll be sure that without | ||
325 | // config these diagnostics are emitted. | ||
326 | // This is required for tests to not become outdated if e.g. diagnostics name changes: | ||
327 | // without this additional run the test will pass simply because a diagnostic with an old name | ||
328 | // will no longer exist. | ||
329 | let diagnostics = files | ||
330 | .into_iter() | ||
331 | .flat_map(|file_id| { | ||
332 | analysis.diagnostics(&DiagnosticsConfig::default(), file_id).unwrap() | ||
333 | }) | ||
334 | .collect::<Vec<_>>(); | ||
335 | |||
336 | assert!( | ||
337 | diagnostics | ||
338 | .into_iter() | ||
339 | .filter_map(|diag| diag.name) | ||
340 | .any(|name| disabled_diagnostics.contains(&name.as_str())), | ||
341 | "At least one of the diagnostics was not emitted even without config; are the diagnostics names correct?" | ||
342 | ); | ||
343 | } | ||
344 | |||
345 | fn check_expect(ra_fixture: &str, expect: Expect) { | 297 | fn check_expect(ra_fixture: &str, expect: Expect) { |
346 | let (analysis, file_id) = single_file(ra_fixture); | 298 | let (analysis, file_id) = single_file(ra_fixture); |
347 | let diagnostics = analysis.diagnostics(&DiagnosticsConfig::default(), file_id).unwrap(); | 299 | let diagnostics = analysis.diagnostics(&DiagnosticsConfig::default(), file_id).unwrap(); |
@@ -604,9 +556,6 @@ fn test_fn() { | |||
604 | expect![[r#" | 556 | expect![[r#" |
605 | [ | 557 | [ |
606 | Diagnostic { | 558 | Diagnostic { |
607 | name: Some( | ||
608 | "unresolved-module", | ||
609 | ), | ||
610 | message: "unresolved module", | 559 | message: "unresolved module", |
611 | range: 0..8, | 560 | range: 0..8, |
612 | severity: Error, | 561 | severity: Error, |
@@ -783,6 +732,15 @@ struct Foo { | |||
783 | 732 | ||
784 | #[test] | 733 | #[test] |
785 | fn test_disabled_diagnostics() { | 734 | fn test_disabled_diagnostics() { |
786 | check_disabled_diagnostics(r#"mod foo;"#, &["unresolved-module"]); | 735 | let mut config = DiagnosticsConfig::default(); |
736 | config.disabled.insert("unresolved-module".into()); | ||
737 | |||
738 | let (analysis, file_id) = single_file(r#"mod foo;"#); | ||
739 | |||
740 | let diagnostics = analysis.diagnostics(&config, file_id).unwrap(); | ||
741 | assert!(diagnostics.is_empty()); | ||
742 | |||
743 | let diagnostics = analysis.diagnostics(&DiagnosticsConfig::default(), file_id).unwrap(); | ||
744 | assert!(!diagnostics.is_empty()); | ||
787 | } | 745 | } |
788 | } | 746 | } |