Permalink
Browse files

Fixed #1311: Add support for destructuring function parameters (PR #1450

)

Signed-off-by: Anton Kovalyov <anton@kovalyov.net>
  • Loading branch information...
1 parent 61cc5e5 commit 9189c74c6f37cfe07d5ece86d1ebc9289db37536 @arai-a arai-a committed with valueof Jan 26, 2014
Showing with 164 additions and 4 deletions.
  1. +17 −4 src/jshint.js
  2. +31 −0 tests/unit/fixtures/destparam.js
  3. +116 −0 tests/unit/parser.js
View
@@ -2572,13 +2572,22 @@ var JSHINT = (function () {
var bracket, brackets = [];
var pn, pn1, i = 0;
var ret;
+ var parens = 1;
do {
pn = peek(i);
+
+ if (pn.value === "(") {
+ parens += 1;
+ } else if (pn.value === ")") {
+ parens -= 1;
+ }
+
i += 1;
pn1 = peek(i);
i += 1;
- } while (pn.value !== ")" && pn1.value !== "=>" && pn1.value !== ";" && pn1.type !== "(end)");
+ } while (!(parens === 0 && pn.value === ")") &&
+ pn1.value !== "=>" && pn1.value !== ";" && pn1.type !== "(end)");
if (state.tokens.next.id === "function") {
state.tokens.next.immed = true;
@@ -2588,7 +2597,7 @@ var JSHINT = (function () {
if (state.tokens.next.id !== ")") {
for (;;) {
- if (pn1.value === "=>" && state.tokens.next.value === "{") {
+ if (pn1.value === "=>" && _.contains(["{", "["], state.tokens.next.value)) {
bracket = state.tokens.next;
bracket.left = destructuringExpression();
brackets.push(bracket);
@@ -2801,7 +2810,7 @@ var JSHINT = (function () {
if (_.contains(["{", "["], curr.id)) {
for (t in curr.left) {
t = tokens[t];
- if (t.id) {
+ if (t && t.id) {
params.push(t.id);
addlabel(t.id, { type: "unused", token: t.token });
}
@@ -2811,7 +2820,7 @@ var JSHINT = (function () {
warning("W104", curr, "spread/rest operator");
}
continue;
- } else {
+ } else if (curr.value !== ",") {
params.push(curr.value);
addlabel(curr.value, { type: "unused", token: curr });
}
@@ -3299,6 +3308,10 @@ var JSHINT = (function () {
}
} else if (state.tokens.next.value === ",") {
identifiers.push({ id: null, token: state.tokens.curr });
+ } else if (state.tokens.next.value === "(") {
+ advance("(");
+ nextInnerDE();
+ advance(")");
} else {
ident = identifier();
if (ident)
@@ -0,0 +1,31 @@
+var foo;
+
+// array
+foo = ([a, b]) => { return a + b; };
+foo = ([a, ((b))]) => { return a + b; };
+foo = ([a, b], [c, d]) => { return a + b + c + d; };
+foo = ([[[a, b], c], d]) => { return a + b + c + d; };
+
+// array elision
+foo = ([, a, b]) => { return a, b; };
+foo = ([, a, , , b]) => { return a, b; };
+
+// object
+foo = ({a}) => { return a; };
+foo = ({a, b}) => { return a + b; };
+foo = ({a, b: y}, {c}) => { return a + y + c; };
+foo = ({a: x, b: y}) => { return x + y; };
+foo = ({a: (x), b: y}) => { return x + y; };
+
+// array in object
+foo = ({a: [x, y]}) => { return x + y; };
+foo = ({a: [x, y], b: z}) => { return x + y + z; };
+foo = ({a: [x, y], b: z, c}) => { return x + y + z + c; };
+foo = ({a: ([x, y]), b: z, c}) => { return x + y + z + c; };
+
+// object in array
+foo = ([{a}]) => { return a; };
+foo = ([{a, b}]) => { return a + b; };
+foo = ([{a, b: y}]) => { return a + y; };
+foo = ([{a: x, b: y}]) => { return x + y; };
+foo = ([{a: (x), b: y}]) => { return x + y; };
View
@@ -4127,3 +4127,119 @@ exports["jshint ignore:start/end should be detected using single line comments"]
test.done();
};
+
+exports["test destructuring function parameters as es5"] = function (test) {
+ var src = fs.readFileSync(__dirname + "/fixtures/destparam.js", "utf8");
+ TestRun(test)
+ .addError(4, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(4, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(5, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(5, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(6, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(7, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(7, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(7, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(7, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(10, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(10, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(11, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(11, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(14, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(14, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(15, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(15, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(16, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(16, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(16, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(17, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(17, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(18, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(18, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(21, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(21, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(21, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(22, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(22, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(22, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(23, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(23, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(23, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(24, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(24, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(24, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(27, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(27, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(27, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(28, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(28, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(28, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(29, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(29, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(29, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(30, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(30, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(30, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .test(src, {unused: true, undef: true});
+
+ test.done();
+};
+
+exports["test destructuring function parameters as legacy JS"] = function (test) {
+ var src = fs.readFileSync(__dirname + "/fixtures/destparam.js", "utf8");
+ TestRun(test)
+ .addError(4, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(4, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(5, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(5, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(6, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(6, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(7, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(7, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(7, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(7, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(10, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(10, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(11, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(11, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(14, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(14, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(15, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(15, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(16, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(16, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(16, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(17, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(17, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(18, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(18, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(21, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(21, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(21, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(22, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(22, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(22, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(23, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(23, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(23, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(24, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(24, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(24, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(27, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(27, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(27, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(28, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(28, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(28, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(29, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(29, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(29, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(30, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(30, "'destructuring expression' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .addError(30, "'arrow function syntax (=>)' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).")
+ .test(src, {es3: true, unused: true, undef: true});
+
+ test.done();
+};

0 comments on commit 9189c74

Please sign in to comment.