Merge branch 'master' of git://github.com/jashkenas/coffee-script into improved-error-messages

Conflicts:
	lib/coffee-script/coffee-script.js
	lib/coffee-script/command.js
	lib/coffee-script/helpers.js
	lib/coffee-script/lexer.js
	lib/coffee-script/nodes.js
	lib/coffee-script/repl.js
	src/coffee-script.coffee
	src/command.coffee
	src/helpers.coffee
	src/lexer.coffee
	src/nodes.coffee
	test/helpers.coffee
This commit is contained in:
Demian Ferreiro
2013-03-10 20:29:36 -03:00
25 changed files with 570 additions and 357 deletions

View File

@@ -0,0 +1,4 @@
class Person
constructor: (options) ->
{@name, @age, @height} = options

View File

@@ -0,0 +1,8 @@
score = 76
grade = switch
when score < 60 then 'F'
when score < 70 then 'D'
when score < 80 then 'C'
when score < 90 then 'B'
else 'A'
# grade == 'C'

View File

@@ -291,13 +291,6 @@ sudo bin/cake install</pre>
command line. For example:<br /><tt>coffee -e "console.log num for num in [10..1]"</tt>
</td>
</tr>
<tr>
<td><code>-r, --require</code></td>
<td>
Load a library before compiling or executing your script. Can be used
to hook in to the compiler (to add Growl notifications, for example).
</td>
</tr>
<tr>
<td><code>-b, --bare</code></td>
<td>
@@ -812,6 +805,11 @@ Expressions
Destructuring assignment can even be combined with splats.
</p>
<%= code_for('patterns_and_splats', 'contents.join("")') %>
<p>
Destructuring assignment is also useful when combined with class constructors
to assign propeties to your instance from an options object passed to the constructor.
</p>
<%= code_for('constructor_destructuring', 'contents.join("")') %>
<p>
<span id="fat-arrow" class="bookmark"></span>
@@ -869,6 +867,11 @@ Expressions
</p>
<%= code_for('switch') %>
<p>
Switch statements can also be used without a control expression, turning them in to a cleaner alternative to if/else chains.
</p>
<%= code_for('switch_with_no_expression') %>
<p>
<span id="try" class="bookmark"></span>
<b class="header">Try/Catch/Finally</b>
@@ -922,7 +925,7 @@ Expressions
<b class="header">Block Regular Expressions</b>
Similar to block strings and comments, CoffeeScript supports block regexes &mdash;
extended regular expressions that ignore internal whitespace and can contain
comments and interpolation. Modeled after Perl's <tt>/x</tt> modifier, CoffeeSctipt's
comments and interpolation. Modeled after Perl's <tt>/x</tt> modifier, CoffeeScript's
block regexes are delimited by <tt>///</tt> and go a long way towards making complex
regular expressions readable. To quote from the CoffeeScript source:
</p>

View File

@@ -0,0 +1,12 @@
// Generated by CoffeeScript 1.3.3
var Person;
Person = (function() {
function Person(options) {
this.name = options.name, this.age = options.age, this.height = options.height;
}
return Person;
})();

View File

@@ -1786,6 +1786,37 @@ _ref <span class="Keyword">=</span> tag.<span class="LibraryFunction">split</spa
tag = "<impossible>";
_ref = tag.split(""), open = _ref[0], contents = 3 <= _ref.length ? __slice.call(_ref, 1, _i = _ref.length - 1) : (_i = 1, []), close = _ref[_i++];
;alert(contents.join(""));'>run: contents.join("")</div><br class='clear' /></div>
<p>
Destructuring assignment is also useful when combined with class constructors
to assign propeties to your instance from an options object passed to the constructor.
</p>
<div class='code'><pre class="idle">class Person
constructor: (options) -&gt;
{@name, @age, @height} = options
</pre><pre class="idle"><span class="Storage">var</span> Person;
Person <span class="Keyword">=</span> (<span class="Storage">function</span>() {
<span class="Storage">function</span> <span class="FunctionName">Person</span>(<span class="FunctionArgument">options</span>) {
<span class="Variable">this</span>.<span class="LibraryConstant">name</span> <span class="Keyword">=</span> options.<span class="LibraryConstant">name</span>, <span class="Variable">this</span>.age <span class="Keyword">=</span> options.age, <span class="Variable">this</span>.<span class="LibraryConstant">height</span> <span class="Keyword">=</span> options.<span class="LibraryConstant">height</span>;
}
<span class="Keyword">return</span> Person;
})();
</pre><script>window.example29 = "class Person\n constructor: (options) -> \n {@name, @age, @height} = options\n\nalert contents.join(\"\")"</script><div class='minibutton load' onclick='javascript: loadConsole(example29);'>load</div><div class='minibutton ok' onclick='javascript: var Person;
Person = (function() {
function Person(options) {
this.name = options.name, this.age = options.age, this.height = options.height;
}
return Person;
})();
;alert(contents.join(""));'>run: contents.join("")</div><br class='clear' /></div>
<p>

View File

@@ -46,7 +46,7 @@
});
exports.run = function() {
var arg, args, _i, _len, _ref, _results;
var arg, args, e, _i, _len, _ref, _results;
global.__originalDirname = fs.realpathSync('.');
process.chdir(cakefileDirectory(__originalDirname));
args = process.argv.slice(2);
@@ -59,7 +59,8 @@
}
try {
options = oparse.parse(args);
} catch (e) {
} catch (_error) {
e = _error;
return fatalError("" + e);
}
_ref = options["arguments"];

View File

@@ -40,14 +40,12 @@
exports.helpers = helpers;
exports.compile = compile = function(code, options) {
var answer, coffeeFile, currentColumn, currentLine, fragment, fragments, header, js, jsFile, merge, newLines, sourceMap, _j, _len1;
var answer, currentColumn, currentLine, fragment, fragments, header, js, merge, newLines, sourceMap, _j, _len1;
if (options == null) {
options = {};
}
merge = exports.helpers.merge;
if (options.sourceMap) {
coffeeFile = helpers.baseFileName(options.filename);
jsFile = helpers.baseFileName(options.filename, true) + ".js";
sourceMap = new sourcemap.SourceMap();
}
fragments = (parser.parse(lexer.tokenize(code, options))).compileToFragments(options);
@@ -81,7 +79,7 @@
};
if (sourceMap) {
answer.sourceMap = sourceMap;
answer.v3SourceMap = sourcemap.generateV3SourceMap(sourceMap, coffeeFile, jsFile);
answer.v3SourceMap = sourcemap.generateV3SourceMap(sourceMap, options);
}
return answer;
} else {

View File

@@ -148,9 +148,12 @@
};
compileScript = function(file, input, base) {
var compiled, message, o, options, t, task, useColors;
var compiled, err, message, o, options, t, task, useColors;
if (base == null) {
base = null;
}
o = opts;
options = compileOptions(file);
options = compileOptions(file, base);
try {
t = task = {
file: file,
@@ -165,6 +168,9 @@
} else if (o.run) {
return CoffeeScript.run(t.input, t.options);
} else if (o.join && t.file !== o.join) {
if (helpers.isLiterate(file)) {
t.input = helpers.invertLiterate(t.input);
}
sourceCode[sources.indexOf(t.file)] = t.input;
return compileJoin();
} else {
@@ -178,12 +184,13 @@
if (o.print) {
return printLine(t.output.trim());
} else if (o.compile || o.map) {
return writeJs(base, t.file, t.output, t.sourceMap);
return writeJs(base, t.file, t.output, options.jsPath, t.sourceMap);
} else if (o.lint) {
return lint(t.file, t.output);
}
}
} catch (err) {
} catch (_error) {
err = _error;
CoffeeScript.emit('failure', err, task);
if (CoffeeScript.listeners('failure').length) {
return;
@@ -230,7 +237,7 @@
};
watch = function(source, base) {
var compile, compileTimeout, prevStats, rewatch, watchErr, watcher;
var compile, compileTimeout, e, prevStats, rewatch, watchErr, watcher;
prevStats = null;
compileTimeout = null;
watchErr = function(e) {
@@ -241,7 +248,8 @@
try {
rewatch();
return compile();
} catch (e) {
} catch (_error) {
e = _error;
removeSource(source, base, true);
return compileJoin();
}
@@ -272,7 +280,8 @@
};
try {
watcher = fs.watch(source, compile);
} catch (e) {
} catch (_error) {
e = _error;
watchErr(e);
}
return rewatch = function() {
@@ -284,7 +293,7 @@
};
watchDir = function(source, base) {
var readdirTimeout, watcher;
var e, readdirTimeout, watcher;
readdirTimeout = null;
try {
return watcher = fs.watch(source, function() {
@@ -319,7 +328,8 @@
});
});
});
} catch (e) {
} catch (_error) {
e = _error;
if (e.code !== 'ENOENT') {
throw e;
}
@@ -384,12 +394,11 @@
return path.join(dir, basename + extension);
};
writeJs = function(base, sourcePath, js, generatedSourceMap) {
var compile, jsDir, jsPath, sourceMapPath;
writeJs = function(base, sourcePath, js, jsPath, generatedSourceMap) {
var compile, jsDir, sourceMapPath;
if (generatedSourceMap == null) {
generatedSourceMap = null;
}
jsPath = outputPath(sourcePath, base);
sourceMapPath = outputPath(sourcePath, base, ".map");
jsDir = path.dirname(jsPath);
compile = function() {
@@ -476,14 +485,35 @@
}
};
compileOptions = function(filename) {
return {
compileOptions = function(filename, base) {
var answer, cwd, jsDir, jsPath;
answer = {
filename: filename,
literate: helpers.isLiterate(filename),
bare: opts.bare,
header: opts.compile,
sourceMap: opts.map
};
if (filename) {
if (base) {
cwd = process.cwd();
jsPath = outputPath(filename, base);
jsDir = path.dirname(jsPath);
answer = helpers.merge(answer, {
jsPath: jsPath,
sourceRoot: path.relative(jsDir, cwd),
sourceFiles: [path.relative(cwd, filename)],
generatedFile: helpers.baseFileName(jsPath)
});
} else {
answer = helpers.merge(answer, {
sourceRoot: "",
sourceFiles: [helpers.baseFileName(filename)],
generatedFile: helpers.baseFileName(filename, true) + ".js"
});
}
}
return answer;
};
forkNode = function() {

View File

@@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.6.1
(function() {
var buildLocationData, extend, flatten, repeat, _ref;
var buildLocationData, extend, flatten, last, repeat, _ref;
exports.starts = function(string, literal, start) {
return literal === string.substr(start, literal.length);
@@ -83,7 +83,7 @@
return val;
};
exports.last = function(array, back) {
exports.last = last = function(array, back) {
return array[array.length - (back || 0) - 1];
};
@@ -98,6 +98,25 @@
return false;
};
exports.invertLiterate = function(code) {
var line, lines, match;
lines = (function() {
var _i, _len, _ref1, _results;
_ref1 = code.split('\n');
_results = [];
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
line = _ref1[_i];
if (match = /^([ ]{4}|\t)/.exec(line)) {
_results.push(line.slice(match[0].length));
} else {
_results.push('# ' + line);
}
}
return _results;
})();
return lines.join('\n');
};
buildLocationData = function(first, last) {
if (!last) {
return first;
@@ -146,7 +165,7 @@
}
parts = file.split('.');
parts.pop();
if (parts[parts.length - 1] === 'coffee') {
if (parts[parts.length - 1] === 'coffee' && parts.length > 1) {
parts.pop();
}
return parts.join('.');

View File

@@ -1,11 +1,11 @@
// Generated by CoffeeScript 1.6.1
(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, LITERATE, 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, key, last, locationDataToString, 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, 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, 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; };
_ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES;
_ref1 = require('./helpers'), count = _ref1.count, starts = _ref1.starts, compact = _ref1.compact, last = _ref1.last, locationDataToString = _ref1.locationDataToString, throwSyntaxError = _ref1.throwSyntaxError;
_ref1 = require('./helpers'), count = _ref1.count, starts = _ref1.starts, compact = _ref1.compact, last = _ref1.last, invertLiterate = _ref1.invertLiterate, locationDataToString = _ref1.locationDataToString, throwSyntaxError = _ref1.throwSyntaxError;
exports.Lexer = Lexer = (function() {
@@ -43,7 +43,6 @@
};
Lexer.prototype.clean = function(code) {
var line, lines, match;
if (code.charCodeAt(0) === BOM) {
code = code.slice(1);
}
@@ -53,21 +52,7 @@
this.chunkLine--;
}
if (this.literate) {
lines = (function() {
var _i, _len, _ref2, _results;
_ref2 = code.split('\n');
_results = [];
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
line = _ref2[_i];
if (match = LITERATE.exec(line)) {
_results.push(line.slice(match[0].length));
} else {
_results.push('# ' + line);
}
}
return _results;
})();
code = lines.join('\n');
code = invertLiterate(code);
}
return code;
};
@@ -605,7 +590,7 @@
};
Lexer.prototype.interpolateString = function(str, options) {
var column, expr, heredoc, i, inner, interpolated, len, letter, lexedLength, line, locationToken, nested, offsetInChunk, pi, plusToken, popped, regex, strOffset, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
var column, expr, heredoc, i, inner, interpolated, len, letter, lexedLength, line, locationToken, nested, offsetInChunk, pi, plusToken, popped, regex, rparen, strOffset, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
if (options == null) {
options = {};
}
@@ -695,7 +680,9 @@
}
}
if (interpolated) {
this.token(')', ')', offsetInChunk + lexedLength, 0);
rparen = this.makeToken(')', ')', offsetInChunk + lexedLength, 0);
rparen.stringEnd = true;
this.tokens.push(rparen);
}
return tokens;
};
@@ -853,8 +840,6 @@
COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|(?:###)$)|^(?:\s*#(?!##[^#]).*)+/;
LITERATE = /^([ ]{4}|\t)/;
CODE = /^[-=]>/;
MULTI_DENT = /^(?:\n[^\n\S]*)+/;

View File

@@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.6.1
(function() {
var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, CodeFragment, Comment, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, 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, last, locationDataToString, merge, multident, some, starts, throwSyntaxError, unfoldSoak, utility, _ref, _ref1,
var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, CodeFragment, Comment, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, 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, last, locationDataToString, merge, multident, some, starts, throwSyntaxError, unfoldSoak, utility, _ref, _ref1, _ref2, _ref3,
__hasProp = {}.hasOwnProperty,
__extends = 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; },
__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; },
@@ -151,15 +151,14 @@
};
Base.prototype.toString = function(idt, name) {
var location, tree;
var tree;
if (idt == null) {
idt = '';
}
if (name == null) {
name = this.constructor.name;
}
location = this.locationData ? locationDataToString(this.locationData) : "??";
tree = '\n' + idt + location + ": " + name;
tree = '\n' + idt + name;
if (this.soak) {
tree += '?';
}
@@ -550,7 +549,8 @@
__extends(Undefined, _super);
function Undefined() {
return Undefined.__super__.constructor.apply(this, arguments);
_ref2 = Undefined.__super__.constructor.apply(this, arguments);
return _ref2;
}
Undefined.prototype.isAssignable = NO;
@@ -570,7 +570,8 @@
__extends(Null, _super);
function Null() {
return Null.__super__.constructor.apply(this, arguments);
_ref3 = Null.__super__.constructor.apply(this, arguments);
return _ref3;
}
Null.prototype.isAssignable = NO;
@@ -624,8 +625,8 @@
Return.prototype.jumps = THIS;
Return.prototype.compileToFragments = function(o, level) {
var expr, _ref2;
expr = (_ref2 = this.expression) != null ? _ref2.makeReturn() : void 0;
var expr, _ref4;
expr = (_ref4 = this.expression) != null ? _ref4.makeReturn() : void 0;
if (expr && !(expr instanceof Return)) {
return expr.compileToFragments(o, level);
} else {
@@ -696,10 +697,10 @@
};
Value.prototype.isAtomic = function() {
var node, _i, _len, _ref2;
_ref2 = this.properties.concat(this.base);
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
node = _ref2[_i];
var node, _i, _len, _ref4;
_ref4 = this.properties.concat(this.base);
for (_i = 0, _len = _ref4.length; _i < _len; _i++) {
node = _ref4[_i];
if (node.soak || node instanceof Call) {
return false;
}
@@ -776,17 +777,17 @@
};
Value.prototype.unfoldSoak = function(o) {
var _ref2,
var _ref4,
_this = this;
return (_ref2 = this.unfoldedSoak) != null ? _ref2 : this.unfoldedSoak = (function() {
var fst, i, ifn, prop, ref, snd, _i, _len, _ref3, _ref4;
return (_ref4 = this.unfoldedSoak) != null ? _ref4 : this.unfoldedSoak = (function() {
var fst, i, ifn, prop, ref, snd, _i, _len, _ref5, _ref6;
if (ifn = _this.base.unfoldSoak(o)) {
(_ref3 = ifn.body.properties).push.apply(_ref3, _this.properties);
(_ref5 = ifn.body.properties).push.apply(_ref5, _this.properties);
return ifn;
}
_ref4 = _this.properties;
for (i = _i = 0, _len = _ref4.length; _i < _len; i = ++_i) {
prop = _ref4[i];
_ref6 = _this.properties;
for (i = _i = 0, _len = _ref6.length; _i < _len; i = ++_i) {
prop = _ref6[i];
if (!prop.soak) {
continue;
}
@@ -850,8 +851,8 @@
Call.prototype.children = ['variable', 'args'];
Call.prototype.newInstance = function() {
var base, _ref2;
base = ((_ref2 = this.variable) != null ? _ref2.base : void 0) || this.variable;
var base, _ref4;
base = ((_ref4 = this.variable) != null ? _ref4.base : void 0) || this.variable;
if (base instanceof Call && !base.isNew) {
base.newInstance();
} else {
@@ -884,13 +885,13 @@
};
Call.prototype.unfoldSoak = function(o) {
var call, ifn, left, list, rite, _i, _len, _ref2, _ref3;
var call, ifn, left, list, rite, _i, _len, _ref4, _ref5;
if (this.soak) {
if (this.variable) {
if (ifn = unfoldSoak(o, this, 'variable')) {
return ifn;
}
_ref2 = new Value(this.variable).cacheReference(o), left = _ref2[0], rite = _ref2[1];
_ref4 = new Value(this.variable).cacheReference(o), left = _ref4[0], rite = _ref4[1];
} else {
left = new Literal(this.superReference(o));
rite = new Value(left);
@@ -918,9 +919,9 @@
break;
}
}
_ref3 = list.reverse();
for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
call = _ref3[_i];
_ref5 = list.reverse();
for (_i = 0, _len = _ref5.length; _i < _len; _i++) {
call = _ref5[_i];
if (ifn) {
if (call.variable instanceof Call) {
call.variable = ifn;
@@ -934,18 +935,18 @@
};
Call.prototype.compileNode = function(o) {
var arg, argIndex, compiledArgs, compiledArray, fragments, preface, _i, _len, _ref2, _ref3;
if ((_ref2 = this.variable) != null) {
_ref2.front = this.front;
var arg, argIndex, compiledArgs, compiledArray, fragments, preface, _i, _len, _ref4, _ref5;
if ((_ref4 = this.variable) != null) {
_ref4.front = this.front;
}
compiledArray = Splat.compileSplattedArray(o, this.args, true);
if (compiledArray.length) {
return this.compileSplat(o, compiledArray);
}
compiledArgs = [];
_ref3 = this.args;
for (argIndex = _i = 0, _len = _ref3.length; _i < _len; argIndex = ++_i) {
arg = _ref3[argIndex];
_ref5 = this.args;
for (argIndex = _i = 0, _len = _ref5.length; _i < _len; argIndex = ++_i) {
arg = _ref5[argIndex];
if (argIndex) {
compiledArgs.push(this.makeCode(", "));
}
@@ -1089,23 +1090,23 @@
}
Range.prototype.compileVariables = function(o) {
var step, _ref2, _ref3, _ref4, _ref5;
var step, _ref4, _ref5, _ref6, _ref7;
o = merge(o, {
top: true
});
_ref2 = this.cacheToCodeFragments(this.from.cache(o, LEVEL_LIST)), this.fromC = _ref2[0], this.fromVar = _ref2[1];
_ref3 = this.cacheToCodeFragments(this.to.cache(o, LEVEL_LIST)), this.toC = _ref3[0], this.toVar = _ref3[1];
_ref4 = this.cacheToCodeFragments(this.from.cache(o, LEVEL_LIST)), this.fromC = _ref4[0], this.fromVar = _ref4[1];
_ref5 = this.cacheToCodeFragments(this.to.cache(o, LEVEL_LIST)), this.toC = _ref5[0], this.toVar = _ref5[1];
if (step = del(o, 'step')) {
_ref4 = this.cacheToCodeFragments(step.cache(o, LEVEL_LIST)), this.step = _ref4[0], this.stepVar = _ref4[1];
_ref6 = this.cacheToCodeFragments(step.cache(o, LEVEL_LIST)), this.step = _ref6[0], this.stepVar = _ref6[1];
}
_ref5 = [this.fromVar.match(SIMPLENUM), this.toVar.match(SIMPLENUM)], this.fromNum = _ref5[0], this.toNum = _ref5[1];
_ref7 = [this.fromVar.match(SIMPLENUM), this.toVar.match(SIMPLENUM)], this.fromNum = _ref7[0], this.toNum = _ref7[1];
if (this.stepVar) {
return this.stepNum = this.stepVar.match(SIMPLENUM);
}
};
Range.prototype.compileNode = function(o) {
var cond, condPart, from, gt, idx, idxName, known, lt, namedIndex, stepPart, to, varPart, _ref2, _ref3;
var cond, condPart, from, gt, idx, idxName, known, lt, namedIndex, stepPart, to, varPart, _ref4, _ref5;
if (!this.fromVar) {
this.compileVariables(o);
}
@@ -1123,8 +1124,8 @@
if (this.step !== this.stepVar) {
varPart += ", " + this.step;
}
_ref2 = ["" + idx + " <" + this.equals, "" + idx + " >" + this.equals], lt = _ref2[0], gt = _ref2[1];
condPart = this.stepNum ? +this.stepNum > 0 ? "" + lt + " " + this.toVar : "" + gt + " " + this.toVar : known ? ((_ref3 = [+this.fromNum, +this.toNum], from = _ref3[0], to = _ref3[1], _ref3), from <= to ? "" + lt + " " + to : "" + gt + " " + to) : (cond = this.stepVar ? "" + this.stepVar + " > 0" : "" + this.fromVar + " <= " + this.toVar, "" + cond + " ? " + lt + " " + this.toVar + " : " + gt + " " + this.toVar);
_ref4 = ["" + idx + " <" + this.equals, "" + idx + " >" + this.equals], lt = _ref4[0], gt = _ref4[1];
condPart = this.stepNum ? +this.stepNum > 0 ? "" + lt + " " + this.toVar : "" + gt + " " + this.toVar : known ? ((_ref5 = [+this.fromNum, +this.toNum], from = _ref5[0], to = _ref5[1], _ref5), from <= to ? "" + lt + " " + to : "" + gt + " " + to) : (cond = this.stepVar ? "" + this.stepVar + " > 0" : "" + this.fromVar + " <= " + this.toVar, "" + cond + " ? " + lt + " " + this.toVar + " : " + gt + " " + this.toVar);
stepPart = this.stepVar ? "" + idx + " += " + this.stepVar : known ? namedIndex ? from <= to ? "++" + idx : "--" + idx : from <= to ? "" + idx + "++" : "" + idx + "--" : namedIndex ? "" + cond + " ? ++" + idx + " : --" + idx : "" + cond + " ? " + idx + "++ : " + idx + "--";
if (namedIndex) {
varPart = "" + idxName + " = " + varPart;
@@ -1136,11 +1137,11 @@
};
Range.prototype.compileArray = function(o) {
var args, body, cond, hasArgs, i, idt, post, pre, range, result, vars, _i, _ref2, _ref3, _results;
var args, body, cond, hasArgs, i, idt, post, pre, range, result, vars, _i, _ref4, _ref5, _results;
if (this.fromNum && this.toNum && Math.abs(this.fromNum - this.toNum) <= 20) {
range = (function() {
_results = [];
for (var _i = _ref2 = +this.fromNum, _ref3 = +this.toNum; _ref2 <= _ref3 ? _i <= _ref3 : _i >= _ref3; _ref2 <= _ref3 ? _i++ : _i--){ _results.push(_i); }
for (var _i = _ref4 = +this.fromNum, _ref5 = +this.toNum; _ref4 <= _ref5 ? _i <= _ref5 : _i >= _ref5; _ref4 <= _ref5 ? _i++ : _i--){ _results.push(_i); }
return _results;
}).apply(this);
if (this.exclusive) {
@@ -1188,8 +1189,8 @@
}
Slice.prototype.compileNode = function(o) {
var compiled, compiledText, from, fromCompiled, to, toStr, _ref2;
_ref2 = this.range, to = _ref2.to, from = _ref2.from;
var compiled, compiledText, from, fromCompiled, to, toStr, _ref4;
_ref4 = this.range, to = _ref4.to, from = _ref4.from;
fromCompiled = from && from.compileToFragments(o, LEVEL_PAREN) || [this.makeCode('0')];
if (to) {
compiled = to.compileToFragments(o, LEVEL_PAREN);
@@ -1237,6 +1238,9 @@
prop = props[i];
join = i === props.length - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n';
indent = prop instanceof Comment ? '' : idt;
if (prop instanceof Assign && prop.variable instanceof Value && prop.variable.hasProperties()) {
throw new SyntaxError('Invalid object key');
}
if (prop instanceof Value && prop["this"]) {
prop = new Assign(prop.properties[0].name, prop, 'object');
}
@@ -1264,10 +1268,10 @@
};
Obj.prototype.assigns = function(name) {
var prop, _i, _len, _ref2;
_ref2 = this.properties;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
prop = _ref2[_i];
var prop, _i, _len, _ref4;
_ref4 = this.properties;
for (_i = 0, _len = _ref4.length; _i < _len; _i++) {
prop = _ref4[_i];
if (prop.assigns(name)) {
return true;
}
@@ -1301,11 +1305,11 @@
}
answer = [];
compiledObjs = (function() {
var _i, _len, _ref2, _results;
_ref2 = this.objects;
var _i, _len, _ref4, _results;
_ref4 = this.objects;
_results = [];
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
obj = _ref2[_i];
for (_i = 0, _len = _ref4.length; _i < _len; _i++) {
obj = _ref4[_i];
_results.push(obj.compileToFragments(o, LEVEL_LIST));
}
return _results;
@@ -1328,10 +1332,10 @@
};
Arr.prototype.assigns = function(name) {
var obj, _i, _len, _ref2;
_ref2 = this.objects;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
obj = _ref2[_i];
var obj, _i, _len, _ref4;
_ref4 = this.objects;
for (_i = 0, _len = _ref4.length; _i < _len; _i++) {
obj = _ref4[_i];
if (obj.assigns(name)) {
return true;
}
@@ -1386,18 +1390,12 @@
};
Class.prototype.addBoundFunctions = function(o) {
var body, bound, func, lhs, name, rhs, _i, _len, _ref2, _ref3;
if (this.boundFuncs.length) {
o.scope.assign('_this', 'this');
_ref2 = this.boundFuncs;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
_ref3 = _ref2[_i], name = _ref3[0], func = _ref3[1];
lhs = new Value(new Literal("this"), [new Access(name)]);
body = new Block([new Return(new Literal("" + this.ctor.name + ".prototype." + name.value + ".apply(_this, arguments)"))]);
rhs = new Code(func.params, body, 'boundfunc');
bound = new Assign(lhs, rhs);
this.ctor.body.unshift(bound);
}
var bvar, lhs, _i, _len, _ref4;
_ref4 = this.boundFuncs;
for (_i = 0, _len = _ref4.length; _i < _len; _i++) {
bvar = _ref4[_i];
lhs = (new Value(new Literal("this"), [new Access(bvar)])).compile(o);
this.ctor.body.unshift(new Literal("" + lhs + " = " + (utility('bind')) + "(" + lhs + ", this)"));
}
};
@@ -1434,7 +1432,7 @@
} else {
assign.variable = new Value(new Literal(name), [new Access(new Literal('prototype')), new Access(base)]);
if (func instanceof Code && func.bound) {
this.boundFuncs.push([base, func]);
this.boundFuncs.push(base);
func.bound = false;
}
}
@@ -1450,15 +1448,15 @@
Class.prototype.walkBody = function(name, o) {
var _this = this;
return this.traverseChildren(false, function(child) {
var cont, exps, i, node, _i, _len, _ref2;
var cont, exps, i, node, _i, _len, _ref4;
cont = true;
if (child instanceof Class) {
return false;
}
if (child instanceof Block) {
_ref2 = exps = child.expressions;
for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
node = _ref2[i];
_ref4 = exps = child.expressions;
for (i = _i = 0, _len = _ref4.length; _i < _len; i = ++_i) {
node = _ref4[i];
if (node instanceof Value && node.isObject(true)) {
cont = false;
exps[i] = _this.addProperties(node, name, o);
@@ -1480,25 +1478,37 @@
return this.directives = expressions.splice(0, index);
};
Class.prototype.ensureConstructor = function(name) {
if (!this.ctor) {
this.ctor = new Code;
if (this.parent) {
this.ctor.body.push(new Literal("" + name + ".__super__.constructor.apply(this, arguments)"));
}
if (this.externalCtor) {
this.ctor.body.push(new Literal("" + this.externalCtor + ".apply(this, arguments)"));
}
this.ctor.body.makeReturn();
this.body.expressions.unshift(this.ctor);
}
Class.prototype.ensureConstructor = function(name, o) {
var missing, ref, superCall;
missing = !this.ctor;
this.ctor || (this.ctor = new Code);
this.ctor.ctor = this.ctor.name = name;
this.ctor.klass = null;
return this.ctor.noReturn = true;
this.ctor.noReturn = true;
if (missing) {
if (this.parent) {
superCall = new Literal("" + name + ".__super__.constructor.apply(this, arguments)");
}
if (this.externalCtor) {
superCall = new Literal("" + this.externalCtor + ".apply(this, arguments)");
}
if (superCall) {
ref = new Literal(o.scope.freeVariable('ref'));
this.ctor.body.unshift(new Assign(ref, superCall));
}
this.addBoundFunctions(o);
if (superCall) {
this.ctor.body.push(ref);
this.ctor.body.makeReturn();
}
return this.body.expressions.unshift(this.ctor);
} else {
return this.addBoundFunctions(o);
}
};
Class.prototype.compileNode = function(o) {
var call, decl, klass, lname, name, params, _ref2;
var call, decl, klass, lname, name, params, _ref4;
decl = this.determineName();
name = decl || '_Class';
if (name.reserved) {
@@ -1508,14 +1518,13 @@
this.hoistDirectivePrologue();
this.setContext(name);
this.walkBody(name, o);
this.ensureConstructor(name);
this.ensureConstructor(name, o);
this.body.spaced = true;
if (!(this.ctor instanceof Code)) {
this.body.expressions.unshift(this.ctor);
}
this.body.expressions.push(lname);
(_ref2 = this.body.expressions).unshift.apply(_ref2, this.directives);
this.addBoundFunctions(o);
(_ref4 = this.body.expressions).unshift.apply(_ref4, this.directives);
call = Closure.wrap(this.body);
if (this.parent) {
this.superClass = new Literal(o.scope.freeVariable('super', false));
@@ -1540,13 +1549,13 @@
__extends(Assign, _super);
function Assign(variable, value, context, options) {
var forbidden, name, _ref2;
var forbidden, name, _ref4;
this.variable = variable;
this.value = value;
this.context = context;
this.param = options && options.param;
this.subpattern = options && options.subpattern;
forbidden = (_ref2 = (name = this.variable.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0);
forbidden = (_ref4 = (name = this.variable.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref4) >= 0);
if (forbidden && this.context !== 'object') {
this.variable.error("variable name may not be \"" + name + "\"");
}
@@ -1567,7 +1576,7 @@
};
Assign.prototype.compileNode = function(o) {
var answer, compiledName, isValue, match, name, val, varBase, _ref2, _ref3, _ref4, _ref5;
var answer, compiledName, isValue, match, name, val, varBase, _ref4, _ref5, _ref6, _ref7;
if (isValue = this.variable instanceof Value) {
if (this.variable.isArray() || this.variable.isObject()) {
return this.compilePatternMatch(o);
@@ -1575,7 +1584,7 @@
if (this.variable.isSplice()) {
return this.compileSplice(o);
}
if ((_ref2 = this.context) === '||=' || _ref2 === '&&=' || _ref2 === '?=') {
if ((_ref4 = this.context) === '||=' || _ref4 === '&&=' || _ref4 === '?=') {
return this.compileConditional(o);
}
}
@@ -1598,7 +1607,7 @@
if (match[1]) {
this.value.klass = match[1];
}
this.value.name = (_ref3 = (_ref4 = (_ref5 = match[2]) != null ? _ref5 : match[3]) != null ? _ref4 : match[4]) != null ? _ref3 : match[5];
this.value.name = (_ref5 = (_ref6 = (_ref7 = match[2]) != null ? _ref7 : match[3]) != null ? _ref6 : match[4]) != null ? _ref5 : match[5];
}
val = this.value.compileToFragments(o, LEVEL_LIST);
if (this.context === 'object') {
@@ -1613,7 +1622,7 @@
};
Assign.prototype.compilePatternMatch = function(o) {
var acc, assigns, code, fragments, i, idx, isObject, ivar, name, obj, objects, olen, ref, rest, splat, top, val, value, vvar, vvarText, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7;
var acc, assigns, code, fragments, i, idx, isObject, ivar, name, obj, objects, olen, ref, rest, splat, top, val, value, vvar, vvarText, _i, _len, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9;
top = o.level === LEVEL_TOP;
value = this.value;
objects = this.variable.base.objects;
@@ -1628,14 +1637,14 @@
isObject = this.variable.isObject();
if (top && olen === 1 && !((obj = objects[0]) instanceof Splat)) {
if (obj instanceof Assign) {
_ref2 = obj, (_ref3 = _ref2.variable, idx = _ref3.base), obj = _ref2.value;
_ref4 = obj, (_ref5 = _ref4.variable, idx = _ref5.base), obj = _ref4.value;
} else {
idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(0);
}
acc = IDENTIFIER.test(idx.unwrap().value || 0);
value = new Value(value);
value.properties.push(new (acc ? Access : Index)(idx));
if (_ref4 = obj.unwrap().value, __indexOf.call(RESERVED, _ref4) >= 0) {
if (_ref6 = obj.unwrap().value, __indexOf.call(RESERVED, _ref6) >= 0) {
obj.error("assignment to a reserved word: " + (obj.compile(o)));
}
return new Assign(obj, value, null, {
@@ -1656,10 +1665,10 @@
idx = i;
if (isObject) {
if (obj instanceof Assign) {
_ref5 = obj, (_ref6 = _ref5.variable, idx = _ref6.base), obj = _ref5.value;
_ref7 = obj, (_ref8 = _ref7.variable, idx = _ref8.base), obj = _ref7.value;
} else {
if (obj.base instanceof Parens) {
_ref7 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref7[0], idx = _ref7[1];
_ref9 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref9[0], idx = _ref9[1];
} else {
idx = obj["this"] ? obj.properties[0].name : obj;
}
@@ -1710,8 +1719,8 @@
};
Assign.prototype.compileConditional = function(o) {
var left, right, _ref2;
_ref2 = this.variable.cacheReference(o), left = _ref2[0], right = _ref2[1];
var left, right, _ref4;
_ref4 = this.variable.cacheReference(o), left = _ref4[0], right = _ref4[1];
if (!left.properties.length && left.base instanceof Literal && left.base.value !== "this" && !o.scope.check(left.base.value)) {
this.variable.error("the variable \"" + left.base.value + "\" can't be assigned with " + this.context + " because it has not been declared before");
}
@@ -1722,11 +1731,11 @@
};
Assign.prototype.compileSplice = function(o) {
var answer, exclusive, from, fromDecl, fromRef, name, to, valDef, valRef, _ref2, _ref3, _ref4;
_ref2 = this.variable.properties.pop().range, from = _ref2.from, to = _ref2.to, exclusive = _ref2.exclusive;
var answer, exclusive, from, fromDecl, fromRef, name, to, valDef, valRef, _ref4, _ref5, _ref6;
_ref4 = this.variable.properties.pop().range, from = _ref4.from, to = _ref4.to, exclusive = _ref4.exclusive;
name = this.variable.compile(o);
if (from) {
_ref3 = this.cacheToCodeFragments(from.cache(o, LEVEL_OP)), fromDecl = _ref3[0], fromRef = _ref3[1];
_ref5 = this.cacheToCodeFragments(from.cache(o, LEVEL_OP)), fromDecl = _ref5[0], fromRef = _ref5[1];
} else {
fromDecl = fromRef = '0';
}
@@ -1745,7 +1754,7 @@
} else {
to = "9e9";
}
_ref4 = this.value.cache(o, LEVEL_LIST), valDef = _ref4[0], valRef = _ref4[1];
_ref6 = this.value.cache(o, LEVEL_LIST), valDef = _ref6[0], valRef = _ref6[1];
answer = [].concat(this.makeCode("[].splice.apply(" + name + ", [" + fromDecl + ", " + to + "].concat("), valDef, this.makeCode(")), "), valRef);
if (o.level > LEVEL_TOP) {
return this.wrapInBraces(answer);
@@ -1780,7 +1789,7 @@
Code.prototype.jumps = NO;
Code.prototype.compileNode = function(o) {
var answer, code, exprs, i, idt, lit, p, param, params, ref, splats, uniqs, val, wasEmpty, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref2, _ref3, _ref4, _ref5, _ref6;
var answer, code, exprs, i, idt, lit, p, param, params, ref, splats, uniqs, val, wasEmpty, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref4, _ref5, _ref6, _ref7, _ref8;
o.scope = new Scope(o.scope, this.body, this);
o.scope.shared = del(o, 'sharedScope');
o.indent += TAB;
@@ -1793,15 +1802,15 @@
return o.scope.parameter(name);
}
});
_ref2 = this.params;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
param = _ref2[_i];
_ref4 = this.params;
for (_i = 0, _len = _ref4.length; _i < _len; _i++) {
param = _ref4[_i];
if (!param.splat) {
continue;
}
_ref3 = this.params;
for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
p = _ref3[_j].name;
_ref5 = this.params;
for (_j = 0, _len1 = _ref5.length; _j < _len1; _j++) {
p = _ref5[_j].name;
if (p["this"]) {
p = p.properties[0].name;
}
@@ -1810,20 +1819,20 @@
}
}
splats = new Assign(new Value(new Arr((function() {
var _k, _len2, _ref4, _results;
_ref4 = this.params;
var _k, _len2, _ref6, _results;
_ref6 = this.params;
_results = [];
for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
p = _ref4[_k];
for (_k = 0, _len2 = _ref6.length; _k < _len2; _k++) {
p = _ref6[_k];
_results.push(p.asReference(o));
}
return _results;
}).call(this))), new Value(new Literal('arguments')));
break;
}
_ref4 = this.params;
for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
param = _ref4[_k];
_ref6 = this.params;
for (_k = 0, _len2 = _ref6.length; _k < _len2; _k++) {
param = _ref6[_k];
if (param.isComplex()) {
val = ref = param.asReference(o);
if (param.value) {
@@ -1849,7 +1858,7 @@
exprs.unshift(splats);
}
if (exprs.length) {
(_ref5 = this.body.expressions).unshift.apply(_ref5, exprs);
(_ref7 = this.body.expressions).unshift.apply(_ref7, exprs);
}
for (i = _l = 0, _len3 = params.length; _l < _len3; i = ++_l) {
p = params[i];
@@ -1867,7 +1876,7 @@
this.body.makeReturn();
}
if (this.bound) {
if ((_ref6 = o.scope.parent.method) != null ? _ref6.bound : void 0) {
if ((_ref8 = o.scope.parent.method) != null ? _ref8.bound : void 0) {
this.bound = this.context = o.scope.parent.method.context;
} else if (!this["static"]) {
o.scope.parent.assign('_this', 'this');
@@ -1903,11 +1912,11 @@
};
Code.prototype.eachParamName = function(iterator) {
var param, _i, _len, _ref2, _results;
_ref2 = this.params;
var param, _i, _len, _ref4, _results;
_ref4 = this.params;
_results = [];
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
param = _ref2[_i];
for (_i = 0, _len = _ref4.length; _i < _len; _i++) {
param = _ref4[_i];
_results.push(param.eachName(iterator));
}
return _results;
@@ -1928,11 +1937,11 @@
__extends(Param, _super);
function Param(name, value, splat) {
var _ref2;
var _ref4;
this.name = name;
this.value = value;
this.splat = splat;
if (_ref2 = (name = this.name.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0) {
if (_ref4 = (name = this.name.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref4) >= 0) {
this.name.error("parameter name \"" + name + "\" is not allowed");
}
}
@@ -1969,7 +1978,7 @@
};
Param.prototype.eachName = function(iterator, name) {
var atParam, node, obj, _i, _len, _ref2;
var atParam, node, obj, _i, _len, _ref4;
if (name == null) {
name = this.name;
}
@@ -1986,9 +1995,9 @@
if (name instanceof Value) {
return atParam(name);
}
_ref2 = name.objects;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
obj = _ref2[_i];
_ref4 = name.objects;
for (_i = 0, _len = _ref4.length; _i < _len; _i++) {
obj = _ref4[_i];
if (obj instanceof Assign) {
this.eachName(iterator, obj.value.unwrap());
} else if (obj instanceof Splat) {
@@ -2065,11 +2074,11 @@
return args[0].concat(node.makeCode(".concat("), concatPart, node.makeCode(")"));
}
base = (function() {
var _j, _len1, _ref2, _results;
_ref2 = list.slice(0, index);
var _j, _len1, _ref4, _results;
_ref4 = list.slice(0, index);
_results = [];
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
node = _ref2[_j];
for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) {
node = _ref4[_j];
_results.push(node.compileToFragments(o, LEVEL_LIST));
}
return _results;
@@ -2210,17 +2219,17 @@
};
Op.prototype.isComplex = function() {
var _ref2;
return !(this.isUnary() && ((_ref2 = this.operator) === '+' || _ref2 === '-')) || this.first.isComplex();
var _ref4;
return !(this.isUnary() && ((_ref4 = this.operator) === '+' || _ref4 === '-')) || this.first.isComplex();
};
Op.prototype.isChainable = function() {
var _ref2;
return (_ref2 = this.operator) === '<' || _ref2 === '>' || _ref2 === '>=' || _ref2 === '<=' || _ref2 === '===' || _ref2 === '!==';
var _ref4;
return (_ref4 = this.operator) === '<' || _ref4 === '>' || _ref4 === '>=' || _ref4 === '<=' || _ref4 === '===' || _ref4 === '!==';
};
Op.prototype.invert = function() {
var allInvertable, curr, fst, op, _ref2;
var allInvertable, curr, fst, op, _ref4;
if (this.isChainable() && this.first.isChainable()) {
allInvertable = true;
curr = this;
@@ -2246,7 +2255,7 @@
return this;
} else if (this.second) {
return new Parens(this).invert();
} else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((_ref2 = fst.operator) === '!' || _ref2 === 'in' || _ref2 === 'instanceof')) {
} else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((_ref4 = fst.operator) === '!' || _ref4 === 'in' || _ref4 === 'instanceof')) {
return fst;
} else {
return new Op('!', this);
@@ -2254,17 +2263,17 @@
};
Op.prototype.unfoldSoak = function(o) {
var _ref2;
return ((_ref2 = this.operator) === '++' || _ref2 === '--' || _ref2 === 'delete') && unfoldSoak(o, this, 'first');
var _ref4;
return ((_ref4 = this.operator) === '++' || _ref4 === '--' || _ref4 === 'delete') && unfoldSoak(o, this, 'first');
};
Op.prototype.generateDo = function(exp) {
var call, func, param, passedParams, ref, _i, _len, _ref2;
var call, func, param, passedParams, ref, _i, _len, _ref4;
passedParams = [];
func = exp instanceof Assign && (ref = exp.value.unwrap()) instanceof Code ? ref : exp;
_ref2 = func.params || [];
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
param = _ref2[_i];
_ref4 = func.params || [];
for (_i = 0, _len = _ref4.length; _i < _len; _i++) {
param = _ref4[_i];
if (param.value) {
passedParams.push(param.value);
delete param.value;
@@ -2278,7 +2287,7 @@
};
Op.prototype.compileNode = function(o) {
var answer, isChain, _ref2, _ref3;
var answer, isChain, _ref4, _ref5;
isChain = this.isChainable() && this.first.isChainable();
if (!isChain) {
this.first.front = this.front;
@@ -2286,7 +2295,7 @@
if (this.operator === 'delete' && o.scope.check(this.first.unwrapAll().value)) {
this.error('delete operand may not be argument or var');
}
if (((_ref2 = this.operator) === '--' || _ref2 === '++') && (_ref3 = this.first.unwrapAll().value, __indexOf.call(STRICT_PROSCRIBED, _ref3) >= 0)) {
if (((_ref4 = this.operator) === '--' || _ref4 === '++') && (_ref5 = this.first.unwrapAll().value, __indexOf.call(STRICT_PROSCRIBED, _ref5) >= 0)) {
this.error("cannot increment/decrement \"" + (this.first.unwrapAll().value) + "\"");
}
if (this.isUnary()) {
@@ -2307,8 +2316,8 @@
};
Op.prototype.compileChain = function(o) {
var fragments, fst, shared, _ref2;
_ref2 = this.first.second.cache(o), this.first.second = _ref2[0], shared = _ref2[1];
var fragments, fst, shared, _ref4;
_ref4 = this.first.second.cache(o), this.first.second = _ref4[0], shared = _ref4[1];
fst = this.first.compileToFragments(o, LEVEL_OP);
fragments = fst.concat(this.makeCode(" " + (this.invert ? '&&' : '||') + " "), shared.compileToFragments(o), this.makeCode(" " + this.operator + " "), this.second.compileToFragments(o, LEVEL_OP));
return this.wrapInBraces(fragments);
@@ -2376,11 +2385,11 @@
In.prototype.invert = NEGATE;
In.prototype.compileNode = function(o) {
var hasSplat, obj, _i, _len, _ref2;
var hasSplat, obj, _i, _len, _ref4;
if (this.array instanceof Value && this.array.isArray()) {
_ref2 = this.array.base.objects;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
obj = _ref2[_i];
_ref4 = this.array.base.objects;
for (_i = 0, _len = _ref4.length; _i < _len; _i++) {
obj = _ref4[_i];
if (!(obj instanceof Splat)) {
continue;
}
@@ -2395,16 +2404,16 @@
};
In.prototype.compileOrTest = function(o) {
var cmp, cnj, i, item, ref, sub, tests, _i, _len, _ref2, _ref3, _ref4;
var cmp, cnj, i, item, ref, sub, tests, _i, _len, _ref4, _ref5, _ref6;
if (this.array.base.objects.length === 0) {
return [this.makeCode("" + (!!this.negated))];
}
_ref2 = this.object.cache(o, LEVEL_OP), sub = _ref2[0], ref = _ref2[1];
_ref3 = this.negated ? [' !== ', ' && '] : [' === ', ' || '], cmp = _ref3[0], cnj = _ref3[1];
_ref4 = this.object.cache(o, LEVEL_OP), sub = _ref4[0], ref = _ref4[1];
_ref5 = this.negated ? [' !== ', ' && '] : [' === ', ' || '], cmp = _ref5[0], cnj = _ref5[1];
tests = [];
_ref4 = this.array.base.objects;
for (i = _i = 0, _len = _ref4.length; _i < _len; i = ++_i) {
item = _ref4[i];
_ref6 = this.array.base.objects;
for (i = _i = 0, _len = _ref6.length; _i < _len; i = ++_i) {
item = _ref6[i];
if (i) {
tests.push(this.makeCode(cnj));
}
@@ -2418,8 +2427,8 @@
};
In.prototype.compileLoopTest = function(o) {
var fragments, ref, sub, _ref2;
_ref2 = this.object.cache(o, LEVEL_LIST), sub = _ref2[0], ref = _ref2[1];
var fragments, ref, sub, _ref4;
_ref4 = this.object.cache(o, LEVEL_LIST), sub = _ref4[0], ref = _ref4[1];
fragments = [].concat(this.makeCode(utility('indexOf') + ".call("), this.array.compileToFragments(o, LEVEL_LIST), this.makeCode(", "), ref, this.makeCode(") " + (this.negated ? '< 0' : '>= 0')));
if ((fragmentsToText(sub)) === (fragmentsToText(ref))) {
return fragments;
@@ -2456,8 +2465,8 @@
Try.prototype.isStatement = YES;
Try.prototype.jumps = function(o) {
var _ref2;
return this.attempt.jumps(o) || ((_ref2 = this.recovery) != null ? _ref2.jumps(o) : void 0);
var _ref4;
return this.attempt.jumps(o) || ((_ref4 = this.recovery) != null ? _ref4.jumps(o) : void 0);
};
Try.prototype.makeReturn = function(res) {
@@ -2471,10 +2480,10 @@
};
Try.prototype.compileNode = function(o) {
var catchPart, ensurePart, placeholder, tryPart, _base, _ref2;
var catchPart, ensurePart, placeholder, tryPart, _ref4;
o.indent += TAB;
tryPart = this.attempt.compileToFragments(o, LEVEL_TOP);
catchPart = this.recovery ? ((typeof (_base = this.errorVariable).isObject === "function" ? _base.isObject() : void 0) ? (placeholder = new Literal('_error'), this.recovery.unshift(new Assign(this.errorVariable, placeholder)), this.errorVariable = placeholder) : void 0, (_ref2 = this.errorVariable.value, __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0) ? this.errorVariable.error("catch variable may not be \"" + this.errorVariable.value + "\"") : void 0, !o.scope.check(this.errorVariable.value) ? o.scope.add(this.errorVariable.value, 'param') : void 0, [].concat(this.makeCode(" catch ("), this.errorVariable.compileToFragments(o), this.makeCode(") {\n"), this.recovery.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab + "}"))) : !(this.ensure || this.recovery) ? [this.makeCode(' catch (_error) {}')] : [];
catchPart = this.recovery ? (placeholder = new Literal('_error'), this.recovery.unshift(new Assign(this.errorVariable, placeholder)), this.errorVariable = placeholder, (_ref4 = this.errorVariable.value, __indexOf.call(STRICT_PROSCRIBED, _ref4) >= 0) ? this.errorVariable.error("catch variable may not be \"" + this.errorVariable.value + "\"") : void 0, [].concat(this.makeCode(" catch ("), this.errorVariable.compileToFragments(o), this.makeCode(") {\n"), this.recovery.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab + "}"))) : !(this.ensure || this.recovery) ? [this.makeCode(' catch (_error) {}')] : [];
ensurePart = this.ensure ? [].concat(this.makeCode(" finally {\n"), this.ensure.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab + "}")) : [];
return [].concat(this.makeCode("" + this.tab + "try {\n"), tryPart, this.makeCode("\n" + this.tab + "}"), catchPart, ensurePart);
};
@@ -2520,11 +2529,11 @@
Existence.prototype.invert = NEGATE;
Existence.prototype.compileNode = function(o) {
var cmp, cnj, code, _ref2;
var cmp, cnj, code, _ref4;
this.expression.front = this.front;
code = this.expression.compile(o, LEVEL_OP);
if (IDENTIFIER.test(code) && !o.scope.check(code)) {
_ref2 = this.negated ? ['===', '||'] : ['!==', '&&'], cmp = _ref2[0], cnj = _ref2[1];
_ref4 = this.negated ? ['===', '||'] : ['!==', '&&'], cmp = _ref4[0], cnj = _ref4[1];
code = "typeof " + code + " " + cmp + " \"undefined\" " + cnj + " " + code + " " + cmp + " null";
} else {
code = "" + code + " " + (this.negated ? '==' : '!=') + " null";
@@ -2579,13 +2588,13 @@
__extends(For, _super);
function For(body, source) {
var _ref2;
var _ref4;
this.source = source.source, this.guard = source.guard, this.step = source.step, this.name = source.name, this.index = source.index;
this.body = Block.wrap([body]);
this.own = !!source.own;
this.object = !!source.object;
if (this.object) {
_ref2 = [this.index, this.name], this.name = _ref2[0], this.index = _ref2[1];
_ref4 = [this.index, this.name], this.name = _ref4[0], this.index = _ref4[1];
}
if (this.index instanceof Value) {
this.index.error('index cannot be a pattern matching expression');
@@ -2604,9 +2613,9 @@
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, resultPart, returnResult, rvar, scope, source, step, stepNum, stepVar, svar, varPart, _ref2, _ref3;
var body, bodyFragments, compare, compareDown, declare, declareDown, defPart, defPartFragments, down, forPartFragments, guardPart, idt1, increment, index, ivar, kvar, kvarAssign, lastJumps, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, step, stepNum, stepVar, svar, varPart, _ref4, _ref5;
body = Block.wrap([this.body]);
lastJumps = (_ref2 = last(body.expressions)) != null ? _ref2.jumps() : void 0;
lastJumps = (_ref4 = last(body.expressions)) != null ? _ref4.jumps() : void 0;
if (lastJumps && lastJumps instanceof Return) {
this.returns = false;
}
@@ -2627,7 +2636,7 @@
kvar = (this.range && name) || index || ivar;
kvarAssign = kvar !== ivar ? "" + kvar + " = " : "";
if (this.step && !this.range) {
_ref3 = this.cacheToCodeFragments(this.step.cache(o, LEVEL_LIST)), step = _ref3[0], stepVar = _ref3[1];
_ref5 = this.cacheToCodeFragments(this.step.cache(o, LEVEL_LIST)), step = _ref5[0], stepVar = _ref5[1];
stepNum = stepVar.match(SIMPLENUM);
}
if (this.pattern) {
@@ -2717,24 +2726,24 @@
};
For.prototype.pluckDirectCall = function(o, body) {
var base, defs, expr, fn, idx, ref, val, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7;
var base, defs, expr, fn, idx, ref, val, _i, _len, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9;
defs = [];
_ref2 = body.expressions;
for (idx = _i = 0, _len = _ref2.length; _i < _len; idx = ++_i) {
expr = _ref2[idx];
_ref4 = body.expressions;
for (idx = _i = 0, _len = _ref4.length; _i < _len; idx = ++_i) {
expr = _ref4[idx];
expr = expr.unwrapAll();
if (!(expr instanceof Call)) {
continue;
}
val = expr.variable.unwrapAll();
if (!((val instanceof Code) || (val instanceof Value && ((_ref3 = val.base) != null ? _ref3.unwrapAll() : void 0) instanceof Code && val.properties.length === 1 && ((_ref4 = (_ref5 = val.properties[0].name) != null ? _ref5.value : void 0) === 'call' || _ref4 === 'apply')))) {
if (!((val instanceof Code) || (val instanceof Value && ((_ref5 = val.base) != null ? _ref5.unwrapAll() : void 0) instanceof Code && val.properties.length === 1 && ((_ref6 = (_ref7 = val.properties[0].name) != null ? _ref7.value : void 0) === 'call' || _ref6 === 'apply')))) {
continue;
}
fn = ((_ref6 = val.base) != null ? _ref6.unwrapAll() : void 0) || val;
fn = ((_ref8 = val.base) != null ? _ref8.unwrapAll() : void 0) || val;
ref = new Literal(o.scope.freeVariable('fn'));
base = new Value(ref);
if (val.base) {
_ref7 = [base, val], val.base = _ref7[0], base = _ref7[1];
_ref9 = [base, val], val.base = _ref9[0], base = _ref9[1];
}
body.expressions[idx] = new Call(base, expr.args);
defs = defs.concat(this.makeCode(this.tab), new Assign(ref, fn).compileToFragments(o, LEVEL_TOP), this.makeCode(';\n'));
@@ -2761,49 +2770,49 @@
Switch.prototype.isStatement = YES;
Switch.prototype.jumps = function(o) {
var block, conds, _i, _len, _ref2, _ref3, _ref4;
var block, conds, _i, _len, _ref4, _ref5, _ref6;
if (o == null) {
o = {
block: true
};
}
_ref2 = this.cases;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
_ref3 = _ref2[_i], conds = _ref3[0], block = _ref3[1];
_ref4 = this.cases;
for (_i = 0, _len = _ref4.length; _i < _len; _i++) {
_ref5 = _ref4[_i], conds = _ref5[0], block = _ref5[1];
if (block.jumps(o)) {
return block;
}
}
return (_ref4 = this.otherwise) != null ? _ref4.jumps(o) : void 0;
return (_ref6 = this.otherwise) != null ? _ref6.jumps(o) : void 0;
};
Switch.prototype.makeReturn = function(res) {
var pair, _i, _len, _ref2, _ref3;
_ref2 = this.cases;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
pair = _ref2[_i];
var pair, _i, _len, _ref4, _ref5;
_ref4 = this.cases;
for (_i = 0, _len = _ref4.length; _i < _len; _i++) {
pair = _ref4[_i];
pair[1].makeReturn(res);
}
if (res) {
this.otherwise || (this.otherwise = new Block([new Literal('void 0')]));
}
if ((_ref3 = this.otherwise) != null) {
_ref3.makeReturn(res);
if ((_ref5 = this.otherwise) != null) {
_ref5.makeReturn(res);
}
return this;
};
Switch.prototype.compileNode = function(o) {
var block, body, cond, conditions, expr, fragments, i, idt1, idt2, _i, _j, _len, _len1, _ref2, _ref3, _ref4;
var block, body, cond, conditions, expr, fragments, i, idt1, idt2, _i, _j, _len, _len1, _ref4, _ref5, _ref6;
idt1 = o.indent + TAB;
idt2 = o.indent = idt1 + TAB;
fragments = [].concat(this.makeCode(this.tab + "switch ("), (this.subject ? this.subject.compileToFragments(o, LEVEL_PAREN) : this.makeCode("false")), this.makeCode(") {\n"));
_ref2 = this.cases;
for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
_ref3 = _ref2[i], conditions = _ref3[0], block = _ref3[1];
_ref4 = flatten([conditions]);
for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) {
cond = _ref4[_j];
_ref4 = this.cases;
for (i = _i = 0, _len = _ref4.length; _i < _len; i = ++_i) {
_ref5 = _ref4[i], conditions = _ref5[0], block = _ref5[1];
_ref6 = flatten([conditions]);
for (_j = 0, _len1 = _ref6.length; _j < _len1; _j++) {
cond = _ref6[_j];
if (!this.subject) {
cond = cond.invert();
}
@@ -2850,13 +2859,13 @@
If.prototype.children = ['condition', 'body', 'elseBody'];
If.prototype.bodyNode = function() {
var _ref2;
return (_ref2 = this.body) != null ? _ref2.unwrap() : void 0;
var _ref4;
return (_ref4 = this.body) != null ? _ref4.unwrap() : void 0;
};
If.prototype.elseBodyNode = function() {
var _ref2;
return (_ref2 = this.elseBody) != null ? _ref2.unwrap() : void 0;
var _ref4;
return (_ref4 = this.elseBody) != null ? _ref4.unwrap() : void 0;
};
If.prototype.addElse = function(elseBody) {
@@ -2870,13 +2879,13 @@
};
If.prototype.isStatement = function(o) {
var _ref2;
return (o != null ? o.level : void 0) === LEVEL_TOP || this.bodyNode().isStatement(o) || ((_ref2 = this.elseBodyNode()) != null ? _ref2.isStatement(o) : void 0);
var _ref4;
return (o != null ? o.level : void 0) === LEVEL_TOP || this.bodyNode().isStatement(o) || ((_ref4 = this.elseBodyNode()) != null ? _ref4.isStatement(o) : void 0);
};
If.prototype.jumps = function(o) {
var _ref2;
return this.body.jumps(o) || ((_ref2 = this.elseBody) != null ? _ref2.jumps(o) : void 0);
var _ref4;
return this.body.jumps(o) || ((_ref4 = this.elseBody) != null ? _ref4.jumps(o) : void 0);
};
If.prototype.compileNode = function(o) {
@@ -3008,6 +3017,9 @@
"extends": function() {
return "function(child, parent) { for (var key in parent) { if (" + (utility('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; }";
},
bind: function() {
return 'function(fn, me){ return function(){ return fn.apply(me, arguments); }; }';
},
indexOf: function() {
return "[].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }";
},

View File

@@ -13,7 +13,7 @@
replDefaults = {
prompt: 'coffee> ',
"eval": function(input, context, filename, cb) {
var Assign, Block, Literal, Value, ast, js, _ref1;
var Assign, Block, Literal, Value, ast, err, js, _ref1;
input = input.replace(/\uFF00/g, '\n');
input = input.replace(/^\(([\s\S]*)\n\)$/m, '$1');
_ref1 = require('./nodes'), Block = _ref1.Block, Assign = _ref1.Assign, Value = _ref1.Value, Literal = _ref1.Literal;
@@ -23,7 +23,8 @@
js = ast.compile({
bare: true
});
} catch (err) {
} catch (_error) {
err = _error;
console.log(prettyErrorMessage(err, filename, input, true));
}
return cb(null, vm.runInContext(js, context, filename));

View File

@@ -267,7 +267,7 @@
}
stack.pop();
}
if ((__indexOf.call(IMPLICIT_FUNC, tag) >= 0 && token.spaced || tag === '?' && i > 0 && !tokens[i - 1].spaced) && (__indexOf.call(IMPLICIT_CALL, nextTag) >= 0 || __indexOf.call(IMPLICIT_UNSPACED_CALL, nextTag) >= 0 && !((_ref = tokens[i + 1]) != null ? _ref.spaced : void 0) && !((_ref1 = tokens[i + 1]) != null ? _ref1.newLine : void 0))) {
if ((__indexOf.call(IMPLICIT_FUNC, tag) >= 0 && token.spaced && !token.stringEnd || tag === '?' && i > 0 && !tokens[i - 1].spaced) && (__indexOf.call(IMPLICIT_CALL, nextTag) >= 0 || __indexOf.call(IMPLICIT_UNSPACED_CALL, nextTag) >= 0 && !((_ref = tokens[i + 1]) != null ? _ref.spaced : void 0) && !((_ref1 = tokens[i + 1]) != null ? _ref1.newLine : void 0))) {
if (tag === '?') {
tag = token[0] = 'FUNC_EXIST';
}

View File

@@ -113,14 +113,14 @@
})();
exports.generateV3SourceMap = function(sourceMap, sourceFile, generatedFile) {
var answer, lastGeneratedColumnWritten, lastSourceColumnWritten, lastSourceLineWritten, mappings, needComma, writingGeneratedLine;
if (sourceFile == null) {
sourceFile = null;
}
if (generatedFile == null) {
generatedFile = null;
exports.generateV3SourceMap = function(sourceMap, options) {
var answer, generatedFile, lastGeneratedColumnWritten, lastSourceColumnWritten, lastSourceLineWritten, mappings, needComma, sourceFiles, sourceRoot, writingGeneratedLine;
if (options == null) {
options = {};
}
sourceRoot = options.sourceRoot || "";
sourceFiles = options.sourceFiles || [""];
generatedFile = options.generatedFile || "";
writingGeneratedLine = 0;
lastGeneratedColumnWritten = 0;
lastSourceLineWritten = 0;
@@ -150,8 +150,8 @@
answer = {
version: 3,
file: generatedFile,
sourceRoot: "",
sources: sourceFile ? [sourceFile] : [],
sourceRoot: sourceRoot,
sources: sourceFiles,
names: [],
mappings: mappings
};

View File

@@ -32,7 +32,8 @@ exports.helpers = helpers
# Compile CoffeeScript code to JavaScript, using the Coffee/Jison compiler.
#
# If `options.sourceMap` is specified, then `options.filename` must also be specified.
# If `options.sourceMap` is specified, then `options.filename` must also be specified. All
# options that can be passed to `generateV3SourceMap()` may also be passed here.
#
# This returns a javascript string, unless `options.sourceMap` is passed,
# in which case this returns a `{js, v3SourceMap, sourceMap}
@@ -40,10 +41,8 @@ exports.helpers = helpers
# lookups.
exports.compile = compile = (code, options = {}) ->
{merge} = exports.helpers
if options.sourceMap
coffeeFile = helpers.baseFileName options.filename
jsFile = helpers.baseFileName(options.filename, yes) + ".js"
sourceMap = new sourcemap.SourceMap()
fragments = (parser.parse lexer.tokenize(code, options)).compileToFragments options
@@ -58,7 +57,7 @@ exports.compile = compile = (code, options = {}) ->
if fragment.locationData
sourceMap.addMapping(
[fragment.locationData.first_line, fragment.locationData.first_column],
[currentLine, currentColumn],
[currentLine, currentColumn],
{noReplace: true})
newLines = helpers.count fragment.code, "\n"
currentLine += newLines
@@ -67,7 +66,6 @@ exports.compile = compile = (code, options = {}) ->
# Copy the code from each fragment into the final JavaScript.
js += fragment.code
if options.header
header = "Generated by CoffeeScript #{@VERSION}"
js = "// #{header}\n#{js}"
@@ -76,7 +74,7 @@ exports.compile = compile = (code, options = {}) ->
answer = {js}
if sourceMap
answer.sourceMap = sourceMap
answer.v3SourceMap = sourcemap.generateV3SourceMap sourceMap, coffeeFile, jsFile
answer.v3SourceMap = sourcemap.generateV3SourceMap(sourceMap, options)
answer
else
js

View File

@@ -5,15 +5,15 @@
# interactive REPL.
# External dependencies.
fs = require 'fs'
path = require 'path'
helpers = require './helpers'
optparse = require './optparse'
CoffeeScript = require './coffee-script'
{spawn, exec} = require 'child_process'
{EventEmitter} = require 'events'
fs = require 'fs'
path = require 'path'
helpers = require './helpers'
optparse = require './optparse'
CoffeeScript = require './coffee-script'
{spawn, exec} = require 'child_process'
{EventEmitter} = require 'events'
exists = fs.exists or path.exists
exists = fs.exists or path.exists
# Allow CoffeeScript to emit Node.js events.
helpers.extend CoffeeScript, new EventEmitter
@@ -112,9 +112,9 @@ compilePath = (source, topLevel, base) ->
# Compile a single source script, containing the given code, according to the
# requested options. If evaluating the script directly sets `__filename`,
# `__dirname` and `module.filename` to be correct relative to the script's path.
compileScript = (file, input, base) ->
compileScript = (file, input, base=null) ->
o = opts
options = compileOptions file
options = compileOptions file, base
try
t = task = {file, input, options}
CoffeeScript.emit 'compile', task
@@ -122,6 +122,7 @@ compileScript = (file, input, base) ->
else if o.nodes then printLine CoffeeScript.nodes(t.input, t.options).toString().trim()
else if o.run then CoffeeScript.run t.input, t.options
else if o.join and t.file isnt o.join
t.input = helpers.invertLiterate t.input if helpers.isLiterate file
sourceCode[sources.indexOf(t.file)] = t.input
compileJoin()
else
@@ -135,7 +136,7 @@ compileScript = (file, input, base) ->
if o.print
printLine t.output.trim()
else if o.compile || o.map
writeJs base, t.file, t.output, t.sourceMap
writeJs base, t.file, t.output, options.jsPath, t.sourceMap
else if o.lint
lint t.file, t.output
catch err
@@ -267,8 +268,7 @@ outputPath = (source, base, extension=".js") ->
#
# If `generatedSourceMap` is provided, this will write a `.map` file into the
# same directory as the `.js` file.
writeJs = (base, sourcePath, js, generatedSourceMap = null) ->
jsPath = outputPath sourcePath, base
writeJs = (base, sourcePath, js, jsPath, generatedSourceMap = null) ->
sourceMapPath = outputPath sourcePath, base, ".map"
jsDir = path.dirname jsPath
compile = ->
@@ -326,14 +326,31 @@ parseOptions = ->
return
# The compile-time options to pass to the CoffeeScript compiler.
compileOptions = (filename) ->
{
compileOptions = (filename, base) ->
answer = {
filename
literate: helpers.isLiterate(filename)
bare: opts.bare
header: opts.compile
sourceMap: opts.map
}
if filename
if base
cwd = process.cwd()
jsPath = outputPath filename, base
jsDir = path.dirname jsPath
answer = helpers.merge answer, {
jsPath
sourceRoot: path.relative jsDir, cwd
sourceFiles: [path.relative cwd, filename]
generatedFile: helpers.baseFileName(jsPath)
}
else
answer = helpers.merge answer,
sourceRoot: ""
sourceFiles: [helpers.baseFileName filename]
generatedFile: helpers.baseFileName(filename, yes) + ".js"
answer
# Start up a new Node.js instance with the arguments in `--nodejs` passed to
# the `node` binary, preserving the other options.

View File

@@ -63,13 +63,24 @@ exports.del = (obj, key) ->
val
# Gets the last item of an array(-like) object.
exports.last = (array, back) -> array[array.length - (back or 0) - 1]
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
false
# Simple function for inverting Literate CoffeeScript code by putting the
# documentation in comments, and bumping the actual code back out to the edge ...
# producing a string of CoffeeScript code that can be compiled "normally".
exports.invertLiterate = (code) ->
lines = for line in code.split('\n')
if match = (/^([ ]{4}|\t)/).exec line
line[match[0].length..]
else
'# ' + line
lines.join '\n'
# Merge two jison-style location data objects together.
# If `last` is not provided, this will simply return `first`.
buildLocationData = (first, last) ->
@@ -110,7 +121,7 @@ exports.baseFileName = (file, stripExt = no) ->
return file unless stripExt
parts = file.split('.')
parts.pop()
parts.pop() if parts[parts.length - 1] is 'coffee'
parts.pop() if parts[parts.length - 1] is 'coffee' and parts.length > 1
parts.join('.')
# Determine if a filename represents a CoffeeScript file.

View File

@@ -12,7 +12,8 @@
{Rewriter, INVERSES} = require './rewriter'
# Import the helpers we need.
{count, starts, compact, last, locationDataToString, throwSyntaxError} = require './helpers'
{count, starts, compact, last, invertLiterate, locationDataToString,
throwSyntaxError} = require './helpers'
# The Lexer Class
# ---------------
@@ -84,13 +85,7 @@ exports.Lexer = class Lexer
if WHITESPACE.test code
code = "\n#{code}"
@chunkLine--
if @literate
lines = for line in code.split('\n')
if match = LITERATE.exec line
line[match[0].length..]
else
'# ' + line
code = lines.join '\n'
code = invertLiterate code if @literate
code
# Tokenizers
@@ -595,7 +590,10 @@ exports.Lexer = class Lexer
@tokens.push token
else
@error "Unexpected #{tag}"
@token ')', ')', offsetInChunk + lexedLength, 0 if interpolated
if interpolated
rparen = @makeToken ')', ')', offsetInChunk + lexedLength, 0
rparen.stringEnd = true
@tokens.push rparen
tokens
# Pairs up a closing token, ensuring that all listed pairs of tokens are
@@ -779,8 +777,6 @@ WHITESPACE = /^[^\n\S]+/
COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|(?:###)$)|^(?:\s*#(?!##[^#]).*)+/
LITERATE = /^([ ]{4}|\t)/
CODE = /^[-=]>/
MULTI_DENT = /^(?:\n[^\n\S]*)+/

View File

@@ -131,8 +131,7 @@ exports.Base = class Base
# `toString` representation of the node, for inspecting the parse tree.
# This is what `coffee --nodes` prints out.
toString: (idt = '', name = @constructor.name) ->
location = if @locationData then locationDataToString @locationData else "??"
tree = '\n' + idt + location + ": " + name
tree = '\n' + idt + name
tree += '?' if @soak
@eachChild (node) -> tree += node.toString idt + TAB
tree
@@ -894,6 +893,8 @@ exports.Obj = class Obj extends Base
else
',\n'
indent = if prop instanceof Comment then '' else idt
if prop instanceof Assign and prop.variable instanceof Value and prop.variable.hasProperties()
throw new SyntaxError 'Invalid object key'
if prop instanceof Value and prop.this
prop = new Assign prop.properties[0].name, prop, 'object'
if prop not instanceof Comment
@@ -981,22 +982,9 @@ exports.Class = class Class extends Base
# Ensure that all functions bound to the instance are proxied in the
# constructor.
addBoundFunctions: (o) ->
if @boundFuncs.length
o.scope.assign '_this', 'this'
for [name, func] in @boundFuncs
lhs = new Value (new Literal "this"), [new Access name]
body = new Block [new Return new Literal "#{@ctor.name}.prototype.#{name.value}.apply(_this, arguments)"]
rhs = new Code func.params, body, 'boundfunc'
bound = new Assign lhs, rhs
@ctor.body.unshift bound
# {base} = assign.variable
# lhs = (new Value (new Literal "this"), [new Access base]).compile o
# @ctor.body.unshift new Literal """#{lhs} = function() {
# #{o.indent} return #{@ctor.name}.prototype.#{base.value}.apply(_this, arguments);
# #{o.indent}}\n
# """
for bvar in @boundFuncs
lhs = (new Value (new Literal "this"), [new Access bvar]).compile o
@ctor.body.unshift new Literal "#{lhs} = #{utility 'bind'}(#{lhs}, this)"
return
# Merge the properties from a top-level object as prototypal properties
@@ -1026,7 +1014,7 @@ exports.Class = class Class extends Base
else
assign.variable = new Value(new Literal(name), [(new Access new Literal 'prototype'), new Access base ])
if func instanceof Code and func.bound
@boundFuncs.push [base, func]
@boundFuncs.push base
func.bound = no
assign
compact exprs
@@ -1056,16 +1044,26 @@ exports.Class = class Class extends Base
# Make sure that a constructor is defined for the class, and properly
# configured.
ensureConstructor: (name) ->
if not @ctor
@ctor = new Code
@ctor.body.push new Literal "#{name}.__super__.constructor.apply(this, arguments)" if @parent
@ctor.body.push new Literal "#{@externalCtor}.apply(this, arguments)" if @externalCtor
@ctor.body.makeReturn()
@body.expressions.unshift @ctor
@ctor.ctor = @ctor.name = name
@ctor.klass = null
ensureConstructor: (name, o) ->
missing = not @ctor
@ctor or= new Code
@ctor.ctor = @ctor.name = name
@ctor.klass = null
@ctor.noReturn = yes
if missing
superCall = new Literal "#{name}.__super__.constructor.apply(this, arguments)" if @parent
superCall = new Literal "#{@externalCtor}.apply(this, arguments)" if @externalCtor
if superCall
ref = new Literal o.scope.freeVariable 'ref'
@ctor.body.unshift new Assign ref, superCall
@addBoundFunctions o
if superCall
@ctor.body.push ref
@ctor.body.makeReturn()
@body.expressions.unshift @ctor
else
@addBoundFunctions o
# Instead of generating the JavaScript string directly, we build up the
# equivalent syntax tree and compile that, in pieces. You can see the
@@ -1079,12 +1077,11 @@ exports.Class = class Class extends Base
@hoistDirectivePrologue()
@setContext name
@walkBody name, o
@ensureConstructor name
@ensureConstructor name, o
@body.spaced = yes
@body.expressions.unshift @ctor unless @ctor instanceof Code
@body.expressions.push lname
@body.expressions.unshift @directives...
@addBoundFunctions o
call = Closure.wrap @body
@@ -1732,13 +1729,11 @@ exports.Try = class Try extends Base
tryPart = @attempt.compileToFragments o, LEVEL_TOP
catchPart = if @recovery
if @errorVariable.isObject?()
placeholder = new Literal '_error'
@recovery.unshift new Assign @errorVariable, placeholder
@errorVariable = placeholder
placeholder = new Literal '_error'
@recovery.unshift new Assign @errorVariable, placeholder
@errorVariable = placeholder
if @errorVariable.value in STRICT_PROSCRIBED
@errorVariable.error "catch variable may not be \"#{@errorVariable.value}\""
o.scope.add @errorVariable.value, 'param' unless o.scope.check @errorVariable.value
[].concat @makeCode(" catch ("), @errorVariable.compileToFragments(o), @makeCode(") {\n"),
@recovery.compileToFragments(o, LEVEL_TOP), @makeCode("\n#{@tab}}")
else unless @ensure or @recovery
@@ -2117,6 +2112,11 @@ UTILITIES =
function(child, parent) { for (var key in parent) { if (#{utility '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; }
"""
# Create a function bound to the current value of "this".
bind: -> '''
function(fn, me){ return function(){ return fn.apply(me, arguments); }; }
'''
# Discover if an item is in an array.
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; }

View File

@@ -213,7 +213,7 @@ class exports.Rewriter
# Recognize standard implicit calls like
# f a, f() b, f? c, h[0] d etc.
if (tag in IMPLICIT_FUNC and token.spaced or
if (tag in IMPLICIT_FUNC and token.spaced and not token.stringEnd or
tag is '?' and i > 0 and not tokens[i - 1].spaced) and
(nextTag in IMPLICIT_CALL or
nextTag in IMPLICIT_UNSPACED_CALL and

View File

@@ -91,8 +91,16 @@ class exports.SourceMap
# Builds a V3 source map from a SourceMap object.
# Returns the generated JSON as a string.
#
# `options.sourceRoot` may be used to specify the sourceRoot written to the source map. Also,
# `options.sourceFiles` and `options.generatedFile` may be passed to set "sources" and "file",
# respectively. Note that `sourceFiles` must be an array.
exports.generateV3SourceMap = (sourceMap, options={}) ->
sourceRoot = options.sourceRoot or ""
sourceFiles = options.sourceFiles or [""]
generatedFile = options.generatedFile or ""
exports.generateV3SourceMap = (sourceMap, sourceFile=null, generatedFile=null) ->
writingGeneratedLine = 0
lastGeneratedColumnWritten = 0
lastSourceLineWritten = 0
@@ -146,8 +154,8 @@ exports.generateV3SourceMap = (sourceMap, sourceFile=null, generatedFile=null) -
answer = {
version: 3
file: generatedFile
sourceRoot: ""
sources: if sourceFile then [sourceFile] else []
sourceRoot
sources: sourceFiles
names: []
mappings
}

View File

@@ -730,13 +730,52 @@ test "#2359: extending native objects that use other typed constructors requires
eq 'yes!', workingArray.method()
test "#2489: removing __bind", ->
test "#2782: non-alphanumeric-named bound functions", ->
class A
'b:c': =>
'd'
class Thing
foo: (a, b, c) ->
bar: (a, b, c) =>
eq (new A)['b:c'](), 'd'
thing = new Thing
eq thing.foo.length, 3
eq thing.bar.length, 3
test "#2781: overriding bound functions", ->
class A
a: ->
@b()
b: =>
1
class B extends A
b: =>
2
b = (new A).b
eq b(), 1
b = (new B).b
eq b(), 2
test "#2791: bound function with destructured argument", ->
class Foo
method: ({a}) => 'Bar'
eq (new Foo).method({a: 'Bar'}), 'Bar'
test "#2796: ditto, ditto, ditto", ->
answer = null
outsideMethod = (func) ->
func.call message: 'wrong!'
class Base
constructor: ->
@message = 'right!'
outsideMethod @echo
echo: =>
answer = @message
new Base
eq answer, 'right!'

View File

@@ -70,3 +70,9 @@ test "#1106: __proto__ compilation", ->
test "reference named hasOwnProperty", ->
CoffeeScript.compile 'hasOwnProperty = 0; a = 1'
test "#1055: invalid keys in real (but not work-product) objects", ->
cantCompile "@key: value"
test "#1066: interpolated strings are not implicit functions", ->
cantCompile '"int#{er}polated" arg'

View File

@@ -2,7 +2,7 @@
# -------
# pull the helpers from `CoffeeScript.helpers` into local variables
{starts, ends, repeat, compact, count, merge, extend, flatten, del, last} = CoffeeScript.helpers
{starts, ends, repeat, compact, count, merge, extend, flatten, del, last, baseFileName} = CoffeeScript.helpers
# `starts`
@@ -103,3 +103,33 @@ test "the `last` helper returns the last item of an array-like object", ->
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", ->
ext = '.js'
sourceToCompiled =
'.coffee': ext
'a.coffee': 'a' + ext
'b.coffee': 'b' + ext
'coffee.coffee': 'coffee' + ext
'.litcoffee': ext
'a.litcoffee': 'a' + ext
'b.litcoffee': 'b' + ext
'coffee.litcoffee': 'coffee' + ext
'.lit': ext
'a.lit': 'a' + ext
'b.lit': 'b' + ext
'coffee.lit': 'coffee' + ext
'.coffee.md': ext
'a.coffee.md': 'a' + ext
'b.coffee.md': 'b' + ext
'coffee.coffee.md': 'coffee' + ext
for sourceFileName, expectedFileName of sourceToCompiled
name = baseFileName sourceFileName, yes
filename = name + ext
eq filename, expectedFileName

View File

@@ -36,8 +36,12 @@ test "SourceMap tests", ->
map.addMapping [1, 9], [2, 8]
map.addMapping [3, 0], [3, 4]
eqJson (sourcemap.generateV3SourceMap map, "source.coffee", "source.js"), '{"version":3,"file":"source.js","sourceRoot":"","sources":["source.coffee"],"names":[],"mappings":"AAAA;;IACK,GAAC,CAAG;IAET"}'
eqJson (sourcemap.generateV3SourceMap map), '{"version":3,"file":null,"sourceRoot":"","sources":[],"names":[],"mappings":"AAAA;;IACK,GAAC,CAAG;IAET"}'
testWithFilenames = sourcemap.generateV3SourceMap map, {
sourceRoot: "",
sourceFiles: ["source.coffee"],
generatedFile: "source.js"}
eqJson testWithFilenames, '{"version":3,"file":"source.js","sourceRoot":"","sources":["source.coffee"],"names":[],"mappings":"AAAA;;IACK,GAAC,CAAG;IAET"}'
eqJson (sourcemap.generateV3SourceMap map), '{"version":3,"file":"","sourceRoot":"","sources":[""],"names":[],"mappings":"AAAA;;IACK,GAAC,CAAG;IAET"}'
# Look up a generated column - should get back the original source position.
arrayEq map.getSourcePosition([2,8]), [1,9]