Skip to content

Commit

Permalink
feat(linter/tree-shaking): support ArrowFunctionExpression (#2883)
Browse files Browse the repository at this point in the history
  • Loading branch information
mysteryven authored Apr 2, 2024
1 parent 4a86dcb commit 15d08f6
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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,
Expand All @@ -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)));
}
_ => {}
}
}
Expand All @@ -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,
)));
}
_ => {}
}
}
Expand Down Expand Up @@ -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);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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>
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]
1ext = 1
Expand Down

0 comments on commit 15d08f6

Please sign in to comment.