Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 31 additions & 14 deletions crates/oxc_linter/src/rules/oxc/bad_array_method_on_arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ use oxc_span::{GetSpan, Span};
use crate::{AstNode, context::LintContext, rule::Rule};

fn bad_array_method_on_arguments_diagnostic(method_name: &str, span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Bad array method on arguments")
OxcDiagnostic::warn("Bad array method on `arguments`.")
.with_help(format!(
"The 'arguments' object does not have a '{method_name}()' method. If you intended to use an array method, consider converting the 'arguments' object to an array or using an ES2015 rest parameter instead."
"The `arguments` object does not have a `{method_name}()` method. If you intended to use an array method, consider using rest parameters instead or converting the `arguments` object to an array."
))
.with_label(span)
}
Expand All @@ -23,9 +23,16 @@ declare_oxc_lint!(
///
/// ### Why is this bad?
///
/// The arguments object is not an array, but an array-like object. It should be converted to a real array before calling an array method.
/// The [arguments object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments)
/// is not an array, but an array-like object. It should be converted to a real array before calling an array method.
/// Otherwise, a TypeError exception will be thrown because of the non-existent method.
///
/// Note that you probably don't need this rule if you are using exclusively
/// TypeScript, as it will catch these errors when typechecking.
///
/// `arguments` usage is usually discouraged in modern JavaScript, and you should prefer using
/// rest parameters instead, e.g. `function sum(...args)`.
///
/// ### Examples
///
/// Examples of **incorrect** code for this rule:
Expand All @@ -43,6 +50,7 @@ declare_oxc_lint!(
/// function add(x, y) {
/// return x + y;
/// }
///
/// function sum(...args) {
/// return args.reduce(add, 0);
/// }
Expand Down Expand Up @@ -76,24 +84,27 @@ impl Rule for BadArrayMethodOnArguments {
}
}

/// `https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#instance_methods`
/// <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#instance_methods>
#[rustfmt::skip]
const ARRAY_METHODS: [&str; 32] = [
const ARRAY_METHODS: [&str; 38] = [
"@@iterator",
"at",
"concat", "copyWithin",
"entries", "every",
"fill", "filter", "find", "findIndex", "flat", "flatMap", "forEach",
"fill", "filter", "find", "findIndex", "findLast", "findLastIndex", "flat", "flatMap", "forEach",
"groupBy",
"includes", "indexOf",
"join",
"keys",
"lastIndexOf",
"map",
"pop", "push", "push",
"pop", "push",
"reduce", "reduceRight", "reverse",
"shift", "slice", "some", "sort", "splice",
"toReversed", "toSorted", "toSpliced",
"unshift",
"values",
"with",
];

#[test]
Expand All @@ -116,13 +127,7 @@ fn test() {
("function fn() {arguments[`${'map'}`]((prev, cur) => prev + cur, 0)}", None),
("function fn() {arguments.toLocaleString(() => {})}", None),
("function fn() {arguments.toString(() => {})}", None),
("function fn() {arguments.findLast(() => {})}", None),
("function fn() {arguments.group(() => {})}", None),
("function fn() {arguments.groupToMap(() => {})}", None),
("function fn() {arguments.toReversed(() => {})}", None),
("function fn() {arguments.toSorted(() => {})}", None),
("function fn() {arguments.toSpliced(0)}", None),
("function fn() {arguments.with(1, 1)}", None),
("function fn() { Array.prototype.slice.call(arguments) }", None),
];

let fail = vec![
Expand All @@ -137,9 +142,12 @@ fn test() {
("function fn() {arguments.filter(() => {})}", None),
("function fn() {arguments.find(() => {})}", None),
("function fn() {arguments.findIndex(() => {})}", None),
("function fn() {arguments.findLast(() => {})}", None),
("function fn() {arguments.findLastIndex(() => {})}", None),
("function fn() {arguments.flat(() => {})}", None),
("function fn() {arguments.flatMap(() => {})}", None),
("function fn() {arguments.forEach(() => {})}", None),
("function fn() {arguments.groupBy(() => {})}", None),
("function fn() {arguments.includes(() => {})}", None),
("function fn() {arguments.indexOf(() => {})}", None),
("function fn() {arguments.join()}", None),
Expand All @@ -156,9 +164,18 @@ fn test() {
("function fn() {arguments.some(() => {})}", None),
("function fn() {arguments.sort(() => {})}", None),
("function fn() {arguments.splice(() => {})}", None),
("function fn() {arguments.toReversed(() => {})}", None),
("function fn() {arguments.toSorted(() => {})}", None),
("function fn() {arguments.toSpliced(0)}", None),
("function fn() {arguments.unshift()}", None),
("function fn() {arguments.values()}", None),
("function fn() {arguments['@@iterator'](() => {})}", None),
(
"const arr = [1, 2, 3, 4, 5];
function fn() { arguments.with(2, 6) }
fn(arr)",
None,
),
];

Tester::new(BadArrayMethodOnArguments::NAME, BadArrayMethodOnArguments::PLUGIN, pass, fail)
Expand Down
Loading
Loading