Skip to content

Commit

Permalink
Fix: support Rest/Spread Properties (fixes #9885)
Browse files Browse the repository at this point in the history
  • Loading branch information
mysticatea committed Feb 5, 2018
1 parent 2af9446 commit 41df283
Show file tree
Hide file tree
Showing 19 changed files with 736 additions and 59 deletions.
5 changes: 3 additions & 2 deletions lib/rules/key-spacing.js
Expand Up @@ -360,9 +360,10 @@ module.exports = {
*/
function isKeyValueProperty(property) {
return !(
(property.method ||
property.method ||
property.shorthand ||
property.kind !== "init" || property.type !== "Property") // Could be "ExperimentalSpreadProperty" or "SpreadProperty"
property.kind !== "init" ||
property.type !== "Property" // Could be "ExperimentalSpreadProperty" or "SpreadElement"
);
}

Expand Down
4 changes: 3 additions & 1 deletion lib/rules/no-self-assign.js
Expand Up @@ -121,7 +121,9 @@ function eachSelfAssignment(left, right, props, report) {
let startJ = 0;

for (let i = right.properties.length - 1; i >= 0; --i) {
if (right.properties[i].type === "ExperimentalSpreadProperty") {
const propType = right.properties[i].type;

if (propType === "SpreadElement" || propType === "ExperimentalSpreadProperty") {
startJ = i + 1;
break;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/no-unused-vars.js
Expand Up @@ -65,7 +65,7 @@ module.exports = {
create(context) {
const sourceCode = context.getSourceCode();

const REST_PROPERTY_TYPE = /^(?:Experimental)?RestProperty$/;
const REST_PROPERTY_TYPE = /^(?:RestElement|(?:Experimental)?RestProperty)$/;

const config = {
vars: "all",
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/object-shorthand.js
Expand Up @@ -131,7 +131,7 @@ module.exports = {
*
*/
function canHaveShorthand(property) {
return (property.kind !== "set" && property.kind !== "get" && property.type !== "SpreadProperty" && property.type !== "ExperimentalSpreadProperty");
return (property.kind !== "set" && property.kind !== "get" && property.type !== "SpreadElement" && property.type !== "SpreadProperty" && property.type !== "ExperimentalSpreadProperty");
}

/**
Expand Down
6 changes: 6 additions & 0 deletions lib/rules/rest-spread-spacing.js
Expand Up @@ -47,9 +47,15 @@ module.exports = {
switch (node.type) {
case "SpreadElement":
type = "spread";
if (node.parent.type === "ObjectExpression") {
type += " property";
}
break;
case "RestElement":
type = "rest";
if (node.parent.type === "ObjectPattern") {
type += " property";
}
break;
case "ExperimentalSpreadProperty":
type = "spread property";
Expand Down
5 changes: 5 additions & 0 deletions tests/lib/rules/comma-dangle.js
Expand Up @@ -134,6 +134,11 @@ ruleTester.run("comma-dangle", rule, {
options: ["always"],
parserOptions: { ecmaVersion: 8, ecmaFeatures: { experimentalObjectRestSpread: true } }
},
{
code: "var {foo, ...bar} = baz",
options: ["always"],
parserOptions: { ecmaVersion: 2018 }
},

// https://github.com/eslint/eslint/issues/3794
{
Expand Down
150 changes: 134 additions & 16 deletions tests/lib/rules/key-spacing.js
Expand Up @@ -383,6 +383,78 @@ ruleTester.run("key-spacing", rule, {
align: "colon"
}],
parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } }
}, {
code: "({a : foo, ...x, b : bar})['a'];",
options: [{
beforeColon: true,
afterColon: true
}],
parserOptions: { ecmaVersion: 2018 }
}, {
code: [
"var obj = {",
" 'a' : (42 - 12),",
" ...x,",
" foobar : 'value',",
" [(expr)]: val",
"};"
].join("\n"),
options: [{
align: "colon"
}],
parserOptions: { ecmaVersion: 2018 }
}, {
code: [
"callExpr(arg, {",
" key :val,",
" ...x,",
" ...y,",
" 'another' :false,",
" [compute] :'value'",
"});"
].join("\n"),
options: [{
align: "colon",
beforeColon: true,
afterColon: false
}],
parserOptions: { ecmaVersion: 2018 }
}, {
code: [
"var obj = {",
" a: (42 - 12),",
" ...x,",
" 'foobar': 'value',",
" bat: function() {",
" return this.a;",
" },",
" baz: 42",
"};"
].join("\n"),
options: [{
align: "value"
}],
parserOptions: { ecmaVersion: 2018 }
}, {
code: [
"({",
" ...x,",
" a : 0,",
" // same group",
" bcd: 0, /*",
" end of group */",
"",
" // different group",
" e: 0,",
" ...y,",
" /* group b */",
" f: 0",
"})"
].join("\n"),
options: [{
align: "colon"
}],
parserOptions: { ecmaVersion: 2018 }
},

// https://github.com/eslint/eslint/issues/4792
Expand Down Expand Up @@ -524,7 +596,7 @@ ruleTester.run("key-spacing", rule, {
beforeColon: true,
afterColon: false
}],
parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } }
parserOptions: { ecmaVersion: 6 }
}, {
code: [
"({",
Expand All @@ -543,7 +615,7 @@ ruleTester.run("key-spacing", rule, {
beforeColon: true,
afterColon: false
}],
parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } }
parserOptions: { ecmaVersion: 6 }
}, {
code: [
"({",
Expand All @@ -561,7 +633,7 @@ ruleTester.run("key-spacing", rule, {
}
}
}],
parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } }
parserOptions: { ecmaVersion: 6 }
}, {
code: [
"({",
Expand All @@ -577,7 +649,7 @@ ruleTester.run("key-spacing", rule, {
afterColon: false
}
}],
parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } },
parserOptions: { ecmaVersion: 6 },
errors: []
}, {
code: [
Expand All @@ -595,7 +667,7 @@ ruleTester.run("key-spacing", rule, {
mode: "minimum"
}
}],
parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } }
parserOptions: { ecmaVersion: 6 }
}, {
code: [
"({",
Expand All @@ -613,7 +685,7 @@ ruleTester.run("key-spacing", rule, {
}
}
}],
parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } }
parserOptions: { ecmaVersion: 6 }
}, {
code: [
"({",
Expand Down Expand Up @@ -647,7 +719,7 @@ ruleTester.run("key-spacing", rule, {
afterColon: true
}
}],
parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } }
parserOptions: { ecmaVersion: 6 }
}, {
code: [
"({",
Expand Down Expand Up @@ -678,7 +750,7 @@ ruleTester.run("key-spacing", rule, {
afterColon: true
}
}],
parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } }
parserOptions: { ecmaVersion: 6 }
}, {
code: [
"({",
Expand Down Expand Up @@ -706,7 +778,7 @@ ruleTester.run("key-spacing", rule, {
afterColon: false
}
}],
parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } }
parserOptions: { ecmaVersion: 6 }
}, {
code: [
"var obj = {",
Expand All @@ -731,7 +803,7 @@ ruleTester.run("key-spacing", rule, {
}
}
}],
parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } }
parserOptions: { ecmaVersion: 6 }
}, {
code: [
"var obj = {",
Expand All @@ -756,7 +828,7 @@ ruleTester.run("key-spacing", rule, {
mode: "minimum"
}
}],
parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } }
parserOptions: { ecmaVersion: 6 }
}],

invalid: [{
Expand Down Expand Up @@ -1323,6 +1395,43 @@ ruleTester.run("key-spacing", rule, {
{ message: "Missing space after key 'a'.", line: 3, column: 5, type: "Identifier" },
{ message: "Extra space after key 'f'.", line: 12, column: 5, type: "Identifier" }
]
}, {
code: [
"({",
" ...x,",
" a : 0,",
" // same group",
" bcd: 0, /*",
" end of group */",
"",
" // different group",
" e: 0,",
" ...y,",
" /* group b */",
" f : 0",
"})"
].join("\n"),
output: [
"({",
" ...x,",
" a : 0,",
" // same group",
" bcd: 0, /*",
" end of group */",
"",
" // different group",
" e: 0,",
" ...y,",
" /* group b */",
" f: 0",
"})"
].join("\n"),
options: [{ align: "colon" }],
parserOptions: { ecmaVersion: 2018 },
errors: [
{ message: "Missing space after key 'a'.", line: 3, column: 5, type: "Identifier" },
{ message: "Extra space after key 'f'.", line: 12, column: 5, type: "Identifier" }
]
},

// https://github.com/eslint/eslint/issues/4792
Expand Down Expand Up @@ -1541,6 +1650,15 @@ ruleTester.run("key-spacing", rule, {
{ message: "Missing space before value for key 'a'.", line: 1, column: 6, type: "Identifier" },
{ message: "Extra space after key 'c'.", line: 1, column: 20, type: "Identifier" }
]
}, {
code: "({ a:b, ...object, c : d })",
output: "({ a: b, ...object, c: d })",
options: [{ align: "colon" }],
parserOptions: { ecmaVersion: 2018 },
errors: [
{ message: "Missing space before value for key 'a'.", line: 1, column: 6, type: "Identifier" },
{ message: "Extra space after key 'c'.", line: 1, column: 20, type: "Identifier" }
]
},

// https://github.com/eslint/eslint/issues/5613
Expand All @@ -1567,7 +1685,7 @@ ruleTester.run("key-spacing", rule, {
mode: "strict"
}
}],
parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } },
parserOptions: { ecmaVersion: 6 },
errors: [
{ message: "Missing space after key 'longName'.", line: 2, column: 5, type: "Identifier" },
{ message: "Missing space before value for key 'longName'.", line: 2, column: 14, type: "Literal" },
Expand Down Expand Up @@ -1615,7 +1733,7 @@ ruleTester.run("key-spacing", rule, {
mode: "strict"
}
}],
parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } },
parserOptions: { ecmaVersion: 6 },
errors: [
{ message: "Missing space before value for key 'func'.", line: 2, column: 10, type: "FunctionExpression" },
{ message: "Missing space after key 'longName'.", line: 5, column: 5, type: "Identifier" },
Expand Down Expand Up @@ -1664,7 +1782,7 @@ ruleTester.run("key-spacing", rule, {
}
}
}],
parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } },
parserOptions: { ecmaVersion: 6 },
errors: [
{ message: "Missing space before value for key 'func'.", line: 2, column: 10, type: "FunctionExpression" },
{ message: "Missing space after key 'small'.", line: 6, column: 5, type: "Identifier" },
Expand Down Expand Up @@ -1706,7 +1824,7 @@ ruleTester.run("key-spacing", rule, {
}
}
}],
parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } },
parserOptions: { ecmaVersion: 6 },
errors: [
{ message: "Extra space before value for key 'key2'.", line: 4, column: 14, type: "Literal" },
{ message: "Extra space before value for key 'key3'.", line: 5, column: 14, type: "Literal" }
Expand Down Expand Up @@ -1744,7 +1862,7 @@ ruleTester.run("key-spacing", rule, {
on: "colon"
}
}],
parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } },
parserOptions: { ecmaVersion: 6 },
errors: [
{ message: "Extra space before value for key 'key2'.", line: 4, column: 14, type: "Literal" },
{ message: "Extra space before value for key 'key3'.", line: 5, column: 14, type: "Literal" }
Expand Down
1 change: 1 addition & 0 deletions tests/lib/rules/no-dupe-keys.js
Expand Up @@ -25,6 +25,7 @@ ruleTester.run("no-dupe-keys", rule, {
"+{ get a() { }, set a(b) { } };",
{ code: "var x = { a: b, [a]: b };", parserOptions: { ecmaVersion: 6 } },
{ code: "var x = { a: b, ...c }", parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } } },
{ code: "var x = { a: b, ...c }", parserOptions: { ecmaVersion: 2018 } },
{ code: "var x = { get a() {}, set a (value) {} };", parserOptions: { ecmaVersion: 6 } },
{ code: "var x = { a: 1, b: { a: 2 } };", parserOptions: { ecmaVersion: 6 } },
{ code: "var {a, a} = obj", parserOptions: { ecmaVersion: 6 } }
Expand Down

0 comments on commit 41df283

Please sign in to comment.