From e608f03c7173e57fc3d2d07645977ad70e44505e Mon Sep 17 00:00:00 2001 From: CarlEkerot Date: Wed, 1 Aug 2012 11:04:19 +0200 Subject: [PATCH] Fix for issue #565. Makes blocks a special case of statements. This fix also prevents jshint from crashing due to unmatched curly-brackets in many cases (such as 'expected {, was (end)' in tests/unit/fixtures/comma.js) --- jshint.js | 8 +++++++- tests/unit/fixtures/blocks.js | 26 ++++++++++++++++++++++++++ tests/unit/parser.js | 21 +++++++++++++++++++-- 3 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 tests/unit/fixtures/blocks.js diff --git a/jshint.js b/jshint.js index 47ac9658a5..fce8b8164a 100644 --- a/jshint.js +++ b/jshint.js @@ -2531,7 +2531,7 @@ loop: for (;;) { advance(":"); scope = Object.create(s); addlabel(t.value, "label"); - if (!nexttoken.labelled) { + if (!nexttoken.labelled && nexttoken.value !== "{") { warning("Label '{a}' on {b} statement.", nexttoken, t.value, nexttoken.value); } @@ -2543,6 +2543,12 @@ loop: for (;;) { t = nexttoken; } +// Is it a lonely block? + if (t.id === "{") { + block(true, true); + return; + } + // Parse the statement. if (!noindent) { diff --git a/tests/unit/fixtures/blocks.js b/tests/unit/fixtures/blocks.js new file mode 100644 index 0000000000..9e156752aa --- /dev/null +++ b/tests/unit/fixtures/blocks.js @@ -0,0 +1,26 @@ +var a, b, c; +a = 1; +{ + b = 2; + { + c = 7; + } + set_to_three: { + a = 3; + } + count: + for (var i = 1; i <= 3; ++i) { + a += i; + } + switchStmt: + switch (a) { + case 0: b = 1; break; + case 1: b = 0; break; + default: b = 2; break; + } +} +c = 3; + +labeledBlock: { + c += a + b; +} diff --git a/tests/unit/parser.js b/tests/unit/parser.js index 0e281246da..26b6ab2c90 100644 --- a/tests/unit/parser.js +++ b/tests/unit/parser.js @@ -333,10 +333,21 @@ exports.comma = function () { .addError(6, 'Expected an identifier and instead saw \')\'.') .addError(6, 'Expected an assignment or function call and instead saw an expression.') .addError(6, 'Missing semicolon.') - .addError(6, 'Expected to see a statement and instead saw a block.') + //.addError(6, 'Expected to see a statement and instead saw a block.') .addError(6, 'Expected an assignment or function call and instead saw an expression.') .addError(6, 'Missing semicolon.') - .addError(8, 'Expected \'(end)\' and instead saw \'}\'.') + //.addError(8, 'Expected \'(end)\' and instead saw \'}\'.') + .addError(15, 'Expected an assignment or function call and instead saw an expression.') + .addError(15, 'Missing semicolon.') + .addError(20, 'Expected \')\' to match \'(\' from line 20 and instead saw \',\'.') + .addError(20, 'Expected an assignment or function call and instead saw an expression.') + .addError(20, 'Missing semicolon.') + .addError(20, 'Expected an identifier and instead saw \')\'.') + .addError(30, 'Expected \')\' to match \'(\' from line 30 and instead saw \',\'.') + .addError(30, 'Expected \')\' and instead saw \'args\'.') + .addError(30, 'Expected an assignment or function call and instead saw an expression.') + .addError(30, 'Missing semicolon.') + .addError(30, 'Expected an identifier and instead saw \')\'.') .test(src); }; @@ -361,6 +372,12 @@ exports.withStatement = function () { .test(src, {white: true, withstmt: true}); }; +exports.blocks = function () { + var src = fs.readFileSync(__dirname + "/fixtures/blocks.js", "utf8"); + + TestRun().test(src); +}; + exports.functionCharaterLocation = function () { var i; var src = fs.readFileSync(__dirname + "/fixtures/nestedFunctions.js", "utf8");