mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
let's try to merge these indexOf patches.
This commit is contained in:
parent
c1d24944dc
commit
113d7ce98f
9 changed files with 113 additions and 114 deletions
|
@ -12,9 +12,6 @@
|
|||
}
|
||||
return -1;
|
||||
}));
|
||||
exports.include = function(list, value) {
|
||||
return indexOf(list, value) >= 0;
|
||||
};
|
||||
exports.starts = function(string, literal, start) {
|
||||
return literal === string.substr(start, literal.length);
|
||||
};
|
||||
|
|
52
lib/lexer.js
52
lib/lexer.js
|
@ -1,7 +1,11 @@
|
|||
(function() {
|
||||
var ASSIGNED, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LEADING_SPACES, LINE_BREAK, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NEXT_CHARACTER, NEXT_ELLIPSIS, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, _ref, compact, count, include, last, op, starts;
|
||||
var ASSIGNED, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LEADING_SPACES, LINE_BREAK, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NEXT_CHARACTER, NEXT_ELLIPSIS, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, _ref, compact, count, last, op, starts;
|
||||
var __indexOf = Array.prototype.indexOf || function(item) {
|
||||
for (var i = 0, l = this.length; i < l; i++) if (this[i] === item) return i;
|
||||
return -1;
|
||||
};
|
||||
Rewriter = require('./rewriter').Rewriter;
|
||||
_ref = require('./helpers'), include = _ref.include, count = _ref.count, starts = _ref.starts, compact = _ref.compact, last = _ref.last;
|
||||
_ref = require('./helpers'), count = _ref.count, starts = _ref.starts, compact = _ref.compact, last = _ref.last;
|
||||
exports.Lexer = (function() {
|
||||
Lexer = (function() {
|
||||
function Lexer() {
|
||||
|
@ -32,7 +36,7 @@
|
|||
return (new Rewriter).rewrite(this.tokens);
|
||||
};
|
||||
Lexer.prototype.identifierToken = function() {
|
||||
var colon, forcedIdentifier, id, input, match, tag;
|
||||
var _ref2, colon, forcedIdentifier, id, input, match, tag;
|
||||
if (!(match = IDENTIFIER.exec(this.chunk))) {
|
||||
return false;
|
||||
}
|
||||
|
@ -44,15 +48,15 @@
|
|||
}
|
||||
forcedIdentifier = colon || this.tagAccessor();
|
||||
tag = 'IDENTIFIER';
|
||||
if (include(JS_KEYWORDS, id) || !forcedIdentifier && include(COFFEE_KEYWORDS, id)) {
|
||||
if ((__indexOf.call(JS_KEYWORDS, id) >= 0) || !forcedIdentifier && (__indexOf.call(COFFEE_KEYWORDS, id) >= 0)) {
|
||||
tag = id.toUpperCase();
|
||||
if (tag === 'WHEN' && include(LINE_BREAK, this.tag())) {
|
||||
if (tag === 'WHEN' && (_ref2 = this.tag(), __indexOf.call(LINE_BREAK, _ref2) >= 0)) {
|
||||
tag = 'LEADING_WHEN';
|
||||
} else if (tag === 'FOR') {
|
||||
this.seenFor = true;
|
||||
} else if (include(UNARY, tag)) {
|
||||
} else if (__indexOf.call(UNARY, tag) >= 0) {
|
||||
tag = 'UNARY';
|
||||
} else if (include(RELATION, tag)) {
|
||||
} else if (__indexOf.call(RELATION, tag) >= 0) {
|
||||
if (tag !== 'INSTANCEOF' && this.seenFor) {
|
||||
this.seenFor = false;
|
||||
tag = 'FOR' + tag;
|
||||
|
@ -65,12 +69,12 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
if (include(JS_FORBIDDEN, id)) {
|
||||
if (__indexOf.call(JS_FORBIDDEN, id) >= 0) {
|
||||
if (forcedIdentifier) {
|
||||
tag = 'IDENTIFIER';
|
||||
id = new String(id);
|
||||
id.reserved = true;
|
||||
} else if (include(RESERVED, id)) {
|
||||
} else if (__indexOf.call(RESERVED, id) >= 0) {
|
||||
this.identifierError(id);
|
||||
}
|
||||
}
|
||||
|
@ -80,9 +84,9 @@
|
|||
}
|
||||
if (id === '!') {
|
||||
tag = 'UNARY';
|
||||
} else if (include(LOGIC, id)) {
|
||||
} else if (__indexOf.call(LOGIC, id) >= 0) {
|
||||
tag = 'LOGIC';
|
||||
} else if (include(BOOL, tag)) {
|
||||
} else if (__indexOf.call(BOOL, tag) >= 0) {
|
||||
id = tag.toLowerCase();
|
||||
tag = 'BOOL';
|
||||
}
|
||||
|
@ -181,14 +185,14 @@
|
|||
return true;
|
||||
};
|
||||
Lexer.prototype.regexToken = function() {
|
||||
var match, regex;
|
||||
var _ref2, match, regex;
|
||||
if (this.chunk.charAt(0) !== '/') {
|
||||
return false;
|
||||
}
|
||||
if (match = HEREGEX.exec(this.chunk)) {
|
||||
return this.heregexToken(match);
|
||||
}
|
||||
if (include(NOT_REGEX, this.tag())) {
|
||||
if (_ref2 = this.tag(), __indexOf.call(NOT_REGEX, _ref2) >= 0) {
|
||||
return false;
|
||||
}
|
||||
if (!(match = REGEX.exec(this.chunk))) {
|
||||
|
@ -322,7 +326,7 @@
|
|||
return true;
|
||||
};
|
||||
Lexer.prototype.literalToken = function() {
|
||||
var _ref2, match, prev, tag, value;
|
||||
var _ref2, _ref3, _ref4, _ref5, match, prev, tag, value;
|
||||
if (match = OPERATOR.exec(this.chunk)) {
|
||||
value = match[0];
|
||||
if (CODE.test(value)) {
|
||||
|
@ -335,10 +339,10 @@
|
|||
tag = value;
|
||||
prev = last(this.tokens);
|
||||
if (value === '=' && prev) {
|
||||
if (!prev[1].reserved && include(JS_FORBIDDEN, prev[1])) {
|
||||
if (!prev[1].reserved && (_ref2 = prev[1], __indexOf.call(JS_FORBIDDEN, _ref2) >= 0)) {
|
||||
this.assignmentError();
|
||||
}
|
||||
if (((_ref2 = prev[1]) === '||' || _ref2 === '&&')) {
|
||||
if (((_ref3 = prev[1]) === '||' || _ref3 === '&&')) {
|
||||
prev[0] = 'COMPOUND_ASSIGN';
|
||||
prev[1] += '=';
|
||||
return true;
|
||||
|
@ -346,27 +350,27 @@
|
|||
}
|
||||
if (';' === value) {
|
||||
tag = 'TERMINATOR';
|
||||
} else if (include(LOGIC, value)) {
|
||||
} else if (__indexOf.call(LOGIC, value) >= 0) {
|
||||
tag = 'LOGIC';
|
||||
} else if (include(MATH, value)) {
|
||||
} else if (__indexOf.call(MATH, value) >= 0) {
|
||||
tag = 'MATH';
|
||||
} else if (include(COMPARE, value)) {
|
||||
} else if (__indexOf.call(COMPARE, value) >= 0) {
|
||||
tag = 'COMPARE';
|
||||
} else if (include(COMPOUND_ASSIGN, value)) {
|
||||
} else if (__indexOf.call(COMPOUND_ASSIGN, value) >= 0) {
|
||||
tag = 'COMPOUND_ASSIGN';
|
||||
} else if (include(UNARY, value)) {
|
||||
} else if (__indexOf.call(UNARY, value) >= 0) {
|
||||
tag = 'UNARY';
|
||||
} else if (include(SHIFT, value)) {
|
||||
} else if (__indexOf.call(SHIFT, value) >= 0) {
|
||||
tag = 'SHIFT';
|
||||
} else if (value === '?' && ((prev != null) ? prev.spaced : undefined)) {
|
||||
tag = 'LOGIC';
|
||||
} else if (prev && !prev.spaced) {
|
||||
if (value === '(' && include(CALLABLE, prev[0])) {
|
||||
if (value === '(' && (_ref4 = prev[0], __indexOf.call(CALLABLE, _ref4) >= 0)) {
|
||||
if (prev[0] === '?') {
|
||||
prev[0] = 'FUNC_EXIST';
|
||||
}
|
||||
tag = 'CALL_START';
|
||||
} else if (value === '[' && include(INDEXABLE, prev[0])) {
|
||||
} else if (value === '[' && (_ref5 = prev[0], __indexOf.call(INDEXABLE, _ref5) >= 0)) {
|
||||
tag = 'INDEX_START';
|
||||
switch (prev[0]) {
|
||||
case '?':
|
||||
|
|
27
lib/nodes.js
27
lib/nodes.js
|
@ -1,14 +1,17 @@
|
|||
(function() {
|
||||
var Accessor, ArrayLiteral, Assign, Base, Call, Class, Closure, Code, Comment, Existence, Expressions, Extends, For, IDENTIFIER, IS_STRING, If, In, Index, Literal, NO, NUMBER, ObjectLiteral, Op, Param, Parens, Push, Range, Return, SIMPLENUM, Scope, Slice, Splat, Switch, TAB, THIS, TRAILING_WHITESPACE, Throw, Try, UTILITIES, Value, While, YES, _ref, compact, del, ends, flatten, include, last, merge, starts, utility;
|
||||
var Accessor, ArrayLiteral, Assign, Base, Call, Class, Closure, Code, Comment, Existence, Expressions, Extends, For, IDENTIFIER, IS_STRING, If, In, Index, Literal, NO, NUMBER, ObjectLiteral, Op, Param, Parens, Push, Range, Return, SIMPLENUM, Scope, Slice, Splat, Switch, TAB, THIS, TRAILING_WHITESPACE, Throw, Try, UTILITIES, Value, While, YES, _ref, compact, del, ends, flatten, last, merge, starts, utility;
|
||||
var __extends = function(child, parent) {
|
||||
function ctor() { this.constructor = child; }
|
||||
ctor.prototype = parent.prototype;
|
||||
child.prototype = new ctor;
|
||||
if (typeof parent.extended === "function") parent.extended(child);
|
||||
child.__super__ = parent.prototype;
|
||||
}, __indexOf = Array.prototype.indexOf || function(item) {
|
||||
for (var i = 0, l = this.length; i < l; i++) if (this[i] === item) return i;
|
||||
return -1;
|
||||
};
|
||||
Scope = require('./scope').Scope;
|
||||
_ref = require('./helpers'), compact = _ref.compact, flatten = _ref.flatten, merge = _ref.merge, del = _ref.del, include = _ref.include, starts = _ref.starts, ends = _ref.ends, last = _ref.last;
|
||||
_ref = require('./helpers'), compact = _ref.compact, flatten = _ref.flatten, merge = _ref.merge, del = _ref.del, starts = _ref.starts, ends = _ref.ends, last = _ref.last;
|
||||
YES = function() {
|
||||
return true;
|
||||
};
|
||||
|
@ -983,7 +986,7 @@
|
|||
Assign.prototype.children = ['variable', 'value'];
|
||||
Assign.prototype.topSensitive = YES;
|
||||
Assign.prototype.compileNode = function(o) {
|
||||
var ifn, isValue, match, name, stmt, top, val;
|
||||
var _ref2, ifn, isValue, match, name, stmt, top, val;
|
||||
if (isValue = this.variable instanceof Value) {
|
||||
if (this.variable.isArray() || this.variable.isObject()) {
|
||||
return this.compilePatternMatch(o);
|
||||
|
@ -995,7 +998,7 @@
|
|||
delete o.top;
|
||||
return ifn.compile(o);
|
||||
}
|
||||
if (include(this.CONDITIONAL, this.context)) {
|
||||
if (_ref2 = this.context, __indexOf.call(this.CONDITIONAL, _ref2) >= 0) {
|
||||
return this.compileConditional(o);
|
||||
}
|
||||
}
|
||||
|
@ -1391,7 +1394,8 @@
|
|||
return this.operator !== '!' || this.first.isComplex();
|
||||
};
|
||||
Op.prototype.isChainable = function() {
|
||||
return include(this.CHAINABLE, this.operator);
|
||||
var _ref2;
|
||||
return (_ref2 = this.operator, __indexOf.call(this.CHAINABLE, _ref2) >= 0);
|
||||
};
|
||||
Op.prototype.invert = function() {
|
||||
var _ref2;
|
||||
|
@ -1404,12 +1408,12 @@
|
|||
return Op.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator);
|
||||
};
|
||||
Op.prototype.compileNode = function(o) {
|
||||
var ifn;
|
||||
var _ref2, ifn;
|
||||
if (this.isChainable() && this.first.unwrap().isChainable()) {
|
||||
return this.compileChain(o);
|
||||
}
|
||||
if (this.isUnary()) {
|
||||
if (include(this.MUTATORS, this.operator) && (ifn = If.unfoldSoak(o, this, 'first'))) {
|
||||
if ((_ref2 = this.operator, __indexOf.call(this.MUTATORS, _ref2) >= 0) && (ifn = If.unfoldSoak(o, this, 'first'))) {
|
||||
return ifn.compile(o);
|
||||
}
|
||||
return this.compileUnary(o);
|
||||
|
@ -1439,8 +1443,8 @@
|
|||
return new Existence(fst).compile(o) + (" ? " + ref + " : " + (this.second.compile(o)));
|
||||
};
|
||||
Op.prototype.compileUnary = function(o) {
|
||||
var parts, space;
|
||||
space = include(this.PREFIX_OPERATORS, this.operator) ? ' ' : '';
|
||||
var _ref2, parts, space;
|
||||
space = (_ref2 = this.operator, __indexOf.call(this.PREFIX_OPERATORS, _ref2) >= 0) ? ' ' : '';
|
||||
parts = [this.operator, space, this.first.compile(o)];
|
||||
return (this.flip ? parts.reverse() : parts).join('');
|
||||
};
|
||||
|
@ -1480,14 +1484,15 @@
|
|||
return "(" + (tests.join(' || ')) + ")";
|
||||
};
|
||||
In.prototype.compileLoopTest = function(o) {
|
||||
var _ref2, obj1, obj2, prefix;
|
||||
var _ref2, code, obj1, obj2, prefix;
|
||||
_ref2 = this.object.compileReference(merge(o, {
|
||||
top: true
|
||||
}), {
|
||||
precompile: true
|
||||
}), obj1 = _ref2[0], obj2 = _ref2[1];
|
||||
prefix = obj1 !== obj2 ? ("" + obj1 + ", ") : '';
|
||||
return "(" + prefix + (utility('indexOf')) + ".call(" + (this.array.compile(o)) + ", " + obj2 + ") >= 0)";
|
||||
code = ("" + prefix + (utility('indexOf')) + ".call(" + (this.array.compile(o)) + ", " + obj2 + ") >= 0");
|
||||
return this.parenthetical ? code : ("(" + code + ")");
|
||||
};
|
||||
return In;
|
||||
})();
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
(function() {
|
||||
var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, _i, _len, _ref, include, left, rite;
|
||||
include = require('./helpers').include;
|
||||
var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, _i, _len, _ref, left, rite;
|
||||
var __indexOf = Array.prototype.indexOf || function(item) {
|
||||
for (var i = 0, l = this.length; i < l; i++) if (this[i] === item) return i;
|
||||
return -1;
|
||||
};
|
||||
exports.Rewriter = (function() {
|
||||
function Rewriter() {
|
||||
return this;
|
||||
|
@ -32,7 +35,7 @@
|
|||
return true;
|
||||
};
|
||||
exports.Rewriter.prototype.detectEnd = function(i, condition, action) {
|
||||
var levels, token, tokens;
|
||||
var _ref, _ref2, levels, token, tokens;
|
||||
tokens = this.tokens;
|
||||
levels = 0;
|
||||
while (token = tokens[i]) {
|
||||
|
@ -42,9 +45,9 @@
|
|||
if (!token || levels < 0) {
|
||||
return action.call(this, token, i - 1);
|
||||
}
|
||||
if (include(EXPRESSION_START, token[0])) {
|
||||
if (_ref = token[0], __indexOf.call(EXPRESSION_START, _ref) >= 0) {
|
||||
levels += 1;
|
||||
} else if (include(EXPRESSION_END, token[0])) {
|
||||
} else if (_ref2 = token[0], __indexOf.call(EXPRESSION_END, _ref2) >= 0) {
|
||||
levels -= 1;
|
||||
}
|
||||
i += 1;
|
||||
|
@ -94,7 +97,8 @@
|
|||
};
|
||||
exports.Rewriter.prototype.removeMidExpressionNewlines = function() {
|
||||
return this.scanTokens(function(token, i, tokens) {
|
||||
if (!(token[0] === 'TERMINATOR' && include(EXPRESSION_CLOSE, this.tag(i + 1)))) {
|
||||
var _ref;
|
||||
if (!(token[0] === 'TERMINATOR' && (_ref = this.tag(i + 1), __indexOf.call(EXPRESSION_CLOSE, _ref) >= 0))) {
|
||||
return 1;
|
||||
}
|
||||
tokens.splice(i, 1);
|
||||
|
@ -149,12 +153,12 @@
|
|||
return this.tokens.splice(i, 0, ['}', '}', token[2]]);
|
||||
};
|
||||
return this.scanTokens(function(token, i, tokens) {
|
||||
var idx, tag, tok;
|
||||
if (include(EXPRESSION_START, tag = token[0])) {
|
||||
var _ref, idx, tag, tok;
|
||||
if (_ref = (tag = token[0]), __indexOf.call(EXPRESSION_START, _ref) >= 0) {
|
||||
stack.push(tag === 'INDENT' && this.tag(i - 1) === '{' ? '{' : tag);
|
||||
return 1;
|
||||
}
|
||||
if (include(EXPRESSION_END, tag)) {
|
||||
if (__indexOf.call(EXPRESSION_END, tag) >= 0) {
|
||||
stack.pop();
|
||||
return 1;
|
||||
}
|
||||
|
@ -182,27 +186,27 @@
|
|||
return this.tokens.splice(idx, 0, ['CALL_END', ')', token[2]]);
|
||||
};
|
||||
return this.scanTokens(function(token, i, tokens) {
|
||||
var callObject, next, prev, seenSingle, tag;
|
||||
var _ref, _ref2, callObject, next, prev, seenSingle, tag;
|
||||
tag = token[0];
|
||||
if (tag === 'CLASS') {
|
||||
classLine = true;
|
||||
}
|
||||
prev = tokens[i - 1];
|
||||
next = tokens[i + 1];
|
||||
callObject = !classLine && tag === 'INDENT' && next && next.generated && next[0] === '{' && prev && include(IMPLICIT_FUNC, prev[0]);
|
||||
callObject = !classLine && tag === 'INDENT' && next && next.generated && next[0] === '{' && prev && (_ref = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref) >= 0);
|
||||
seenSingle = false;
|
||||
if (include(LINEBREAKS, tag)) {
|
||||
if (__indexOf.call(LINEBREAKS, tag) >= 0) {
|
||||
classLine = false;
|
||||
}
|
||||
if (prev && !prev.spaced && tag === '?') {
|
||||
token.call = true;
|
||||
}
|
||||
if (!(callObject || ((prev != null) ? prev.spaced : undefined) && (prev.call || include(IMPLICIT_FUNC, prev[0])) && (include(IMPLICIT_CALL, tag) || include(IMPLICIT_UNSPACED_CALL, tag) && !token.spaced))) {
|
||||
if (!(callObject || ((prev != null) ? prev.spaced : undefined) && (prev.call || (_ref2 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref2) >= 0)) && ((__indexOf.call(IMPLICIT_CALL, tag) >= 0) || (__indexOf.call(IMPLICIT_UNSPACED_CALL, tag) >= 0) && !token.spaced))) {
|
||||
return 1;
|
||||
}
|
||||
tokens.splice(i, 0, ['CALL_START', '(', token[2]]);
|
||||
this.detectEnd(i + (callObject ? 2 : 1), function(token, i) {
|
||||
var post;
|
||||
var _ref3, post;
|
||||
if (!seenSingle && token.fromThen) {
|
||||
return true;
|
||||
}
|
||||
|
@ -213,7 +217,7 @@
|
|||
if (tag === 'PROPERTY_ACCESS' && this.tag(i - 1) === 'OUTDENT') {
|
||||
return true;
|
||||
}
|
||||
return !token.generated && this.tag(i - 1) !== ',' && include(IMPLICIT_END, tag) && (tag !== 'INDENT' || (this.tag(i - 2) !== 'CLASS' && !include(IMPLICIT_BLOCK, this.tag(i - 1)) && !((post = this.tokens[i + 1]) && post.generated && post[0] === '{')));
|
||||
return !token.generated && this.tag(i - 1) !== ',' && (__indexOf.call(IMPLICIT_END, tag) >= 0) && (tag !== 'INDENT' || (this.tag(i - 2) !== 'CLASS' && !(_ref3 = this.tag(i - 1), __indexOf.call(IMPLICIT_BLOCK, _ref3) >= 0) && !((post = this.tokens[i + 1]) && post.generated && post[0] === '{')));
|
||||
}, action);
|
||||
if (prev[0] === '?') {
|
||||
prev[0] = 'FUNC_EXIST';
|
||||
|
@ -233,7 +237,7 @@
|
|||
tokens.splice.apply(tokens, [i + 2, 0].concat(this.indentation(token)));
|
||||
return 4;
|
||||
}
|
||||
if (include(SINGLE_LINERS, tag) && this.tag(i + 1) !== 'INDENT' && !(tag === 'ELSE' && this.tag(i + 1) === 'IF')) {
|
||||
if ((__indexOf.call(SINGLE_LINERS, tag) >= 0) && this.tag(i + 1) !== 'INDENT' && !(tag === 'ELSE' && this.tag(i + 1) === 'IF')) {
|
||||
starter = tag;
|
||||
_ref2 = this.indentation(token), indent = _ref2[0], outdent = _ref2[1];
|
||||
if (starter === 'THEN') {
|
||||
|
@ -242,7 +246,8 @@
|
|||
indent.generated = (outdent.generated = true);
|
||||
tokens.splice(i + 1, 0, indent);
|
||||
condition = function(token, i) {
|
||||
return token[1] !== ';' && include(SINGLE_CLOSERS, token[0]) && !(token[0] === 'ELSE' && !(starter === 'IF' || starter === 'THEN'));
|
||||
var _ref3;
|
||||
return token[1] !== ';' && (_ref3 = token[0], __indexOf.call(SINGLE_CLOSERS, _ref3) >= 0) && !(token[0] === 'ELSE' && !(starter === 'IF' || starter === 'THEN'));
|
||||
};
|
||||
action = function(token, i) {
|
||||
return this.tokens.splice(this.tag(i - 1) === ',' ? i - 1 : i, 0, outdent);
|
||||
|
@ -320,12 +325,12 @@
|
|||
(debt[key] = 0);
|
||||
}
|
||||
return this.scanTokens(function(token, i, tokens) {
|
||||
var inv, match, mtag, oppos, tag, val;
|
||||
if (include(EXPRESSION_START, tag = token[0])) {
|
||||
var _ref, inv, match, mtag, oppos, tag, val;
|
||||
if (_ref = (tag = token[0]), __indexOf.call(EXPRESSION_START, _ref) >= 0) {
|
||||
stack.push(token);
|
||||
return 1;
|
||||
}
|
||||
if (!include(EXPRESSION_END, tag)) {
|
||||
if (!(__indexOf.call(EXPRESSION_END, tag) >= 0)) {
|
||||
return 1;
|
||||
}
|
||||
if (debt[(inv = INVERSES[tag])] > 0) {
|
||||
|
|
|
@ -14,10 +14,6 @@ indexOf = exports.indexOf = Array.indexOf or
|
|||
return index
|
||||
-1
|
||||
|
||||
# Does a list include a value?
|
||||
exports.include = (list, value) ->
|
||||
indexOf(list, value) >= 0
|
||||
|
||||
# Peek at the beginning of a given string to see if it matches a sequence.
|
||||
exports.starts = (string, literal, start) ->
|
||||
literal is string.substr start, literal.length
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
{Rewriter} = require './rewriter'
|
||||
|
||||
# Import the helpers we need.
|
||||
{include, count, starts, compact, last} = require './helpers'
|
||||
{count, starts, compact, last} = require './helpers'
|
||||
|
||||
# The Lexer Class
|
||||
# ---------------
|
||||
|
@ -80,16 +80,16 @@ exports.Lexer = class Lexer
|
|||
return true
|
||||
forcedIdentifier = colon or @tagAccessor()
|
||||
tag = 'IDENTIFIER'
|
||||
if include(JS_KEYWORDS, id) or
|
||||
not forcedIdentifier and include(COFFEE_KEYWORDS, id)
|
||||
if id in JS_KEYWORDS or
|
||||
not forcedIdentifier and id in COFFEE_KEYWORDS
|
||||
tag = id.toUpperCase()
|
||||
if tag is 'WHEN' and include LINE_BREAK, @tag()
|
||||
if tag is 'WHEN' and @tag() in LINE_BREAK
|
||||
tag = 'LEADING_WHEN'
|
||||
else if tag is 'FOR'
|
||||
@seenFor = yes
|
||||
else if include UNARY, tag
|
||||
else if tag in UNARY
|
||||
tag = 'UNARY'
|
||||
else if include RELATION, tag
|
||||
else if tag in RELATION
|
||||
if tag isnt 'INSTANCEOF' and @seenFor
|
||||
@seenFor = no
|
||||
tag = 'FOR' + tag
|
||||
|
@ -98,20 +98,20 @@ exports.Lexer = class Lexer
|
|||
if @value() is '!'
|
||||
@tokens.pop()
|
||||
id = '!' + id
|
||||
if include JS_FORBIDDEN, id
|
||||
if id in JS_FORBIDDEN
|
||||
if forcedIdentifier
|
||||
tag = 'IDENTIFIER'
|
||||
id = new String id
|
||||
id.reserved = yes
|
||||
else if include RESERVED, id
|
||||
else if id in RESERVED
|
||||
@identifierError id
|
||||
unless forcedIdentifier
|
||||
tag = id = COFFEE_ALIASES[id] if COFFEE_ALIASES.hasOwnProperty id
|
||||
if id is '!'
|
||||
tag = 'UNARY'
|
||||
else if include LOGIC, id
|
||||
else if id in LOGIC
|
||||
tag = 'LOGIC'
|
||||
else if include BOOL, tag
|
||||
else if tag in BOOL
|
||||
id = tag.toLowerCase()
|
||||
tag = 'BOOL'
|
||||
@token tag, id
|
||||
|
@ -187,7 +187,7 @@ exports.Lexer = class Lexer
|
|||
regexToken: ->
|
||||
return false if @chunk.charAt(0) isnt '/'
|
||||
return @heregexToken match if match = HEREGEX.exec @chunk
|
||||
return false if include NOT_REGEX, @tag()
|
||||
return false if @tag() in NOT_REGEX
|
||||
return false unless match = REGEX.exec @chunk
|
||||
[regex] = match
|
||||
@token 'REGEX', if regex is '//' then '/(?:)/' else regex
|
||||
|
@ -313,24 +313,24 @@ exports.Lexer = class Lexer
|
|||
tag = value
|
||||
prev = last @tokens
|
||||
if value is '=' and prev
|
||||
@assignmentError() if not prev[1].reserved and include JS_FORBIDDEN, prev[1]
|
||||
@assignmentError() if not prev[1].reserved and prev[1] in JS_FORBIDDEN
|
||||
if prev[1] in ['||', '&&']
|
||||
prev[0] = 'COMPOUND_ASSIGN'
|
||||
prev[1] += '='
|
||||
return true
|
||||
if ';' is value then tag = 'TERMINATOR'
|
||||
else if include LOGIC , value then tag = 'LOGIC'
|
||||
else if include MATH , value then tag = 'MATH'
|
||||
else if include COMPARE , value then tag = 'COMPARE'
|
||||
else if include COMPOUND_ASSIGN, value then tag = 'COMPOUND_ASSIGN'
|
||||
else if include UNARY , value then tag = 'UNARY'
|
||||
else if include SHIFT , value then tag = 'SHIFT'
|
||||
if ';' is value then tag = 'TERMINATOR'
|
||||
else if value in LOGIC then tag = 'LOGIC'
|
||||
else if value in MATH then tag = 'MATH'
|
||||
else if value in COMPARE then tag = 'COMPARE'
|
||||
else if value in COMPOUND_ASSIGN then tag = 'COMPOUND_ASSIGN'
|
||||
else if value in UNARY then tag = 'UNARY'
|
||||
else if value in SHIFT then tag = 'SHIFT'
|
||||
else if value is '?' and prev?.spaced then tag = 'LOGIC'
|
||||
else if prev and not prev.spaced
|
||||
if value is '(' and include CALLABLE, prev[0]
|
||||
if value is '(' and prev[0] in CALLABLE
|
||||
prev[0] = 'FUNC_EXIST' if prev[0] is '?'
|
||||
tag = 'CALL_START'
|
||||
else if value is '[' and include INDEXABLE, prev[0]
|
||||
else if value is '[' and prev[0] in INDEXABLE
|
||||
tag = 'INDEX_START'
|
||||
switch prev[0]
|
||||
when '?' then prev[0] = 'INDEX_SOAK'
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
{Scope} = require './scope'
|
||||
|
||||
# Import the helpers we plan to use.
|
||||
{compact, flatten, merge, del, include, starts, ends, last} = require './helpers'
|
||||
{compact, flatten, merge, del, starts, ends, last} = require './helpers'
|
||||
|
||||
# Constant functions for nodes that don't need customization.
|
||||
YES = -> yes
|
||||
|
@ -857,7 +857,7 @@ exports.Assign = class Assign extends Base
|
|||
if ifn = If.unfoldSoak o, this, 'variable'
|
||||
delete o.top
|
||||
return ifn.compile o
|
||||
return @compileConditional o if include @CONDITIONAL, @context
|
||||
return @compileConditional o if @context in @CONDITIONAL
|
||||
top = del o, 'top'
|
||||
stmt = del o, 'asStatement'
|
||||
name = @variable.compile o
|
||||
|
@ -1192,7 +1192,7 @@ exports.Op = class Op extends Base
|
|||
isComplex: -> @operator isnt '!' or @first.isComplex()
|
||||
|
||||
isChainable: ->
|
||||
include(@CHAINABLE, @operator)
|
||||
@operator in @CHAINABLE
|
||||
|
||||
invert: ->
|
||||
if @operator in ['===', '!==']
|
||||
|
@ -1209,7 +1209,7 @@ exports.Op = class Op extends Base
|
|||
compileNode: (o) ->
|
||||
return @compileChain o if @isChainable() and @first.unwrap().isChainable()
|
||||
if @isUnary()
|
||||
return ifn.compile o if include(@MUTATORS, @operator) and ifn = If.unfoldSoak o, this, 'first'
|
||||
return ifn.compile o if @operator in @MUTATORS and ifn = If.unfoldSoak o, this, 'first'
|
||||
return @compileUnary o
|
||||
return @compileExistence o if @operator is '?'
|
||||
@first.tags.front = @tags.front
|
||||
|
@ -1237,7 +1237,7 @@ exports.Op = class Op extends Base
|
|||
|
||||
# Compile a unary **Op**.
|
||||
compileUnary: (o) ->
|
||||
space = if include @PREFIX_OPERATORS, @operator then ' ' else ''
|
||||
space = if @operator in @PREFIX_OPERATORS then ' ' else ''
|
||||
parts = [@operator, space, @first.compile(o)]
|
||||
(if @flip then parts.reverse() else parts).join ''
|
||||
|
||||
|
@ -1264,7 +1264,8 @@ exports.In = class In extends Base
|
|||
compileLoopTest: (o) ->
|
||||
[obj1, obj2] = @object.compileReference merge(o, top: yes), precompile: yes
|
||||
prefix = if obj1 isnt obj2 then "#{obj1}, " else ''
|
||||
"(#{prefix}#{utility 'indexOf'}.call(#{@array.compile o}, #{obj2}) >= 0)"
|
||||
code = "#{prefix}#{utility 'indexOf'}.call(#{@array.compile o}, #{obj2}) >= 0"
|
||||
if @parenthetical then code else "(#{code})"
|
||||
|
||||
#### Try
|
||||
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
# shorthand into the unambiguous long form, add implicit indentation and
|
||||
# parentheses, balance incorrect nestings, and generally clean things up.
|
||||
|
||||
# Import the helpers we need.
|
||||
{include} = require './helpers'
|
||||
|
||||
# The **Rewriter** class is used by the [Lexer](lexer.html), directly against
|
||||
# its internal array of tokens.
|
||||
class exports.Rewriter
|
||||
|
@ -51,9 +48,9 @@ class exports.Rewriter
|
|||
while token = tokens[i]
|
||||
return action.call this, token, i if levels is 0 and condition.call this, token, i
|
||||
return action.call this, token, i - 1 if not token or levels < 0
|
||||
if include EXPRESSION_START, token[0]
|
||||
if token[0] in EXPRESSION_START
|
||||
levels += 1
|
||||
else if include EXPRESSION_END, token[0]
|
||||
else if token[0] in EXPRESSION_END
|
||||
levels -= 1
|
||||
i += 1
|
||||
i - 1
|
||||
|
@ -93,7 +90,7 @@ class exports.Rewriter
|
|||
# this, remove their trailing newlines.
|
||||
removeMidExpressionNewlines: ->
|
||||
@scanTokens (token, i, tokens) ->
|
||||
return 1 unless token[0] is 'TERMINATOR' and include EXPRESSION_CLOSE, @tag(i + 1)
|
||||
return 1 unless token[0] is 'TERMINATOR' and @tag(i + 1) in EXPRESSION_CLOSE
|
||||
tokens.splice i, 1
|
||||
0
|
||||
|
||||
|
@ -131,10 +128,10 @@ class exports.Rewriter
|
|||
tag is ',' and one?[0] not in ['IDENTIFIER', 'NUMBER', 'STRING', '@', 'TERMINATOR', 'OUTDENT']
|
||||
action = (token, i) -> @tokens.splice i, 0, ['}', '}', token[2]]
|
||||
@scanTokens (token, i, tokens) ->
|
||||
if include EXPRESSION_START, tag = token[0]
|
||||
if (tag = token[0]) in EXPRESSION_START
|
||||
stack.push if tag is 'INDENT' and @tag(i - 1) is '{' then '{' else tag
|
||||
return 1
|
||||
if include EXPRESSION_END, tag
|
||||
if tag in EXPRESSION_END
|
||||
stack.pop()
|
||||
return 1
|
||||
return 1 unless tag is ':' and stack[stack.length - 1] isnt '{'
|
||||
|
@ -162,22 +159,22 @@ class exports.Rewriter
|
|||
next = tokens[i + 1]
|
||||
callObject = not classLine and tag is 'INDENT' and
|
||||
next and next.generated and next[0] is '{' and
|
||||
prev and include(IMPLICIT_FUNC, prev[0])
|
||||
prev and prev[0] in IMPLICIT_FUNC
|
||||
seenSingle = no
|
||||
classLine = no if include LINEBREAKS, tag
|
||||
classLine = no if tag in LINEBREAKS
|
||||
token.call = yes if prev and not prev.spaced and tag is '?'
|
||||
return 1 unless callObject or
|
||||
prev?.spaced and (prev.call or include(IMPLICIT_FUNC, prev[0])) and
|
||||
(include(IMPLICIT_CALL, tag) or include(IMPLICIT_UNSPACED_CALL, tag) and not token.spaced)
|
||||
prev?.spaced and (prev.call or prev[0] in IMPLICIT_FUNC) and
|
||||
(tag in IMPLICIT_CALL or tag in IMPLICIT_UNSPACED_CALL and not token.spaced)
|
||||
tokens.splice i, 0, ['CALL_START', '(', token[2]]
|
||||
@detectEnd i + (if callObject then 2 else 1), (token, i) ->
|
||||
return yes if not seenSingle and token.fromThen
|
||||
[tag] = token
|
||||
seenSingle = yes if tag in ['IF', 'ELSE', 'UNLESS', '->', '=>']
|
||||
return yes if tag is 'PROPERTY_ACCESS' and @tag(i - 1) is 'OUTDENT'
|
||||
not token.generated and @tag(i - 1) isnt ',' and include(IMPLICIT_END, tag) and
|
||||
not token.generated and @tag(i - 1) isnt ',' and tag in IMPLICIT_END and
|
||||
(tag isnt 'INDENT' or
|
||||
(@tag(i - 2) isnt 'CLASS' and not include(IMPLICIT_BLOCK, @tag(i - 1)) and
|
||||
(@tag(i - 2) isnt 'CLASS' and not (@tag(i - 1) in IMPLICIT_BLOCK) and
|
||||
not ((post = @tokens[i + 1]) and post.generated and post[0] is '{')))
|
||||
, action
|
||||
prev[0] = 'FUNC_EXIST' if prev[0] is '?'
|
||||
|
@ -196,7 +193,7 @@ class exports.Rewriter
|
|||
if tag is 'CATCH' and @tag(i + 2) in ['TERMINATOR', 'FINALLY']
|
||||
tokens.splice i + 2, 0, @indentation(token)...
|
||||
return 4
|
||||
if include(SINGLE_LINERS, tag) and @tag(i + 1) isnt 'INDENT' and
|
||||
if tag in SINGLE_LINERS and @tag(i + 1) isnt 'INDENT' and
|
||||
not (tag is 'ELSE' and @tag(i + 1) is 'IF')
|
||||
starter = tag
|
||||
[indent, outdent] = @indentation token
|
||||
|
@ -204,7 +201,7 @@ class exports.Rewriter
|
|||
indent.generated = outdent.generated = true
|
||||
tokens.splice i + 1, 0, indent
|
||||
condition = (token, i) ->
|
||||
token[1] isnt ';' and include(SINGLE_CLOSERS, token[0]) and
|
||||
token[1] isnt ';' and token[0] in SINGLE_CLOSERS and
|
||||
not (token[0] is 'ELSE' and starter not in ['IF', 'THEN'])
|
||||
action = (token, i) ->
|
||||
@tokens.splice (if @tag(i - 1) is ',' then i - 1 else i), 0, outdent
|
||||
|
@ -265,10 +262,10 @@ class exports.Rewriter
|
|||
debt = {}
|
||||
(debt[key] = 0) for all key of INVERSES
|
||||
@scanTokens (token, i, tokens) ->
|
||||
if include EXPRESSION_START, tag = token[0]
|
||||
if (tag = token[0]) in EXPRESSION_START
|
||||
stack.push token
|
||||
return 1
|
||||
return 1 unless include EXPRESSION_END, tag
|
||||
return 1 unless tag in EXPRESSION_END
|
||||
if debt[inv = INVERSES[tag]] > 0
|
||||
debt[inv] -= 1
|
||||
tokens.splice i, 1
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{indexOf, include, starts, ends, compact, count, merge, extend, flatten, del, last} = CoffeeScript.helpers
|
||||
{indexOf, starts, ends, compact, count, merge, extend, flatten, del, last} = CoffeeScript.helpers
|
||||
|
||||
array = [0..4]
|
||||
string = array.join ''
|
||||
|
@ -10,12 +10,6 @@ eq 2, indexOf array, 2
|
|||
eq 4, indexOf array, 4
|
||||
eq(-1, indexOf array, 6)
|
||||
|
||||
# Test `include`
|
||||
ok include array, 0
|
||||
ok include array, 2
|
||||
ok include array, 4
|
||||
ok not include array, 6
|
||||
|
||||
# Test `starts`
|
||||
ok starts string, '012'
|
||||
ok starts string, '34', 3
|
||||
|
|
Loading…
Reference in a new issue