mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
feat(linter/tree-shaking): support ForStatement (#3078)
This commit is contained in:
parent
d109767330
commit
88ded0cef5
3 changed files with 157 additions and 31 deletions
|
|
@ -5,11 +5,11 @@ use oxc_ast::{
|
|||
Argument, ArrayExpressionElement, ArrowFunctionExpression, AssignmentTarget,
|
||||
BinaryExpression, BindingIdentifier, BindingPattern, BindingPatternKind, CallExpression,
|
||||
Class, ClassBody, ClassElement, ComputedMemberExpression, ConditionalExpression,
|
||||
Declaration, ExportDefaultDeclarationKind, ExportSpecifier, Expression, FormalParameter,
|
||||
Function, IdentifierReference, MemberExpression, ModuleDeclaration, ModuleExportName,
|
||||
NewExpression, ParenthesizedExpression, PrivateFieldExpression, Program, PropertyKey,
|
||||
SimpleAssignmentTarget, Statement, StaticMemberExpression, ThisExpression,
|
||||
VariableDeclarator,
|
||||
Declaration, ExportDefaultDeclarationKind, ExportSpecifier, Expression, ForStatementInit,
|
||||
ForStatementLeft, FormalParameter, Function, IdentifierReference, MemberExpression,
|
||||
ModuleDeclaration, ModuleExportName, NewExpression, ParenthesizedExpression,
|
||||
PrivateFieldExpression, Program, PropertyKey, SimpleAssignmentTarget, Statement,
|
||||
StaticMemberExpression, ThisExpression, VariableDeclarator,
|
||||
},
|
||||
AstKind,
|
||||
};
|
||||
|
|
@ -152,11 +152,53 @@ impl<'a> ListenerMap for Statement<'a> {
|
|||
Self::DebuggerStatement(stmt) => {
|
||||
options.ctx.diagnostic(NoSideEffectsDiagnostic::Debugger(stmt.span));
|
||||
}
|
||||
Self::ForStatement(stmt) => {
|
||||
if let Some(init) = &stmt.init {
|
||||
init.report_effects(options);
|
||||
}
|
||||
if let Some(test) = &stmt.test {
|
||||
test.report_effects(options);
|
||||
}
|
||||
if let Some(update) = &stmt.update {
|
||||
update.report_effects(options);
|
||||
}
|
||||
stmt.body.report_effects(options);
|
||||
}
|
||||
Self::ForInStatement(stmt) => {
|
||||
if let ForStatementLeft::AssignmentTarget(assign) = &stmt.left {
|
||||
assign.report_effects_when_assigned(options);
|
||||
}
|
||||
stmt.right.report_effects(options);
|
||||
stmt.body.report_effects(options);
|
||||
}
|
||||
Self::ForOfStatement(stmt) => {
|
||||
if let ForStatementLeft::AssignmentTarget(assign) = &stmt.left {
|
||||
assign.report_effects_when_assigned(options);
|
||||
}
|
||||
stmt.right.report_effects(options);
|
||||
stmt.body.report_effects(options);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for ForStatementInit<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
match self {
|
||||
Self::Expression(expr) => {
|
||||
expr.report_effects(options);
|
||||
}
|
||||
Self::UsingDeclaration(decl) => {
|
||||
decl.declarations.iter().for_each(|decl| decl.report_effects(options));
|
||||
}
|
||||
Self::VariableDeclaration(decl) => {
|
||||
decl.declarations.iter().for_each(|decl| decl.report_effects(options));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for ExportSpecifier<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
let ctx = options.ctx;
|
||||
|
|
|
|||
|
|
@ -200,14 +200,14 @@ fn test() {
|
|||
"export const /* tree-shaking no-side-effects-when-called */ x = function(){}",
|
||||
"export function /* tree-shaking no-side-effects-when-called */ x(){}",
|
||||
"const x = function(){}; export {/* tree-shaking no-side-effects-when-called */ x}",
|
||||
// // ExpressionStatement
|
||||
// "const x = 1",
|
||||
// // ForInStatement
|
||||
// "for(const x in ext){x = 1}",
|
||||
// "let x; for(x in ext){}",
|
||||
// // ForStatement
|
||||
// "for(let i = 0; i < 3; i++){i++}",
|
||||
// "for(;;){}",
|
||||
// ExpressionStatement
|
||||
"const x = 1",
|
||||
// ForInStatement
|
||||
"for(const x in ext){x = 1}",
|
||||
"let x; for(x in ext){}",
|
||||
// ForStatement
|
||||
"for(let i = 0; i < 3; i++){i++}",
|
||||
"for(;;){}",
|
||||
// // FunctionDeclaration
|
||||
// "function x(a){a(); ext()}",
|
||||
// // FunctionDeclaration when called
|
||||
|
|
@ -465,24 +465,24 @@ fn test() {
|
|||
"export const /* tree-shaking no-side-effects-when-called */ x = ext",
|
||||
"export function /* tree-shaking no-side-effects-when-called */ x(){ext()}",
|
||||
"const x = ext; export {/* tree-shaking no-side-effects-when-called */ x}",
|
||||
// // ExpressionStatement
|
||||
// "ext()",
|
||||
// // ForInStatement
|
||||
// "for(ext in {a: 1}){}",
|
||||
// "for(const x in ext()){}",
|
||||
// "for(const x in {a: 1}){ext()}",
|
||||
// "for(const x in {a: 1}) ext()",
|
||||
// // ForOfStatement
|
||||
// "for(ext of {a: 1}){}",
|
||||
// "for(const x of ext()){}",
|
||||
// "for(const x of {a: 1}){ext()}",
|
||||
// "for(const x of {a: 1}) ext()",
|
||||
// // ForStatement
|
||||
// "for(ext();;){}",
|
||||
// "for(;ext();){}",
|
||||
// "for(;true;ext()){}",
|
||||
// "for(;true;) ext()",
|
||||
// "for(;true;){ext()}",
|
||||
// ExpressionStatement
|
||||
"ext()",
|
||||
// ForInStatement
|
||||
"for(ext in {a: 1}){}",
|
||||
"for(const x in ext()){}",
|
||||
"for(const x in {a: 1}){ext()}",
|
||||
"for(const x in {a: 1}) ext()",
|
||||
// ForOfStatement
|
||||
"for(ext of {a: 1}){}",
|
||||
"for(const x of ext()){}",
|
||||
"for(const x of {a: 1}){ext()}",
|
||||
"for(const x of {a: 1}) ext()",
|
||||
// ForStatement
|
||||
"for(ext();;){}",
|
||||
"for(;ext();){}",
|
||||
"for(;true;ext()){}",
|
||||
"for(;true;) ext()",
|
||||
"for(;true;){ext()}",
|
||||
// // FunctionDeclaration when called
|
||||
// "function x(){ext()}; x()",
|
||||
// "function x(){ext()}; const y = new x()",
|
||||
|
|
|
|||
|
|
@ -410,6 +410,90 @@ 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:1]
|
||||
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:5]
|
||||
1 │ for(ext in {a: 1}){}
|
||||
· ───
|
||||
╰────
|
||||
|
||||
⚠ 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:16]
|
||||
1 │ for(const x in 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:24]
|
||||
1 │ for(const x in {a: 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:24]
|
||||
1 │ for(const x in {a: 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:5]
|
||||
1 │ for(ext of {a: 1}){}
|
||||
· ───
|
||||
╰────
|
||||
|
||||
⚠ 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:16]
|
||||
1 │ for(const x of 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:24]
|
||||
1 │ for(const x of {a: 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:24]
|
||||
1 │ for(const x of {a: 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:5]
|
||||
1 │ for(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:6]
|
||||
1 │ for(;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:11]
|
||||
1 │ for(;true;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:13]
|
||||
1 │ for(;true;) 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:13]
|
||||
1 │ for(;true;){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:5]
|
||||
1 │ if (ext()>0){}
|
||||
|
|
|
|||
Loading…
Reference in a new issue