diff --git a/lib/rules/prefer-object-has-own.js b/lib/rules/prefer-object-has-own.js index 0359141b955..3bb0f99d5df 100644 --- a/lib/rules/prefer-object-has-own.js +++ b/lib/rules/prefer-object-has-own.js @@ -12,6 +12,10 @@ const astUtils = require("./utils/ast-utils"); +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + /** * Checks if the given node is considered to be an access to a property of `Object.prototype`. * @param {ASTNode} node `MemberExpression` node to evaluate. @@ -36,6 +40,26 @@ function hasLeftHandObject(node) { return false; } +/** + * Checks if the given token is `await` Identefier, `of` Itentifier or a keyword token + * Inspired from eslint-plugin-unicorn/rules/fix/fix-space-around-keywords.js + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is is `await` Identefier, `of` Itentifier or a keyword token + */ +function isProblematicToken(token) { + const { type, value } = token; + + if ( + (type === "Keyword" && /^[a-z]*$/u.test(value)) || + + // AwaitExpression or ForOfStatement + (type === "Identifier" && (value === "of" || value === "await"))) { + return true; + } + + return false; +} + //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ @@ -87,10 +111,10 @@ module.exports = { return null; } - const tokenJustBeforeNode = sourceCode.getTokensBefore(node, 1)[0]; + const tokenJustBeforeNode = sourceCode.getTokenBefore(node, { includeComments: true }); // for https://github.com/eslint/eslint/pull/15346#issuecomment-991417335 - if (tokenJustBeforeNode && tokenJustBeforeNode.type === "Keyword" && !sourceCode.isSpaceBetween(node, tokenJustBeforeNode)) { + if (tokenJustBeforeNode && isProblematicToken(tokenJustBeforeNode) && !sourceCode.isSpaceBetween(node, tokenJustBeforeNode)) { return fixer.replaceText(node.callee, " Object.hasOwn"); } diff --git a/tests/lib/rules/prefer-object-has-own.js b/tests/lib/rules/prefer-object-has-own.js index 0f14497ca9b..ff26868870d 100644 --- a/tests/lib/rules/prefer-object-has-own.js +++ b/tests/lib/rules/prefer-object-has-own.js @@ -303,6 +303,39 @@ ruleTester.run("prefer-object-has-own", rule, { endColumn: 62 }] }, + { + code: "function foo(){return/*comment*/{}.hasOwnProperty.call(object, property)}", + output: "function foo(){return/*comment*/Object.hasOwn(object, property)}", + errors: [{ + messageId: "useHasOwn", + line: 1, + column: 33, + endLine: 1, + endColumn: 73 + }] + }, + { + code: "async function foo(){return await{}.hasOwnProperty.call(object, property)}", + output: "async function foo(){return await Object.hasOwn(object, property)}", + errors: [{ + messageId: "useHasOwn", + line: 1, + column: 34, + endLine: 1, + endColumn: 74 + }] + }, + { + code: "async function foo(){return await/*comment*/{}.hasOwnProperty.call(object, property)}", + output: "async function foo(){return await/*comment*/Object.hasOwn(object, property)}", + errors: [{ + messageId: "useHasOwn", + line: 1, + column: 45, + endLine: 1, + endColumn: 85 + }] + }, { code: "Object['prototype']['hasOwnProperty']['call'](object, property);", output: "Object.hasOwn(object, property);",