Merge pull request #3841 from lydell/last
Replace `last array` helper with `[..., last] = array`
This commit is contained in:
commit
53c7891599
|
@ -1,6 +1,6 @@
|
|||
// Generated by CoffeeScript 1.9.0
|
||||
(function() {
|
||||
var buildLocationData, extend, flatten, last, ref, repeat, syntaxErrorToString;
|
||||
var buildLocationData, extend, flatten, ref, repeat, syntaxErrorToString;
|
||||
|
||||
exports.starts = function(string, literal, start) {
|
||||
return literal === string.substr(start, literal.length);
|
||||
|
@ -83,10 +83,6 @@
|
|||
return val;
|
||||
};
|
||||
|
||||
exports.last = last = function(array, back) {
|
||||
return array[array.length - (back || 0) - 1];
|
||||
};
|
||||
|
||||
exports.some = (ref = Array.prototype.some) != null ? ref : function(fn) {
|
||||
var e, i, len1;
|
||||
for (i = 0, len1 = this.length; i < len1; i++) {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
// Generated by CoffeeScript 1.9.0
|
||||
(function() {
|
||||
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HERECOMMENT_ILLEGAL, HEREDOC_DOUBLE, HEREDOC_INDENT, HEREDOC_SINGLE, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDENTABLE_CLOSERS, INDEXABLE, INVALID_ESCAPE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LEADING_BLANK_LINE, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTI_DENT, NOT_REGEX, NUMBER, OPERATOR, POSSIBLY_DIVISION, REGEX, REGEX_FLAGS, REGEX_ILLEGAL, RELATION, RESERVED, Rewriter, SHIFT, SIMPLE_STRING_OMIT, STRICT_PROSCRIBED, STRING_DOUBLE, STRING_OMIT, STRING_SINGLE, STRING_START, TRAILING_BLANK_LINE, TRAILING_SPACES, UNARY, UNARY_MATH, VALID_FLAGS, WHITESPACE, compact, count, invertLiterate, key, last, locationDataToString, ref, ref1, repeat, starts, throwSyntaxError,
|
||||
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HERECOMMENT_ILLEGAL, HEREDOC_DOUBLE, HEREDOC_INDENT, HEREDOC_SINGLE, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDENTABLE_CLOSERS, INDEXABLE, INVALID_ESCAPE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LEADING_BLANK_LINE, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTI_DENT, NOT_REGEX, NUMBER, OPERATOR, POSSIBLY_DIVISION, REGEX, REGEX_FLAGS, REGEX_ILLEGAL, RELATION, RESERVED, Rewriter, SHIFT, SIMPLE_STRING_OMIT, STRICT_PROSCRIBED, STRING_DOUBLE, STRING_OMIT, STRING_SINGLE, STRING_START, TRAILING_BLANK_LINE, TRAILING_SPACES, UNARY, UNARY_MATH, VALID_FLAGS, WHITESPACE, compact, count, invertLiterate, key, locationDataToString, ref, ref1, repeat, starts, throwSyntaxError,
|
||||
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;
|
||||
|
||||
ref1 = require('./helpers'), count = ref1.count, starts = ref1.starts, compact = ref1.compact, last = ref1.last, repeat = ref1.repeat, invertLiterate = ref1.invertLiterate, locationDataToString = ref1.locationDataToString, throwSyntaxError = ref1.throwSyntaxError;
|
||||
ref1 = require('./helpers'), count = ref1.count, starts = ref1.starts, compact = ref1.compact, repeat = ref1.repeat, invertLiterate = ref1.invertLiterate, locationDataToString = ref1.locationDataToString, throwSyntaxError = ref1.throwSyntaxError;
|
||||
|
||||
exports.Lexer = Lexer = (function() {
|
||||
function Lexer() {}
|
||||
|
@ -64,7 +64,7 @@
|
|||
};
|
||||
|
||||
Lexer.prototype.identifierToken = function() {
|
||||
var colon, colonOffset, forcedIdentifier, id, idLength, input, match, poppedToken, prev, ref2, ref3, ref4, tag, tagToken;
|
||||
var colon, colonOffset, forcedIdentifier, id, idLength, input, match, poppedToken, prev, ref2, ref3, ref4, ref5, tag, tagToken;
|
||||
if (!(match = IDENTIFIER.exec(this.chunk))) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -79,11 +79,12 @@
|
|||
this.token('FROM', id);
|
||||
return id.length;
|
||||
}
|
||||
forcedIdentifier = colon || (prev = last(this.tokens)) && (((ref2 = prev[0]) === '.' || ref2 === '?.' || ref2 === '::' || ref2 === '?::') || !prev.spaced && prev[0] === '@');
|
||||
ref2 = this.tokens, prev = ref2[ref2.length - 1];
|
||||
forcedIdentifier = colon || (prev != null) && (((ref3 = prev[0]) === '.' || ref3 === '?.' || ref3 === '::' || ref3 === '?::') || !prev.spaced && prev[0] === '@');
|
||||
tag = 'IDENTIFIER';
|
||||
if (!forcedIdentifier && (indexOf.call(JS_KEYWORDS, id) >= 0 || indexOf.call(COFFEE_KEYWORDS, id) >= 0)) {
|
||||
tag = id.toUpperCase();
|
||||
if (tag === 'WHEN' && (ref3 = this.tag(), indexOf.call(LINE_BREAK, ref3) >= 0)) {
|
||||
if (tag === 'WHEN' && (ref4 = this.tag(), indexOf.call(LINE_BREAK, ref4) >= 0)) {
|
||||
tag = 'LEADING_WHEN';
|
||||
} else if (tag === 'FOR') {
|
||||
this.seenFor = true;
|
||||
|
@ -143,7 +144,7 @@
|
|||
tagToken = this.token(tag, id, 0, idLength);
|
||||
tagToken.variable = !forcedIdentifier;
|
||||
if (poppedToken) {
|
||||
ref4 = [poppedToken[2].first_line, poppedToken[2].first_column], tagToken[2].first_line = ref4[0], tagToken[2].first_column = ref4[1];
|
||||
ref5 = [poppedToken[2].first_line, poppedToken[2].first_column], tagToken[2].first_line = ref5[0], tagToken[2].first_column = ref5[1];
|
||||
}
|
||||
if (colon) {
|
||||
colonOffset = input.lastIndexOf(':');
|
||||
|
@ -296,7 +297,7 @@
|
|||
};
|
||||
|
||||
Lexer.prototype.regexToken = function() {
|
||||
var body, closed, end, errorToken, flags, index, match, prev, ref2, ref3, regex, rparen, tokens;
|
||||
var body, closed, end, errorToken, flags, index, match, prev, ref2, ref3, ref4, regex, rparen, tokens;
|
||||
switch (false) {
|
||||
case !(match = REGEX_ILLEGAL.exec(this.chunk)):
|
||||
this.error("regular expressions cannot begin with " + match[2], {
|
||||
|
@ -312,13 +313,13 @@
|
|||
isRegex: true
|
||||
});
|
||||
index = regex.length;
|
||||
prev = last(this.tokens);
|
||||
ref2 = this.tokens, prev = ref2[ref2.length - 1];
|
||||
if (prev) {
|
||||
if (prev.spaced && (ref2 = prev[0], indexOf.call(CALLABLE, ref2) >= 0) && !prev.stringEnd && !prev.regexEnd) {
|
||||
if (prev.spaced && (ref3 = prev[0], indexOf.call(CALLABLE, ref3) >= 0) && !prev.stringEnd && !prev.regexEnd) {
|
||||
if (!closed || POSSIBLY_DIVISION.test(regex)) {
|
||||
return 0;
|
||||
}
|
||||
} else if (ref3 = prev[0], indexOf.call(NOT_REGEX, ref3) >= 0) {
|
||||
} else if (ref4 = prev[0], indexOf.call(NOT_REGEX, ref4) >= 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -449,11 +450,11 @@
|
|||
};
|
||||
|
||||
Lexer.prototype.whitespaceToken = function() {
|
||||
var match, nline, prev;
|
||||
var match, nline, prev, ref2;
|
||||
if (!((match = WHITESPACE.exec(this.chunk)) || (nline = this.chunk.charAt(0) === '\n'))) {
|
||||
return 0;
|
||||
}
|
||||
prev = last(this.tokens);
|
||||
ref2 = this.tokens, prev = ref2[ref2.length - 1];
|
||||
if (prev) {
|
||||
prev[match ? 'spaced' : 'newLine'] = true;
|
||||
}
|
||||
|
@ -482,7 +483,7 @@
|
|||
};
|
||||
|
||||
Lexer.prototype.literalToken = function() {
|
||||
var match, prev, ref2, ref3, ref4, ref5, tag, token, value;
|
||||
var match, prev, ref2, ref3, ref4, ref5, ref6, tag, token, value;
|
||||
if (match = OPERATOR.exec(this.chunk)) {
|
||||
value = match[0];
|
||||
if (CODE.test(value)) {
|
||||
|
@ -492,12 +493,12 @@
|
|||
value = this.chunk.charAt(0);
|
||||
}
|
||||
tag = value;
|
||||
prev = last(this.tokens);
|
||||
ref2 = this.tokens, prev = ref2[ref2.length - 1];
|
||||
if (value === '=' && prev) {
|
||||
if (!prev[1].reserved && (ref2 = prev[1], indexOf.call(JS_FORBIDDEN, ref2) >= 0)) {
|
||||
if (!prev[1].reserved && (ref3 = prev[1], indexOf.call(JS_FORBIDDEN, ref3) >= 0)) {
|
||||
this.error("reserved word '" + prev[1] + "' can't be assigned", prev[2]);
|
||||
}
|
||||
if ((ref3 = prev[1]) === '||' || ref3 === '&&') {
|
||||
if ((ref4 = prev[1]) === '||' || ref4 === '&&') {
|
||||
prev[0] = 'COMPOUND_ASSIGN';
|
||||
prev[1] += '=';
|
||||
return value.length;
|
||||
|
@ -521,12 +522,12 @@
|
|||
} else if (indexOf.call(LOGIC, value) >= 0 || value === '?' && (prev != null ? prev.spaced : void 0)) {
|
||||
tag = 'LOGIC';
|
||||
} else if (prev && !prev.spaced) {
|
||||
if (value === '(' && (ref4 = prev[0], indexOf.call(CALLABLE, ref4) >= 0) && !prev.stringEnd && !prev.regexEnd) {
|
||||
if (value === '(' && (ref5 = prev[0], indexOf.call(CALLABLE, ref5) >= 0) && !prev.stringEnd && !prev.regexEnd) {
|
||||
if (prev[0] === '?') {
|
||||
prev[0] = 'FUNC_EXIST';
|
||||
}
|
||||
tag = 'CALL_START';
|
||||
} else if (value === '[' && (ref5 = prev[0], indexOf.call(INDEXABLE, ref5) >= 0)) {
|
||||
} else if (value === '[' && (ref6 = prev[0], indexOf.call(INDEXABLE, ref6) >= 0)) {
|
||||
tag = 'INDEX_START';
|
||||
switch (prev[0]) {
|
||||
case '?':
|
||||
|
@ -706,19 +707,21 @@
|
|||
};
|
||||
|
||||
Lexer.prototype.pair = function(tag) {
|
||||
var ref2, wanted;
|
||||
if (tag !== (wanted = (ref2 = last(this.ends)) != null ? ref2.tag : void 0)) {
|
||||
var lastIndent, prev, ref2, ref3, wanted;
|
||||
ref2 = this.ends, prev = ref2[ref2.length - 1];
|
||||
if (tag !== (wanted = prev != null ? prev.tag : void 0)) {
|
||||
if ('OUTDENT' !== wanted) {
|
||||
this.error("unmatched " + tag);
|
||||
}
|
||||
this.outdentToken(last(this.indents), true);
|
||||
ref3 = this.indents, lastIndent = ref3[ref3.length - 1];
|
||||
this.outdentToken(lastIndent, true);
|
||||
return this.pair(tag);
|
||||
}
|
||||
return this.ends.pop();
|
||||
};
|
||||
|
||||
Lexer.prototype.getLineAndColumnFromChunk = function(offset) {
|
||||
var column, lineCount, lines, string;
|
||||
var column, lastLine, lineCount, ref2, string;
|
||||
if (offset === 0) {
|
||||
return [this.chunkLine, this.chunkColumn];
|
||||
}
|
||||
|
@ -730,8 +733,8 @@
|
|||
lineCount = count(string, '\n');
|
||||
column = this.chunkColumn;
|
||||
if (lineCount > 0) {
|
||||
lines = string.split('\n');
|
||||
column = last(lines).length;
|
||||
ref2 = string.split('\n'), lastLine = ref2[ref2.length - 1];
|
||||
column = lastLine.length;
|
||||
} else {
|
||||
column += string.length;
|
||||
}
|
||||
|
@ -764,14 +767,16 @@
|
|||
return token;
|
||||
};
|
||||
|
||||
Lexer.prototype.tag = function(index, tag) {
|
||||
var tok;
|
||||
return (tok = last(this.tokens, index)) && (tag ? tok[0] = tag : tok[0]);
|
||||
Lexer.prototype.tag = function() {
|
||||
var ref2, token;
|
||||
ref2 = this.tokens, token = ref2[ref2.length - 1];
|
||||
return token != null ? token[0] : void 0;
|
||||
};
|
||||
|
||||
Lexer.prototype.value = function(index, val) {
|
||||
var tok;
|
||||
return (tok = last(this.tokens, index)) && (val ? tok[1] = val : tok[1]);
|
||||
Lexer.prototype.value = function() {
|
||||
var ref2, token;
|
||||
ref2 = this.tokens, token = ref2[ref2.length - 1];
|
||||
return token != null ? token[1] : void 0;
|
||||
};
|
||||
|
||||
Lexer.prototype.unfinished = function() {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Generated by CoffeeScript 1.9.0
|
||||
(function() {
|
||||
var Access, Arr, Assign, Base, Block, Call, Class, Code, CodeFragment, Comment, Existence, Expansion, Extends, For, HEXNUM, IDENTIFIER, IS_REGEX, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, NEGATE, NO, NUMBER, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, STRICT_PROSCRIBED, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, addLocationDataFn, compact, del, ends, extend, flatten, fragmentsToText, isComplexOrAssignable, isLiteralArguments, isLiteralThis, last, locationDataToString, merge, multident, parseNum, ref1, ref2, some, starts, throwSyntaxError, unfoldSoak, utility,
|
||||
var Access, Arr, Assign, Base, Block, Call, Class, Code, CodeFragment, Comment, Existence, Expansion, Extends, For, HEXNUM, IDENTIFIER, IS_REGEX, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, NEGATE, NO, NUMBER, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, STRICT_PROSCRIBED, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, addLocationDataFn, compact, del, ends, extend, flatten, fragmentsToText, isComplexOrAssignable, isLiteralArguments, isLiteralThis, locationDataToString, merge, multident, parseNum, ref1, ref2, some, starts, throwSyntaxError, unfoldSoak, utility,
|
||||
extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
||||
hasProp = {}.hasOwnProperty,
|
||||
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; },
|
||||
|
@ -12,7 +12,7 @@
|
|||
|
||||
ref1 = require('./lexer'), RESERVED = ref1.RESERVED, STRICT_PROSCRIBED = ref1.STRICT_PROSCRIBED;
|
||||
|
||||
ref2 = require('./helpers'), compact = ref2.compact, flatten = ref2.flatten, extend = ref2.extend, merge = ref2.merge, del = ref2.del, starts = ref2.starts, ends = ref2.ends, last = ref2.last, some = ref2.some, addLocationDataFn = ref2.addLocationDataFn, locationDataToString = ref2.locationDataToString, throwSyntaxError = ref2.throwSyntaxError;
|
||||
ref2 = require('./helpers'), compact = ref2.compact, flatten = ref2.flatten, extend = ref2.extend, merge = ref2.merge, del = ref2.del, starts = ref2.starts, ends = ref2.ends, some = ref2.some, addLocationDataFn = ref2.addLocationDataFn, locationDataToString = ref2.locationDataToString, throwSyntaxError = ref2.throwSyntaxError;
|
||||
|
||||
exports.extend = extend;
|
||||
|
||||
|
@ -760,7 +760,9 @@
|
|||
};
|
||||
|
||||
Value.prototype.isSplice = function() {
|
||||
return last(this.properties) instanceof Slice;
|
||||
var lastProp, ref3;
|
||||
ref3 = this.properties, lastProp = ref3[ref3.length - 1];
|
||||
return lastProp instanceof Slice;
|
||||
};
|
||||
|
||||
Value.prototype.looksStatic = function(className) {
|
||||
|
@ -777,8 +779,8 @@
|
|||
};
|
||||
|
||||
Value.prototype.cacheReference = function(o) {
|
||||
var base, bref, name, nref;
|
||||
name = last(this.properties);
|
||||
var base, bref, name, nref, ref3;
|
||||
ref3 = this.properties, name = ref3[ref3.length - 1];
|
||||
if (this.properties.length < 2 && !this.base.isComplex() && !(name != null ? name.isComplex() : void 0)) {
|
||||
return [this, this];
|
||||
}
|
||||
|
@ -1407,11 +1409,12 @@
|
|||
Class.prototype.children = ['variable', 'parent', 'body'];
|
||||
|
||||
Class.prototype.determineName = function() {
|
||||
var decl, tail;
|
||||
var decl, ref3, tail;
|
||||
if (!this.variable) {
|
||||
return null;
|
||||
}
|
||||
decl = (tail = last(this.variable.properties)) ? tail instanceof Access && tail.name.value : this.variable.base.value;
|
||||
ref3 = this.variable.properties, tail = ref3[ref3.length - 1];
|
||||
decl = tail ? tail instanceof Access && tail.name.value : this.variable.base.value;
|
||||
if (indexOf.call(STRICT_PROSCRIBED, decl) >= 0) {
|
||||
this.variable.error("class variable name may not be " + decl);
|
||||
}
|
||||
|
@ -2127,7 +2130,7 @@
|
|||
};
|
||||
|
||||
Splat.compileSplattedArray = function(o, list, apply) {
|
||||
var args, base, compiledNode, concatPart, fragments, i, index, j, len1, node;
|
||||
var args, base, compiledNode, concatPart, fragments, i, index, j, last, len1, node;
|
||||
index = -1;
|
||||
while ((node = list[++index]) && !(node instanceof Splat)) {
|
||||
continue;
|
||||
|
@ -2166,7 +2169,8 @@
|
|||
})();
|
||||
base = list[0].joinFragmentArrays(base, ', ');
|
||||
concatPart = list[index].joinFragmentArrays(args, ', ');
|
||||
return [].concat(list[0].makeCode("["), base, list[index].makeCode("].concat("), concatPart, (last(list)).makeCode(")"));
|
||||
last = list[list.length - 1];
|
||||
return [].concat(list[0].makeCode("["), base, list[index].makeCode("].concat("), concatPart, last.makeCode(")"));
|
||||
};
|
||||
|
||||
return Splat;
|
||||
|
@ -2767,10 +2771,10 @@
|
|||
For.prototype.children = ['body', 'source', 'guard', 'step'];
|
||||
|
||||
For.prototype.compileNode = function(o) {
|
||||
var body, bodyFragments, compare, compareDown, declare, declareDown, defPart, defPartFragments, down, forPartFragments, guardPart, idt1, increment, index, ivar, kvar, kvarAssign, lastJumps, lvar, name, namePart, ref, ref3, ref4, resultPart, returnResult, rvar, scope, source, step, stepNum, stepVar, svar, varPart;
|
||||
var body, bodyFragments, compare, compareDown, declare, declareDown, defPart, defPartFragments, down, forPartFragments, guardPart, idt1, increment, index, ivar, kvar, kvarAssign, last, lvar, name, namePart, ref, ref3, ref4, resultPart, returnResult, rvar, scope, source, step, stepNum, stepVar, svar, varPart;
|
||||
body = Block.wrap([this.body]);
|
||||
lastJumps = (ref3 = last(body.expressions)) != null ? ref3.jumps() : void 0;
|
||||
if (lastJumps && lastJumps instanceof Return) {
|
||||
ref3 = body.expressions, last = ref3[ref3.length - 1];
|
||||
if ((last != null ? last.jumps() : void 0) instanceof Return) {
|
||||
this.returns = false;
|
||||
}
|
||||
source = this.range ? this.source.base : this.source;
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
// Generated by CoffeeScript 1.9.0
|
||||
(function() {
|
||||
var Scope, extend, last, ref,
|
||||
var Scope,
|
||||
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('./helpers'), extend = ref.extend, last = ref.last;
|
||||
|
||||
exports.Scope = Scope = (function() {
|
||||
function Scope(parent, expressions, method, referencedVars) {
|
||||
var ref1, ref2;
|
||||
var ref, ref1;
|
||||
this.parent = parent;
|
||||
this.expressions = expressions;
|
||||
this.method = method;
|
||||
|
@ -22,7 +20,7 @@
|
|||
if (!this.parent) {
|
||||
this.utilities = {};
|
||||
}
|
||||
this.root = (ref1 = (ref2 = this.parent) != null ? ref2.root : void 0) != null ? ref1 : this;
|
||||
this.root = (ref = (ref1 = this.parent) != null ? ref1.root : void 0) != null ? ref : this;
|
||||
}
|
||||
|
||||
Scope.prototype.add = function(name, type, immediate) {
|
||||
|
@ -40,8 +38,8 @@
|
|||
};
|
||||
|
||||
Scope.prototype.namedMethod = function() {
|
||||
var ref1;
|
||||
if (((ref1 = this.method) != null ? ref1.name : void 0) || !this.parent) {
|
||||
var ref;
|
||||
if (((ref = this.method) != null ? ref.name : void 0) || !this.parent) {
|
||||
return this.method;
|
||||
}
|
||||
return this.parent.namedMethod();
|
||||
|
@ -63,8 +61,8 @@
|
|||
};
|
||||
|
||||
Scope.prototype.check = function(name) {
|
||||
var ref1;
|
||||
return !!(this.type(name) || ((ref1 = this.parent) != null ? ref1.check(name) : void 0));
|
||||
var ref;
|
||||
return !!(this.type(name) || ((ref = this.parent) != null ? ref.check(name) : void 0));
|
||||
};
|
||||
|
||||
Scope.prototype.temporary = function(name, index, single) {
|
||||
|
@ -79,10 +77,10 @@
|
|||
};
|
||||
|
||||
Scope.prototype.type = function(name) {
|
||||
var i, len, ref1, v;
|
||||
ref1 = this.variables;
|
||||
for (i = 0, len = ref1.length; i < len; i++) {
|
||||
v = ref1[i];
|
||||
var i, len, ref, v;
|
||||
ref = this.variables;
|
||||
for (i = 0, len = ref.length; i < len; i++) {
|
||||
v = ref[i];
|
||||
if (v.name === name) {
|
||||
return v.type;
|
||||
}
|
||||
|
@ -91,7 +89,7 @@
|
|||
};
|
||||
|
||||
Scope.prototype.freeVariable = function(name, options) {
|
||||
var index, ref1, temp;
|
||||
var index, ref, temp;
|
||||
if (options == null) {
|
||||
options = {};
|
||||
}
|
||||
|
@ -103,7 +101,7 @@
|
|||
}
|
||||
index++;
|
||||
}
|
||||
if ((ref1 = options.reserve) != null ? ref1 : true) {
|
||||
if ((ref = options.reserve) != null ? ref : true) {
|
||||
this.add(temp, 'var', true);
|
||||
}
|
||||
return temp;
|
||||
|
@ -124,11 +122,11 @@
|
|||
Scope.prototype.declaredVariables = function() {
|
||||
var v;
|
||||
return ((function() {
|
||||
var i, len, ref1, results;
|
||||
ref1 = this.variables;
|
||||
var i, len, ref, results;
|
||||
ref = this.variables;
|
||||
results = [];
|
||||
for (i = 0, len = ref1.length; i < len; i++) {
|
||||
v = ref1[i];
|
||||
for (i = 0, len = ref.length; i < len; i++) {
|
||||
v = ref[i];
|
||||
if (v.type === 'var') {
|
||||
results.push(v.name);
|
||||
}
|
||||
|
@ -138,11 +136,11 @@
|
|||
};
|
||||
|
||||
Scope.prototype.assignedVariables = function() {
|
||||
var i, len, ref1, results, v;
|
||||
ref1 = this.variables;
|
||||
var i, len, ref, results, v;
|
||||
ref = this.variables;
|
||||
results = [];
|
||||
for (i = 0, len = ref1.length; i < len; i++) {
|
||||
v = ref1[i];
|
||||
for (i = 0, len = ref.length; i < len; i++) {
|
||||
v = ref[i];
|
||||
if (v.type.assigned) {
|
||||
results.push(v.name + " = " + v.type.value);
|
||||
}
|
||||
|
|
|
@ -62,9 +62,6 @@ exports.del = (obj, key) ->
|
|||
delete obj[key]
|
||||
val
|
||||
|
||||
# Gets the last item of an array(-like) object.
|
||||
exports.last = last = (array, back) -> array[array.length - (back or 0) - 1]
|
||||
|
||||
# Typical Array::some
|
||||
exports.some = Array::some ? (fn) ->
|
||||
return true for e in this when fn e
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
{Rewriter, INVERSES} = require './rewriter'
|
||||
|
||||
# Import the helpers we need.
|
||||
{count, starts, compact, last, repeat, invertLiterate,
|
||||
{count, starts, compact, repeat, invertLiterate,
|
||||
locationDataToString, throwSyntaxError} = require './helpers'
|
||||
|
||||
# The Lexer Class
|
||||
|
@ -112,8 +112,9 @@ exports.Lexer = class Lexer
|
|||
if id is 'from' and @tag() is 'YIELD'
|
||||
@token 'FROM', id
|
||||
return id.length
|
||||
forcedIdentifier = colon or
|
||||
(prev = last @tokens) and (prev[0] in ['.', '?.', '::', '?::'] or
|
||||
[..., prev] = @tokens
|
||||
forcedIdentifier = colon or prev? and
|
||||
(prev[0] in ['.', '?.', '::', '?::'] or
|
||||
not prev.spaced and prev[0] is '@')
|
||||
tag = 'IDENTIFIER'
|
||||
|
||||
|
@ -264,7 +265,7 @@ exports.Lexer = class Lexer
|
|||
[regex, body, closed] = match
|
||||
@validateEscapes regex, isRegex: yes
|
||||
index = regex.length
|
||||
prev = last @tokens
|
||||
[..., prev] = @tokens
|
||||
if prev
|
||||
if prev.spaced and prev[0] in CALLABLE and not prev.stringEnd and not prev.regexEnd
|
||||
return 0 if not closed or POSSIBLY_DIVISION.test regex
|
||||
|
@ -372,7 +373,7 @@ exports.Lexer = class Lexer
|
|||
whitespaceToken: ->
|
||||
return 0 unless (match = WHITESPACE.exec @chunk) or
|
||||
(nline = @chunk.charAt(0) is '\n')
|
||||
prev = last @tokens
|
||||
[..., prev] = @tokens
|
||||
prev[if match then 'spaced' else 'newLine'] = true if prev
|
||||
if match then match[0].length else 0
|
||||
|
||||
|
@ -400,7 +401,7 @@ exports.Lexer = class Lexer
|
|||
else
|
||||
value = @chunk.charAt 0
|
||||
tag = value
|
||||
prev = last @tokens
|
||||
[..., prev] = @tokens
|
||||
if value is '=' and prev
|
||||
if not prev[1].reserved and prev[1] in JS_FORBIDDEN
|
||||
@error "reserved word '#{prev[1]}' can't be assigned", prev[2]
|
||||
|
@ -596,14 +597,16 @@ exports.Lexer = class Lexer
|
|||
# Pairs up a closing token, ensuring that all listed pairs of tokens are
|
||||
# correctly balanced throughout the course of the token stream.
|
||||
pair: (tag) ->
|
||||
unless tag is wanted = last(@ends)?.tag
|
||||
[..., prev] = @ends
|
||||
unless tag is wanted = prev?.tag
|
||||
@error "unmatched #{tag}" unless 'OUTDENT' is wanted
|
||||
# Auto-close INDENT to support syntax like this:
|
||||
#
|
||||
# el.click((event) ->
|
||||
# el.hide())
|
||||
#
|
||||
@outdentToken last(@indents), true
|
||||
[..., lastIndent] = @indents
|
||||
@outdentToken lastIndent, true
|
||||
return @pair tag
|
||||
@ends.pop()
|
||||
|
||||
|
@ -626,8 +629,8 @@ exports.Lexer = class Lexer
|
|||
|
||||
column = @chunkColumn
|
||||
if lineCount > 0
|
||||
lines = string.split '\n'
|
||||
column = last(lines).length
|
||||
[..., lastLine] = string.split '\n'
|
||||
column = lastLine.length
|
||||
else
|
||||
column += string.length
|
||||
|
||||
|
@ -662,13 +665,15 @@ exports.Lexer = class Lexer
|
|||
@tokens.push token
|
||||
token
|
||||
|
||||
# Peek at a tag in the current token stream.
|
||||
tag: (index, tag) ->
|
||||
(tok = last @tokens, index) and if tag then tok[0] = tag else tok[0]
|
||||
# Peek at the last tag in the token stream.
|
||||
tag: ->
|
||||
[..., token] = @tokens
|
||||
token?[0]
|
||||
|
||||
# Peek at a value in the current token stream.
|
||||
value: (index, val) ->
|
||||
(tok = last @tokens, index) and if val then tok[1] = val else tok[1]
|
||||
# Peek at the last value in the token stream.
|
||||
value: ->
|
||||
[..., token] = @tokens
|
||||
token?[1]
|
||||
|
||||
# Are we in the midst of an unfinished expression?
|
||||
unfinished: ->
|
||||
|
|
|
@ -9,7 +9,7 @@ Error.stackTraceLimit = Infinity
|
|||
{RESERVED, STRICT_PROSCRIBED} = require './lexer'
|
||||
|
||||
# Import the helpers we plan to use.
|
||||
{compact, flatten, extend, merge, del, starts, ends, last, some,
|
||||
{compact, flatten, extend, merge, del, starts, ends, some,
|
||||
addLocationDataFn, locationDataToString, throwSyntaxError} = require './helpers'
|
||||
|
||||
# Functions required by parser
|
||||
|
@ -510,7 +510,8 @@ exports.Value = class Value extends Base
|
|||
(@base instanceof Obj) and (not onlyGenerated or @base.generated)
|
||||
|
||||
isSplice: ->
|
||||
last(@properties) instanceof Slice
|
||||
[..., lastProp] = @properties
|
||||
lastProp instanceof Slice
|
||||
|
||||
looksStatic: (className) ->
|
||||
@base.value is className and @properties.length is 1 and
|
||||
|
@ -525,7 +526,7 @@ exports.Value = class Value extends Base
|
|||
# We cache them separately for compiling complex expressions.
|
||||
# `a()[b()] ?= c` -> `(_base = a())[_name = b()] ? _base[_name] = c`
|
||||
cacheReference: (o) ->
|
||||
name = last @properties
|
||||
[..., name] = @properties
|
||||
if @properties.length < 2 and not @base.isComplex() and not name?.isComplex()
|
||||
return [this, this] # `a` `a.b`
|
||||
base = new Value @base, @properties[...-1]
|
||||
|
@ -1006,7 +1007,8 @@ exports.Class = class Class extends Base
|
|||
# Figure out the appropriate name for the constructor function of this class.
|
||||
determineName: ->
|
||||
return null unless @variable
|
||||
decl = if tail = last @variable.properties
|
||||
[..., tail] = @variable.properties
|
||||
decl = if tail
|
||||
tail instanceof Access and tail.name.value
|
||||
else
|
||||
@variable.base.value
|
||||
|
@ -1540,7 +1542,8 @@ exports.Splat = class Splat extends Base
|
|||
base = (node.compileToFragments o, LEVEL_LIST for node in list[...index])
|
||||
base = list[0].joinFragmentArrays base, ', '
|
||||
concatPart = list[index].joinFragmentArrays args, ', '
|
||||
[].concat list[0].makeCode("["), base, list[index].makeCode("].concat("), concatPart, (last list).makeCode(")")
|
||||
[..., last] = list
|
||||
[].concat list[0].makeCode("["), base, list[index].makeCode("].concat("), concatPart, last.makeCode(")")
|
||||
|
||||
#### Expansion
|
||||
|
||||
|
@ -1976,27 +1979,27 @@ exports.For = class For extends While
|
|||
# comprehensions. Some of the generated code can be shared in common, and
|
||||
# some cannot.
|
||||
compileNode: (o) ->
|
||||
body = Block.wrap [@body]
|
||||
lastJumps = last(body.expressions)?.jumps()
|
||||
@returns = no if lastJumps and lastJumps instanceof Return
|
||||
source = if @range then @source.base else @source
|
||||
scope = o.scope
|
||||
name = @name and (@name.compile o, LEVEL_LIST) if not @pattern
|
||||
index = @index and (@index.compile o, LEVEL_LIST)
|
||||
body = Block.wrap [@body]
|
||||
[..., last] = body.expressions
|
||||
@returns = no if last?.jumps() instanceof Return
|
||||
source = if @range then @source.base else @source
|
||||
scope = o.scope
|
||||
name = @name and (@name.compile o, LEVEL_LIST) if not @pattern
|
||||
index = @index and (@index.compile o, LEVEL_LIST)
|
||||
scope.find(name) if name and not @pattern
|
||||
scope.find(index) if index
|
||||
rvar = scope.freeVariable 'results' if @returns
|
||||
ivar = (@object and index) or scope.freeVariable 'i', single: true
|
||||
kvar = (@range and name) or index or ivar
|
||||
kvarAssign = if kvar isnt ivar then "#{kvar} = " else ""
|
||||
rvar = scope.freeVariable 'results' if @returns
|
||||
ivar = (@object and index) or scope.freeVariable 'i', single: true
|
||||
kvar = (@range and name) or index or ivar
|
||||
kvarAssign = if kvar isnt ivar then "#{kvar} = " else ""
|
||||
if @step and not @range
|
||||
[step, stepVar] = @cacheToCodeFragments @step.cache o, LEVEL_LIST, isComplexOrAssignable
|
||||
stepNum = stepVar.match NUMBER
|
||||
name = ivar if @pattern
|
||||
varPart = ''
|
||||
guardPart = ''
|
||||
defPart = ''
|
||||
idt1 = @tab + TAB
|
||||
name = ivar if @pattern
|
||||
varPart = ''
|
||||
guardPart = ''
|
||||
defPart = ''
|
||||
idt1 = @tab + TAB
|
||||
if @range
|
||||
forPartFragments = source.compileToFragments merge o,
|
||||
{index: ivar, name, @step, isComplex: isComplexOrAssignable}
|
||||
|
|
|
@ -5,10 +5,6 @@ and has a reference to its parent enclosing scope. In this way, we know which
|
|||
variables are new and need to be declared with `var`, and which are shared
|
||||
with external scopes.
|
||||
|
||||
Import the helpers we plan to use.
|
||||
|
||||
{extend, last} = require './helpers'
|
||||
|
||||
exports.Scope = class Scope
|
||||
|
||||
Initialize a scope with its parent, for lookups up the chain,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# -------
|
||||
|
||||
# pull the helpers from `CoffeeScript.helpers` into local variables
|
||||
{starts, ends, repeat, compact, count, merge, extend, flatten, del, last, baseFileName} = CoffeeScript.helpers
|
||||
{starts, ends, repeat, compact, count, merge, extend, flatten, del, baseFileName} = CoffeeScript.helpers
|
||||
|
||||
|
||||
# `starts`
|
||||
|
@ -94,16 +94,6 @@ test "the `del` helper deletes a property from an object and returns the deleted
|
|||
ok 1 not of obj
|
||||
|
||||
|
||||
# `last`
|
||||
|
||||
test "the `last` helper returns the last item of an array-like object", ->
|
||||
ary = [0, 1, 2, 3, 4]
|
||||
eq 4, last(ary)
|
||||
|
||||
test "the `last` helper allows one to specify an optional offset", ->
|
||||
ary = [0, 1, 2, 3, 4]
|
||||
eq 2, last(ary, 2)
|
||||
|
||||
# `baseFileName`
|
||||
|
||||
test "the `baseFileName` helper returns the file name to write to", ->
|
||||
|
|
Loading…
Reference in New Issue