Skip to content

Commit

Permalink
docs(linter): add docs to no-unused-vars and Tester (#6558)
Browse files Browse the repository at this point in the history
Misc doc changes made while authoring the previous PR in this stack.
  • Loading branch information
DonIsaac committed Oct 16, 2024
1 parent 1e7fab3 commit 557f941
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ fn fixme() {
Tester::new(NoUnusedVars::NAME, pass, fail).intentionally_allow_no_fix_tests().test();
}

/// !!!! STOP !!!
/// Are you fixing a bug in this rules and want to add a test case? Please put
/// it in `oxc.rs`. These are _only_ the test cases ported from the original
/// ESLint rule.
#[test]
fn test() {
let pass = vec![
Expand Down
39 changes: 33 additions & 6 deletions crates/oxc_linter/src/rules/eslint/no_unused_vars/usage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,25 @@ use oxc_span::{GetSpan, Span};
use super::{ignored::FoundStatus, NoUnusedVars, Symbol};

impl<'s, 'a> Symbol<'s, 'a> {
// =========================================================================
// ==================== ENABLE/DISABLE USAGE SUB-CHECKS ====================
// =========================================================================

// NOTE(@don): all of these should be `#[inline]` and `const`. by inlining
// it, rustc should be able to detect redundant flag checks and optimize
// them away. Note that I haven't actually checked the assembly output to
// confirm this; if you are reading this and decide to do so, please let me
// know the results.

/// 1. Imported functions will never have calls to themselves within their
/// own declaration since they are declared outside the current module
/// 2. Catch variables are always parameter-like and will therefore never have
/// a function declaration.
#[inline]
const fn is_maybe_callable(&self) -> bool {
// NOTE: imports are technically callable, but that call will never
// occur within its own declaration since it's declared in another
// module.
const IMPORT: SymbolFlags = SymbolFlags::Import.union(SymbolFlags::TypeImport);
// note: intetionally do not use `SymbolFlags::is_type` here, since that
// can return `true` for values
Expand Down Expand Up @@ -59,14 +72,26 @@ impl<'s, 'a> Symbol<'s, 'a> {
&& !f.contains(SymbolFlags::ConstVariable.union(SymbolFlags::Function))
}

/// Checks if this [`Symbol`] could be used as a type reference within its
/// own declaration.
///
/// This does _not_ imply this symbol is a type (negative cases include type
/// imports, type parameters, etc).
#[inline]
const fn could_have_type_reference_within_own_decl(&self) -> bool {
const TYPE_DECLS: SymbolFlags =
SymbolFlags::TypeAlias.union(SymbolFlags::Interface).union(SymbolFlags::Class);
#[rustfmt::skip]
const TYPE_DECLS: SymbolFlags = SymbolFlags::TypeAlias
.union(SymbolFlags::Interface)
.union(SymbolFlags::Class);

self.flags().intersects(TYPE_DECLS)
}

/// Check if this [`Symbol`] has an [`Reference`]s that are considered a usage.
// =========================================================================
// ============================= USAGE CHECKS ==============================
// =========================================================================

/// Check if this [`Symbol`] has any [`Reference`]s that are considered a usage.
pub fn has_usages(&self, options: &NoUnusedVars) -> bool {
// Use symbol flags to skip the usage checks we are certain don't need
// to be run.
Expand All @@ -87,7 +112,8 @@ impl<'s, 'a> Symbol<'s, 'a> {
);
assert!(reference.symbol_id().is_some_and(|id| id == self.id()));

// Write usage checks
// ====================== Write usage checks =======================

if reference.is_write() {
if do_reassignment_checks
&& (self.is_assigned_to_ignored_destructure(reference, options)
Expand All @@ -103,7 +129,8 @@ impl<'s, 'a> Symbol<'s, 'a> {
}
}

// Type usage checks
// ======================= Type usage checks =======================

if reference.is_type() {
// e.g. `type Foo = Array<Foo>`
if do_type_self_usage_checks && self.is_type_self_usage(reference) {
Expand All @@ -112,7 +139,7 @@ impl<'s, 'a> Symbol<'s, 'a> {
return true;
}

// Read usage checks
// ======================= Read usage checks =======================

// e.g. `let a = 0; a = a + 1`
if do_reassignment_checks && self.is_self_reassignment(reference) {
Expand Down
25 changes: 24 additions & 1 deletion crates/oxc_linter/src/tester.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,30 @@ impl Tester {
self
}

/// Change the extension of the path
/// Change the extension of the path. Do not include the dot.
///
/// By default, the extension is `tsx`.
///
/// ## Example
/// ```ignore
/// use crate::tester::Tester;
/// use oxc_macros::declare_oxc_lint;
///
/// declare_oxc_lint! (
/// /// docs
/// MyRule,
/// correctness,
/// );
///
/// #[test]
/// fn test() {
/// let pass = vec!["let x = 1;"];
/// let fail = vec![];
/// Tester::new(MyRule::NAME, pass, fail)
/// .change_rule_path_extension("ts")
/// .test_and_snapshot();
/// }
/// ```
pub fn change_rule_path_extension(mut self, ext: &str) -> Self {
self.rule_path = self.rule_path.with_extension(ext);
self
Expand Down

0 comments on commit 557f941

Please sign in to comment.