diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-10-20 17:35:05 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-10-20 17:35:05 +0100 |
commit | 20d369a826e8f333cba1988325480a49a730f00e (patch) | |
tree | 266845de2212273c0967ed6455bdc0c7b485f225 /crates/ide | |
parent | 5dd99aa016bd9f7b8bcbc0eb47998723b675bb26 (diff) | |
parent | 74ac83a5acc9f53db69577fc32a4a6e3985d2ef9 (diff) |
Merge #6299
6299: Diagnose items that are #[cfg]d out r=jonas-schievink a=jonas-schievink
This emits a hint-level diagnostic with `Unnecessary` tag to "gray out" any items whose `#[cfg]` attributes remove the item before name resolution.
Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/ide')
-rw-r--r-- | crates/ide/src/diagnostics.rs | 89 | ||||
-rw-r--r-- | crates/ide/src/diagnostics/field_shorthand.rs | 32 |
2 files changed, 63 insertions, 58 deletions
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index 1e5ea4617..90574cb35 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs | |||
@@ -10,7 +10,10 @@ mod field_shorthand; | |||
10 | use std::cell::RefCell; | 10 | use std::cell::RefCell; |
11 | 11 | ||
12 | use base_db::SourceDatabase; | 12 | use base_db::SourceDatabase; |
13 | use hir::{diagnostics::DiagnosticSinkBuilder, Semantics}; | 13 | use hir::{ |
14 | diagnostics::{Diagnostic as _, DiagnosticSinkBuilder}, | ||
15 | Semantics, | ||
16 | }; | ||
14 | use ide_db::RootDatabase; | 17 | use ide_db::RootDatabase; |
15 | use itertools::Itertools; | 18 | use itertools::Itertools; |
16 | use rustc_hash::FxHashSet; | 19 | use rustc_hash::FxHashSet; |
@@ -31,6 +34,25 @@ pub struct Diagnostic { | |||
31 | pub range: TextRange, | 34 | pub range: TextRange, |
32 | pub severity: Severity, | 35 | pub severity: Severity, |
33 | pub fix: Option<Fix>, | 36 | pub fix: Option<Fix>, |
37 | pub unused: bool, | ||
38 | } | ||
39 | |||
40 | impl Diagnostic { | ||
41 | fn error(range: TextRange, message: String) -> Self { | ||
42 | Self { message, range, severity: Severity::Error, fix: None, unused: false } | ||
43 | } | ||
44 | |||
45 | fn hint(range: TextRange, message: String) -> Self { | ||
46 | Self { message, range, severity: Severity::WeakWarning, fix: None, unused: false } | ||
47 | } | ||
48 | |||
49 | fn with_fix(self, fix: Option<Fix>) -> Self { | ||
50 | Self { fix, ..self } | ||
51 | } | ||
52 | |||
53 | fn with_unused(self, unused: bool) -> Self { | ||
54 | Self { unused, ..self } | ||
55 | } | ||
34 | } | 56 | } |
35 | 57 | ||
36 | #[derive(Debug)] | 58 | #[derive(Debug)] |
@@ -71,13 +93,13 @@ pub(crate) fn diagnostics( | |||
71 | let mut res = Vec::new(); | 93 | let mut res = Vec::new(); |
72 | 94 | ||
73 | // [#34344] Only take first 128 errors to prevent slowing down editor/ide, the number 128 is chosen arbitrarily. | 95 | // [#34344] Only take first 128 errors to prevent slowing down editor/ide, the number 128 is chosen arbitrarily. |
74 | res.extend(parse.errors().iter().take(128).map(|err| Diagnostic { | 96 | res.extend( |
75 | // name: None, | 97 | parse |
76 | range: err.range(), | 98 | .errors() |
77 | message: format!("Syntax Error: {}", err), | 99 | .iter() |
78 | severity: Severity::Error, | 100 | .take(128) |
79 | fix: None, | 101 | .map(|err| Diagnostic::error(err.range(), format!("Syntax Error: {}", err))), |
80 | })); | 102 | ); |
81 | 103 | ||
82 | for node in parse.tree().syntax().descendants() { | 104 | for node in parse.tree().syntax().descendants() { |
83 | check_unnecessary_braces_in_use_statement(&mut res, file_id, &node); | 105 | check_unnecessary_braces_in_use_statement(&mut res, file_id, &node); |
@@ -100,6 +122,13 @@ pub(crate) fn diagnostics( | |||
100 | .on::<hir::diagnostics::IncorrectCase, _>(|d| { | 122 | .on::<hir::diagnostics::IncorrectCase, _>(|d| { |
101 | res.borrow_mut().push(warning_with_fix(d, &sema)); | 123 | res.borrow_mut().push(warning_with_fix(d, &sema)); |
102 | }) | 124 | }) |
125 | .on::<hir::diagnostics::InactiveCode, _>(|d| { | ||
126 | // Override severity and mark as unused. | ||
127 | res.borrow_mut().push( | ||
128 | Diagnostic::hint(sema.diagnostics_display_range(d).range, d.message()) | ||
129 | .with_unused(true), | ||
130 | ); | ||
131 | }) | ||
103 | // Only collect experimental diagnostics when they're enabled. | 132 | // Only collect experimental diagnostics when they're enabled. |
104 | .filter(|diag| !(diag.is_experimental() && config.disable_experimental)) | 133 | .filter(|diag| !(diag.is_experimental() && config.disable_experimental)) |
105 | .filter(|diag| !config.disabled.contains(diag.code().as_str())); | 134 | .filter(|diag| !config.disabled.contains(diag.code().as_str())); |
@@ -108,13 +137,8 @@ pub(crate) fn diagnostics( | |||
108 | let mut sink = sink_builder | 137 | let mut sink = sink_builder |
109 | // Diagnostics not handled above get no fix and default treatment. | 138 | // Diagnostics not handled above get no fix and default treatment. |
110 | .build(|d| { | 139 | .build(|d| { |
111 | res.borrow_mut().push(Diagnostic { | 140 | res.borrow_mut() |
112 | // name: Some(d.name().into()), | 141 | .push(Diagnostic::error(sema.diagnostics_display_range(d).range, d.message())); |
113 | message: d.message(), | ||
114 | range: sema.diagnostics_display_range(d).range, | ||
115 | severity: Severity::Error, | ||
116 | fix: None, | ||
117 | }) | ||
118 | }); | 142 | }); |
119 | 143 | ||
120 | if let Some(m) = sema.to_module_def(file_id) { | 144 | if let Some(m) = sema.to_module_def(file_id) { |
@@ -125,22 +149,11 @@ pub(crate) fn diagnostics( | |||
125 | } | 149 | } |
126 | 150 | ||
127 | fn diagnostic_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabase>) -> Diagnostic { | 151 | fn diagnostic_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabase>) -> Diagnostic { |
128 | Diagnostic { | 152 | Diagnostic::error(sema.diagnostics_display_range(d).range, d.message()).with_fix(d.fix(&sema)) |
129 | // name: Some(d.name().into()), | ||
130 | range: sema.diagnostics_display_range(d).range, | ||
131 | message: d.message(), | ||
132 | severity: Severity::Error, | ||
133 | fix: d.fix(&sema), | ||
134 | } | ||
135 | } | 153 | } |
136 | 154 | ||
137 | fn warning_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabase>) -> Diagnostic { | 155 | fn warning_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabase>) -> Diagnostic { |
138 | Diagnostic { | 156 | Diagnostic::hint(sema.diagnostics_display_range(d).range, d.message()).with_fix(d.fix(&sema)) |
139 | range: sema.diagnostics_display_range(d).range, | ||
140 | message: d.message(), | ||
141 | severity: Severity::WeakWarning, | ||
142 | fix: d.fix(&sema), | ||
143 | } | ||
144 | } | 157 | } |
145 | 158 | ||
146 | fn check_unnecessary_braces_in_use_statement( | 159 | fn check_unnecessary_braces_in_use_statement( |
@@ -161,17 +174,14 @@ fn check_unnecessary_braces_in_use_statement( | |||
161 | edit_builder.finish() | 174 | edit_builder.finish() |
162 | }); | 175 | }); |
163 | 176 | ||
164 | acc.push(Diagnostic { | 177 | acc.push( |
165 | // name: None, | 178 | Diagnostic::hint(use_range, "Unnecessary braces in use statement".to_string()) |
166 | range: use_range, | 179 | .with_fix(Some(Fix::new( |
167 | message: "Unnecessary braces in use statement".to_string(), | 180 | "Remove unnecessary braces", |
168 | severity: Severity::WeakWarning, | 181 | SourceFileEdit { file_id, edit }.into(), |
169 | fix: Some(Fix::new( | 182 | use_range, |
170 | "Remove unnecessary braces", | 183 | ))), |
171 | SourceFileEdit { file_id, edit }.into(), | 184 | ); |
172 | use_range, | ||
173 | )), | ||
174 | }); | ||
175 | } | 185 | } |
176 | 186 | ||
177 | Some(()) | 187 | Some(()) |
@@ -578,6 +588,7 @@ fn test_fn() { | |||
578 | fix_trigger_range: 0..8, | 588 | fix_trigger_range: 0..8, |
579 | }, | 589 | }, |
580 | ), | 590 | ), |
591 | unused: false, | ||
581 | }, | 592 | }, |
582 | ] | 593 | ] |
583 | "#]], | 594 | "#]], |
diff --git a/crates/ide/src/diagnostics/field_shorthand.rs b/crates/ide/src/diagnostics/field_shorthand.rs index 2c4acd783..54e9fce9e 100644 --- a/crates/ide/src/diagnostics/field_shorthand.rs +++ b/crates/ide/src/diagnostics/field_shorthand.rs | |||
@@ -6,7 +6,7 @@ use ide_db::source_change::SourceFileEdit; | |||
6 | use syntax::{ast, match_ast, AstNode, SyntaxNode}; | 6 | use syntax::{ast, match_ast, AstNode, SyntaxNode}; |
7 | use text_edit::TextEdit; | 7 | use text_edit::TextEdit; |
8 | 8 | ||
9 | use crate::{Diagnostic, Fix, Severity}; | 9 | use crate::{Diagnostic, Fix}; |
10 | 10 | ||
11 | pub(super) fn check(acc: &mut Vec<Diagnostic>, file_id: FileId, node: &SyntaxNode) { | 11 | pub(super) fn check(acc: &mut Vec<Diagnostic>, file_id: FileId, node: &SyntaxNode) { |
12 | match_ast! { | 12 | match_ast! { |
@@ -46,17 +46,15 @@ fn check_expr_field_shorthand( | |||
46 | let edit = edit_builder.finish(); | 46 | let edit = edit_builder.finish(); |
47 | 47 | ||
48 | let field_range = record_field.syntax().text_range(); | 48 | let field_range = record_field.syntax().text_range(); |
49 | acc.push(Diagnostic { | 49 | acc.push( |
50 | // name: None, | 50 | Diagnostic::hint(field_range, "Shorthand struct initialization".to_string()).with_fix( |
51 | range: field_range, | 51 | Some(Fix::new( |
52 | message: "Shorthand struct initialization".to_string(), | 52 | "Use struct shorthand initialization", |
53 | severity: Severity::WeakWarning, | 53 | SourceFileEdit { file_id, edit }.into(), |
54 | fix: Some(Fix::new( | 54 | field_range, |
55 | "Use struct shorthand initialization", | 55 | )), |
56 | SourceFileEdit { file_id, edit }.into(), | 56 | ), |
57 | field_range, | 57 | ); |
58 | )), | ||
59 | }); | ||
60 | } | 58 | } |
61 | } | 59 | } |
62 | 60 | ||
@@ -88,17 +86,13 @@ fn check_pat_field_shorthand( | |||
88 | let edit = edit_builder.finish(); | 86 | let edit = edit_builder.finish(); |
89 | 87 | ||
90 | let field_range = record_pat_field.syntax().text_range(); | 88 | let field_range = record_pat_field.syntax().text_range(); |
91 | acc.push(Diagnostic { | 89 | acc.push(Diagnostic::hint(field_range, "Shorthand struct pattern".to_string()).with_fix( |
92 | // name: None, | 90 | Some(Fix::new( |
93 | range: field_range, | ||
94 | message: "Shorthand struct pattern".to_string(), | ||
95 | severity: Severity::WeakWarning, | ||
96 | fix: Some(Fix::new( | ||
97 | "Use struct field shorthand", | 91 | "Use struct field shorthand", |
98 | SourceFileEdit { file_id, edit }.into(), | 92 | SourceFileEdit { file_id, edit }.into(), |
99 | field_range, | 93 | field_range, |
100 | )), | 94 | )), |
101 | }); | 95 | )); |
102 | } | 96 | } |
103 | } | 97 | } |
104 | 98 | ||