mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
feat(linter/tree-shaking): support ArrowFunctionExpression (#2883)
This commit is contained in:
parent
4a86dcb322
commit
15d08f6635
3 changed files with 105 additions and 18 deletions
|
|
@ -11,7 +11,7 @@ use oxc_ast::{
|
||||||
AstKind,
|
AstKind,
|
||||||
};
|
};
|
||||||
use oxc_semantic::{AstNode, SymbolId};
|
use oxc_semantic::{AstNode, SymbolId};
|
||||||
use oxc_span::GetSpan;
|
use oxc_span::{GetSpan, Span};
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -66,6 +66,11 @@ impl<'a> ListenerMap for Statement<'a> {
|
||||||
Self::Declaration(decl) => {
|
Self::Declaration(decl) => {
|
||||||
decl.report_effects(options);
|
decl.report_effects(options);
|
||||||
}
|
}
|
||||||
|
Self::ReturnStatement(stmt) => {
|
||||||
|
if let Some(arg) = &stmt.argument {
|
||||||
|
arg.report_effects(options);
|
||||||
|
}
|
||||||
|
}
|
||||||
Self::ModuleDeclaration(decl) => {
|
Self::ModuleDeclaration(decl) => {
|
||||||
if matches!(
|
if matches!(
|
||||||
decl.0,
|
decl.0,
|
||||||
|
|
@ -92,6 +97,16 @@ impl<'a> ListenerMap for AstNode<'a> {
|
||||||
init.report_effects_when_called(options);
|
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);
|
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> {
|
impl<'a> ListenerMap for FormalParameter<'a> {
|
||||||
fn report_effects(&self, _options: &NodeListenerOptions) {
|
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||||
// TODO: Not work now, need report side effects.
|
self.pattern.report_effects(options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,10 @@ enum NoSideEffectsDiagnostic {
|
||||||
#[diagnostic(severity(warning))]
|
#[diagnostic(severity(warning))]
|
||||||
MutationOfFunctionReturnValue(#[label] Span),
|
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")]
|
#[error("eslint-plugin-tree-shaking(no-side-effects-in-initialization): Cannot determine side-effects of calling")]
|
||||||
#[diagnostic(severity(warning))]
|
#[diagnostic(severity(warning))]
|
||||||
Call(#[label] Span),
|
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}`")]
|
#[error("eslint-plugin-tree-shaking(no-side-effects-in-initialization): Cannot determine side-effects of calling global function `{0}`")]
|
||||||
#[diagnostic(severity(warning))]
|
#[diagnostic(severity(warning))]
|
||||||
CallGlobal(CompactStr, #[label] Span),
|
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>
|
/// <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] = []",
|
||||||
"const [,x,] = []",
|
"const [,x,] = []",
|
||||||
// // ArrowFunctionExpression
|
// // ArrowFunctionExpression
|
||||||
// "const x = a=>{a(); ext()}",
|
"const x = a=>{a(); ext()}",
|
||||||
// // ArrowFunctionExpression when called
|
// // ArrowFunctionExpression when called
|
||||||
// "(()=>{})()",
|
"(()=>{})()",
|
||||||
// "(a=>{})()",
|
"(a=>{})()",
|
||||||
// "((...a)=>{})()",
|
"((...a)=>{})()",
|
||||||
// "(({a})=>{})()",
|
"(({a})=>{})()",
|
||||||
// // ArrowFunctionExpression when mutated
|
// // ArrowFunctionExpression when mutated
|
||||||
// "const x = ()=>{}; x.y = 1",
|
"const x = ()=>{}; x.y = 1",
|
||||||
// // AssignmentExpression
|
// // AssignmentExpression
|
||||||
"var x;x = {}",
|
"var x;x = {}",
|
||||||
"var x;x += 1",
|
"var x;x += 1",
|
||||||
|
|
@ -360,15 +368,15 @@ fn test() {
|
||||||
"const [x = ext()] = []",
|
"const [x = ext()] = []",
|
||||||
"const [,x = ext(),] = []",
|
"const [,x = ext(),] = []",
|
||||||
// // ArrowFunctionExpression when called
|
// // ArrowFunctionExpression when called
|
||||||
// "(()=>{ext()})()",
|
"(()=>{ext()})()",
|
||||||
// "(({a = ext()})=>{})()",
|
"(({a = ext()})=>{})()",
|
||||||
// "(a=>{a()})(ext)",
|
"(a=>{a()})(ext)",
|
||||||
// "((...a)=>{a()})(ext)",
|
"((...a)=>{a()})(ext)",
|
||||||
// "(({a})=>{a()})(ext)",
|
"(({a})=>{a()})(ext)",
|
||||||
// "(a=>{a.x = 1})(ext)",
|
"(a=>{a.x = 1})(ext)",
|
||||||
// "(a=>{const b = a;b.x = 1})(ext)",
|
"(a=>{const b = a;b.x = 1})(ext)",
|
||||||
// "((...a)=>{a.x = 1})(ext)",
|
"((...a)=>{a.x = 1})(ext)",
|
||||||
// "(({a})=>{a.x = 1})(ext)",
|
"(({a})=>{a.x = 1})(ext)",
|
||||||
// // AssignmentExpression
|
// // AssignmentExpression
|
||||||
"ext = 1",
|
"ext = 1",
|
||||||
"ext += 1",
|
"ext += 1",
|
||||||
|
|
|
||||||
|
|
@ -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`
|
⚠ 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]
|
╭─[no_side_effects_in_initialization.tsx:1:1]
|
||||||
1 │ ext = 1
|
1 │ ext = 1
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue