diff --git a/lib/rules/no-array-prototype-extensions.js b/lib/rules/no-array-prototype-extensions.js index d830c4aaca..53a2d3be62 100644 --- a/lib/rules/no-array-prototype-extensions.js +++ b/lib/rules/no-array-prototype-extensions.js @@ -28,7 +28,7 @@ const EXTENSION_METHODS = new Set([ 'without', /** * https://api.emberjs.com/ember/release/classes/MutableArray - * MutableArray methods excluding `replace` since it's part of string native functions + * MutableArray methods excluding `replace`. `replace` is handled differently as it's also part of String.prototype. * */ 'addObject', 'addObjects', @@ -47,6 +47,8 @@ const EXTENSION_METHODS = new Set([ 'unshiftObjects', ]); +const REPLACE_METHOD = 'replace'; + /** * https://api.emberjs.com/ember/release/classes/EmberArray * EmberArray properties excluding native props: [], length. @@ -98,6 +100,13 @@ module.exports = { if (EXTENSION_METHODS.has(node.callee.property.name)) { context.report({ node, messageId: 'main' }); } + + // Example: someArray.replace(1, 2, [1, 2, 3]); + // We can differentiate String.prototype.replace and Array.prototype.replace by arguments length + // String.prototype.replace can only have 2 arguments, Array.prototype.replace needs to have exact 3 arguments + if (node.callee.property.name === REPLACE_METHOD && node.arguments.length === 3) { + context.report({ node, messageId: 'main' }); + } }, /** diff --git a/tests/lib/rules/no-array-prototype-extensions.js b/tests/lib/rules/no-array-prototype-extensions.js index c703051e8c..2f00d9b418 100644 --- a/tests/lib/rules/no-array-prototype-extensions.js +++ b/tests/lib/rules/no-array-prototype-extensions.js @@ -33,12 +33,15 @@ ruleTester.run('no-array-prototype-extensions', rule, { 'something[something.length - 1]', 'something.isAny', "something['compact']", + 'replace()', + 'replace(foo)', + 'replace(foo, bar, baz)', /** Optional chaining */ 'arr?.notfirstObject?.foo', 'arr?.filter?.()', - /** Replace is part of string native prototypes */ - "'something'.replace()", - 'something.replace()', + /** String.prototype.replace() */ + "'something'.replace(regexp, 'substring')", + "something.replace(regexp, 'substring')", ], invalid: [ { @@ -272,5 +275,10 @@ ruleTester.run('no-array-prototype-extensions', rule, { output: null, errors: [{ messageId: 'main', type: 'CallExpression' }], }, + { + code: 'something.replace(1, 2, someArray)', + output: null, + errors: [{ messageId: 'main', type: 'CallExpression' }], + }, ], });