1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

Disallow single-line IF expr ELSE without THEN

* Supplement missing block before `ELSE` token only for multi-line `if`.
* Don't prematurely remove `TERMINATOR` before `ELSE` (so we can  differentiate single- and multi-line forms).
* Cleanup: Remove `WHEN` from `EXPRESSION_CLOSE`. (Only `LEADING_WHEN` tokens are preceded by a `TERMINATOR`.)
* Cleanup: Remove really old, inapplicable text from comment.
This commit is contained in:
Marc Häfner 2013-07-30 17:24:46 +02:00
parent f48aa44386
commit fdd5796f5e
3 changed files with 26 additions and 21 deletions

View file

@ -365,19 +365,21 @@
return this.tokens.splice((this.tag(i - 1) === ',' ? i - 1 : i), 0, outdent);
};
return this.scanTokens(function(token, i, tokens) {
var j, tag, _i, _ref, _ref1;
var j, tag, _i, _ref, _ref1, _ref2;
tag = token[0];
if (tag === 'TERMINATOR' && this.tag(i + 1) === 'THEN') {
tokens.splice(i, 1);
return 0;
}
if (tag === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') {
tokens.splice.apply(tokens, [i, 0].concat(__slice.call(this.indentation())));
return 2;
if (tag === 'TERMINATOR') {
if (this.tag(i + 1) === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') {
tokens.splice.apply(tokens, [i, 1].concat(__slice.call(this.indentation())));
return 1;
}
if ((_ref = this.tag(i + 1)) === 'THEN' || _ref === 'ELSE') {
tokens.splice(i, 1);
return 0;
}
}
if (tag === 'CATCH') {
for (j = _i = 1; _i <= 2; j = ++_i) {
if (!((_ref = this.tag(i + j)) === 'OUTDENT' || _ref === 'TERMINATOR' || _ref === 'FINALLY')) {
if (!((_ref1 = this.tag(i + j)) === 'OUTDENT' || _ref1 === 'TERMINATOR' || _ref1 === 'FINALLY')) {
continue;
}
tokens.splice.apply(tokens, [i + j, 0].concat(__slice.call(this.indentation())));
@ -386,7 +388,7 @@
}
if (__indexOf.call(SINGLE_LINERS, tag) >= 0 && this.tag(i + 1) !== 'INDENT' && !(tag === 'ELSE' && this.tag(i + 1) === 'IF')) {
starter = tag;
_ref1 = this.indentation(true), indent = _ref1[0], outdent = _ref1[1];
_ref2 = this.indentation(true), indent = _ref2[0], outdent = _ref2[1];
if (starter === 'THEN') {
indent.fromThen = true;
}
@ -466,7 +468,7 @@
EXPRESSION_END.push(INVERSES[left] = rite);
}
EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END);
EXPRESSION_CLOSE = ['CATCH', 'FINALLY'].concat(EXPRESSION_END);
IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];

View file

@ -355,8 +355,7 @@ class exports.Rewriter
# Because our grammar is LALR(1), it can't handle some single-line
# expressions that lack ending delimiters. The **Rewriter** adds the implicit
# blocks, so it doesn't need to. ')' can close a single-line block,
# but we need to make sure it's balanced.
# blocks, so it doesn't need to.
addImplicitIndentation: ->
starter = indent = outdent = null
@ -370,12 +369,13 @@ class exports.Rewriter
@scanTokens (token, i, tokens) ->
[tag] = token
if tag is 'TERMINATOR' and @tag(i + 1) is 'THEN'
tokens.splice i, 1
return 0
if tag is 'ELSE' and @tag(i - 1) isnt 'OUTDENT'
tokens.splice i, 0, @indentation()...
return 2
if tag is 'TERMINATOR'
if @tag(i + 1) is 'ELSE' and @tag(i - 1) isnt 'OUTDENT'
tokens.splice i, 1, @indentation()...
return 1
if @tag(i + 1) in ['THEN', 'ELSE']
tokens.splice i, 1
return 0
if tag is 'CATCH'
for j in [1..2] when @tag(i + j) in ['OUTDENT', 'TERMINATOR', 'FINALLY']
tokens.splice i + j, 0, @indentation()...
@ -452,7 +452,7 @@ for [left, rite] in BALANCED_PAIRS
EXPRESSION_END .push INVERSES[left] = rite
# Tokens that indicate the close of a clause of an expression.
EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat EXPRESSION_END
EXPRESSION_CLOSE = ['CATCH', 'FINALLY'].concat EXPRESSION_END
# Tokens that, if followed by an `IMPLICIT_CALL`, indicate a function invocation.
IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS']

View file

@ -84,4 +84,7 @@ test "#2944: implicit call with a regex argument", ->
CoffeeScript.compile 'o[key] /regex/'
test "#3001: `own` shouldn't be allowed in a `for`-`in` loop", ->
cantCompile "a for own b in c"
cantCompile "a for own b in c"
test "#2994: single-line `if` requires `then`", ->
cantCompile "if b else x"