mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
commit
d2f90d2236
3 changed files with 55 additions and 27 deletions
|
@ -1,6 +1,6 @@
|
||||||
// Generated by CoffeeScript 1.6.3
|
// Generated by CoffeeScript 1.6.3
|
||||||
(function() {
|
(function() {
|
||||||
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, invertLiterate, key, last, locationDataToString, repeat, starts, throwSyntaxError, _ref, _ref1,
|
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDENTABLE_CLOSERS, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, invertLiterate, key, last, locationDataToString, repeat, starts, throwSyntaxError, _ref, _ref1,
|
||||||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||||
|
|
||||||
_ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES;
|
_ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES;
|
||||||
|
@ -351,36 +351,42 @@
|
||||||
this.indents.push(diff);
|
this.indents.push(diff);
|
||||||
this.ends.push('OUTDENT');
|
this.ends.push('OUTDENT');
|
||||||
this.outdebt = this.indebt = 0;
|
this.outdebt = this.indebt = 0;
|
||||||
|
this.indent = size;
|
||||||
} else if (size < this.baseIndent) {
|
} else if (size < this.baseIndent) {
|
||||||
this.error('missing indentation', indent.length);
|
this.error('missing indentation', indent.length);
|
||||||
} else {
|
} else {
|
||||||
this.indebt = 0;
|
this.indebt = 0;
|
||||||
this.outdentToken(this.indent - size, noNewlines, indent.length);
|
this.outdentToken(this.indent - size, noNewlines, indent.length);
|
||||||
}
|
}
|
||||||
this.indent = size;
|
|
||||||
return indent.length;
|
return indent.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
Lexer.prototype.outdentToken = function(moveOut, noNewlines, outdentLength) {
|
Lexer.prototype.outdentToken = function(moveOut, noNewlines, outdentLength) {
|
||||||
var dent, len;
|
var decreasedIndent, dent, lastIndent, _ref2;
|
||||||
|
decreasedIndent = this.indent - moveOut;
|
||||||
while (moveOut > 0) {
|
while (moveOut > 0) {
|
||||||
len = this.indents.length - 1;
|
lastIndent = this.indents[this.indents.length - 1];
|
||||||
if (this.indents[len] === void 0) {
|
if (!lastIndent) {
|
||||||
moveOut = 0;
|
moveOut = 0;
|
||||||
} else if (this.indents[len] === this.outdebt) {
|
} else if (lastIndent === this.outdebt) {
|
||||||
moveOut -= this.outdebt;
|
moveOut -= this.outdebt;
|
||||||
this.outdebt = 0;
|
this.outdebt = 0;
|
||||||
} else if (this.indents[len] < this.outdebt) {
|
} else if (lastIndent < this.outdebt) {
|
||||||
this.outdebt -= this.indents[len];
|
this.outdebt -= lastIndent;
|
||||||
moveOut -= this.indents[len];
|
moveOut -= lastIndent;
|
||||||
} else {
|
} else {
|
||||||
dent = this.indents.pop() + this.outdebt;
|
dent = this.indents.pop() + this.outdebt;
|
||||||
moveOut -= dent;
|
if (outdentLength && (_ref2 = this.chunk[outdentLength], __indexOf.call(INDENTABLE_CLOSERS, _ref2) >= 0)) {
|
||||||
|
decreasedIndent -= dent - moveOut;
|
||||||
|
moveOut = dent;
|
||||||
|
}
|
||||||
this.outdebt = 0;
|
this.outdebt = 0;
|
||||||
this.pair('OUTDENT');
|
this.pair('OUTDENT');
|
||||||
this.token('OUTDENT', dent, 0, outdentLength);
|
this.token('OUTDENT', moveOut, 0, outdentLength);
|
||||||
|
moveOut -= dent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.indent = decreasedIndent;
|
||||||
if (dent) {
|
if (dent) {
|
||||||
this.outdebt -= moveOut;
|
this.outdebt -= moveOut;
|
||||||
}
|
}
|
||||||
|
@ -685,13 +691,12 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
Lexer.prototype.pair = function(tag) {
|
Lexer.prototype.pair = function(tag) {
|
||||||
var size, wanted;
|
var wanted;
|
||||||
if (tag !== (wanted = last(this.ends))) {
|
if (tag !== (wanted = last(this.ends))) {
|
||||||
if ('OUTDENT' !== wanted) {
|
if ('OUTDENT' !== wanted) {
|
||||||
this.error("unmatched " + tag);
|
this.error("unmatched " + tag);
|
||||||
}
|
}
|
||||||
this.indent -= size = last(this.indents);
|
this.outdentToken(last(this.indents), true);
|
||||||
this.outdentToken(size, true);
|
|
||||||
return this.pair(tag);
|
return this.pair(tag);
|
||||||
}
|
}
|
||||||
return this.ends.pop();
|
return this.ends.pop();
|
||||||
|
@ -910,4 +915,6 @@
|
||||||
|
|
||||||
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
|
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
|
||||||
|
|
||||||
|
INDENTABLE_CLOSERS = [')', '}', ']'];
|
||||||
|
|
||||||
}).call(this);
|
}).call(this);
|
||||||
|
|
|
@ -327,37 +327,43 @@ exports.Lexer = class Lexer
|
||||||
@indents.push diff
|
@indents.push diff
|
||||||
@ends.push 'OUTDENT'
|
@ends.push 'OUTDENT'
|
||||||
@outdebt = @indebt = 0
|
@outdebt = @indebt = 0
|
||||||
|
@indent = size
|
||||||
else if size < @baseIndent
|
else if size < @baseIndent
|
||||||
@error 'missing indentation', indent.length
|
@error 'missing indentation', indent.length
|
||||||
else
|
else
|
||||||
@indebt = 0
|
@indebt = 0
|
||||||
@outdentToken @indent - size, noNewlines, indent.length
|
@outdentToken @indent - size, noNewlines, indent.length
|
||||||
@indent = size
|
|
||||||
indent.length
|
indent.length
|
||||||
|
|
||||||
# Record an outdent token or multiple tokens, if we happen to be moving back
|
# Record an outdent token or multiple tokens, if we happen to be moving back
|
||||||
# inwards past several recorded indents.
|
# inwards past several recorded indents. Sets new @indent value.
|
||||||
outdentToken: (moveOut, noNewlines, outdentLength) ->
|
outdentToken: (moveOut, noNewlines, outdentLength) ->
|
||||||
|
decreasedIndent = @indent - moveOut
|
||||||
while moveOut > 0
|
while moveOut > 0
|
||||||
len = @indents.length - 1
|
lastIndent = @indents[@indents.length - 1]
|
||||||
if @indents[len] is undefined
|
if not lastIndent
|
||||||
moveOut = 0
|
moveOut = 0
|
||||||
else if @indents[len] is @outdebt
|
else if lastIndent is @outdebt
|
||||||
moveOut -= @outdebt
|
moveOut -= @outdebt
|
||||||
@outdebt = 0
|
@outdebt = 0
|
||||||
else if @indents[len] < @outdebt
|
else if lastIndent < @outdebt
|
||||||
@outdebt -= @indents[len]
|
@outdebt -= lastIndent
|
||||||
moveOut -= @indents[len]
|
moveOut -= lastIndent
|
||||||
else
|
else
|
||||||
dent = @indents.pop() + @outdebt
|
dent = @indents.pop() + @outdebt
|
||||||
moveOut -= dent
|
if outdentLength and @chunk[outdentLength] in INDENTABLE_CLOSERS
|
||||||
|
decreasedIndent -= dent - moveOut
|
||||||
|
moveOut = dent
|
||||||
@outdebt = 0
|
@outdebt = 0
|
||||||
|
# pair might call outdentToken, so preserve decreasedIndent
|
||||||
@pair 'OUTDENT'
|
@pair 'OUTDENT'
|
||||||
@token 'OUTDENT', dent, 0, outdentLength
|
@token 'OUTDENT', moveOut, 0, outdentLength
|
||||||
|
moveOut -= dent
|
||||||
@outdebt -= moveOut if dent
|
@outdebt -= moveOut if dent
|
||||||
@tokens.pop() while @value() is ';'
|
@tokens.pop() while @value() is ';'
|
||||||
|
|
||||||
@token 'TERMINATOR', '\n', outdentLength, 0 unless @tag() is 'TERMINATOR' or noNewlines
|
@token 'TERMINATOR', '\n', outdentLength, 0 unless @tag() is 'TERMINATOR' or noNewlines
|
||||||
|
@indent = decreasedIndent
|
||||||
this
|
this
|
||||||
|
|
||||||
# Matches and consumes non-meaningful whitespace. Tag the previous token
|
# Matches and consumes non-meaningful whitespace. Tag the previous token
|
||||||
|
@ -606,8 +612,7 @@ exports.Lexer = class Lexer
|
||||||
# el.click((event) ->
|
# el.click((event) ->
|
||||||
# el.hide())
|
# el.hide())
|
||||||
#
|
#
|
||||||
@indent -= size = last @indents
|
@outdentToken last(@indents), true
|
||||||
@outdentToken size, true
|
|
||||||
return @pair tag
|
return @pair tag
|
||||||
@ends.pop()
|
@ends.pop()
|
||||||
|
|
||||||
|
@ -881,3 +886,6 @@ INDEXABLE = CALLABLE.concat 'NUMBER', 'BOOL', 'NULL', 'UNDEFINED'
|
||||||
# occurs at the start of a line. We disambiguate these from trailing whens to
|
# occurs at the start of a line. We disambiguate these from trailing whens to
|
||||||
# avoid an ambiguity in the grammar.
|
# avoid an ambiguity in the grammar.
|
||||||
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR']
|
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR']
|
||||||
|
|
||||||
|
# Additional indent in front of these is ignored.
|
||||||
|
INDENTABLE_CLOSERS = [')', '}', ']']
|
||||||
|
|
|
@ -199,7 +199,7 @@ test "#1299: Disallow token misnesting", ->
|
||||||
|
|
||||||
test "#2981: Enforce initial indentation", ->
|
test "#2981: Enforce initial indentation", ->
|
||||||
try
|
try
|
||||||
CoffeeScript.compile ' a\nb'
|
CoffeeScript.compile ' a\nb-'
|
||||||
ok no
|
ok no
|
||||||
catch e
|
catch e
|
||||||
eq 'missing indentation', e.message
|
eq 'missing indentation', e.message
|
||||||
|
@ -212,3 +212,16 @@ test "'single-line' expression containing multiple lines", ->
|
||||||
then -b
|
then -b
|
||||||
else null
|
else null
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
test "#1275: allow indentation before closing brackets", ->
|
||||||
|
array = [
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
]
|
||||||
|
eq array, array
|
||||||
|
do ->
|
||||||
|
(
|
||||||
|
a = 1
|
||||||
|
)
|
||||||
|
eq 1, a
|
||||||
|
|
Loading…
Add table
Reference in a new issue