Skip to content

Commit

Permalink
[[FIX]] Correct invalid function invocation
Browse files Browse the repository at this point in the history
The second parameter of the `expression` function accepts a value that
modifies how the next token is parsed. When set to `true`, the token is
interpreted as the beginning of a statement; otherwise, it is
interpreted as the beginning of an expression.

Two call sites within the `for` statement's parsing logic specified the
string value `"for"`. Due to inconsistencies in how the parameter was
interpreted internally, this causes `expression` to mix parsing
strategies. Specifically:

- It used the "statement" parsing strategy to mark the token value as
  beginning a statement. This could be observed in the application of
  the `singleGroups` linting option. Further, it disqualify it for
  consideration as a Mozilla "let expression"
- It used the "expression" parsing strategy to ignore the token's `fud`
  method

Since the grammar does not allow a statement in either location, the
"expression" parsing strategy should be used consistently.

Achieve this by removing the argument from the call site, thereby
falling back to the default behavior of the `expression` function.
Update `expression` to consistently interpret the parameter for
"truthiness" in order to discourage similar ambiguity in the future.
  • Loading branch information
jugglinmike committed Dec 23, 2018
1 parent 58967ea commit cda02ae
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 7 deletions.
6 changes: 3 additions & 3 deletions src/jshint.js
Expand Up @@ -924,7 +924,7 @@ var JSHINT = (function() {
state.tokens.curr.beginsStmt = true;
}

if (initial === true && state.tokens.curr.fud) {
if (initial && state.tokens.curr.fud) {
left = state.tokens.curr.fud();
} else {
if (state.tokens.curr.nud) {
Expand Down Expand Up @@ -4514,7 +4514,7 @@ var JSHINT = (function() {
state.tokens.curr.fud();
} else {
for (;;) {
expression(0, "for");
expression(0);
if (state.tokens.next.id !== ",") {
break;
}
Expand All @@ -4538,7 +4538,7 @@ var JSHINT = (function() {
}
if (state.tokens.next.id !== ")") {
for (;;) {
expression(0, "for");
expression(0);
if (state.tokens.next.id !== ",") {
break;
}
Expand Down
12 changes: 10 additions & 2 deletions tests/unit/options.js
Expand Up @@ -3330,13 +3330,17 @@ singleGroups.objectLiterals = function (test) {
// Invalid forms
"var a = ({}).method();",
"if (({}).method()) {}",
"var b = { a: ({}).method() };"
"var b = { a: ({}).method() };",
"for (({}); ;) {}",
"for (; ;({})) {}"
];

TestRun(test, "grouping operator not required")
.addError(4, 9, "Unnecessary grouping operator.")
.addError(5, 5, "Unnecessary grouping operator.")
.addError(6, 14, "Unnecessary grouping operator.")
.addError(7, 6, "Unnecessary grouping operator.")
.addError(8, 9, "Unnecessary grouping operator.")
.test(code, { singleGroups: true });

test.done();
Expand Down Expand Up @@ -3458,13 +3462,17 @@ singleGroups.destructuringAssign = function (test) {
"([ x ] = [ 1 ]);",
// expressions
"1, ({ x } = { x : 1 });",
"1, ([ x ] = [ 1 ]);"
"1, ([ x ] = [ 1 ]);",
"for (({ x } = { X: 1 }); ;) {}",
"for (; ;({ x } = { X: 1 })) {}"
];

TestRun(test)
.addError(2, 1, "Unnecessary grouping operator.")
.addError(3, 4, "Unnecessary grouping operator.")
.addError(4, 4, "Unnecessary grouping operator.")
.addError(5, 6, "Unnecessary grouping operator.")
.addError(6, 9, "Unnecessary grouping operator.")
.test(code, { esversion: 6, singleGroups: true, expr: true });

test.done();
Expand Down
8 changes: 6 additions & 2 deletions tests/unit/parser.js
Expand Up @@ -3148,7 +3148,8 @@ exports["let block and let expression"] = function (test) {
"{",
" let(t=4) print(x, y, z, t);",
" print(let(u=4) u,x);",
"}"
"}",
"for (; ; let (x = 1) x) {}"
];

TestRun(test)
Expand All @@ -3163,14 +3164,17 @@ exports["let block and let expression as esnext"] = function (test) {
"{",
" let(t=4) print(x, y, z, t);",
" print(let(u=4) u,x);",
"}"
"}",
"for (; ; let (x = 1) x) {}"
];

TestRun(test)
.addError(1, 5, "'let block' is only available in Mozilla JavaScript extensions (use moz option).")
.addError(3, 6, "'let block' is only available in Mozilla JavaScript extensions (use moz option).")
.addError(4, 9, "'let expressions' is only available in Mozilla JavaScript extensions " +
"(use moz option).")
.addError(6, 10, "'let expressions' is only available in Mozilla JavaScript extensions " +
"(use moz option).")
.test(code, {esnext: true, unused: true, undef: true, predef: ["print"]});
test.done();
};
Expand Down

0 comments on commit cda02ae

Please sign in to comment.