mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-05-03 03:00:14 -04:00
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:
4
documentation/coffee/constructor_destructuring.coffee
Normal file
4
documentation/coffee/constructor_destructuring.coffee
Normal file
@@ -0,0 +1,4 @@
|
||||
class Person
|
||||
constructor: (options) ->
|
||||
{@name, @age, @height} = options
|
||||
|
||||
8
documentation/coffee/switch_with_no_expression.coffee
Normal file
8
documentation/coffee/switch_with_no_expression.coffee
Normal 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'
|
||||
@@ -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 —
|
||||
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>
|
||||
|
||||
12
documentation/js/constructor_destructuring.js
Normal file
12
documentation/js/constructor_destructuring.js
Normal 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;
|
||||
|
||||
})();
|
||||
31
index.html
31
index.html
@@ -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) ->
|
||||
{@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>
|
||||
|
||||
@@ -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"];
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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('.');
|
||||
|
||||
@@ -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]*)+/;
|
||||
|
||||
@@ -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; }";
|
||||
},
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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]*)+/
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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!'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user