Skip to content

Commit

Permalink
snapshot pain
Browse files Browse the repository at this point in the history
  • Loading branch information
DonIsaac committed Jul 23, 2024
1 parent 6883506 commit eea8737
Show file tree
Hide file tree
Showing 10 changed files with 2,241 additions and 290 deletions.
116 changes: 102 additions & 14 deletions crates/oxc_linter/src/rules/eslint/no_unused_vars/allowed.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
//! This module checks if an unused variable is allowed. Note that this does not
//! consider variables ignored by name pattern, but by where they are declared.
#[allow(clippy::wildcard_imports)]
use oxc_ast::{ast::*, AstKind};
use oxc_ast::{ast::*, syntax_directed_operations::BoundNames, AstKind};
use oxc_semantic::Semantic;
use oxc_syntax::operator::UnaryOperator;

use crate::rules::eslint::no_unused_vars::binding_pattern::{BindingContext, HasAnyUsedBinding};

use super::binding_pattern::CheckBinding;
use super::{options::ArgsOption, NoUnusedVars, Symbol};

impl<'s, 'a> Symbol<'s, 'a> {
/// Returns `true` if this function is a callback passed to another function
pub fn is_function_callback(&self) -> bool {
/// Returns `true` if this function is a callback passed to another
/// function. Includes IIFEs.
pub fn is_callback_or_iife(&self) -> bool {
debug_assert!(self.declaration().kind().is_function_like());

for parent in self.iter_parents() {
Expand All @@ -20,6 +24,10 @@ impl<'s, 'a> Symbol<'s, 'a> {
AstKind::CallExpression(_) => {
return true;
}
// !function() {}; is an IIFE
AstKind::UnaryExpression(expr) => {
return expr.operator == UnaryOperator::LogicalNot;
}
_ => {
return false;
}
Expand Down Expand Up @@ -56,8 +64,47 @@ impl<'s, 'a> Symbol<'s, 'a> {

false
}

fn is_declared_in_for_of_loop(&self) -> bool {
for parent in self.iter_parents() {
match parent.kind() {
AstKind::ParenthesizedExpression(_)
| AstKind::VariableDeclaration(_)
| AstKind::BindingIdentifier(_)
| AstKind::SimpleAssignmentTarget(_)
| AstKind::AssignmentTarget(_) => continue,
AstKind::ForInStatement(ForInStatement { body, ..}) | AstKind::ForOfStatement(ForOfStatement { body, ..}) => {
match body {
Statement::ReturnStatement(_) => return true,
Statement::BlockStatement(b) => {
return b.body.get(0).is_some_and(|s| matches!(s, Statement::ReturnStatement(_)))
},
_ => return false
}
}
_ => return false,
}
}

false
}
}

impl NoUnusedVars {
pub(super) fn is_allowed_class<'a>(&self, class: &Class<'a>) -> bool {
if self.ignore_class_with_static_init_block
&& class.body.body.iter().any(|el| matches!(el, ClassElement::StaticBlock(_)))
{
return true;
}

false
}

pub(super) fn is_allowed_function<'a>(&self, symbol: &Symbol<'_, 'a>) -> bool {
symbol.is_callback_or_iife() || symbol.is_function_assigned_to_same_name_variable()
}

/// Returns `true` if this unused variable declaration should be allowed
/// (i.e. not reported)
pub(super) fn is_allowed_variable_declaration<'a>(
Expand All @@ -69,10 +116,17 @@ impl NoUnusedVars {
return true;
}

// allow unused iterators, since they're required for valid syntax
if symbol.is_declared_in_for_of_loop() {
return true;
}

// check if res is an array/object unpacking pattern that should be ignored
matches!(decl.id.check_unused_binding_pattern(self, symbol), Some(res) if res.is_ignore())
}

/// Returns `true` if this unused parameter should be allowed (i.e. not
/// reported)
pub(super) fn is_allowed_argument<'a>(
&self,
semantic: &Semantic<'a>,
Expand Down Expand Up @@ -115,9 +169,35 @@ impl NoUnusedVars {
return true;
}

// match self.args {
// ArgsOption::All => {

// // Parameters are always checked. Must be done after above checks,
// // because in those cases a parameter is required. However, if
// // this is a destructuring pattern, it may be ignored using
// // `ignoreRestSiblings` or `destructuredArrayIgnorePattern`.
// if param.pattern.kind.is_destructuring_pattern() {
// // allow unpacked parameters that are ignored via destructuredArrayIgnorePattern
// let maybe_unused_binding_pattern =
// param.pattern.check_unused_binding_pattern(self, symbol);
// return maybe_unused_binding_pattern.map_or(false, |res| res.is_ignore());
// }
// },
// ArgsOption::AfterUsed => {

// },
// ArgsOption::None => unreachable!()
// }
// Parameters are always checked. Must be done after above checks,
// because in those cases a parameter is required
if self.args.is_none() {
// because in those cases a parameter is required. However, even if
// `args` is `all`, it may be ignored using `ignoreRestSiblings` or `destructuredArrayIgnorePattern`.
if self.args.is_all() {
if param.pattern.kind.is_destructuring_pattern() {
// allow unpacked parameters that are ignored via destructuredArrayIgnorePattern
let maybe_unused_binding_pattern =
param.pattern.check_unused_binding_pattern(self, symbol);
return maybe_unused_binding_pattern.map_or(false, |res| res.is_ignore());
}
return false;
}

Expand All @@ -131,7 +211,7 @@ impl NoUnusedVars {
// check if this is a positional argument - unused non-positional
// arguments are never allowed
if param.pattern.kind.is_destructuring_pattern() {
// allow unpacked parameters that are ignored
// allow unpacked parameters that are ignored via destructuredArrayIgnorePattern
let maybe_unused_binding_pattern =
param.pattern.check_unused_binding_pattern(self, symbol);
return maybe_unused_binding_pattern.map_or(false, |res| res.is_ignore());
Expand All @@ -154,15 +234,23 @@ impl NoUnusedVars {
return false;
}

let ctx = BindingContext { options: self, semantic };
params.items.iter().skip(position + 1).any(|p| {
let Some(id) = p.pattern.get_binding_identifier() else {
return false;
};
let Some(symbol_id) = id.symbol_id.get() else {
return false;
};
let symbol = Symbol::new(semantic, symbol_id);
symbol.has_usages()
p.pattern.has_any_used_binding(ctx)
// let mut is_used = false;

// p.pattern.bound_names(&mut |id| {
// if is_used {
// return;
// }
// let Some(symbol_id) = id.symbol_id.get() else {
// return;
// };
// let symbol = Symbol::new(semantic, symbol_id);
// is_used = symbol.has_usages(self);
// });

// is_used
})
}
}
Loading

0 comments on commit eea8737

Please sign in to comment.