mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
refactor(linter): all ast_util functions take Semantic (#6753)
Needed in `oxc/no-map-spread` rule.
This commit is contained in:
parent
744aa74e81
commit
b8845773f7
4 changed files with 192 additions and 181 deletions
|
|
@ -1,26 +1,24 @@
|
|||
use oxc_ast::{ast::BindingIdentifier, AstKind};
|
||||
use oxc_ecmascript::ToBoolean;
|
||||
use oxc_semantic::{AstNode, IsGlobalReference, NodeId, SymbolId};
|
||||
use oxc_semantic::{AstNode, IsGlobalReference, NodeId, Semantic, SymbolId};
|
||||
use oxc_span::{GetSpan, Span};
|
||||
use oxc_syntax::operator::{AssignmentOperator, BinaryOperator, LogicalOperator, UnaryOperator};
|
||||
|
||||
#[allow(clippy::wildcard_imports)]
|
||||
use oxc_ast::ast::*;
|
||||
|
||||
use crate::context::LintContext;
|
||||
|
||||
/// Test if an AST node is a boolean value that never changes. Specifically we
|
||||
/// test for:
|
||||
/// 1. Literal booleans (`true` or `false`)
|
||||
/// 2. Unary `!` expressions with a constant value
|
||||
/// 3. Constant booleans created via the `Boolean` global function
|
||||
pub fn is_static_boolean<'a>(expr: &Expression<'a>, ctx: &LintContext<'a>) -> bool {
|
||||
pub fn is_static_boolean<'a>(expr: &Expression<'a>, semantic: &Semantic<'a>) -> bool {
|
||||
match expr {
|
||||
Expression::BooleanLiteral(_) => true,
|
||||
Expression::CallExpression(call_expr) => call_expr.is_constant(true, ctx),
|
||||
Expression::CallExpression(call_expr) => call_expr.is_constant(true, semantic),
|
||||
Expression::UnaryExpression(unary_expr) => {
|
||||
unary_expr.operator == UnaryOperator::LogicalNot
|
||||
&& unary_expr.argument.is_constant(true, ctx)
|
||||
&& unary_expr.argument.is_constant(true, semantic)
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
|
|
@ -64,11 +62,11 @@ fn is_logical_identity(op: LogicalOperator, expr: &Expression) -> bool {
|
|||
/// When `false`, checks if -- for both string and number --
|
||||
/// if coerced to that type, the value will be constant.
|
||||
pub trait IsConstant<'a, 'b> {
|
||||
fn is_constant(&self, in_boolean_position: bool, ctx: &LintContext<'a>) -> bool;
|
||||
fn is_constant(&self, in_boolean_position: bool, semantic: &Semantic<'a>) -> bool;
|
||||
}
|
||||
|
||||
impl<'a, 'b> IsConstant<'a, 'b> for Expression<'a> {
|
||||
fn is_constant(&self, in_boolean_position: bool, ctx: &LintContext<'a>) -> bool {
|
||||
fn is_constant(&self, in_boolean_position: bool, semantic: &Semantic<'a>) -> bool {
|
||||
match self {
|
||||
Self::ArrowFunctionExpression(_)
|
||||
| Self::FunctionExpression(_)
|
||||
|
|
@ -80,29 +78,29 @@ impl<'a, 'b> IsConstant<'a, 'b> for Expression<'a> {
|
|||
quasi.value.cooked.as_ref().map_or(false, |cooked| !cooked.is_empty())
|
||||
});
|
||||
let test_expressions =
|
||||
template.expressions.iter().all(|expr| expr.is_constant(false, ctx));
|
||||
template.expressions.iter().all(|expr| expr.is_constant(false, semantic));
|
||||
test_quasis || test_expressions
|
||||
}
|
||||
Self::ArrayExpression(expr) => {
|
||||
if in_boolean_position {
|
||||
return true;
|
||||
}
|
||||
expr.elements.iter().all(|element| element.is_constant(false, ctx))
|
||||
expr.elements.iter().all(|element| element.is_constant(false, semantic))
|
||||
}
|
||||
Self::UnaryExpression(expr) => match expr.operator {
|
||||
UnaryOperator::Void => true,
|
||||
UnaryOperator::Typeof if in_boolean_position => true,
|
||||
UnaryOperator::LogicalNot => expr.argument.is_constant(true, ctx),
|
||||
_ => expr.argument.is_constant(false, ctx),
|
||||
UnaryOperator::LogicalNot => expr.argument.is_constant(true, semantic),
|
||||
_ => expr.argument.is_constant(false, semantic),
|
||||
},
|
||||
Self::BinaryExpression(expr) => {
|
||||
expr.operator != BinaryOperator::In
|
||||
&& expr.left.is_constant(false, ctx)
|
||||
&& expr.right.is_constant(false, ctx)
|
||||
&& expr.left.is_constant(false, semantic)
|
||||
&& expr.right.is_constant(false, semantic)
|
||||
}
|
||||
Self::LogicalExpression(expr) => {
|
||||
let is_left_constant = expr.left.is_constant(in_boolean_position, ctx);
|
||||
let is_right_constant = expr.right.is_constant(in_boolean_position, ctx);
|
||||
let is_left_constant = expr.left.is_constant(in_boolean_position, semantic);
|
||||
let is_right_constant = expr.right.is_constant(in_boolean_position, semantic);
|
||||
let is_left_short_circuit =
|
||||
is_left_constant && is_logical_identity(expr.operator, &expr.left);
|
||||
let is_right_short_circuit = in_boolean_position
|
||||
|
|
@ -114,7 +112,7 @@ impl<'a, 'b> IsConstant<'a, 'b> for Expression<'a> {
|
|||
}
|
||||
Self::NewExpression(_) => in_boolean_position,
|
||||
Self::AssignmentExpression(expr) => match expr.operator {
|
||||
AssignmentOperator::Assign => expr.right.is_constant(in_boolean_position, ctx),
|
||||
AssignmentOperator::Assign => expr.right.is_constant(in_boolean_position, semantic),
|
||||
AssignmentOperator::LogicalAnd if in_boolean_position => {
|
||||
is_logical_identity(LogicalOperator::And, &expr.right)
|
||||
}
|
||||
|
|
@ -127,13 +125,13 @@ impl<'a, 'b> IsConstant<'a, 'b> for Expression<'a> {
|
|||
.expressions
|
||||
.iter()
|
||||
.last()
|
||||
.map_or(false, |last| last.is_constant(in_boolean_position, ctx)),
|
||||
Self::CallExpression(call_expr) => call_expr.is_constant(in_boolean_position, ctx),
|
||||
.map_or(false, |last| last.is_constant(in_boolean_position, semantic)),
|
||||
Self::CallExpression(call_expr) => call_expr.is_constant(in_boolean_position, semantic),
|
||||
Self::ParenthesizedExpression(paren_expr) => {
|
||||
paren_expr.expression.is_constant(in_boolean_position, ctx)
|
||||
paren_expr.expression.is_constant(in_boolean_position, semantic)
|
||||
}
|
||||
Self::Identifier(ident) => {
|
||||
ident.name == "undefined" && ctx.semantic().is_reference_to_global_variable(ident)
|
||||
ident.name == "undefined" && semantic.is_reference_to_global_variable(ident)
|
||||
}
|
||||
_ if self.is_literal() => true,
|
||||
_ => false,
|
||||
|
|
@ -142,12 +140,16 @@ impl<'a, 'b> IsConstant<'a, 'b> for Expression<'a> {
|
|||
}
|
||||
|
||||
impl<'a, 'b> IsConstant<'a, 'b> for CallExpression<'a> {
|
||||
fn is_constant(&self, _in_boolean_position: bool, ctx: &LintContext<'a>) -> bool {
|
||||
fn is_constant(&self, _in_boolean_position: bool, semantic: &Semantic<'a>) -> bool {
|
||||
if let Expression::Identifier(ident) = &self.callee {
|
||||
if ident.name == "Boolean"
|
||||
&& self.arguments.iter().next().map_or(true, |first| first.is_constant(true, ctx))
|
||||
&& self
|
||||
.arguments
|
||||
.iter()
|
||||
.next()
|
||||
.map_or(true, |first| first.is_constant(true, semantic))
|
||||
{
|
||||
return ctx.semantic().is_reference_to_global_variable(ident);
|
||||
return semantic.is_reference_to_global_variable(ident);
|
||||
}
|
||||
}
|
||||
false
|
||||
|
|
@ -155,27 +157,31 @@ impl<'a, 'b> IsConstant<'a, 'b> for CallExpression<'a> {
|
|||
}
|
||||
|
||||
impl<'a, 'b> IsConstant<'a, 'b> for Argument<'a> {
|
||||
fn is_constant(&self, in_boolean_position: bool, ctx: &LintContext<'a>) -> bool {
|
||||
fn is_constant(&self, in_boolean_position: bool, semantic: &Semantic<'a>) -> bool {
|
||||
match self {
|
||||
Self::SpreadElement(element) => element.is_constant(in_boolean_position, ctx),
|
||||
match_expression!(Self) => self.to_expression().is_constant(in_boolean_position, ctx),
|
||||
Self::SpreadElement(element) => element.is_constant(in_boolean_position, semantic),
|
||||
match_expression!(Self) => {
|
||||
self.to_expression().is_constant(in_boolean_position, semantic)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> IsConstant<'a, 'b> for ArrayExpressionElement<'a> {
|
||||
fn is_constant(&self, in_boolean_position: bool, ctx: &LintContext<'a>) -> bool {
|
||||
fn is_constant(&self, in_boolean_position: bool, semantic: &Semantic<'a>) -> bool {
|
||||
match self {
|
||||
Self::SpreadElement(element) => element.is_constant(in_boolean_position, ctx),
|
||||
match_expression!(Self) => self.to_expression().is_constant(in_boolean_position, ctx),
|
||||
Self::SpreadElement(element) => element.is_constant(in_boolean_position, semantic),
|
||||
match_expression!(Self) => {
|
||||
self.to_expression().is_constant(in_boolean_position, semantic)
|
||||
}
|
||||
Self::Elision(_) => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> IsConstant<'a, 'b> for SpreadElement<'a> {
|
||||
fn is_constant(&self, in_boolean_position: bool, ctx: &LintContext<'a>) -> bool {
|
||||
self.argument.is_constant(in_boolean_position, ctx)
|
||||
fn is_constant(&self, in_boolean_position: bool, semantic: &Semantic<'a>) -> bool {
|
||||
self.argument.is_constant(in_boolean_position, semantic)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -183,7 +189,7 @@ impl<'a, 'b> IsConstant<'a, 'b> for SpreadElement<'a> {
|
|||
/// enclosing the specified node
|
||||
pub fn get_enclosing_function<'a, 'b>(
|
||||
node: &'b AstNode<'a>,
|
||||
ctx: &'b LintContext<'a>,
|
||||
semantic: &'b Semantic<'a>,
|
||||
) -> Option<&'b AstNode<'a>> {
|
||||
let mut current_node = node;
|
||||
loop {
|
||||
|
|
@ -194,7 +200,7 @@ pub fn get_enclosing_function<'a, 'b>(
|
|||
{
|
||||
return Some(current_node);
|
||||
}
|
||||
current_node = ctx.nodes().parent_node(current_node.id())?;
|
||||
current_node = semantic.nodes().parent_node(current_node.id())?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -205,11 +211,14 @@ pub fn is_nth_argument<'a>(call: &CallExpression<'a>, arg: &Argument<'a>, n: usi
|
|||
}
|
||||
|
||||
/// Jump to the outer most of chained parentheses if any
|
||||
pub fn outermost_paren<'a, 'b>(node: &'b AstNode<'a>, ctx: &'b LintContext<'a>) -> &'b AstNode<'a> {
|
||||
pub fn outermost_paren<'a, 'b>(
|
||||
node: &'b AstNode<'a>,
|
||||
semantic: &'b Semantic<'a>,
|
||||
) -> &'b AstNode<'a> {
|
||||
let mut node = node;
|
||||
|
||||
loop {
|
||||
if let Some(parent) = ctx.nodes().parent_node(node.id()) {
|
||||
if let Some(parent) = semantic.nodes().parent_node(node.id()) {
|
||||
if let AstKind::ParenthesizedExpression(_) = parent.kind() {
|
||||
node = parent;
|
||||
continue;
|
||||
|
|
@ -224,9 +233,10 @@ pub fn outermost_paren<'a, 'b>(node: &'b AstNode<'a>, ctx: &'b LintContext<'a>)
|
|||
|
||||
pub fn outermost_paren_parent<'a, 'b>(
|
||||
node: &'b AstNode<'a>,
|
||||
ctx: &'b LintContext<'a>,
|
||||
semantic: &'b Semantic<'a>,
|
||||
) -> Option<&'b AstNode<'a>> {
|
||||
ctx.nodes()
|
||||
semantic
|
||||
.nodes()
|
||||
.iter_parents(node.id())
|
||||
.skip(1)
|
||||
.find(|parent| !matches!(parent.kind(), AstKind::ParenthesizedExpression(_)))
|
||||
|
|
@ -234,10 +244,11 @@ pub fn outermost_paren_parent<'a, 'b>(
|
|||
|
||||
pub fn nth_outermost_paren_parent<'a, 'b>(
|
||||
node: &'b AstNode<'a>,
|
||||
ctx: &'b LintContext<'a>,
|
||||
semantic: &'b Semantic<'a>,
|
||||
n: usize,
|
||||
) -> Option<&'b AstNode<'a>> {
|
||||
ctx.nodes()
|
||||
semantic
|
||||
.nodes()
|
||||
.iter_parents(node.id())
|
||||
.skip(1)
|
||||
.filter(|parent| !matches!(parent.kind(), AstKind::ParenthesizedExpression(_)))
|
||||
|
|
@ -245,11 +256,11 @@ pub fn nth_outermost_paren_parent<'a, 'b>(
|
|||
}
|
||||
/// Iterate over parents of `node`, skipping nodes that are also ignored by
|
||||
/// [`Expression::get_inner_expression`].
|
||||
pub fn iter_outer_expressions<'a, 'ctx>(
|
||||
ctx: &'ctx LintContext<'a>,
|
||||
pub fn iter_outer_expressions<'a, 's>(
|
||||
semantic: &'s Semantic<'a>,
|
||||
node_id: NodeId,
|
||||
) -> impl Iterator<Item = &'ctx AstNode<'a>> + 'ctx {
|
||||
ctx.nodes().iter_parents(node_id).skip(1).filter(|parent| {
|
||||
) -> impl Iterator<Item = &'s AstNode<'a>> + 's {
|
||||
semantic.nodes().iter_parents(node_id).skip(1).filter(|parent| {
|
||||
!matches!(
|
||||
parent.kind(),
|
||||
AstKind::ParenthesizedExpression(_)
|
||||
|
|
@ -263,19 +274,19 @@ pub fn iter_outer_expressions<'a, 'ctx>(
|
|||
}
|
||||
|
||||
pub fn get_declaration_of_variable<'a, 'b>(
|
||||
ident: &IdentifierReference,
|
||||
ctx: &'b LintContext<'a>,
|
||||
ident: &IdentifierReference<'a>,
|
||||
semantic: &'b Semantic<'a>,
|
||||
) -> Option<&'b AstNode<'a>> {
|
||||
let symbol_id = get_symbol_id_of_variable(ident, ctx)?;
|
||||
let symbol_table = ctx.semantic().symbols();
|
||||
Some(ctx.nodes().get_node(symbol_table.get_declaration(symbol_id)))
|
||||
let symbol_id = get_symbol_id_of_variable(ident, semantic)?;
|
||||
let symbol_table = semantic.symbols();
|
||||
Some(semantic.nodes().get_node(symbol_table.get_declaration(symbol_id)))
|
||||
}
|
||||
|
||||
pub fn get_symbol_id_of_variable(
|
||||
ident: &IdentifierReference,
|
||||
ctx: &LintContext<'_>,
|
||||
semantic: &Semantic<'_>,
|
||||
) -> Option<SymbolId> {
|
||||
let symbol_table = ctx.semantic().symbols();
|
||||
let symbol_table = semantic.symbols();
|
||||
let reference_id = ident.reference_id.get()?;
|
||||
let reference = symbol_table.get_reference(reference_id);
|
||||
reference.symbol_id()
|
||||
|
|
@ -389,7 +400,7 @@ pub fn get_new_expr_ident_name<'a>(new_expr: &'a NewExpression<'a>) -> Option<&'
|
|||
Some(ident.name.as_str())
|
||||
}
|
||||
|
||||
pub fn is_global_require_call(call_expr: &CallExpression, ctx: &LintContext) -> bool {
|
||||
pub fn is_global_require_call(call_expr: &CallExpression, ctx: &Semantic) -> bool {
|
||||
if call_expr.arguments.len() != 1 {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -407,7 +418,7 @@ pub fn is_function_node(node: &AstNode) -> bool {
|
|||
|
||||
pub fn get_function_like_declaration<'b>(
|
||||
node: &AstNode<'b>,
|
||||
ctx: &LintContext<'b>,
|
||||
ctx: &Semantic<'b>,
|
||||
) -> Option<&'b BindingIdentifier<'b>> {
|
||||
let parent = outermost_paren_parent(node, ctx)?;
|
||||
let decl = parent.kind().as_variable_declarator()?;
|
||||
|
|
|
|||
|
|
@ -29,24 +29,24 @@ use crate::{
|
|||
},
|
||||
};
|
||||
|
||||
pub trait ListenerMap {
|
||||
fn report_effects(&self, _options: &NodeListenerOptions) {}
|
||||
fn report_effects_when_assigned(&self, _options: &NodeListenerOptions) {}
|
||||
fn report_effects_when_called(&self, _options: &NodeListenerOptions) {}
|
||||
fn report_effects_when_mutated(&self, _options: &NodeListenerOptions) {}
|
||||
fn get_value_and_report_effects(&self, _options: &NodeListenerOptions) -> Value {
|
||||
pub trait ListenerMap<'a> {
|
||||
fn report_effects(&self, _options: &NodeListenerOptions<'a, '_>) {}
|
||||
fn report_effects_when_assigned(&self, _options: &NodeListenerOptions<'a, '_>) {}
|
||||
fn report_effects_when_called(&self, _options: &NodeListenerOptions<'a, '_>) {}
|
||||
fn report_effects_when_mutated(&self, _options: &NodeListenerOptions<'a, '_>) {}
|
||||
fn get_value_and_report_effects(&self, _options: &NodeListenerOptions<'a, '_>) -> Value {
|
||||
Value::Unknown
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for Program<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for Program<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.body.iter().for_each(|stmt| stmt.report_effects(options));
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for Statement<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for Statement<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
Self::ExpressionStatement(expr_stmt) => {
|
||||
expr_stmt.expression.report_effects(options);
|
||||
|
|
@ -179,8 +179,8 @@ impl<'a> ListenerMap for Statement<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for ForStatementInit<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for ForStatementInit<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
match_expression!(Self) => self.to_expression().report_effects(options),
|
||||
Self::VariableDeclaration(decl) => {
|
||||
|
|
@ -190,8 +190,8 @@ impl<'a> ListenerMap for ForStatementInit<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for ExportSpecifier<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for ExportSpecifier<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
let ctx = options.ctx;
|
||||
let symbol_table = ctx.symbols();
|
||||
if has_comment_about_side_effect_check(self.exported.span(), ctx) {
|
||||
|
|
@ -220,8 +220,8 @@ impl<'a> ListenerMap for ExportSpecifier<'a> {
|
|||
// we don't need implement all AstNode
|
||||
// it's same as `reportSideEffectsInDefinitionWhenCalled` in eslint-plugin-tree-shaking
|
||||
// <https://github.com/lukastaegert/eslint-plugin-tree-shaking/blob/463fa1f0bef7caa2b231a38b9c3557051f506c92/src/rules/no-side-effects-in-initialization.ts#L1070-L1080>
|
||||
impl<'a> ListenerMap for AstNode<'a> {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for AstNode<'a> {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self.kind() {
|
||||
AstKind::VariableDeclarator(decl) => {
|
||||
if let Some(init) = &decl.init {
|
||||
|
|
@ -273,7 +273,7 @@ impl<'a> ListenerMap for AstNode<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn report_effects_when_mutated(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_mutated(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self.kind() {
|
||||
AstKind::VariableDeclarator(decl) => {
|
||||
if let Some(init) = &decl.init {
|
||||
|
|
@ -315,8 +315,8 @@ fn report_on_imported_call(span: Span, name: &str, node_id: NodeId, options: &No
|
|||
options.ctx.diagnostic(super::call_import(span));
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for Declaration<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for Declaration<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
Self::VariableDeclaration(decl) => {
|
||||
decl.declarations.iter().for_each(|decl| decl.report_effects(options));
|
||||
|
|
@ -336,15 +336,15 @@ impl<'a> ListenerMap for Declaration<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for Class<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for Class<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
if let Some(super_class) = &self.super_class {
|
||||
super_class.report_effects(options);
|
||||
}
|
||||
self.body.report_effects(options);
|
||||
}
|
||||
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
if let Some(super_class) = &self.super_class {
|
||||
super_class.report_effects_when_called(options);
|
||||
}
|
||||
|
|
@ -352,14 +352,14 @@ impl<'a> ListenerMap for Class<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for ClassBody<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for ClassBody<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.body.iter().for_each(|class_element| {
|
||||
class_element.report_effects(options);
|
||||
});
|
||||
}
|
||||
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
let constructor = self.body.iter().find(|class_element| {
|
||||
if let ClassElement::MethodDefinition(definition) = class_element {
|
||||
return definition.kind.is_constructor();
|
||||
|
|
@ -383,8 +383,8 @@ impl<'a> ListenerMap for ClassBody<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for ClassElement<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for ClassElement<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
Self::MethodDefinition(method) => {
|
||||
method.key.report_effects(options);
|
||||
|
|
@ -396,7 +396,7 @@ impl<'a> ListenerMap for ClassElement<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
Self::MethodDefinition(method) => {
|
||||
method.value.report_effects_when_called(options);
|
||||
|
|
@ -411,8 +411,8 @@ impl<'a> ListenerMap for ClassElement<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for PropertyKey<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for PropertyKey<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self.as_expression() {
|
||||
Some(expr) => expr.report_effects(options),
|
||||
None => no_effects(),
|
||||
|
|
@ -420,8 +420,8 @@ impl<'a> ListenerMap for PropertyKey<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for VariableDeclarator<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for VariableDeclarator<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.id.report_effects(options);
|
||||
if has_comment_about_side_effect_check(self.id.span(), options.ctx) {
|
||||
self.id.report_effects_when_called(options);
|
||||
|
|
@ -433,8 +433,8 @@ impl<'a> ListenerMap for VariableDeclarator<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for BindingPattern<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for BindingPattern<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match &self.kind {
|
||||
BindingPatternKind::BindingIdentifier(_) => {}
|
||||
BindingPatternKind::ArrayPattern(array) => {
|
||||
|
|
@ -457,19 +457,19 @@ impl<'a> ListenerMap for BindingPattern<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
if let BindingPatternKind::BindingIdentifier(ident) = &self.kind {
|
||||
ident.report_effects_when_called(options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for BindingIdentifier<'a> {
|
||||
fn report_effects(&self, _options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for BindingIdentifier<'a> {
|
||||
fn report_effects(&self, _options: &NodeListenerOptions<'a, '_>) {
|
||||
no_effects();
|
||||
}
|
||||
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
let ctx = options.ctx;
|
||||
if let Some(symbol_id) = self.symbol_id.get() {
|
||||
let symbol_table = ctx.semantic().symbols();
|
||||
|
|
@ -487,8 +487,8 @@ impl<'a> ListenerMap for BindingIdentifier<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for Expression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for Expression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
Self::ArrayExpression(array_expr) => {
|
||||
array_expr.elements.iter().for_each(|el| el.report_effects(options));
|
||||
|
|
@ -569,7 +569,7 @@ impl<'a> ListenerMap for Expression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn report_effects_when_mutated(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_mutated(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
Self::Identifier(ident) => {
|
||||
ident.report_effects_when_mutated(options);
|
||||
|
|
@ -591,7 +591,7 @@ impl<'a> ListenerMap for Expression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
Self::CallExpression(expr) => {
|
||||
expr.report_effects_when_called(options);
|
||||
|
|
@ -631,7 +631,7 @@ impl<'a> ListenerMap for Expression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_value_and_report_effects(&self, options: &NodeListenerOptions) -> Value {
|
||||
fn get_value_and_report_effects(&self, options: &NodeListenerOptions<'a, '_>) -> Value {
|
||||
match self {
|
||||
Self::BooleanLiteral(_)
|
||||
| Self::StringLiteral(_)
|
||||
|
|
@ -665,8 +665,8 @@ fn defined_custom_report_effects_when_called(expr: &Expression) -> bool {
|
|||
)
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for SwitchCase<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for SwitchCase<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
if let Some(test) = &self.test {
|
||||
test.report_effects(options);
|
||||
}
|
||||
|
|
@ -676,8 +676,8 @@ impl<'a> ListenerMap for SwitchCase<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for SequenceExpression<'a> {
|
||||
fn get_value_and_report_effects(&self, options: &NodeListenerOptions) -> Value {
|
||||
impl<'a> ListenerMap<'a> for SequenceExpression<'a> {
|
||||
fn get_value_and_report_effects(&self, options: &NodeListenerOptions<'a, '_>) -> Value {
|
||||
let mut val = Value::Unknown;
|
||||
for expr in &self.expressions {
|
||||
val = expr.get_value_and_report_effects(options);
|
||||
|
|
@ -686,8 +686,8 @@ impl<'a> ListenerMap for SequenceExpression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for UnaryExpression<'a> {
|
||||
fn get_value_and_report_effects(&self, options: &NodeListenerOptions) -> Value {
|
||||
impl<'a> ListenerMap<'a> for UnaryExpression<'a> {
|
||||
fn get_value_and_report_effects(&self, options: &NodeListenerOptions<'a, '_>) -> Value {
|
||||
if self.operator == UnaryOperator::Delete {
|
||||
match &self.argument {
|
||||
Expression::StaticMemberExpression(expr) => {
|
||||
|
|
@ -709,8 +709,8 @@ impl<'a> ListenerMap for UnaryExpression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for LogicalExpression<'a> {
|
||||
fn get_value_and_report_effects(&self, options: &NodeListenerOptions) -> Value {
|
||||
impl<'a> ListenerMap<'a> for LogicalExpression<'a> {
|
||||
fn get_value_and_report_effects(&self, options: &NodeListenerOptions<'a, '_>) -> Value {
|
||||
let left = self.left.get_value_and_report_effects(options);
|
||||
// `false && foo`
|
||||
if self.operator == LogicalOperator::And
|
||||
|
|
@ -729,8 +729,8 @@ impl<'a> ListenerMap for LogicalExpression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for ObjectExpression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for ObjectExpression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.properties.iter().for_each(|property| match property {
|
||||
ObjectPropertyKind::ObjectProperty(p) => {
|
||||
p.key.report_effects(options);
|
||||
|
|
@ -743,8 +743,8 @@ impl<'a> ListenerMap for ObjectExpression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for JSXElement<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for JSXElement<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.opening_element.report_effects(options);
|
||||
self.children.iter().for_each(|child| {
|
||||
child.report_effects(options);
|
||||
|
|
@ -752,8 +752,8 @@ impl<'a> ListenerMap for JSXElement<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for JSXChild<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for JSXChild<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
JSXChild::Element(element) => {
|
||||
element.report_effects(options);
|
||||
|
|
@ -774,15 +774,15 @@ impl<'a> ListenerMap for JSXChild<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for JSXOpeningElement<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for JSXOpeningElement<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.name.report_effects_when_called(options);
|
||||
self.attributes.iter().for_each(|attr| attr.report_effects(options));
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for JSXElementName<'a> {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for JSXElementName<'a> {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
Self::Identifier(_) | Self::NamespacedName(_) => {}
|
||||
Self::IdentifierReference(ident) => ident.report_effects_when_called(options),
|
||||
|
|
@ -792,14 +792,14 @@ impl<'a> ListenerMap for JSXElementName<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for JSXMemberExpression<'a> {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for JSXMemberExpression<'a> {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
options.ctx.diagnostic(super::call_member(self.property.span()));
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for JSXAttributeItem<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for JSXAttributeItem<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
Self::Attribute(attribute) => {
|
||||
attribute.report_effects(options);
|
||||
|
|
@ -811,8 +811,8 @@ impl<'a> ListenerMap for JSXAttributeItem<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for JSXAttribute<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for JSXAttribute<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
if let Some(value) = &self.value {
|
||||
match value {
|
||||
JSXAttributeValue::ExpressionContainer(container) => {
|
||||
|
|
@ -832,14 +832,14 @@ impl<'a> ListenerMap for JSXAttribute<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for JSXExpressionContainer<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for JSXExpressionContainer<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.expression.report_effects(options);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for JSXExpression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for JSXExpression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
Self::ArrayExpression(array_expr) => {
|
||||
array_expr.elements.iter().for_each(|el| el.report_effects(options));
|
||||
|
|
@ -902,14 +902,14 @@ impl<'a> ListenerMap for JSXExpression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for JSXFragment<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for JSXFragment<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.children.iter().for_each(|child| child.report_effects(options));
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for ConditionalExpression<'a> {
|
||||
fn get_value_and_report_effects(&self, options: &NodeListenerOptions) -> Value {
|
||||
impl<'a> ListenerMap<'a> for ConditionalExpression<'a> {
|
||||
fn get_value_and_report_effects(&self, options: &NodeListenerOptions<'a, '_>) -> Value {
|
||||
let test_result = self.test.get_value_and_report_effects(options);
|
||||
|
||||
if let Some(is_falsy) = test_result.get_falsy_value() {
|
||||
|
|
@ -925,7 +925,7 @@ impl<'a> ListenerMap for ConditionalExpression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
let test_result = self.test.get_value_and_report_effects(options);
|
||||
|
||||
if let Some(falsy) = test_result.get_falsy_value() {
|
||||
|
|
@ -941,24 +941,24 @@ impl<'a> ListenerMap for ConditionalExpression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for BinaryExpression<'a> {
|
||||
fn get_value_and_report_effects(&self, options: &NodeListenerOptions) -> Value {
|
||||
impl<'a> ListenerMap<'a> for BinaryExpression<'a> {
|
||||
fn get_value_and_report_effects(&self, options: &NodeListenerOptions<'a, '_>) -> Value {
|
||||
let left = self.left.get_value_and_report_effects(options);
|
||||
let right = self.right.get_value_and_report_effects(options);
|
||||
calculate_binary_operation(self.operator, left, right)
|
||||
}
|
||||
}
|
||||
|
||||
impl ListenerMap for ThisExpression {
|
||||
fn report_effects_when_mutated(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for ThisExpression {
|
||||
fn report_effects_when_mutated(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
if !options.has_valid_this.get() {
|
||||
options.ctx.diagnostic(super::mutate_of_this(self.span));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for NewExpression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for NewExpression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
if has_pure_notation(self.span, options.ctx) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -970,37 +970,37 @@ impl<'a> ListenerMap for NewExpression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for ParenthesizedExpression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for ParenthesizedExpression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.expression.report_effects(options);
|
||||
}
|
||||
|
||||
fn report_effects_when_assigned(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_assigned(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.expression.report_effects_when_assigned(options);
|
||||
}
|
||||
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.expression.report_effects_when_called(options);
|
||||
}
|
||||
|
||||
fn report_effects_when_mutated(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_mutated(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.expression.report_effects_when_mutated(options);
|
||||
}
|
||||
|
||||
fn get_value_and_report_effects(&self, options: &NodeListenerOptions) -> Value {
|
||||
fn get_value_and_report_effects(&self, options: &NodeListenerOptions<'a, '_>) -> Value {
|
||||
self.expression.get_value_and_report_effects(options)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for ArrowFunctionExpression<'a> {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for ArrowFunctionExpression<'a> {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.params.items.iter().for_each(|param| param.report_effects(options));
|
||||
self.body.statements.iter().for_each(|stmt| stmt.report_effects(options));
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for Function<'a> {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for Function<'a> {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.params.items.iter().for_each(|param| param.report_effects(options));
|
||||
|
||||
if let Some(body) = &self.body {
|
||||
|
|
@ -1009,14 +1009,14 @@ impl<'a> ListenerMap for Function<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for FormalParameter<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for FormalParameter<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.pattern.report_effects(options);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for CallExpression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for CallExpression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.arguments.iter().for_each(|arg| arg.report_effects(options));
|
||||
if defined_custom_report_effects_when_called(&self.callee) {
|
||||
let old_value = options.called_with_new.get();
|
||||
|
|
@ -1028,7 +1028,7 @@ impl<'a> ListenerMap for CallExpression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
let ctx = options.ctx;
|
||||
if let Expression::Identifier(ident) = &self.callee {
|
||||
if let Some(node) = get_declaration_of_variable(ident, ctx) {
|
||||
|
|
@ -1042,13 +1042,13 @@ impl<'a> ListenerMap for CallExpression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn report_effects_when_mutated(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_mutated(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
options.ctx.diagnostic(super::mutate_function_return_value(self.span));
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for Argument<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for Argument<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
match_expression!(Self) => self.to_expression().report_effects(options),
|
||||
Self::SpreadElement(spread) => {
|
||||
|
|
@ -1058,8 +1058,8 @@ impl<'a> ListenerMap for Argument<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for AssignmentTarget<'a> {
|
||||
fn report_effects_when_assigned(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for AssignmentTarget<'a> {
|
||||
fn report_effects_when_assigned(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
match_simple_assignment_target!(Self) => {
|
||||
self.to_simple_assignment_target().report_effects_when_assigned(options);
|
||||
|
|
@ -1069,8 +1069,8 @@ impl<'a> ListenerMap for AssignmentTarget<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for SimpleAssignmentTarget<'a> {
|
||||
fn report_effects_when_assigned(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for SimpleAssignmentTarget<'a> {
|
||||
fn report_effects_when_assigned(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
Self::AssignmentTargetIdentifier(ident) => {
|
||||
ident.report_effects_when_assigned(options);
|
||||
|
|
@ -1088,14 +1088,14 @@ impl<'a> ListenerMap for SimpleAssignmentTarget<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for IdentifierReference<'a> {
|
||||
fn report_effects_when_assigned(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for IdentifierReference<'a> {
|
||||
fn report_effects_when_assigned(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
if get_symbol_id_of_variable(self, options.ctx).is_none() {
|
||||
options.ctx.diagnostic(super::assignment(self.name.as_str(), self.span));
|
||||
}
|
||||
}
|
||||
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
if is_pure_function(&FunctionName::Identifier(self), options) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -1150,7 +1150,7 @@ impl<'a> ListenerMap for IdentifierReference<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn report_effects_when_mutated(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_mutated(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
let ctx = options.ctx;
|
||||
if let Some(symbol_id) = get_symbol_id_of_variable(self, ctx) {
|
||||
if options.insert_mutated_node(symbol_id) {
|
||||
|
|
@ -1173,8 +1173,8 @@ impl<'a> ListenerMap for IdentifierReference<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for MemberExpression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for MemberExpression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
Self::ComputedMemberExpression(expr) => {
|
||||
expr.report_effects(options);
|
||||
|
|
@ -1188,7 +1188,7 @@ impl<'a> ListenerMap for MemberExpression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn report_effects_when_assigned(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_assigned(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
Self::ComputedMemberExpression(expr) => {
|
||||
expr.report_effects_when_assigned(options);
|
||||
|
|
@ -1202,7 +1202,7 @@ impl<'a> ListenerMap for MemberExpression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
Self::ComputedMemberExpression(expr) => {
|
||||
expr.report_effects_when_called(options);
|
||||
|
|
@ -1217,13 +1217,13 @@ impl<'a> ListenerMap for MemberExpression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for ComputedMemberExpression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for ComputedMemberExpression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.expression.report_effects(options);
|
||||
self.object.report_effects(options);
|
||||
}
|
||||
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.report_effects(options);
|
||||
|
||||
let mut node = &self.object;
|
||||
|
|
@ -1247,18 +1247,18 @@ impl<'a> ListenerMap for ComputedMemberExpression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn report_effects_when_assigned(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_assigned(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.report_effects(options);
|
||||
self.object.report_effects_when_mutated(options);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for StaticMemberExpression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for StaticMemberExpression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.object.report_effects(options);
|
||||
}
|
||||
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.report_effects(options);
|
||||
|
||||
let mut root_member_expr = &self.object;
|
||||
|
|
@ -1300,18 +1300,18 @@ impl<'a> ListenerMap for StaticMemberExpression<'a> {
|
|||
options.ctx.diagnostic(super::call_member(self.span));
|
||||
}
|
||||
|
||||
fn report_effects_when_assigned(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_assigned(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.report_effects(options);
|
||||
self.object.report_effects_when_mutated(options);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for PrivateFieldExpression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for PrivateFieldExpression<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.object.report_effects(options);
|
||||
}
|
||||
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_called(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.report_effects(options);
|
||||
|
||||
let mut node = &self.object;
|
||||
|
|
@ -1335,14 +1335,14 @@ impl<'a> ListenerMap for PrivateFieldExpression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn report_effects_when_assigned(&self, options: &NodeListenerOptions) {
|
||||
fn report_effects_when_assigned(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
self.report_effects(options);
|
||||
self.object.report_effects_when_mutated(options);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ListenerMap for ArrayExpressionElement<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions) {
|
||||
impl<'a> ListenerMap<'a> for ArrayExpressionElement<'a> {
|
||||
fn report_effects(&self, options: &NodeListenerOptions<'a, '_>) {
|
||||
match self {
|
||||
match_expression!(Self) => self.to_expression().report_effects(options),
|
||||
Self::SpreadElement(spreed) => {
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ impl Rule for NoTypeofUndefined {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_global_variable(ident: &Expression, ctx: &LintContext) -> bool {
|
||||
fn is_global_variable<'a>(ident: &Expression<'a>, ctx: &LintContext<'a>) -> bool {
|
||||
let Expression::Identifier(ident) = ident else {
|
||||
return false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ impl Rule for PreferSetSize {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_set(maybe_set: &Expression, ctx: &LintContext) -> bool {
|
||||
fn is_set<'a>(maybe_set: &Expression<'a>, ctx: &LintContext<'a>) -> bool {
|
||||
if let Expression::NewExpression(new_expr) = maybe_set {
|
||||
if let Expression::Identifier(identifier) = &new_expr.callee {
|
||||
return identifier.name == "Set";
|
||||
|
|
|
|||
Loading…
Reference in a new issue