From 5f12ef892e2a106169f38fcde7a6f545364458a0 Mon Sep 17 00:00:00 2001 From: Nick Heiner Date: Tue, 14 Jun 2016 15:07:24 -0400 Subject: [PATCH] New: Add fixer for object-shorthand (fixes #6412) --- lib/rules/object-shorthand.js | 80 +++++++++++++++++++++++++++-- tests/lib/rules/object-shorthand.js | 66 ++++++++++++------------ 2 files changed, 108 insertions(+), 38 deletions(-) diff --git a/lib/rules/object-shorthand.js b/lib/rules/object-shorthand.js index aba2a13b0bf4..8737d7e6ca20 100644 --- a/lib/rules/object-shorthand.js +++ b/lib/rules/object-shorthand.js @@ -23,6 +23,8 @@ module.exports = { recommended: false }, + fixable: "code", + schema: { anyOf: [ { @@ -132,12 +134,36 @@ module.exports = { // if we're "never" and concise we should warn now if (APPLY_NEVER && isConciseProperty) { type = node.method ? "method" : "property"; - context.report(node, "Expected longform " + type + " syntax."); + context.report({ + node: node, + message: "Expected longform " + type + " syntax.", + fix: function(fixer) { + if (node.method) { + if (node.value.generator) { + return fixer.replaceTextRange([node.range[0], node.key.range[1]], node.key.name + ": function*"); + } + + return fixer.insertTextAfter(node.key, ": function"); + } + + return fixer.insertTextAfter(node.key, ": " + node.key.name); + } + }); } // {'xyz'() {}} should be written as {'xyz': function() {}} if (AVOID_QUOTES && isStringLiteral(node.key) && isConciseProperty) { - context.report(node, "Expected longform method syntax for string literal keys."); + context.report({ + node: node, + message: "Expected longform method syntax for string literal keys.", + fix: function(fixer) { + if (node.computed) { + return fixer.insertTextAfterRange([node.key.range[0], node.key.range[1] + 1], ": function"); + } + + return fixer.insertTextAfter(node.key, ": function"); + } + }); } // at this point if we're concise or if we're "never" we can leave @@ -160,16 +186,60 @@ module.exports = { return; } + // {[x]: function(){}} should be written as {[x]() {}} + if (node.computed) { + context.report({ + node: node, + message: "Expected method shorthand.", + fix: function(fixer) { + if (node.value.generator) { + return fixer.replaceTextRange( + [node.key.range[0], node.value.range[0] + "function*".length], + "*[" + node.key.name + "]" + ); + } + + return fixer.removeRange([node.key.range[1] + 1, node.value.range[0] + "function".length]); + } + }); + return; + } + // {x: function(){}} should be written as {x() {}} - context.report(node, "Expected method shorthand."); + context.report({ + node: node, + message: "Expected method shorthand.", + fix: function(fixer) { + if (node.value.generator) { + return fixer.replaceTextRange( + [node.key.range[0], node.value.range[0] + "function*".length], + "*" + node.key.name + ); + } + + return fixer.removeRange([node.key.range[1], node.value.range[0] + "function".length]); + } + }); } else if (node.value.type === "Identifier" && node.key.name === node.value.name && APPLY_TO_PROPS) { // {x: x} should be written as {x} - context.report(node, "Expected property shorthand."); + context.report({ + node: node, + message: "Expected property shorthand.", + fix: function(fixer) { + return fixer.replaceText(node, node.value.name); + } + }); } else if (node.value.type === "Identifier" && node.key.type === "Literal" && node.key.value === node.value.name && APPLY_TO_PROPS) { // {"x": x} should be written as {x} - context.report(node, "Expected property shorthand."); + context.report({ + node: node, + message: "Expected property shorthand.", + fix: function(fixer) { + return fixer.replaceText(node, node.value.name); + } + }); } } }; diff --git a/tests/lib/rules/object-shorthand.js b/tests/lib/rules/object-shorthand.js index 561cb3ee96b9..472bafcc35d9 100644 --- a/tests/lib/rules/object-shorthand.js +++ b/tests/lib/rules/object-shorthand.js @@ -96,40 +96,40 @@ ruleTester.run("object-shorthand", rule, { { code: "let {a, b} = o;", parserOptions: { ecmaVersion: 6 }, options: ["never"] } ], invalid: [ - { code: "var x = {x: x}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }] }, - { code: "var x = {'x': x}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }] }, - { code: "var x = {y: y, x: x}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }, { message: "Expected property shorthand.", type: "Property" }] }, - { code: "var x = {y: z, x: x, a: b}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }] }, - { code: "var x = {y: function() {}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }] }, - { code: "var x = {y: function*() {}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }] }, - { code: "var x = {x: y, y: z, a: a}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }] }, - { code: "var x = {ConstructorFunction: function(){}, a: b}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }] }, - { code: "var x = {x: y, y: z, a: function(){}, b() {}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }] }, - { code: "var x = {x: x, y: function() {}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }, { message: "Expected method shorthand.", type: "Property" }]}, - { code: "doSomething({x: x})", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }] }, - { code: "doSomething({'x': x})", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }] }, - { code: "doSomething({a: 'a', 'x': x})", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }] }, - { code: "doSomething({y: function() {}})", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }] }, - { code: "doSomething({[y]: function() {}})", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }] }, - { code: "doSomething({['y']: function() {}})", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }] }, + { code: "var x = {x: x}", output: "var x = {x}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }] }, + { code: "var x = {'x': x}", output: "var x = {x}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }] }, + { code: "var x = {y: y, x: x}", output: "var x = {y, x}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }, { message: "Expected property shorthand.", type: "Property" }] }, + { code: "var x = {y: z, x: x, a: b}", output: "var x = {y: z, x, a: b}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }] }, + { code: "var x = {y: function() {}}", output: "var x = {y() {}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }] }, + { code: "var x = {y: function*() {}}", output: "var x = {*y() {}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }] }, + { code: "var x = {x: y, y: z, a: a}", output: "var x = {x: y, y: z, a}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }] }, + { code: "var x = {ConstructorFunction: function(){}, a: b}", output: "var x = {ConstructorFunction(){}, a: b}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }] }, + { code: "var x = {x: y, y: z, a: function(){}, b() {}}", output: "var x = {x: y, y: z, a(){}, b() {}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }] }, + { code: "var x = {x: x, y: function() {}}", output: "var x = {x, y() {}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }, { message: "Expected method shorthand.", type: "Property" }]}, + { code: "doSomething({x: x})", output: "doSomething({x})", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }] }, + { code: "doSomething({'x': x})", output: "doSomething({x})", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }] }, + { code: "doSomething({a: 'a', 'x': x})", output: "doSomething({a: 'a', x})", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }] }, + { code: "doSomething({y: function() {}})", output: "doSomething({y() {}})", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }] }, + { code: "doSomething({[y]: function() {}})", output: "doSomething({[y]() {}})", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }] }, + { code: "doSomething({['y']: function() {}})", output: "doSomething({['y']() {}})", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }] }, // options - { code: "var x = {y: function() {}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }], options: ["methods"] }, - { code: "var x = {x, y() {}, z: function() {}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }], options: ["methods"] }, - { code: "var x = {ConstructorFunction: function(){}, a: b}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }], options: ["methods"] }, - { code: "var x = {[y]: function() {}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }], options: ["methods"] }, - { code: "var x = {x: x}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }], options: ["properties"] }, - { code: "var x = {a, b, c(){}, x: x}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }], options: ["properties"] }, - { code: "var x = {y() {}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected longform method syntax.", type: "Property" }], options: ["never"] }, - { code: "var x = {*y() {}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected longform method syntax.", type: "Property" }], options: ["never"] }, - { code: "var x = {y}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected longform property syntax.", type: "Property" }], options: ["never"]}, - { code: "var x = {y, a: b, *x(){}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected longform property syntax.", type: "Property" }, { message: "Expected longform method syntax.", type: "Property" }], options: ["never"]}, - { code: "var x = {y: {x}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected longform property syntax.", type: "Property" }], options: ["never"]}, - { code: "var x = {ConstructorFunction(){}, a: b}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected longform method syntax.", type: "Property" }], options: ["never"] }, - { code: "var x = {notConstructorFunction(){}, b: c}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected longform method syntax.", type: "Property" }], options: ["never"] }, - - // avoidQuotes - { code: "var x = {'a'(){}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected longform method syntax for string literal keys.", type: "Property" }], options: ["always", {avoidQuotes: true}] }, - { code: "var x = {['a'](){}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected longform method syntax for string literal keys.", type: "Property" }], options: ["methods", {avoidQuotes: true}] } + { code: "var x = {y: function() {}}", output: "var x = {y() {}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }], options: ["methods"] }, + { code: "var x = {x, y() {}, z: function() {}}", output: "var x = {x, y() {}, z() {}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }], options: ["methods"] }, + { code: "var x = {ConstructorFunction: function(){}, a: b}", output: "var x = {ConstructorFunction(){}, a: b}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }], options: ["methods"] }, + { code: "var x = {[y]: function() {}}", output: "var x = {[y]() {}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected method shorthand.", type: "Property" }], options: ["methods"] }, + { code: "var x = {x: x}", output: "var x = {x}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }], options: ["properties"] }, + { code: "var x = {a, b, c(){}, x: x}", output: "var x = {a, b, c(){}, x}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected property shorthand.", type: "Property" }], options: ["properties"] }, + { code: "var x = {y() {}}", output: "var x = {y: function() {}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected longform method syntax.", type: "Property" }], options: ["never"] }, + { code: "var x = {*y() {}}", output: "var x = {y: function*() {}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected longform method syntax.", type: "Property" }], options: ["never"] }, + { code: "var x = {y}", output: "var x = {y: y}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected longform property syntax.", type: "Property" }], options: ["never"]}, + { code: "var x = {y, a: b, *x(){}}", output: "var x = {y: y, a: b, x: function*(){}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected longform property syntax.", type: "Property" }, { message: "Expected longform method syntax.", type: "Property" }], options: ["never"]}, + { code: "var x = {y: {x}}", output: "var x = {y: {x: x}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected longform property syntax.", type: "Property" }], options: ["never"]}, + { code: "var x = {ConstructorFunction(){}, a: b}", output: "var x = {ConstructorFunction: function(){}, a: b}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected longform method syntax.", type: "Property" }], options: ["never"] }, + { code: "var x = {notConstructorFunction(){}, b: c}", output: "var x = {notConstructorFunction: function(){}, b: c}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected longform method syntax.", type: "Property" }], options: ["never"] }, + + // // avoidQuotes + { code: "var x = {'a'(){}}", output: "var x = {'a': function(){}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected longform method syntax for string literal keys.", type: "Property" }], options: ["always", {avoidQuotes: true}] }, + { code: "var x = {['a'](){}}", output: "var x = {['a']: function(){}}", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Expected longform method syntax for string literal keys.", type: "Property" }], options: ["methods", {avoidQuotes: true}] } ] });