mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
* indent closes implicit object [Fixes #4564] * add test for just implicit object * remove stray lib file
This commit is contained in:
parent
9a48566b24
commit
5e90b224c2
3 changed files with 43 additions and 16 deletions
|
@ -1,6 +1,6 @@
|
|||
// Generated by CoffeeScript 2.0.0-beta2
|
||||
(function() {
|
||||
var BALANCED_PAIRS, CALL_CLOSERS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, Rewriter, SINGLE_CLOSERS, SINGLE_LINERS, generate, k, left, len, rite, throwSyntaxError,
|
||||
var BALANCED_PAIRS, CALL_CLOSERS, CONTROL_IN_IMPLICIT, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, Rewriter, SINGLE_CLOSERS, SINGLE_LINERS, generate, k, left, len, rite, throwSyntaxError,
|
||||
indexOf = [].indexOf;
|
||||
|
||||
({throwSyntaxError} = require('./helpers'));
|
||||
|
@ -255,7 +255,7 @@
|
|||
}
|
||||
return this.looksObjectish(nextTerminatorIdx + 1);
|
||||
};
|
||||
if (inImplicitCall() && (tag === 'IF' || tag === 'TRY' || tag === 'FINALLY' || tag === 'CATCH' || tag === 'CLASS' || tag === 'SWITCH')) {
|
||||
if ((inImplicitCall() || inImplicitObject()) && indexOf.call(CONTROL_IN_IMPLICIT, tag) >= 0 || inImplicitObject() && prevTag === ':' && tag === 'FOR') {
|
||||
stack.push([
|
||||
'CONTROL', i, {
|
||||
ours: true
|
||||
|
@ -265,8 +265,12 @@
|
|||
}
|
||||
if (tag === 'INDENT' && inImplicit()) {
|
||||
if (prevTag !== '=>' && prevTag !== '->' && prevTag !== '[' && prevTag !== '(' && prevTag !== ',' && prevTag !== '{' && prevTag !== 'ELSE' && prevTag !== '=') {
|
||||
while (inImplicitCall()) {
|
||||
endImplicitCall();
|
||||
while (inImplicitCall() || inImplicitObject() && prevTag !== ':') {
|
||||
if (inImplicitCall()) {
|
||||
endImplicitCall();
|
||||
} else {
|
||||
endImplicitObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (inImplicitControl()) {
|
||||
|
@ -318,7 +322,6 @@
|
|||
while (this.tag(s - 2) === 'HERECOMMENT') {
|
||||
s -= 2;
|
||||
}
|
||||
this.insideForDeclaration = nextTag === 'FOR';
|
||||
startsLine = s === 0 || (ref = this.tag(s - 1), indexOf.call(LINEBREAKS, ref) >= 0) || tokens[s - 1].newLine;
|
||||
if (stackTop()) {
|
||||
[stackTag, stackIdx] = stackTop();
|
||||
|
@ -343,7 +346,7 @@
|
|||
[stackTag, stackIdx, {sameLine, startsLine}] = stackTop();
|
||||
if (inImplicitCall() && prevTag !== ',') {
|
||||
endImplicitCall();
|
||||
} else if (inImplicitObject() && !this.insideForDeclaration && sameLine && tag !== 'TERMINATOR' && prevTag !== ':' && !(tag === 'POST_IF' && startsLine && implicitObjectContinues(i + 1))) {
|
||||
} else if (inImplicitObject() && sameLine && tag !== 'TERMINATOR' && prevTag !== ':' && !(tag === 'POST_IF' && startsLine && implicitObjectContinues(i + 1))) {
|
||||
endImplicitObject();
|
||||
} else if (inImplicitObject() && tag === 'TERMINATOR' && prevTag !== ',' && !(startsLine && this.looksObjectish(i + 1))) {
|
||||
if (nextTag === 'HERECOMMENT') {
|
||||
|
@ -355,7 +358,7 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
if (tag === ',' && !this.looksObjectish(i + 1) && inImplicitObject() && !this.insideForDeclaration && (nextTag !== 'TERMINATOR' || !this.looksObjectish(i + 2))) {
|
||||
if (tag === ',' && !this.looksObjectish(i + 1) && inImplicitObject() && (nextTag !== 'TERMINATOR' || !this.looksObjectish(i + 2))) {
|
||||
offset = nextTag === 'OUTDENT' ? 1 : 0;
|
||||
while (inImplicitObject()) {
|
||||
endImplicitObject(i + offset);
|
||||
|
@ -558,4 +561,6 @@
|
|||
|
||||
CALL_CLOSERS = ['.', '?.', '::', '?::'];
|
||||
|
||||
CONTROL_IN_IMPLICIT = ['IF', 'TRY', 'FINALLY', 'CATCH', 'CLASS', 'SWITCH'];
|
||||
|
||||
}).call(this);
|
||||
|
|
|
@ -192,9 +192,11 @@ exports.Rewriter = class Rewriter
|
|||
return no unless nextTerminatorIdx?
|
||||
@looksObjectish nextTerminatorIdx + 1
|
||||
|
||||
# Don't end an implicit call on next indent if any of these are in an argument
|
||||
if inImplicitCall() and tag in ['IF', 'TRY', 'FINALLY', 'CATCH',
|
||||
'CLASS', 'SWITCH']
|
||||
# Don't end an implicit call/object on next indent if any of these are in an argument/value
|
||||
if (
|
||||
(inImplicitCall() or inImplicitObject()) and tag in CONTROL_IN_IMPLICIT or
|
||||
inImplicitObject() and prevTag is ':' and tag is 'FOR'
|
||||
)
|
||||
stack.push ['CONTROL', i, ours: yes]
|
||||
return forward(1)
|
||||
|
||||
|
@ -206,7 +208,11 @@ exports.Rewriter = class Rewriter
|
|||
# 2. The last token before the indent is part of the list below
|
||||
#
|
||||
if prevTag not in ['=>', '->', '[', '(', ',', '{', 'ELSE', '=']
|
||||
endImplicitCall() while inImplicitCall()
|
||||
while inImplicitCall() or inImplicitObject() and prevTag isnt ':'
|
||||
if inImplicitCall()
|
||||
endImplicitCall()
|
||||
else
|
||||
endImplicitObject()
|
||||
stack.pop() if inImplicitControl()
|
||||
stack.push [tag, i]
|
||||
return forward(1)
|
||||
|
@ -273,9 +279,6 @@ exports.Rewriter = class Rewriter
|
|||
else i - 1
|
||||
s -= 2 while @tag(s - 2) is 'HERECOMMENT'
|
||||
|
||||
# Mark if the value is a for loop
|
||||
@insideForDeclaration = nextTag is 'FOR'
|
||||
|
||||
startsLine = s is 0 or @tag(s - 1) in LINEBREAKS or tokens[s - 1].newLine
|
||||
# Are we just continuing an already declared object?
|
||||
if stackTop()
|
||||
|
@ -316,7 +319,7 @@ exports.Rewriter = class Rewriter
|
|||
endImplicitCall()
|
||||
# Close implicit objects such as:
|
||||
# return a: 1, b: 2 unless true
|
||||
else if inImplicitObject() and not @insideForDeclaration and sameLine and
|
||||
else if inImplicitObject() and sameLine and
|
||||
tag isnt 'TERMINATOR' and prevTag isnt ':' and
|
||||
not (tag is 'POST_IF' and startsLine and implicitObjectContinues(i + 1))
|
||||
endImplicitObject()
|
||||
|
@ -344,7 +347,6 @@ exports.Rewriter = class Rewriter
|
|||
# f a, b: c, d: e, f, g: h: i, j
|
||||
#
|
||||
if tag is ',' and not @looksObjectish(i + 1) and inImplicitObject() and
|
||||
not @insideForDeclaration and
|
||||
(nextTag isnt 'TERMINATOR' or not @looksObjectish(i + 2))
|
||||
# When nextTag is OUTDENT the comma is insignificant and
|
||||
# should just be ignored so embed it in the implicit object.
|
||||
|
@ -540,3 +542,6 @@ LINEBREAKS = ['TERMINATOR', 'INDENT', 'OUTDENT']
|
|||
|
||||
# Tokens that close open calls when they follow a newline.
|
||||
CALL_CLOSERS = ['.', '?.', '::', '?::']
|
||||
|
||||
# Tokens that prevent a subsequent indent from ending implicit calls/objects
|
||||
CONTROL_IN_IMPLICIT = ['IF', 'TRY', 'FINALLY', 'CATCH', 'CLASS', 'SWITCH']
|
||||
|
|
|
@ -594,6 +594,23 @@ test "#1263: Braceless object return", ->
|
|||
eq 2, obj.b
|
||||
eq 3, obj.c()
|
||||
|
||||
test "#4564: indent should close implicit object", ->
|
||||
f = (x) -> x
|
||||
|
||||
arrayEq ['a'],
|
||||
for key of f a: 1
|
||||
key
|
||||
|
||||
g = null
|
||||
if f a: 1
|
||||
g = 3
|
||||
eq g, 3
|
||||
|
||||
h = null
|
||||
if a: (i for i in [1, 2, 3])
|
||||
h = 4
|
||||
eq h, 4
|
||||
|
||||
test "#4544: Postfix conditionals in first line of implicit object literals", ->
|
||||
two =
|
||||
foo:
|
||||
|
|
Loading…
Reference in a new issue