feat(linter/tree-shaking): support ArrowFunctionExpression (#2883)

This commit is contained in:
Wang Wenzhe 2024-04-02 10:34:32 +08:00 committed by GitHub
parent 4a86dcb322
commit 15d08f6635
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 105 additions and 18 deletions

View file

@ -11,7 +11,7 @@ use oxc_ast::{
AstKind,
};
use oxc_semantic::{AstNode, SymbolId};
use oxc_span::GetSpan;
use oxc_span::{GetSpan, Span};
use rustc_hash::FxHashSet;
use crate::{
@ -66,6 +66,11 @@ impl<'a> ListenerMap for Statement<'a> {
Self::Declaration(decl) => {
decl.report_effects(options);
}
Self::ReturnStatement(stmt) => {
if let Some(arg) = &stmt.argument {
arg.report_effects(options);
}
}
Self::ModuleDeclaration(decl) => {
if matches!(
decl.0,
@ -92,6 +97,16 @@ impl<'a> ListenerMap for AstNode<'a> {
init.report_effects_when_called(options);
}
}
AstKind::FormalParameter(param) => {
options.ctx.diagnostic(NoSideEffectsDiagnostic::CallParameter(param.span));
}
AstKind::BindingRestElement(rest) => {
let start = rest.span.start + 3;
let end = rest.span.end;
options
.ctx
.diagnostic(NoSideEffectsDiagnostic::CallParameter(Span::new(start, end)));
}
_ => {}
}
}
@ -103,6 +118,16 @@ impl<'a> ListenerMap for AstNode<'a> {
init.report_effects_when_mutated(options);
}
}
AstKind::FormalParameter(param) => {
options.ctx.diagnostic(NoSideEffectsDiagnostic::MutationOfParameter(param.span));
}
AstKind::BindingRestElement(rest) => {
let start = rest.span.start + 3;
let end = rest.span.end;
options.ctx.diagnostic(NoSideEffectsDiagnostic::MutationOfParameter(Span::new(
start, end,
)));
}
_ => {}
}
}
@ -272,8 +297,8 @@ impl<'a> ListenerMap for Function<'a> {
}
impl<'a> ListenerMap for FormalParameter<'a> {
fn report_effects(&self, _options: &NodeListenerOptions) {
// TODO: Not work now, need report side effects.
fn report_effects(&self, options: &NodeListenerOptions) {
self.pattern.report_effects(options);
}
}

View file

@ -30,6 +30,10 @@ enum NoSideEffectsDiagnostic {
#[diagnostic(severity(warning))]
MutationOfFunctionReturnValue(#[label] Span),
#[error("eslint-plugin-tree-shaking(no-side-effects-in-initialization): Cannot determine side-effects of mutating function parameter")]
#[diagnostic(severity(warning))]
MutationOfParameter(#[label] Span),
#[error("eslint-plugin-tree-shaking(no-side-effects-in-initialization): Cannot determine side-effects of calling")]
#[diagnostic(severity(warning))]
Call(#[label] Span),
@ -41,6 +45,10 @@ enum NoSideEffectsDiagnostic {
#[error("eslint-plugin-tree-shaking(no-side-effects-in-initialization): Cannot determine side-effects of calling global function `{0}`")]
#[diagnostic(severity(warning))]
CallGlobal(CompactStr, #[label] Span),
#[error("eslint-plugin-tree-shaking(no-side-effects-in-initialization): Cannot determine side-effects of calling function parameter")]
#[diagnostic(severity(warning))]
CallParameter(#[label] Span),
}
/// <https://github.com/lukastaegert/eslint-plugin-tree-shaking/blob/master/src/rules/no-side-effects-in-initialization.ts>
@ -91,14 +99,14 @@ fn test() {
"const [x] = []",
"const [,x,] = []",
// // ArrowFunctionExpression
// "const x = a=>{a(); ext()}",
"const x = a=>{a(); ext()}",
// // ArrowFunctionExpression when called
// "(()=>{})()",
// "(a=>{})()",
// "((...a)=>{})()",
// "(({a})=>{})()",
"(()=>{})()",
"(a=>{})()",
"((...a)=>{})()",
"(({a})=>{})()",
// // ArrowFunctionExpression when mutated
// "const x = ()=>{}; x.y = 1",
"const x = ()=>{}; x.y = 1",
// // AssignmentExpression
"var x;x = {}",
"var x;x += 1",
@ -360,15 +368,15 @@ fn test() {
"const [x = ext()] = []",
"const [,x = ext(),] = []",
// // ArrowFunctionExpression when called
// "(()=>{ext()})()",
// "(({a = ext()})=>{})()",
// "(a=>{a()})(ext)",
// "((...a)=>{a()})(ext)",
// "(({a})=>{a()})(ext)",
// "(a=>{a.x = 1})(ext)",
// "(a=>{const b = a;b.x = 1})(ext)",
// "((...a)=>{a.x = 1})(ext)",
// "(({a})=>{a.x = 1})(ext)",
"(()=>{ext()})()",
"(({a = ext()})=>{})()",
"(a=>{a()})(ext)",
"((...a)=>{a()})(ext)",
"(({a})=>{a()})(ext)",
"(a=>{a.x = 1})(ext)",
"(a=>{const b = a;b.x = 1})(ext)",
"((...a)=>{a.x = 1})(ext)",
"(({a})=>{a.x = 1})(ext)",
// // AssignmentExpression
"ext = 1",
"ext += 1",

View file

@ -26,6 +26,60 @@ expression: no_side_effects_in_initialization
· ───
╰────
⚠ eslint-plugin-tree-shaking(no-side-effects-in-initialization): Cannot determine side-effects of calling global function `ext`
╭─[no_side_effects_in_initialization.tsx:1:7]
1 │ (()=>{ext()})()
· ───
╰────
⚠ eslint-plugin-tree-shaking(no-side-effects-in-initialization): Cannot determine side-effects of calling global function `ext`
╭─[no_side_effects_in_initialization.tsx:1:8]
1 │ (({a = ext()})=>{})()
· ───
╰────
⚠ eslint-plugin-tree-shaking(no-side-effects-in-initialization): Cannot determine side-effects of calling function parameter
╭─[no_side_effects_in_initialization.tsx:1:2]
1 │ (a=>{a()})(ext)
· ─
╰────
⚠ eslint-plugin-tree-shaking(no-side-effects-in-initialization): Cannot determine side-effects of calling function parameter
╭─[no_side_effects_in_initialization.tsx:1:6]
1 │ ((...a)=>{a()})(ext)
· ─
╰────
⚠ eslint-plugin-tree-shaking(no-side-effects-in-initialization): Cannot determine side-effects of calling function parameter
╭─[no_side_effects_in_initialization.tsx:1:3]
1 │ (({a})=>{a()})(ext)
· ───
╰────
⚠ eslint-plugin-tree-shaking(no-side-effects-in-initialization): Cannot determine side-effects of mutating function parameter
╭─[no_side_effects_in_initialization.tsx:1:2]
1 │ (a=>{a.x = 1})(ext)
· ─
╰────
⚠ eslint-plugin-tree-shaking(no-side-effects-in-initialization): Cannot determine side-effects of mutating function parameter
╭─[no_side_effects_in_initialization.tsx:1:2]
1 │ (a=>{const b = a;b.x = 1})(ext)
· ─
╰────
⚠ eslint-plugin-tree-shaking(no-side-effects-in-initialization): Cannot determine side-effects of mutating function parameter
╭─[no_side_effects_in_initialization.tsx:1:6]
1 │ ((...a)=>{a.x = 1})(ext)
· ─
╰────
⚠ eslint-plugin-tree-shaking(no-side-effects-in-initialization): Cannot determine side-effects of mutating function parameter
╭─[no_side_effects_in_initialization.tsx:1:3]
1 │ (({a})=>{a.x = 1})(ext)
· ───
╰────
⚠ eslint-plugin-tree-shaking(no-side-effects-in-initialization): Cannot determine side-effects of assignment to `ext`
╭─[no_side_effects_in_initialization.tsx:1:1]
1 │ ext = 1