-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(es/lints): Implement
valid-typeof
rule (#4095)
- Loading branch information
1 parent
b31ead5
commit 9ceefa7
Showing
9 changed files
with
236 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"jsc": { | ||
"lints": { | ||
"valid-typeof": [ | ||
"error" | ||
] | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
typeof foo === "strnig"; | ||
typeof foo == "undefimed"; | ||
typeof bar != "nunber"; | ||
typeof bar !== "fucntion"; | ||
typeof bar !== foo(); | ||
typeof foo > "strnig"; | ||
typeof bar !== "function"; | ||
typeof x === typeof y; | ||
a === b; |
30 changes: 30 additions & 0 deletions
30
crates/swc/tests/errors/lints/valid-typeof/default/output.swc-stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
|
||
x Invalid typeof comparison value | ||
,---- | ||
1 | typeof foo === "strnig"; | ||
: ^^^^^^^^^^^^^^^^^^^^^^^ | ||
`---- | ||
|
||
x Invalid typeof comparison value | ||
,---- | ||
2 | typeof foo == "undefimed"; | ||
: ^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
`---- | ||
|
||
x Invalid typeof comparison value | ||
,---- | ||
3 | typeof bar != "nunber"; | ||
: ^^^^^^^^^^^^^^^^^^^^^^ | ||
`---- | ||
|
||
x Invalid typeof comparison value | ||
,---- | ||
4 | typeof bar !== "fucntion"; | ||
: ^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
`---- | ||
|
||
x Invalid typeof comparison value | ||
,---- | ||
5 | typeof bar !== foo(); | ||
: ^^^^^^^^^^^^^^^^^^^^ | ||
`---- |
12 changes: 12 additions & 0 deletions
12
crates/swc/tests/errors/lints/valid-typeof/disable-strict-checks/.swcrc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"jsc": { | ||
"lints": { | ||
"valid-typeof": [ | ||
"error", | ||
{ | ||
"requireStringLiterals": false | ||
} | ||
] | ||
} | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
crates/swc/tests/errors/lints/valid-typeof/disable-strict-checks/input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
typeof foo === "strnig" | ||
typeof foo == "undefimed" | ||
typeof bar != "nunber" | ||
typeof bar !== "fucntion" | ||
|
||
typeof bar !== foo() | ||
|
||
typeof bar !== ident | ||
|
||
// Just for test =) | ||
typeof foo > "strnig" | ||
typeof bar !== "function" | ||
typeof x === typeof y |
24 changes: 24 additions & 0 deletions
24
crates/swc/tests/errors/lints/valid-typeof/disable-strict-checks/output.swc-stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
|
||
x Invalid typeof comparison value | ||
,---- | ||
1 | typeof foo === "strnig" | ||
: ^^^^^^^^^^^^^^^^^^^^^^^ | ||
`---- | ||
|
||
x Invalid typeof comparison value | ||
,---- | ||
2 | typeof foo == "undefimed" | ||
: ^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
`---- | ||
|
||
x Invalid typeof comparison value | ||
,---- | ||
3 | typeof bar != "nunber" | ||
: ^^^^^^^^^^^^^^^^^^^^^^ | ||
`---- | ||
|
||
x Invalid typeof comparison value | ||
,---- | ||
4 | typeof bar !== "fucntion" | ||
: ^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
`---- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
use serde::{Deserialize, Serialize}; | ||
use swc_common::{errors::HANDLER, Span}; | ||
use swc_ecma_ast::*; | ||
use swc_ecma_visit::{Visit, VisitWith}; | ||
|
||
use crate::{ | ||
config::{LintRuleReaction, RuleConfig}, | ||
rule::{visitor_rule, Rule}, | ||
}; | ||
|
||
const MESSAGE: &str = "Invalid typeof comparison value"; | ||
|
||
const VALID_TYPES: &[&str] = &[ | ||
"undefined", | ||
"object", | ||
"boolean", | ||
"number", | ||
"string", | ||
"function", | ||
"symbol", | ||
"bigint", | ||
]; | ||
|
||
#[derive(Debug, Default, Clone, Serialize, Deserialize)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct ValidTypeofConfig { | ||
require_string_literals: Option<bool>, | ||
} | ||
|
||
pub fn valid_typeof(config: &RuleConfig<ValidTypeofConfig>) -> Option<Box<dyn Rule>> { | ||
match config.get_rule_reaction() { | ||
LintRuleReaction::Off => None, | ||
_ => Some(visitor_rule(ValidTypeof::new(config))), | ||
} | ||
} | ||
|
||
#[derive(Debug, Default)] | ||
struct ValidTypeof { | ||
expected_reaction: LintRuleReaction, | ||
require_string_literals: bool, | ||
} | ||
|
||
impl ValidTypeof { | ||
fn new(config: &RuleConfig<ValidTypeofConfig>) -> Self { | ||
let rule_config = config.get_rule_config(); | ||
|
||
Self { | ||
expected_reaction: config.get_rule_reaction(), | ||
require_string_literals: rule_config.require_string_literals.unwrap_or(true), | ||
} | ||
} | ||
|
||
fn emit_report(&self, span: Span) { | ||
HANDLER.with(|handler| match self.expected_reaction { | ||
LintRuleReaction::Error => { | ||
handler.struct_span_err(span, MESSAGE).emit(); | ||
} | ||
LintRuleReaction::Warning => { | ||
handler.struct_span_warn(span, MESSAGE).emit(); | ||
} | ||
_ => {} | ||
}); | ||
} | ||
|
||
fn check(&self, span: Span, str_operand: &str) { | ||
if !VALID_TYPES.contains(&str_operand) { | ||
self.emit_report(span); | ||
} | ||
} | ||
} | ||
|
||
impl Visit for ValidTypeof { | ||
fn visit_bin_expr(&mut self, bin_expr: &BinExpr) { | ||
if let op!("==") | op!("===") | op!("!=") | op!("!==") = bin_expr.op { | ||
match (bin_expr.left.as_ref(), bin_expr.right.as_ref()) { | ||
// case typeof x === "type" | ||
( | ||
Expr::Unary(UnaryExpr { | ||
op: op!("typeof"), .. | ||
}), | ||
Expr::Lit(Lit::Str(Str { value, .. })), | ||
) => { | ||
self.check(bin_expr.span, &*value); | ||
} | ||
// case "type" === typeof x | ||
( | ||
Expr::Lit(Lit::Str(Str { value, .. })), | ||
Expr::Unary(UnaryExpr { | ||
op: op!("typeof"), .. | ||
}), | ||
) => { | ||
self.check(bin_expr.span, &*value); | ||
} | ||
// case typeof x === typeof y | ||
( | ||
Expr::Unary(UnaryExpr { | ||
op: op!("typeof"), .. | ||
}), | ||
Expr::Unary(UnaryExpr { | ||
op: op!("typeof"), .. | ||
}), | ||
) => {} | ||
// case typeof x === foo() | ||
( | ||
Expr::Unary(UnaryExpr { | ||
op: op!("typeof"), .. | ||
}), | ||
_, | ||
) => { | ||
if self.require_string_literals { | ||
self.emit_report(bin_expr.span); | ||
} | ||
} | ||
// case foo() === typeof x | ||
( | ||
_, | ||
Expr::Unary(UnaryExpr { | ||
op: op!("typeof"), .. | ||
}), | ||
) => { | ||
if self.require_string_literals { | ||
self.emit_report(bin_expr.span); | ||
} | ||
} | ||
_ => {} | ||
} | ||
} | ||
|
||
bin_expr.visit_children_with(self); | ||
} | ||
} |
9ceefa7
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Benchmark
base_tr_fixer
23074
ns/iter (± 406
)30073
ns/iter (± 2558
)0.77
base_tr_resolver_and_hygiene
92992
ns/iter (± 7549
)122298
ns/iter (± 34200
)0.76
codegen_es2015
31344
ns/iter (± 316
)36473
ns/iter (± 8515
)0.86
codegen_es2016
31272
ns/iter (± 150
)35910
ns/iter (± 6413
)0.87
codegen_es2017
31223
ns/iter (± 208
)38216
ns/iter (± 5787
)0.82
codegen_es2018
31398
ns/iter (± 168
)36777
ns/iter (± 5952
)0.85
codegen_es2019
31320
ns/iter (± 170
)35774
ns/iter (± 5112
)0.88
codegen_es2020
31390
ns/iter (± 159
)35345
ns/iter (± 5574
)0.89
codegen_es3
31431
ns/iter (± 131
)35835
ns/iter (± 5184
)0.88
codegen_es5
31437
ns/iter (± 159
)36089
ns/iter (± 3874
)0.87
full_es2015
138391125
ns/iter (± 13273576
)156253598
ns/iter (± 10659414
)0.89
full_es2016
137908949
ns/iter (± 3477138
)155090921
ns/iter (± 10699741
)0.89
full_es2017
137136771
ns/iter (± 3575407
)153614856
ns/iter (± 9986336
)0.89
full_es2018
137042229
ns/iter (± 2533075
)154695495
ns/iter (± 11980513
)0.89
full_es2019
136810023
ns/iter (± 8047948
)156494154
ns/iter (± 11795701
)0.87
full_es2020
118835584
ns/iter (± 2409664
)142855115
ns/iter (± 12005590
)0.83
full_es3
182931818
ns/iter (± 4111203
)200717826
ns/iter (± 13739640
)0.91
full_es5
173155347
ns/iter (± 3415339
)190185859
ns/iter (± 12404967
)0.91
parser
563562
ns/iter (± 12087
)685395
ns/iter (± 141397
)0.82
ser_ast_node
145
ns/iter (± 2
)164
ns/iter (± 43
)0.88
ser_serde
144
ns/iter (± 1
)149
ns/iter (± 23
)0.97
emit_colors
12145215
ns/iter (± 7411750
)9576515
ns/iter (± 6332516
)1.27
emit_large
71025515
ns/iter (± 93443200
)48512012
ns/iter (± 70646269
)1.46
base_clone
2600099
ns/iter (± 361766
)2473483
ns/iter (± 458642
)1.05
fold_span
3771277
ns/iter (± 38257
)4314678
ns/iter (± 1104126
)0.87
fold_span_panic
3970135
ns/iter (± 82855
)4383202
ns/iter (± 697569
)0.91
visit_mut_span
2720041
ns/iter (± 10886
)2904239
ns/iter (± 444601
)0.94
visit_mut_span_panic
2762541
ns/iter (± 10820
)2929332
ns/iter (± 429583
)0.94
usage_builtin_type
15857229
ns/iter (± 9874220
)17082852
ns/iter (± 11133799
)0.93
usage_property
397525
ns/iter (± 7123
)417274
ns/iter (± 65727
)0.95
boxing_boxed
134
ns/iter (± 10
)167
ns/iter (± 57
)0.80
boxing_boxed_clone
72
ns/iter (± 0
)69
ns/iter (± 13
)1.04
boxing_unboxed
128
ns/iter (± 1
)136
ns/iter (± 24
)0.94
boxing_unboxed_clone
63
ns/iter (± 0
)67
ns/iter (± 11
)0.94
time_10
344
ns/iter (± 29
)334
ns/iter (± 45
)1.03
time_15
706
ns/iter (± 18
)701
ns/iter (± 111
)1.01
time_20
1288
ns/iter (± 11
)1226
ns/iter (± 220
)1.05
time_40
7122
ns/iter (± 41
)4447
ns/iter (± 701
)1.60
time_5
101
ns/iter (± 1
)110
ns/iter (± 25
)0.92
time_60
16157
ns/iter (± 43
)10141
ns/iter (± 2543
)1.59
total
0
ns/iter (± 0
)0
ns/iter (± 0
)NaN
This comment was automatically generated by workflow using github-action-benchmark.