Skip to content

Commit 630023a

Browse files
authored
BREAKING: always enable ban-unknown-rule-code and ban-unused-ignore & add these docs (#769)
1 parent fe6689f commit 630023a

File tree

9 files changed

+174
-141
lines changed

9 files changed

+174
-141
lines changed

examples/dlint/main.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,7 @@ fn run_linter(
189189

190190
let mut linter_builder = LinterBuilder::default()
191191
.rules(rules)
192-
.syntax(determine_syntax(file_path))
193-
.lint_unknown_rules(true)
194-
.lint_unused_ignore_directives(true);
192+
.syntax(determine_syntax(file_path));
195193

196194
for plugin_path in &plugin_paths {
197195
let js_runner = js::JsRuleRunner::new(plugin_path);

src/context.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ impl<'view> Context<'view> {
150150
filtered
151151
}
152152

153+
/// Lint rule implementation for `ban-unused-ignore`.
154+
/// This should be run after all normal rules have been finished because this
155+
/// works for diagnostics reported by other rules.
153156
pub(crate) fn ban_unused_ignore(
154157
&self,
155158
specified_rules: &[Box<dyn LintRule>],
@@ -211,6 +214,10 @@ impl<'view> Context<'view> {
211214
diagnostics
212215
}
213216

217+
/// Lint rule implementation for `ban-unknown-rule-code`.
218+
/// This should be run after all normal rules have been finished because
219+
/// currently we collect the rule codes of plugins as they are run and thus
220+
/// there's no way of knowing what are the "known" rule codes beforehand.
214221
pub(crate) fn ban_unknown_rule_code(&self) -> Vec<LintDiagnostic> {
215222
let builtin_all_rule_codes: HashSet<&'static str> =
216223
get_all_rules().into_iter().map(|r| r.code()).collect();

src/lib.rs

Lines changed: 23 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,8 @@ mod lint_tests {
3636
use swc_common::SourceMap;
3737
use swc_ecmascript::ast::Program;
3838

39-
fn lint(
40-
source: &str,
41-
unknown_rules: bool,
42-
unused_dir: bool,
43-
rules: Vec<Box<dyn LintRule>>,
44-
) -> Vec<LintDiagnostic> {
45-
let linter = LinterBuilder::default()
46-
.lint_unknown_rules(unknown_rules)
47-
.lint_unused_ignore_directives(unused_dir)
48-
.rules(rules)
49-
.build();
39+
fn lint(source: &str, rules: Vec<Box<dyn LintRule>>) -> Vec<LintDiagnostic> {
40+
let linter = LinterBuilder::default().rules(rules).build();
5041

5142
let (_, diagnostics) = linter
5243
.lint("lint_test.ts".to_string(), source.to_string())
@@ -59,15 +50,9 @@ mod lint_tests {
5950
comments: SingleThreadedComments,
6051
source_map: Rc<SourceMap>,
6152
tokens: Vec<TokenAndSpan>,
62-
unknown_rules: bool,
63-
unused_dir: bool,
6453
rules: Vec<Box<dyn LintRule>>,
6554
) -> Vec<LintDiagnostic> {
66-
let linter = LinterBuilder::default()
67-
.lint_unknown_rules(unknown_rules)
68-
.lint_unused_ignore_directives(unused_dir)
69-
.rules(rules)
70-
.build();
55+
let linter = LinterBuilder::default().rules(rules).build();
7156

7257
let (_, diagnostics) = linter
7358
.lint_with_ast(
@@ -81,78 +66,46 @@ mod lint_tests {
8166
diagnostics
8267
}
8368

84-
fn lint_recommended_rules(
85-
source: &str,
86-
unknown_rules: bool,
87-
unused_dir: bool,
88-
) -> Vec<LintDiagnostic> {
89-
lint(source, unknown_rules, unused_dir, get_recommended_rules())
69+
fn lint_recommended_rules(source: &str) -> Vec<LintDiagnostic> {
70+
lint(source, get_recommended_rules())
9071
}
9172

9273
fn lint_recommended_rules_with_ast(
9374
ast: Program,
9475
comments: SingleThreadedComments,
9576
source_map: Rc<SourceMap>,
9677
tokens: Vec<TokenAndSpan>,
97-
unknown_rules: bool,
98-
unused_dir: bool,
9978
) -> Vec<LintDiagnostic> {
100-
lint_with_ast(
101-
ast,
102-
comments,
103-
source_map,
104-
tokens,
105-
unknown_rules,
106-
unused_dir,
107-
get_recommended_rules(),
108-
)
79+
lint_with_ast(ast, comments, source_map, tokens, get_recommended_rules())
10980
}
11081

11182
fn lint_specified_rule<T: LintRule + 'static>(
11283
source: &str,
113-
unknown_rules: bool,
114-
unused_dir: bool,
11584
) -> Vec<LintDiagnostic> {
116-
lint(source, unknown_rules, unused_dir, vec![T::new()])
85+
lint(source, vec![T::new()])
11786
}
11887

11988
#[test]
12089
fn empty_file() {
121-
let diagnostics = lint_recommended_rules("", true, false);
90+
let diagnostics = lint_recommended_rules("");
12291
assert!(diagnostics.is_empty());
12392
}
12493

12594
#[test]
126-
fn warn_unknown_rules() {
95+
fn ban_unknown_rule_code() {
12796
let src = r#"
12897
// deno-lint-ignore some-rule
12998
function _foo() {
13099
// deno-lint-ignore some-rule-2 some-rule-3
131100
let _bar_foo = true
132101
}
133102
"#;
134-
let diagnostics = lint_recommended_rules(src, true, false);
103+
let diagnostics = lint_recommended_rules(src);
135104

136105
assert_diagnostic(&diagnostics[0], "ban-unknown-rule-code", 2, 1, src);
137106
assert_diagnostic(&diagnostics[1], "ban-unknown-rule-code", 4, 3, src);
138107
}
139108

140-
#[test]
141-
fn ignore_unknown_rules() {
142-
let diagnostics = lint_recommended_rules(
143-
r#"
144-
// deno-lint-ignore some-rule
145-
function _foo() {
146-
// pass
147-
}
148-
"#,
149-
false,
150-
false,
151-
);
152-
153-
assert_eq!(diagnostics.len(), 0);
154-
}
155-
156109
#[test]
157110
fn unknown_rules_always_know_available_rules() {
158111
use crate::rules::camelcase::Camelcase;
@@ -161,15 +114,13 @@ mod lint_tests {
161114
// deno-lint-ignore no-explicit-any
162115
const fooBar: any = 42;
163116
"#,
164-
true,
165-
false,
166117
);
167118

168119
assert!(diagnostics.is_empty());
169120
}
170121

171122
#[test]
172-
fn ban_unused_ignore_enabled() {
123+
fn ban_unused_ignore() {
173124
let src = r#"
174125
// deno-lint-ignore no-explicit-any
175126
function _bar(_p: boolean) {
@@ -178,31 +129,13 @@ const fooBar: any = 42;
178129
}
179130
"#;
180131

181-
let diagnostics = lint_recommended_rules(
182-
src, false, true, // enables `ban-unused-ignore`
183-
);
132+
let diagnostics = lint_recommended_rules(src);
184133

185134
assert_eq!(diagnostics.len(), 2);
186135
assert_diagnostic(&diagnostics[0], "ban-unused-ignore", 2, 1, src);
187136
assert_diagnostic(&diagnostics[1], "ban-unused-ignore", 4, 3, src);
188137
}
189138

190-
#[test]
191-
fn ban_unused_ignore_disabled() {
192-
let diagnostics = lint_recommended_rules(
193-
r#"
194-
// deno-lint-ignore no-explicit-any
195-
function _bar(_p: boolean) {
196-
// pass
197-
}
198-
"#,
199-
false,
200-
false, // disables `ban-unused-ignore`
201-
);
202-
203-
assert_eq!(diagnostics.len(), 0);
204-
}
205-
206139
#[test]
207140
fn ban_unused_ignore_not_report_unexecuted_rule() {
208141
use crate::rules::camelcase::Camelcase;
@@ -211,8 +144,6 @@ const fooBar: any = 42;
211144
// deno-lint-ignore no-explicit-any
212145
const _fooBar = 42;
213146
"#,
214-
false,
215-
true, // enables `ban-unused-ignore`
216147
);
217148

218149
assert!(diagnostics.is_empty());
@@ -227,8 +158,6 @@ const _fooBar = 42;
227158
// deno-lint-ignore no-explicit-any
228159
const _foo = 42;
229160
"#,
230-
false,
231-
true, // enables `ban-unused-ignore`
232161
);
233162

234163
assert!(diagnostics.is_empty());
@@ -241,12 +170,15 @@ const _foo = 42;
241170
// deno-lint-ignore no-explicit-any ban-unused-ignore
242171
const _foo = 42;
243172
"#;
244-
let diagnostics = lint_recommended_rules(
245-
src, false, true, // enables `ban-unused-ignore`
246-
);
173+
let diagnostics = lint_recommended_rules(src);
247174

248-
assert_eq!(diagnostics.len(), 1);
175+
assert_eq!(diagnostics.len(), 2);
176+
177+
// Both `no-explicit-any` and `ban-unused-ignore` are considered "unused"
178+
// ignore directives in this case. Remember that `ban-unused-ignore`, if
179+
// it's ignored at a line level, doesn't have any effect.
249180
assert_diagnostic(&diagnostics[0], "ban-unused-ignore", 2, 0, src);
181+
assert_diagnostic(&diagnostics[1], "ban-unused-ignore", 2, 0, src);
250182
}
251183

252184
#[test]
@@ -259,8 +191,6 @@ const _foo = 42;
259191
// pass
260192
}
261193
"#,
262-
false,
263-
false,
264194
);
265195

266196
assert_eq!(diagnostics.len(), 0);
@@ -275,9 +205,7 @@ const _foo = 42;
275205
// pass
276206
}
277207
"#;
278-
let diagnostics = lint_recommended_rules(
279-
src, false, true, // enables `ban-unused-ignore`
280-
);
208+
let diagnostics = lint_recommended_rules(src);
281209

282210
assert_eq!(diagnostics.len(), 1);
283211
assert_diagnostic(&diagnostics[0], "ban-unused-ignore", 2, 1, src);
@@ -293,7 +221,7 @@ const _foo = 42;
293221
// pass
294222
}
295223
"#;
296-
let diagnostics = lint_recommended_rules(src, false, true);
224+
let diagnostics = lint_recommended_rules(src);
297225

298226
assert_eq!(diagnostics.len(), 1);
299227
assert_diagnostic(&diagnostics[0], "ban-unused-ignore", 4, 1, src);
@@ -302,9 +230,8 @@ const _foo = 42;
302230
#[test]
303231
fn empty_file_with_ast() {
304232
let (ast, comments, source_map, tokens) = parse("");
305-
let diagnostics = lint_recommended_rules_with_ast(
306-
ast, comments, source_map, tokens, true, false,
307-
);
233+
let diagnostics =
234+
lint_recommended_rules_with_ast(ast, comments, source_map, tokens);
308235
assert!(diagnostics.is_empty());
309236
}
310237
}

src/linter.rs

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ pub use swc_common::SourceFile;
2525
pub struct LinterBuilder {
2626
ignore_file_directive: String,
2727
ignore_diagnostic_directive: String,
28-
lint_unused_ignore_directives: bool,
29-
lint_unknown_rules: bool,
3028
syntax: swc_ecmascript::parser::Syntax,
3129
rules: Vec<Box<dyn LintRule>>,
3230
plugins: Vec<Box<dyn Plugin>>,
@@ -37,8 +35,6 @@ impl LinterBuilder {
3735
Self {
3836
ignore_file_directive: "deno-lint-ignore-file".to_string(),
3937
ignore_diagnostic_directive: "deno-lint-ignore".to_string(),
40-
lint_unused_ignore_directives: true,
41-
lint_unknown_rules: true,
4238
syntax: get_default_ts_config(),
4339
rules: vec![],
4440
plugins: vec![],
@@ -49,8 +45,6 @@ impl LinterBuilder {
4945
Linter::new(
5046
self.ignore_file_directive,
5147
self.ignore_diagnostic_directive,
52-
self.lint_unused_ignore_directives,
53-
self.lint_unknown_rules,
5448
self.syntax,
5549
self.rules,
5650
self.plugins,
@@ -67,19 +61,6 @@ impl LinterBuilder {
6761
self
6862
}
6963

70-
pub fn lint_unused_ignore_directives(
71-
mut self,
72-
lint_unused_ignore_directives: bool,
73-
) -> Self {
74-
self.lint_unused_ignore_directives = lint_unused_ignore_directives;
75-
self
76-
}
77-
78-
pub fn lint_unknown_rules(mut self, lint_unknown_rules: bool) -> Self {
79-
self.lint_unknown_rules = lint_unknown_rules;
80-
self
81-
}
82-
8364
pub fn syntax(mut self, syntax: Syntax) -> Self {
8465
self.syntax = syntax;
8566
self
@@ -100,8 +81,6 @@ pub struct Linter {
10081
ast_parser: AstParser,
10182
ignore_file_directive: String,
10283
ignore_diagnostic_directive: String,
103-
lint_unused_ignore_directives: bool,
104-
lint_unknown_rules: bool,
10584
syntax: Syntax,
10685
rules: Vec<Box<dyn LintRule>>,
10786
plugins: Vec<Box<dyn Plugin>>,
@@ -111,8 +90,6 @@ impl Linter {
11190
fn new(
11291
ignore_file_directive: String,
11392
ignore_diagnostic_directive: String,
114-
lint_unused_ignore_directives: bool,
115-
lint_unknown_rules: bool,
11693
syntax: Syntax,
11794
rules: Vec<Box<dyn LintRule>>,
11895
plugins: Vec<Box<dyn Plugin>>,
@@ -121,8 +98,6 @@ impl Linter {
12198
ast_parser: AstParser::new(),
12299
ignore_file_directive,
123100
ignore_diagnostic_directive,
124-
lint_unused_ignore_directives,
125-
lint_unknown_rules,
126101
syntax,
127102
rules,
128103
plugins,
@@ -200,12 +175,10 @@ impl Linter {
200175
let start = Instant::now();
201176

202177
let mut filtered_diagnostics = context.check_ignore_directive_usage();
203-
if self.lint_unused_ignore_directives {
204-
filtered_diagnostics.extend(context.ban_unused_ignore(&self.rules));
205-
}
206-
if self.lint_unknown_rules {
207-
filtered_diagnostics.extend(context.ban_unknown_rule_code());
208-
}
178+
// Run `ban-unused-ignore`
179+
filtered_diagnostics.extend(context.ban_unused_ignore(&self.rules));
180+
// Run `ban-unknown-rule-code`
181+
filtered_diagnostics.extend(context.ban_unknown_rule_code());
209182
filtered_diagnostics.sort_by_key(|d| d.range.start.line);
210183

211184
let end = Instant::now();

src/rules.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ use dprint_swc_ecma_ast_view::Program as ProgramView;
55
pub mod adjacent_overload_signatures;
66
pub mod ban_ts_comment;
77
pub mod ban_types;
8+
pub mod ban_unknown_rule_code;
89
pub mod ban_untagged_ignore;
910
pub mod ban_untagged_todo;
11+
pub mod ban_unused_ignore;
1012
pub mod camelcase;
1113
pub mod constructor_super;
1214
pub mod default_param_last;
@@ -144,8 +146,10 @@ pub fn get_all_rules() -> Vec<Box<dyn LintRule>> {
144146
adjacent_overload_signatures::AdjacentOverloadSignatures::new(),
145147
ban_ts_comment::BanTsComment::new(),
146148
ban_types::BanTypes::new(),
149+
ban_unknown_rule_code::BanUnknownRuleCode::new(),
147150
ban_untagged_ignore::BanUntaggedIgnore::new(),
148151
ban_untagged_todo::BanUntaggedTodo::new(),
152+
ban_unused_ignore::BanUnusedIgnore::new(),
149153
camelcase::Camelcase::new(),
150154
constructor_super::ConstructorSuper::new(),
151155
default_param_last::DefaultParamLast::new(),

0 commit comments

Comments
 (0)