Skip to content

Commit

Permalink
New: Add fixer for object-shorthand (fixes eslint#6412)
Browse files Browse the repository at this point in the history
  • Loading branch information
NickHeiner committed Jun 15, 2016
1 parent 9ea4e44 commit 536c094
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 38 deletions.
80 changes: 75 additions & 5 deletions lib/rules/object-shorthand.js
Expand Up @@ -23,6 +23,8 @@ module.exports = {
recommended: false
},

fixable: "code",

schema: {
anyOf: [
{
Expand Down Expand Up @@ -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
Expand All @@ -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);
}
});
}
}
};
Expand Down
67 changes: 34 additions & 33 deletions tests/lib/rules/object-shorthand.js
Expand Up @@ -96,40 +96,41 @@ 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: z,\n x: x,\n a: b\n // comment \n}", output: "var x = {y: z,\n x,\n a: b\n // comment \n}", 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}] }
]
});

0 comments on commit 536c094

Please sign in to comment.