diff --git a/docs/rules/no-array-prototype-extensions.md b/docs/rules/no-array-prototype-extensions.md index 2bc629ec8b..c530caac5e 100644 --- a/docs/rules/no-array-prototype-extensions.md +++ b/docs/rules/no-array-prototype-extensions.md @@ -117,6 +117,15 @@ export default class SampleComponent extends Component { } ``` +```js +/** Direct usage of `@ember/array` **/ +/** Use A() is OK **/ +import { A } from '@ember/array'; + +const arr = A(['a', 'a', 'b', 'b']); +arr.uniq(); +``` + ## References - [EmberArray](https://api.emberjs.com/ember/release/classes/EmberArray) diff --git a/lib/rules/no-array-prototype-extensions.js b/lib/rules/no-array-prototype-extensions.js index d3aa8799b1..e5b428b58d 100644 --- a/lib/rules/no-array-prototype-extensions.js +++ b/lib/rules/no-array-prototype-extensions.js @@ -621,6 +621,7 @@ module.exports = { let importedGetName; let importedSetName; let importedCompareName; + let importedEmberArrayName; // Track some information about the current class we're inside. const classStack = new Stack(); @@ -635,6 +636,10 @@ module.exports = { importedCompareName = importedCompareName || getImportIdentifier(node, '@ember/utils', 'compare'); } + if (node.source.value === '@ember/array') { + importedEmberArrayName = + importedEmberArrayName || getImportIdentifier(node, '@ember/array', 'A'); + } }, /** * Cover cases when `EXTENSION_METHODS` is getting called. @@ -714,6 +719,16 @@ module.exports = { return; } + // Direct usage of `@ember/array` is allowed. + if ( + node.type === 'CallExpression' && + importedEmberArrayName && + nodeInitializedTo.callee.type === 'Identifier' && + importedEmberArrayName === nodeInitializedTo.callee.name + ) { + return; + } + if (EXTENSION_METHODS.has(node.callee.property.name)) { context.report({ node, diff --git a/tests/lib/rules/no-array-prototype-extensions.js b/tests/lib/rules/no-array-prototype-extensions.js index 899732e232..98b38edc1a 100644 --- a/tests/lib/rules/no-array-prototype-extensions.js +++ b/tests/lib/rules/no-array-prototype-extensions.js @@ -203,6 +203,25 @@ ruleTester.run('no-array-prototype-extensions', rule, { parser: require.resolve('@typescript-eslint/parser'), }, + // Methods called directly on EmberArray. + ` + import { A } from '@ember/array' + + const array = A([1, 2, 3]) + array.toArray() + `, + ` + import { A } from '@ember/array' + + A([1, 2, 3]).toArray(); + `, + ` + import { A as SomeWeirdName } from '@ember/array' + + const array = SomeWeirdName([1, 2, 3]) + array.without(2) + `, + // TODO: handle non-Identifier property names: 'foo["clear"]();', ],