aboutsummaryrefslogtreecommitdiff
path: root/crates/ide
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-10-20 17:35:05 +0100
committerGitHub <[email protected]>2020-10-20 17:35:05 +0100
commit20d369a826e8f333cba1988325480a49a730f00e (patch)
tree266845de2212273c0967ed6455bdc0c7b485f225 /crates/ide
parent5dd99aa016bd9f7b8bcbc0eb47998723b675bb26 (diff)
parent74ac83a5acc9f53db69577fc32a4a6e3985d2ef9 (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.rs89
-rw-r--r--crates/ide/src/diagnostics/field_shorthand.rs32
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;
10use std::cell::RefCell; 10use std::cell::RefCell;
11 11
12use base_db::SourceDatabase; 12use base_db::SourceDatabase;
13use hir::{diagnostics::DiagnosticSinkBuilder, Semantics}; 13use hir::{
14 diagnostics::{Diagnostic as _, DiagnosticSinkBuilder},
15 Semantics,
16};
14use ide_db::RootDatabase; 17use ide_db::RootDatabase;
15use itertools::Itertools; 18use itertools::Itertools;
16use rustc_hash::FxHashSet; 19use 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
40impl 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
127fn diagnostic_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabase>) -> Diagnostic { 151fn 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
137fn warning_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabase>) -> Diagnostic { 155fn 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
146fn check_unnecessary_braces_in_use_statement( 159fn 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;
6use syntax::{ast, match_ast, AstNode, SyntaxNode}; 6use syntax::{ast, match_ast, AstNode, SyntaxNode};
7use text_edit::TextEdit; 7use text_edit::TextEdit;
8 8
9use crate::{Diagnostic, Fix, Severity}; 9use crate::{Diagnostic, Fix};
10 10
11pub(super) fn check(acc: &mut Vec<Diagnostic>, file_id: FileId, node: &SyntaxNode) { 11pub(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