diff --git a/lib/rules/no-incorrect-computed-macros.js b/lib/rules/no-incorrect-computed-macros.js index 2f33089833..1006ac52b5 100644 --- a/lib/rules/no-incorrect-computed-macros.js +++ b/lib/rules/no-incorrect-computed-macros.js @@ -5,8 +5,6 @@ const types = require('../utils/types'); const ERROR_MESSAGE_AND_OR = 'Computed property macro should be used with 2+ arguments'; -const COMPUTED_MACROS_AND_OR = ['and', 'or']; - module.exports = { meta: { type: 'problem', @@ -24,22 +22,27 @@ module.exports = { ERROR_MESSAGE_AND_OR, create(context) { - let macroIdentifiersAndOr = []; + let importNameAnd = undefined; + let importNameOr = undefined; + let importNameReadOnly = undefined; return { ImportDeclaration(node) { - if (node.source.value !== '@ember/object/computed') { - return; + if (node.source.value === '@ember/object/computed') { + // Gather the identifiers that these macros are imported under. + importNameAnd = + importNameAnd || getImportIdentifier(node, '@ember/object/computed', 'and'); + importNameOr = importNameOr || getImportIdentifier(node, '@ember/object/computed', 'or'); + importNameReadOnly = + importNameReadOnly || getImportIdentifier(node, '@ember/object/computed', 'readOnly'); } - - // Gather the identifiers that these macros are imported under. - macroIdentifiersAndOr = COMPUTED_MACROS_AND_OR.map((fn) => - getImportIdentifier(node, '@ember/object/computed', fn) - ); }, CallExpression(node) { - if (types.isIdentifier(node.callee) && macroIdentifiersAndOr.includes(node.callee.name)) { + if ( + types.isIdentifier(node.callee) && + [importNameAnd, importNameOr].includes(node.callee.name) + ) { if ( node.arguments.length === 1 && types.isStringLiteral(node.arguments[0]) && @@ -49,7 +52,18 @@ module.exports = { node: node.callee, message: ERROR_MESSAGE_AND_OR, fix(fixer) { - return fixer.replaceText(node.callee, 'readOnly'); + if (importNameReadOnly) { + return fixer.replaceText(node.callee, importNameReadOnly); + } else { + const sourceCode = context.getSourceCode(); + return [ + fixer.insertTextBefore( + sourceCode.ast, + "import { readOnly } from '@ember/object/computed';\n" + ), + fixer.replaceText(node.callee, 'readOnly'), + ]; + } }, }); } else if (node.arguments.length === 0) { diff --git a/tests/lib/rules/no-incorrect-computed-macros.js b/tests/lib/rules/no-incorrect-computed-macros.js index 05305baba4..cb27713073 100644 --- a/tests/lib/rules/no-incorrect-computed-macros.js +++ b/tests/lib/rules/no-incorrect-computed-macros.js @@ -92,7 +92,8 @@ ruleTester.run('no-incorrect-computed-macros', rule, { import { and } from '@ember/object/computed'; and('someProperty')`, output: ` - import { and } from '@ember/object/computed'; + import { readOnly } from '@ember/object/computed'; +import { and } from '@ember/object/computed'; readOnly('someProperty')`, errors: [ { @@ -106,7 +107,8 @@ ruleTester.run('no-incorrect-computed-macros', rule, { import { or } from '@ember/object/computed'; or('someProperty')`, output: ` - import { or } from '@ember/object/computed'; + import { readOnly } from '@ember/object/computed'; +import { or } from '@ember/object/computed'; readOnly('someProperty')`, errors: [ { @@ -121,7 +123,8 @@ ruleTester.run('no-incorrect-computed-macros', rule, { import { and } from '@ember/object/computed'; class Test { @and('someProperty') prop }`, output: ` - import { and } from '@ember/object/computed'; + import { readOnly } from '@ember/object/computed'; +import { and } from '@ember/object/computed'; class Test { @readOnly('someProperty') prop }`, errors: [ {