From ad34fdf40090c687531f5bc3e96d9c7fdf91ef2e Mon Sep 17 00:00:00 2001 From: Milos Djermanovic Date: Sat, 6 Aug 2022 22:53:13 +0200 Subject: [PATCH] feat: add `methodsIgnorePattern` option to object-shorthand rule Fixes #15796 --- docs/src/rules/object-shorthand.md | 17 ++++++ lib/rules/object-shorthand.js | 15 +++++ tests/lib/rules/object-shorthand.js | 90 +++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+) diff --git a/docs/src/rules/object-shorthand.md b/docs/src/rules/object-shorthand.md index d4e5f016b6d..aa05bb3f083 100644 --- a/docs/src/rules/object-shorthand.md +++ b/docs/src/rules/object-shorthand.md @@ -115,6 +115,7 @@ Additionally, the rule takes an optional object configuration: * `"avoidQuotes": true` indicates that long-form syntax is preferred whenever the object key is a string literal (default: `false`). Note that this option can only be enabled when the string option is set to `"always"`, `"methods"`, or `"properties"`. * `"ignoreConstructors": true` can be used to prevent the rule from reporting errors for constructor functions. (By default, the rule treats constructors the same way as other functions.) Note that this option can only be enabled when the string option is set to `"always"` or `"methods"`. +* `"methodsIgnorePattern"` (`string`) for methods whose names match this regex pattern, the method shorthand will not be enforced. Note that this option can only be used when the string option is set to `"always"` or `"methods"`. * `"avoidExplicitReturnArrows": true` indicates that methods are preferred over explicit-return arrow functions for function properties. (By default, the rule allows either of these.) Note that this option can only be enabled when the string option is set to `"always"` or `"methods"`. ### `avoidQuotes` @@ -179,6 +180,22 @@ var foo = { ::: +### `methodsIgnorePattern` + +Example of **correct** code for this rule with the `"always", { "methodsIgnorePattern": "^bar$" }` option: + +::: correct + +```js +/*eslint object-shorthand: ["error", "always", { "methodsIgnorePattern": "^bar$" }]*/ + +var foo = { + bar: function() {} +}; +``` + +::: + ### `avoidExplicitReturnArrows` ```json diff --git a/lib/rules/object-shorthand.js b/lib/rules/object-shorthand.js index 8cd3978ca35..b755aea3f48 100644 --- a/lib/rules/object-shorthand.js +++ b/lib/rules/object-shorthand.js @@ -78,6 +78,9 @@ module.exports = { ignoreConstructors: { type: "boolean" }, + methodsIgnorePattern: { + type: "string" + }, avoidQuotes: { type: "boolean" }, @@ -115,6 +118,9 @@ module.exports = { const PARAMS = context.options[1] || {}; const IGNORE_CONSTRUCTORS = PARAMS.ignoreConstructors; + const METHODS_IGNORE_PATTERN = PARAMS.methodsIgnorePattern + ? new RegExp(PARAMS.methodsIgnorePattern, "u") + : null; const AVOID_QUOTES = PARAMS.avoidQuotes; const AVOID_EXPLICIT_RETURN_ARROWS = !!PARAMS.avoidExplicitReturnArrows; const sourceCode = context.getSourceCode(); @@ -457,6 +463,15 @@ module.exports = { if (IGNORE_CONSTRUCTORS && node.key.type === "Identifier" && isConstructor(node.key.name)) { return; } + + if (METHODS_IGNORE_PATTERN) { + const propertyName = astUtils.getStaticPropertyName(node); + + if (propertyName !== null && METHODS_IGNORE_PATTERN.test(propertyName)) { + return; + } + } + if (AVOID_QUOTES && isStringLiteral(node.key)) { return; } diff --git a/tests/lib/rules/object-shorthand.js b/tests/lib/rules/object-shorthand.js index 01a72f4e6f0..58bb5708327 100644 --- a/tests/lib/rules/object-shorthand.js +++ b/tests/lib/rules/object-shorthand.js @@ -185,6 +185,52 @@ ruleTester.run("object-shorthand", rule, { options: ["never"] }, + // methodsIgnorePattern + { + code: "var x = { foo: function() {} }", + options: ["always", { methodsIgnorePattern: "^foo$" }] + }, + { + code: "var x = { foo: function() {} }", + options: ["methods", { methodsIgnorePattern: "^foo$" }] + }, + { + code: "var x = { foo: function*() {} }", + options: ["always", { methodsIgnorePattern: "^foo$" }] + }, + { + code: "var x = { foo: async function() {} }", + options: ["always", { methodsIgnorePattern: "^foo$" }] + }, + { + code: "var x = { foo: () => { return 5; } }", + options: ["always", { methodsIgnorePattern: "^foo$", avoidExplicitReturnArrows: true }] + }, + { + code: "var x = { 'foo': function() {} }", + options: ["always", { methodsIgnorePattern: "^foo$" }] + }, + { + code: "var x = { ['foo']: function() {} }", + options: ["always", { methodsIgnorePattern: "^foo$" }] + }, + { + code: "var x = { 123: function() {} }", + options: ["always", { methodsIgnorePattern: "^123$" }] + }, + { + code: "var x = { afoob: function() {} }", + options: ["always", { methodsIgnorePattern: "foo" }] + }, + { + code: "var x = { afoob: function() {} }", + options: ["always", { methodsIgnorePattern: "^.foo.$" }] + }, + { + code: "var x = { '👍foo👍': function() {} }", // this wouldn't pass without the "u" flag + options: ["always", { methodsIgnorePattern: "^.foo.$" }] + }, + // avoidQuotes { code: "var x = {'a': function(){}}", @@ -781,6 +827,50 @@ ruleTester.run("object-shorthand", rule, { errors: [METHOD_ERROR] }, + // methodsIgnorePattern + { + code: "var x = { afoob: function() {} }", + output: "var x = { afoob() {} }", + options: ["always", { methodsIgnorePattern: "^foo$" }], + errors: [METHOD_ERROR] + }, + { + code: "var x = { afoob: function() {} }", + output: "var x = { afoob() {} }", + options: ["methods", { methodsIgnorePattern: "^foo$" }], + errors: [METHOD_ERROR] + }, + { + code: "var x = { 'afoob': function() {} }", + output: "var x = { 'afoob'() {} }", + options: ["always", { methodsIgnorePattern: "^foo$" }], + errors: [METHOD_ERROR] + }, + { + code: "var x = { 1234: function() {} }", + output: "var x = { 1234() {} }", + options: ["always", { methodsIgnorePattern: "^123$" }], + errors: [METHOD_ERROR] + }, + { + code: "var x = { bar: function() {} }", + output: "var x = { bar() {} }", + options: ["always", { methodsIgnorePattern: "foo" }], + errors: [METHOD_ERROR] + }, + { + code: "var x = { [foo]: function() {} }", + output: "var x = { [foo]() {} }", + options: ["always", { methodsIgnorePattern: "foo" }], + errors: [METHOD_ERROR] + }, + { + code: "var x = { foo: foo }", // does not apply to properties + output: "var x = { foo }", + options: ["always", { methodsIgnorePattern: "^foo$" }], + errors: [PROPERTY_ERROR] + }, + // avoidQuotes { code: "var x = {a: a}",