mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-05-03 03:00:14 -04:00
Merge remote-tracking branch 'refs/remotes/upstream/master'
This commit is contained in:
@@ -131,9 +131,7 @@
|
||||
compiles one-to-one into the equivalent JS, and there is
|
||||
no interpretation at runtime. You can use any existing JavaScript library
|
||||
seamlessly from CoffeeScript (and vice-versa). The compiled output is
|
||||
readable and pretty-printed, passes through
|
||||
<a href="http://www.javascriptlint.com/">JavaScript Lint</a>
|
||||
without warnings, will work in every JavaScript runtime, and tends
|
||||
readable and pretty-printed, will work in every JavaScript runtime, and tends
|
||||
to run as fast or faster than the equivalent handwritten JavaScript.
|
||||
</p>
|
||||
|
||||
@@ -267,13 +265,9 @@ sudo bin/cake install</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>-l, --lint</code></td>
|
||||
<td><code>-l, --literate</code></td>
|
||||
<td>
|
||||
If the <tt>jsl</tt>
|
||||
(<a href="http://www.javascriptlint.com/">JavaScript Lint</a>)
|
||||
command is installed, use it
|
||||
to check the compilation of a CoffeeScript file. (Handy in
|
||||
conjunction with <br /> <tt>--watch</tt>)
|
||||
Parses the code as Literate CoffeeScript.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
# JavaScriptLint configuration file for CoffeeScript.
|
||||
|
||||
+no_return_value # function {0} does not always return a value
|
||||
+duplicate_formal # duplicate formal argument {0}
|
||||
-equal_as_assign # test for equality (==) mistyped as assignment (=)?{0}
|
||||
+var_hides_arg # variable {0} hides argument
|
||||
+redeclared_var # redeclaration of {0} {1}
|
||||
-anon_no_return_value # anonymous function does not always return a value
|
||||
+missing_semicolon # missing semicolon
|
||||
+meaningless_block # meaningless block; curly braces have no impact
|
||||
-comma_separated_stmts # multiple statements separated by commas (use semicolons?)
|
||||
+unreachable_code # unreachable code
|
||||
+missing_break # missing break statement
|
||||
-missing_break_for_last_case # missing break statement for last case in switch
|
||||
-comparison_type_conv # comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==)
|
||||
-inc_dec_within_stmt # increment (++) and decrement (--) operators used as part of greater statement
|
||||
-useless_void # use of the void type may be unnecessary (void is always undefined)
|
||||
+multiple_plus_minus # unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs
|
||||
+use_of_label # use of label
|
||||
-block_without_braces # block statement without curly braces
|
||||
+leading_decimal_point # leading decimal point may indicate a number or an object member
|
||||
+trailing_decimal_point # trailing decimal point may indicate a number or an object member
|
||||
+octal_number # leading zeros make an octal number
|
||||
+nested_comment # nested comment
|
||||
+misplaced_regex # regular expressions should be preceded by a left parenthesis, assignment, colon, or comma
|
||||
+ambiguous_newline # unexpected end of line; it is ambiguous whether these lines are part of the same statement
|
||||
+empty_statement # empty statement or extra semicolon
|
||||
-missing_option_explicit # the "option explicit" control comment is missing
|
||||
+partial_option_explicit # the "option explicit" control comment, if used, must be in the first script tag
|
||||
+dup_option_explicit # duplicate "option explicit" control comment
|
||||
+useless_assign # useless assignment
|
||||
+ambiguous_nested_stmt # block statements containing block statements should use curly braces to resolve ambiguity
|
||||
+ambiguous_else_stmt # the else statement could be matched with one of multiple if statements (use curly braces to indicate intent)
|
||||
-missing_default_case # missing default case in switch statement
|
||||
+duplicate_case_in_switch # duplicate case in switch statements
|
||||
+default_not_at_end # the default case is not at the end of the switch statement
|
||||
+legacy_cc_not_understood # couldn't understand control comment using /*@keyword@*/ syntax
|
||||
+jsl_cc_not_understood # couldn't understand control comment using /*jsl:keyword*/ syntax
|
||||
+useless_comparison # useless comparison; comparing identical expressions
|
||||
+with_statement # with statement hides undeclared variables; use temporary variable instead
|
||||
+trailing_comma_in_array # extra comma is not recommended in array initializers
|
||||
+assign_to_function_call # assignment to a function call
|
||||
+parseint_missing_radix # parseInt missing radix parameter
|
||||
+lambda_assign_requires_semicolon
|
||||
@@ -364,13 +364,9 @@ sudo bin/cake install</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>-l, --lint</code></td>
|
||||
<td><code>-l, --literate</code></td>
|
||||
<td>
|
||||
If the <tt>jsl</tt>
|
||||
(<a href="http://www.javascriptlint.com/">JavaScript Lint</a>)
|
||||
command is installed, use it
|
||||
to check the compilation of a CoffeeScript file. (Handy in
|
||||
conjunction with <br /> <tt>--watch</tt>)
|
||||
Parses the code as Literate CoffeeScript.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -10,11 +10,10 @@
|
||||
compile = CoffeeScript.compile;
|
||||
|
||||
CoffeeScript["eval"] = function(code, options) {
|
||||
var _ref;
|
||||
if (options == null) {
|
||||
options = {};
|
||||
}
|
||||
if ((_ref = options.bare) == null) {
|
||||
if (options.bare == null) {
|
||||
options.bare = true;
|
||||
}
|
||||
return eval(compile(code, options));
|
||||
|
||||
@@ -28,11 +28,11 @@
|
||||
if (options == null) {
|
||||
options = {};
|
||||
}
|
||||
merge = exports.helpers.merge;
|
||||
merge = helpers.merge;
|
||||
if (options.sourceMap) {
|
||||
map = new SourceMap;
|
||||
}
|
||||
fragments = (parser.parse(lexer.tokenize(code, options))).compileToFragments(options);
|
||||
fragments = parser.parse(lexer.tokenize(code, options)).compileToFragments(options);
|
||||
currentLine = 0;
|
||||
if (options.header) {
|
||||
currentLine += 1;
|
||||
@@ -85,12 +85,12 @@
|
||||
};
|
||||
|
||||
exports.run = function(code, options) {
|
||||
var answer, mainModule, _ref;
|
||||
var answer, mainModule;
|
||||
if (options == null) {
|
||||
options = {};
|
||||
}
|
||||
mainModule = require.main;
|
||||
if ((_ref = options.sourceMap) == null) {
|
||||
if (options.sourceMap == null) {
|
||||
options.sourceMap = true;
|
||||
}
|
||||
mainModule.filename = process.argv[1] = options.filename ? fs.realpathSync(options.filename) : '.';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Generated by CoffeeScript 1.6.2
|
||||
(function() {
|
||||
var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, exists, forkNode, fs, helpers, hidden, joinTimeout, lint, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, removeSource, sourceCode, sources, spawn, timeLog, unwatchDir, usage, useWinPathSep, version, wait, watch, watchDir, watchers, writeJs, _ref;
|
||||
var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, exists, forkNode, fs, helpers, hidden, joinTimeout, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, removeSource, sourceCode, sources, spawn, timeLog, unwatchDir, usage, useWinPathSep, version, wait, watch, watchDir, watchers, writeJs, _ref;
|
||||
|
||||
fs = require('fs');
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
BANNER = 'Usage: coffee [options] path/to/script.coffee -- [args]\n\nIf called without options, `coffee` will run your script.';
|
||||
|
||||
SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-l', '--lint', 'pipe the compiled JavaScript through JavaScript Lint'], ['-m', '--map', 'generate source map and save as .map files'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['-o', '--output [DIR]', 'set the output directory for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']];
|
||||
SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-m', '--map', 'generate source map and save as .map files'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['-o', '--output [DIR]', 'set the output directory for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-l', '--literate', 'treat stdio as literate style coffee-script'], ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']];
|
||||
|
||||
opts = {};
|
||||
|
||||
@@ -187,8 +187,6 @@
|
||||
return printLine(t.output.trim());
|
||||
} else if (o.compile || o.map) {
|
||||
return writeJs(base, t.file, t.output, options.jsPath, t.sourceMap);
|
||||
} else if (o.lint) {
|
||||
return lint(t.file, t.output);
|
||||
}
|
||||
}
|
||||
} catch (_error) {
|
||||
@@ -444,19 +442,6 @@
|
||||
return console.log("" + ((new Date).toLocaleTimeString()) + " - " + message);
|
||||
};
|
||||
|
||||
lint = function(file, js) {
|
||||
var conf, jsl, printIt;
|
||||
printIt = function(buffer) {
|
||||
return printLine(file + ':\t' + buffer.toString().trim());
|
||||
};
|
||||
conf = __dirname + '/../../extras/jsl.conf';
|
||||
jsl = spawn('jsl', ['-nologo', '-stdin', '-conf', conf]);
|
||||
jsl.stdout.on('data', printIt);
|
||||
jsl.stderr.on('data', printIt);
|
||||
jsl.stdin.write(js);
|
||||
return jsl.stdin.end();
|
||||
};
|
||||
|
||||
printTokens = function(tokens) {
|
||||
var strings, tag, token, value;
|
||||
strings = (function() {
|
||||
@@ -478,7 +463,7 @@
|
||||
optionParser = new optparse.OptionParser(SWITCHES, BANNER);
|
||||
o = opts = optionParser.parse(process.argv.slice(2));
|
||||
o.compile || (o.compile = !!o.output);
|
||||
o.run = !(o.compile || o.print || o.lint || o.map);
|
||||
o.run = !(o.compile || o.print || o.map);
|
||||
o.print = !!(o.print || (o["eval"] || o.stdio && o.compile));
|
||||
sources = o["arguments"];
|
||||
for (i = _i = 0, _len = sources.length; _i < _len; i = ++_i) {
|
||||
@@ -491,7 +476,7 @@
|
||||
var answer, cwd, jsDir, jsPath;
|
||||
answer = {
|
||||
filename: filename,
|
||||
literate: helpers.isLiterate(filename),
|
||||
literate: opts.literate || helpers.isLiterate(filename),
|
||||
bare: opts.bare,
|
||||
header: opts.compile,
|
||||
sourceMap: opts.map
|
||||
|
||||
@@ -187,11 +187,11 @@
|
||||
};
|
||||
|
||||
exports.throwSyntaxError = function(message, location) {
|
||||
var error, _ref1, _ref2;
|
||||
if ((_ref1 = location.last_line) == null) {
|
||||
var error;
|
||||
if (location.last_line == null) {
|
||||
location.last_line = location.first_line;
|
||||
}
|
||||
if ((_ref2 = location.last_column) == null) {
|
||||
if (location.last_column == null) {
|
||||
location.last_column = location.first_column;
|
||||
}
|
||||
error = new SyntaxError(message);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// Generated by CoffeeScript 1.6.2
|
||||
(function() {
|
||||
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, invertLiterate, key, last, locationDataToString, 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, repeat, starts, throwSyntaxError, _ref, _ref1,
|
||||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||
|
||||
_ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES;
|
||||
|
||||
_ref1 = require('./helpers'), count = _ref1.count, starts = _ref1.starts, compact = _ref1.compact, last = _ref1.last, invertLiterate = _ref1.invertLiterate, locationDataToString = _ref1.locationDataToString, throwSyntaxError = _ref1.throwSyntaxError;
|
||||
_ref1 = require('./helpers'), count = _ref1.count, starts = _ref1.starts, compact = _ref1.compact, last = _ref1.last, repeat = _ref1.repeat, invertLiterate = _ref1.invertLiterate, locationDataToString = _ref1.locationDataToString, throwSyntaxError = _ref1.throwSyntaxError;
|
||||
|
||||
exports.Lexer = Lexer = (function() {
|
||||
function Lexer() {}
|
||||
@@ -155,10 +155,10 @@
|
||||
}
|
||||
lexedLength = number.length;
|
||||
if (octalLiteral = /^0o([0-7]+)/.exec(number)) {
|
||||
number = '0x' + (parseInt(octalLiteral[1], 8)).toString(16);
|
||||
number = '0x' + parseInt(octalLiteral[1], 8).toString(16);
|
||||
}
|
||||
if (binaryLiteral = /^0b([01]+)/.exec(number)) {
|
||||
number = '0x' + (parseInt(binaryLiteral[1], 2)).toString(16);
|
||||
number = '0x' + parseInt(binaryLiteral[1], 2).toString(16);
|
||||
}
|
||||
this.token('NUMBER', number, 0, lexedLength);
|
||||
return lexedLength;
|
||||
@@ -228,7 +228,7 @@
|
||||
if (here) {
|
||||
this.token('HERECOMMENT', this.sanitizeHeredoc(here, {
|
||||
herecomment: true,
|
||||
indent: Array(this.indent + 1).join(' ')
|
||||
indent: repeat(' ', this.indent)
|
||||
}), 0, comment.length);
|
||||
}
|
||||
return comment.length;
|
||||
@@ -710,7 +710,7 @@
|
||||
column = this.chunkColumn;
|
||||
if (lineCount > 0) {
|
||||
lines = string.split('\n');
|
||||
column = (last(lines)).length;
|
||||
column = last(lines).length;
|
||||
} else {
|
||||
column += string.length;
|
||||
}
|
||||
@@ -876,9 +876,9 @@
|
||||
|
||||
BOOL = ['TRUE', 'FALSE'];
|
||||
|
||||
NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '++', '--', ']'];
|
||||
NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '++', '--'];
|
||||
|
||||
NOT_SPACED_REGEX = NOT_REGEX.concat(')', '}', 'THIS', 'IDENTIFIER', 'STRING');
|
||||
NOT_SPACED_REGEX = NOT_REGEX.concat(')', '}', 'THIS', 'IDENTIFIER', 'STRING', ']');
|
||||
|
||||
CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER'];
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
}
|
||||
|
||||
CodeFragment.prototype.toString = function() {
|
||||
return "" + this.code + [this.locationData ? ": " + locationDataToString(this.locationData) : void 0];
|
||||
return "" + this.code + (this.locationData ? ": " + locationDataToString(this.locationData) : '');
|
||||
};
|
||||
|
||||
return CodeFragment;
|
||||
@@ -476,6 +476,8 @@
|
||||
fragments.push(this.makeCode(scope.assignedVariables().join(",\n" + (this.tab + TAB))));
|
||||
}
|
||||
fragments.push(this.makeCode(";\n" + (this.spaced ? '\n' : '')));
|
||||
} else if (fragments.length && post.length) {
|
||||
fragments.push(this.makeCode("\n"));
|
||||
}
|
||||
}
|
||||
return fragments.concat(post);
|
||||
@@ -635,7 +637,7 @@
|
||||
Return.prototype.compileNode = function(o) {
|
||||
var answer;
|
||||
answer = [];
|
||||
answer.push(this.makeCode(this.tab + ("return" + [this.expression ? " " : void 0])));
|
||||
answer.push(this.makeCode(this.tab + ("return" + (this.expression ? " " : ""))));
|
||||
if (this.expression) {
|
||||
answer = answer.concat(this.expression.compileToFragments(o, LEVEL_PAREN));
|
||||
}
|
||||
@@ -774,17 +776,16 @@
|
||||
};
|
||||
|
||||
Value.prototype.unfoldSoak = function(o) {
|
||||
var _ref4,
|
||||
_this = this;
|
||||
return (_ref4 = this.unfoldedSoak) != null ? _ref4 : this.unfoldedSoak = (function() {
|
||||
var fst, i, ifn, prop, ref, snd, _i, _len, _ref5, _ref6;
|
||||
var _this = this;
|
||||
return this.unfoldedSoak != null ? this.unfoldedSoak : this.unfoldedSoak = (function() {
|
||||
var fst, i, ifn, prop, ref, snd, _i, _len, _ref4, _ref5;
|
||||
if (ifn = _this.base.unfoldSoak(o)) {
|
||||
(_ref5 = ifn.body.properties).push.apply(_ref5, _this.properties);
|
||||
(_ref4 = ifn.body.properties).push.apply(_ref4, _this.properties);
|
||||
return ifn;
|
||||
}
|
||||
_ref6 = _this.properties;
|
||||
for (i = _i = 0, _len = _ref6.length; _i < _len; i = ++_i) {
|
||||
prop = _ref6[i];
|
||||
_ref5 = _this.properties;
|
||||
for (i = _i = 0, _len = _ref5.length; _i < _len; i = ++_i) {
|
||||
prop = _ref5[i];
|
||||
if (!prop.soak) {
|
||||
continue;
|
||||
}
|
||||
@@ -1309,7 +1310,7 @@
|
||||
}
|
||||
answer.push.apply(answer, fragments);
|
||||
}
|
||||
if ((fragmentsToText(answer)).indexOf('\n') >= 0) {
|
||||
if (fragmentsToText(answer).indexOf('\n') >= 0) {
|
||||
answer.unshift(this.makeCode("[\n" + o.indent));
|
||||
answer.push(this.makeCode("\n" + this.tab + "]"));
|
||||
} else {
|
||||
@@ -2307,7 +2308,7 @@
|
||||
|
||||
Op.prototype.compileExistence = function(o) {
|
||||
var fst, ref;
|
||||
if (this.first.isComplex()) {
|
||||
if (!o.isExistentialEquals && this.first.isComplex()) {
|
||||
ref = new Literal(o.scope.freeVariable('ref'));
|
||||
fst = new Parens(new Assign(ref, this.first));
|
||||
} else {
|
||||
@@ -2411,7 +2412,7 @@
|
||||
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))) {
|
||||
if (fragmentsToText(sub) === fragmentsToText(ref)) {
|
||||
return fragments;
|
||||
}
|
||||
fragments = sub.concat(this.makeCode(', '), fragments);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Generated by CoffeeScript 1.6.2
|
||||
(function() {
|
||||
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments;
|
||||
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments, repeat;
|
||||
|
||||
repeat = require('./helpers').repeat;
|
||||
|
||||
exports.OptionParser = OptionParser = (function() {
|
||||
function OptionParser(rules, banner) {
|
||||
@@ -66,7 +68,7 @@
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
rule = _ref[_i];
|
||||
spaces = 15 - rule.longFlag.length;
|
||||
spaces = spaces > 0 ? Array(spaces + 1).join(' ') : '';
|
||||
spaces = spaces > 0 ? repeat(' ', spaces) : '';
|
||||
letPart = rule.shortFlag ? rule.shortFlag + ', ' : ' ';
|
||||
lines.push(' ' + letPart + rule.longFlag + spaces + rule.description);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
replDefaults = {
|
||||
prompt: 'coffee> ',
|
||||
historyFile: path.join(process.env.HOME, '.coffee_history'),
|
||||
historyFile: process.env.HOME ? path.join(process.env.HOME, '.coffee_history') : void 0,
|
||||
historyMaxInputSize: 10240,
|
||||
"eval": function(input, context, filename, cb) {
|
||||
var Assign, Block, Literal, Value, ast, err, js, _ref1;
|
||||
@@ -118,8 +118,8 @@
|
||||
return lastLine = code;
|
||||
}
|
||||
});
|
||||
process.on('exit', function() {
|
||||
return fs.closeSync(fd);
|
||||
repl.rli.on('exit', function() {
|
||||
return fs.close(fd);
|
||||
});
|
||||
return repl.commands['.history'] = {
|
||||
help: 'Show command history',
|
||||
|
||||
@@ -24,16 +24,16 @@ exports.helpers = helpers
|
||||
# options that can be passed to `SourceMap#generate` may also be passed here.
|
||||
#
|
||||
# This returns a javascript string, unless `options.sourceMap` is passed,
|
||||
# in which case this returns a `{js, v3SourceMap, sourceMap}
|
||||
# in which case this returns a `{js, v3SourceMap, sourceMap}`
|
||||
# object, where sourceMap is a sourcemap.coffee#SourceMap object, handy for doing programatic
|
||||
# lookups.
|
||||
exports.compile = compile = (code, options = {}) ->
|
||||
{merge} = exports.helpers
|
||||
{merge} = helpers
|
||||
|
||||
if options.sourceMap
|
||||
map = new SourceMap
|
||||
|
||||
fragments = (parser.parse lexer.tokenize(code, options)).compileToFragments options
|
||||
fragments = parser.parse(lexer.tokenize code, options).compileToFragments options
|
||||
|
||||
currentLine = 0
|
||||
currentLine += 1 if options.header
|
||||
@@ -45,8 +45,8 @@ exports.compile = compile = (code, options = {}) ->
|
||||
if options.sourceMap
|
||||
if fragment.locationData
|
||||
map.add(
|
||||
[fragment.locationData.first_line, fragment.locationData.first_column],
|
||||
[currentLine, currentColumn],
|
||||
[fragment.locationData.first_line, fragment.locationData.first_column]
|
||||
[currentLine, currentColumn]
|
||||
{noReplace: true})
|
||||
newLines = helpers.count fragment.code, "\n"
|
||||
currentLine += newLines
|
||||
@@ -87,7 +87,7 @@ exports.run = (code, options = {}) ->
|
||||
options.sourceMap ?= true
|
||||
# Set the filename.
|
||||
mainModule.filename = process.argv[1] =
|
||||
if options.filename then fs.realpathSync(options.filename) else '.'
|
||||
if options.filename then fs.realpathSync(options.filename) else '.'
|
||||
|
||||
# Clear the module cache.
|
||||
mainModule.moduleCache and= {}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# The `coffee` utility. Handles command-line compilation of CoffeeScript
|
||||
# into various forms: saved into `.js` files or printed to stdout, piped to
|
||||
# [JavaScript Lint](http://javascriptlint.com/) or recompiled every time the source is
|
||||
# saved, printed as a token stream or as the syntax tree, or launch an
|
||||
# into various forms: saved into `.js` files or printed to stdout
|
||||
# or recompiled every time the source is saved,
|
||||
# printed as a token stream or as the syntax tree, or launch an
|
||||
# interactive REPL.
|
||||
|
||||
# External dependencies.
|
||||
@@ -39,13 +39,13 @@ SWITCHES = [
|
||||
['-h', '--help', 'display this help message']
|
||||
['-i', '--interactive', 'run an interactive CoffeeScript REPL']
|
||||
['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling']
|
||||
['-l', '--lint', 'pipe the compiled JavaScript through JavaScript Lint']
|
||||
['-m', '--map', 'generate source map and save as .map files']
|
||||
['-n', '--nodes', 'print out the parse tree that the parser produces']
|
||||
[ '--nodejs [ARGS]', 'pass options directly to the "node" binary']
|
||||
['-o', '--output [DIR]', 'set the output directory for compiled JavaScript']
|
||||
['-p', '--print', 'print out the compiled JavaScript']
|
||||
['-s', '--stdio', 'listen for and compile scripts over stdio']
|
||||
['-l', '--literate', 'treat stdio as literate style coffee-script']
|
||||
['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce']
|
||||
['-v', '--version', 'display the version number']
|
||||
['-w', '--watch', 'watch scripts for changes and rerun commands']
|
||||
@@ -68,7 +68,7 @@ exports.run = ->
|
||||
return usage() if opts.help
|
||||
return version() if opts.version
|
||||
return require('./repl').start() if opts.interactive
|
||||
if opts.watch and !fs.watch
|
||||
if opts.watch and not fs.watch
|
||||
return printWarn "The --watch feature depends on Node v0.6.0+. You are running #{process.version}."
|
||||
return compileStdio() if opts.stdio
|
||||
return compileScript null, sources[0] if opts.eval
|
||||
@@ -136,10 +136,8 @@ compileScript = (file, input, base=null) ->
|
||||
CoffeeScript.emit 'success', task
|
||||
if o.print
|
||||
printLine t.output.trim()
|
||||
else if o.compile || o.map
|
||||
else if o.compile or o.map
|
||||
writeJs base, t.file, t.output, options.jsPath, t.sourceMap
|
||||
else if o.lint
|
||||
lint t.file, t.output
|
||||
catch err
|
||||
CoffeeScript.emit 'failure', err, task
|
||||
return if CoffeeScript.listeners('failure').length
|
||||
@@ -173,7 +171,7 @@ compileJoin = ->
|
||||
|
||||
# Watch a source CoffeeScript file using `fs.watch`, recompiling it every
|
||||
# time the file is updated. May be used in combination with other options,
|
||||
# such as `--lint` or `--print`.
|
||||
# such as `--print`.
|
||||
watch = (source, base) ->
|
||||
|
||||
prevStats = null
|
||||
@@ -295,17 +293,6 @@ wait = (milliseconds, func) -> setTimeout func, milliseconds
|
||||
timeLog = (message) ->
|
||||
console.log "#{(new Date).toLocaleTimeString()} - #{message}"
|
||||
|
||||
# Pipe compiled JS through JSLint (requires a working `jsl` command), printing
|
||||
# any errors or warnings that arise.
|
||||
lint = (file, js) ->
|
||||
printIt = (buffer) -> printLine file + ':\t' + buffer.toString().trim()
|
||||
conf = __dirname + '/../../extras/jsl.conf'
|
||||
jsl = spawn 'jsl', ['-nologo', '-stdin', '-conf', conf]
|
||||
jsl.stdout.on 'data', printIt
|
||||
jsl.stderr.on 'data', printIt
|
||||
jsl.stdin.write js
|
||||
jsl.stdin.end()
|
||||
|
||||
# Pretty-print a stream of tokens, sans location data.
|
||||
printTokens = (tokens) ->
|
||||
strings = for token in tokens
|
||||
@@ -320,7 +307,7 @@ parseOptions = ->
|
||||
optionParser = new optparse.OptionParser SWITCHES, BANNER
|
||||
o = opts = optionParser.parse process.argv[2..]
|
||||
o.compile or= !!o.output
|
||||
o.run = not (o.compile or o.print or o.lint or o.map)
|
||||
o.run = not (o.compile or o.print or o.map)
|
||||
o.print = !! (o.print or (o.eval or o.stdio and o.compile))
|
||||
sources = o.arguments
|
||||
sourceCode[i] = null for source, i in sources
|
||||
@@ -330,7 +317,7 @@ parseOptions = ->
|
||||
compileOptions = (filename, base) ->
|
||||
answer = {
|
||||
filename
|
||||
literate: helpers.isLiterate(filename)
|
||||
literate: opts.literate or helpers.isLiterate(filename)
|
||||
bare: opts.bare
|
||||
header: opts.compile
|
||||
sourceMap: opts.map
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
{Rewriter, INVERSES} = require './rewriter'
|
||||
|
||||
# Import the helpers we need.
|
||||
{count, starts, compact, last, invertLiterate, locationDataToString,
|
||||
throwSyntaxError} = require './helpers'
|
||||
{count, starts, compact, last, repeat, invertLiterate,
|
||||
locationDataToString, throwSyntaxError} = require './helpers'
|
||||
|
||||
# The Lexer Class
|
||||
# ---------------
|
||||
@@ -176,9 +176,9 @@ exports.Lexer = class Lexer
|
||||
@error "octal literal '#{number}' must be prefixed with '0o'"
|
||||
lexedLength = number.length
|
||||
if octalLiteral = /^0o([0-7]+)/.exec number
|
||||
number = '0x' + (parseInt octalLiteral[1], 8).toString 16
|
||||
number = '0x' + parseInt(octalLiteral[1], 8).toString 16
|
||||
if binaryLiteral = /^0b([01]+)/.exec number
|
||||
number = '0x' + (parseInt binaryLiteral[1], 2).toString 16
|
||||
number = '0x' + parseInt(binaryLiteral[1], 2).toString 16
|
||||
@token 'NUMBER', number, 0, lexedLength
|
||||
lexedLength
|
||||
|
||||
@@ -222,7 +222,7 @@ exports.Lexer = class Lexer
|
||||
if here
|
||||
@token 'HERECOMMENT',
|
||||
(@sanitizeHeredoc here,
|
||||
herecomment: true, indent: Array(@indent + 1).join(' ')),
|
||||
herecomment: true, indent: repeat ' ', @indent),
|
||||
0, comment.length
|
||||
comment.length
|
||||
|
||||
@@ -630,7 +630,7 @@ exports.Lexer = class Lexer
|
||||
column = @chunkColumn
|
||||
if lineCount > 0
|
||||
lines = string.split '\n'
|
||||
column = (last lines).length
|
||||
column = last(lines).length
|
||||
else
|
||||
column += string.length
|
||||
|
||||
@@ -647,7 +647,7 @@ exports.Lexer = class Lexer
|
||||
# so if last_column == first_column, then we're looking at a character of length 1.
|
||||
lastCharacter = Math.max 0, length - 1
|
||||
[locationData.last_line, locationData.last_column] =
|
||||
@getLineAndColumnFromChunk offsetInChunk + (lastCharacter)
|
||||
@getLineAndColumnFromChunk offsetInChunk + lastCharacter
|
||||
|
||||
token = [tag, value, locationData]
|
||||
|
||||
@@ -846,11 +846,11 @@ BOOL = ['TRUE', 'FALSE']
|
||||
# See: http://www.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions
|
||||
#
|
||||
# Our list is shorter, due to sans-parentheses method calls.
|
||||
NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '++', '--', ']']
|
||||
NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '++', '--']
|
||||
|
||||
# If the previous token is not spaced, there are more preceding tokens that
|
||||
# force a division parse:
|
||||
NOT_SPACED_REGEX = NOT_REGEX.concat ')', '}', 'THIS', 'IDENTIFIER', 'STRING'
|
||||
NOT_SPACED_REGEX = NOT_REGEX.concat ')', '}', 'THIS', 'IDENTIFIER', 'STRING', ']'
|
||||
|
||||
# Tokens which could legitimately be invoked or indexed. An opening
|
||||
# parentheses or bracket following these tokens will be recorded as the start
|
||||
|
||||
@@ -34,8 +34,8 @@ exports.CodeFragment = class CodeFragment
|
||||
@locationData = parent?.locationData
|
||||
@type = parent?.constructor?.name or 'unknown'
|
||||
|
||||
toString: () ->
|
||||
"#{@code}#{[if @locationData then ": " + locationDataToString(@locationData)]}"
|
||||
toString: ->
|
||||
"#{@code}#{if @locationData then ": " + locationDataToString(@locationData) else ''}"
|
||||
|
||||
# Convert an array of CodeFragments into a string.
|
||||
fragmentsToText = (fragments) ->
|
||||
@@ -336,7 +336,7 @@ exports.Block = class Block extends Base
|
||||
if i
|
||||
rest = @expressions.splice i, 9e9
|
||||
[spaced, @spaced] = [@spaced, no]
|
||||
[fragments, @spaced] = [(@compileNode o), spaced]
|
||||
[fragments, @spaced] = [@compileNode(o), spaced]
|
||||
@expressions = rest
|
||||
post = @compileNode o
|
||||
{scope} = o
|
||||
@@ -347,11 +347,13 @@ exports.Block = class Block extends Base
|
||||
fragments.push @makeCode '\n' if i
|
||||
fragments.push @makeCode "#{@tab}var "
|
||||
if declars
|
||||
fragments.push @makeCode(scope.declaredVariables().join ', ')
|
||||
fragments.push @makeCode scope.declaredVariables().join(', ')
|
||||
if assigns
|
||||
fragments.push @makeCode ",\n#{@tab + TAB}" if declars
|
||||
fragments.push @makeCode (scope.assignedVariables().join ",\n#{@tab + TAB}")
|
||||
fragments.push @makeCode scope.assignedVariables().join(",\n#{@tab + TAB}")
|
||||
fragments.push @makeCode ";\n#{if @spaced then '\n' else ''}"
|
||||
else if fragments.length and post.length
|
||||
fragments.push @makeCode "\n"
|
||||
fragments.concat post
|
||||
|
||||
# Wrap up the given nodes as a **Block**, unless it already happens
|
||||
@@ -437,9 +439,9 @@ exports.Return = class Return extends Base
|
||||
compileNode: (o) ->
|
||||
answer = []
|
||||
# TODO: If we call expression.compile() here twice, we'll sometimes get back different results!
|
||||
answer.push @makeCode(@tab + "return#{[" " if @expression]}")
|
||||
answer.push @makeCode @tab + "return#{if @expression then " " else ""}"
|
||||
if @expression
|
||||
answer = answer.concat @expression.compileToFragments(o, LEVEL_PAREN)
|
||||
answer = answer.concat @expression.compileToFragments o, LEVEL_PAREN
|
||||
answer.push @makeCode ";"
|
||||
return answer
|
||||
|
||||
@@ -647,7 +649,7 @@ exports.Call = class Call extends Base
|
||||
fragments.push @makeCode preface
|
||||
else
|
||||
if @isNew then fragments.push @makeCode 'new '
|
||||
fragments.push (@variable.compileToFragments(o, LEVEL_ACCESS))...
|
||||
fragments.push @variable.compileToFragments(o, LEVEL_ACCESS)...
|
||||
fragments.push @makeCode "("
|
||||
fragments.push compiledArgs...
|
||||
fragments.push @makeCode ")"
|
||||
@@ -739,7 +741,7 @@ exports.Index = class Index extends Base
|
||||
children: ['index']
|
||||
|
||||
compileToFragments: (o) ->
|
||||
[].concat @makeCode("["), (@index.compileToFragments o, LEVEL_PAREN), @makeCode("]")
|
||||
[].concat @makeCode("["), @index.compileToFragments(o, LEVEL_PAREN), @makeCode("]")
|
||||
|
||||
isComplex: ->
|
||||
@index.isComplex()
|
||||
@@ -936,7 +938,7 @@ exports.Arr = class Arr extends Base
|
||||
if index
|
||||
answer.push @makeCode ", "
|
||||
answer.push fragments...
|
||||
if (fragmentsToText answer).indexOf('\n') >= 0
|
||||
if fragmentsToText(answer).indexOf('\n') >= 0
|
||||
answer.unshift @makeCode "[\n#{o.indent}"
|
||||
answer.push @makeCode "\n#{@tab}]"
|
||||
else
|
||||
@@ -1015,7 +1017,7 @@ exports.Class = class Class extends Base
|
||||
if func.bound
|
||||
func.context = name
|
||||
else
|
||||
assign.variable = new Value(new Literal(name), [(new Access new Literal 'prototype'), new Access base ])
|
||||
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.bound = no
|
||||
@@ -1237,7 +1239,7 @@ exports.Assign = class Assign extends Base
|
||||
left.base.value != "this" and not o.scope.check left.base.value
|
||||
@variable.error "the variable \"#{left.base.value}\" can't be assigned with #{@context} because it has not been declared before"
|
||||
if "?" in @context then o.isExistentialEquals = true
|
||||
new Op(@context[...-1], left, new Assign(right, @value, '=') ).compileToFragments o
|
||||
new Op(@context[...-1], left, new Assign(right, @value, '=')).compileToFragments o
|
||||
|
||||
# Compile the assignment from an array splice literal, using JavaScript's
|
||||
# `Array#splice` method.
|
||||
@@ -1558,7 +1560,7 @@ exports.Op = class Op extends Base
|
||||
not @second
|
||||
|
||||
isComplex: ->
|
||||
not (@isUnary() and (@operator in ['+', '-'])) or @first.isComplex()
|
||||
not (@isUnary() and @operator in ['+', '-']) or @first.isComplex()
|
||||
|
||||
# Am I capable of
|
||||
# [Python-style comparison chaining](http://docs.python.org/reference/expressions.html#notin)?
|
||||
@@ -1639,8 +1641,9 @@ exports.Op = class Op extends Base
|
||||
(shared.compileToFragments o), @makeCode(" #{@operator} "), (@second.compileToFragments o, LEVEL_OP)
|
||||
@wrapInBraces fragments
|
||||
|
||||
# Keep reference to the left expression, unless this an existential assignment
|
||||
compileExistence: (o) ->
|
||||
if @first.isComplex()
|
||||
if !o.isExistentialEquals and @first.isComplex()
|
||||
ref = new Literal o.scope.freeVariable 'ref'
|
||||
fst = new Parens new Assign ref, @first
|
||||
else
|
||||
@@ -1661,7 +1664,7 @@ exports.Op = class Op extends Base
|
||||
plusMinus = op in ['+', '-']
|
||||
parts.push [@makeCode(' ')] if op in ['new', 'typeof', 'delete'] or
|
||||
plusMinus and @first instanceof Op and @first.operator is op
|
||||
if (plusMinus && @first instanceof Op) or (op is 'new' and @first.isStatement o)
|
||||
if (plusMinus and @first instanceof Op) or (op is 'new' and @first.isStatement o)
|
||||
@first = new Parens @first
|
||||
parts.push @first.compileToFragments o, LEVEL_OP
|
||||
parts.reverse() if @flip
|
||||
@@ -1701,7 +1704,7 @@ exports.In = class In extends Base
|
||||
[sub, ref] = @object.cache o, LEVEL_LIST
|
||||
fragments = [].concat @makeCode(utility('indexOf') + ".call("), @array.compileToFragments(o, LEVEL_LIST),
|
||||
@makeCode(", "), ref, @makeCode(") " + if @negated then '< 0' else '>= 0')
|
||||
return fragments if (fragmentsToText sub) is (fragmentsToText ref)
|
||||
return fragments if fragmentsToText(sub) is fragmentsToText(ref)
|
||||
fragments = sub.concat @makeCode(', '), fragments
|
||||
if o.level < LEVEL_LIST then fragments else @wrapInBraces fragments
|
||||
|
||||
@@ -1741,7 +1744,8 @@ exports.Try = class Try extends Base
|
||||
else
|
||||
[]
|
||||
|
||||
ensurePart = if @ensure then ([].concat @makeCode(" finally {\n"), (@ensure.compileToFragments o, LEVEL_TOP), @makeCode("\n#{@tab}}")) else []
|
||||
ensurePart = if @ensure then ([].concat @makeCode(" finally {\n"), @ensure.compileToFragments(o, LEVEL_TOP),
|
||||
@makeCode("\n#{@tab}}")) else []
|
||||
|
||||
[].concat @makeCode("#{@tab}try {\n"),
|
||||
tryPart,
|
||||
@@ -1762,7 +1766,7 @@ exports.Throw = class Throw extends Base
|
||||
makeReturn: THIS
|
||||
|
||||
compileNode: (o) ->
|
||||
[].concat @makeCode(@tab + "throw "), (@expression.compileToFragments o), @makeCode(";")
|
||||
[].concat @makeCode(@tab + "throw "), @expression.compileToFragments(o), @makeCode(";")
|
||||
|
||||
#### Existence
|
||||
|
||||
@@ -1959,7 +1963,7 @@ exports.Switch = class Switch extends Base
|
||||
idt1 = o.indent + TAB
|
||||
idt2 = o.indent = idt1 + TAB
|
||||
fragments = [].concat @makeCode(@tab + "switch ("),
|
||||
(if @subject then @subject.compileToFragments(o, LEVEL_PAREN) else @makeCode("false")),
|
||||
(if @subject then @subject.compileToFragments(o, LEVEL_PAREN) else @makeCode "false"),
|
||||
@makeCode(") {\n")
|
||||
for [conditions, block], i in @cases
|
||||
for cond in flatten [conditions]
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
{repeat} = require './helpers'
|
||||
|
||||
# A simple **OptionParser** class to parse option flags from the command-line.
|
||||
# Use it like so:
|
||||
#
|
||||
@@ -62,7 +64,7 @@ exports.OptionParser = class OptionParser
|
||||
lines.unshift "#{@banner}\n" if @banner
|
||||
for rule in @rules
|
||||
spaces = 15 - rule.longFlag.length
|
||||
spaces = if spaces > 0 then Array(spaces + 1).join(' ') else ''
|
||||
spaces = if spaces > 0 then repeat ' ', spaces else ''
|
||||
letPart = if rule.shortFlag then rule.shortFlag + ', ' else ' '
|
||||
lines.push ' ' + letPart + rule.longFlag + spaces + rule.description
|
||||
"\n#{ lines.join('\n') }\n"
|
||||
|
||||
@@ -7,7 +7,7 @@ CoffeeScript = require './coffee-script'
|
||||
|
||||
replDefaults =
|
||||
prompt: 'coffee> ',
|
||||
historyFile: path.join(process.env.HOME, '.coffee_history')
|
||||
historyFile: path.join process.env.HOME, '.coffee_history' if process.env.HOME
|
||||
historyMaxInputSize: 10240
|
||||
eval: (input, context, filename, cb) ->
|
||||
# XXX: multiline hack.
|
||||
@@ -36,8 +36,8 @@ addMultilineHandler = (repl) ->
|
||||
|
||||
multiline =
|
||||
enabled: off
|
||||
initialPrompt: repl.prompt.replace(/^[^> ]*/, (x) -> x.replace /./g, '-')
|
||||
prompt: repl.prompt.replace(/^[^> ]*>?/, (x) -> x.replace /./g, '.')
|
||||
initialPrompt: repl.prompt.replace /^[^> ]*/, (x) -> x.replace /./g, '-'
|
||||
prompt: repl.prompt.replace /^[^> ]*>?/, (x) -> x.replace /./g, '.'
|
||||
buffer: ''
|
||||
|
||||
# Proxy node's line listener
|
||||
@@ -108,8 +108,7 @@ addHistory = (repl, filename, maxSize) ->
|
||||
fs.write fd, "#{code}\n"
|
||||
lastLine = code
|
||||
|
||||
process.on 'exit', ->
|
||||
fs.closeSync fd
|
||||
repl.rli.on 'exit', -> fs.close fd
|
||||
|
||||
# Add a command to show the history stack
|
||||
repl.commands['.history'] =
|
||||
|
||||
@@ -351,7 +351,7 @@ class exports.Rewriter
|
||||
first_column: column
|
||||
last_line: line
|
||||
last_column: column
|
||||
1
|
||||
return 1
|
||||
|
||||
# Because our grammar is LALR(1), it can't handle some single-line
|
||||
# expressions that lack ending delimiters. The **Rewriter** adds the implicit
|
||||
@@ -409,7 +409,7 @@ class exports.Rewriter
|
||||
return 1 unless token[0] is 'IF'
|
||||
original = token
|
||||
@detectEnd i + 1, condition, action
|
||||
1
|
||||
return 1
|
||||
|
||||
# Generate the indentation tokens, based on another token on the same line.
|
||||
indentation: (implicit = no) ->
|
||||
|
||||
@@ -78,4 +78,7 @@ test "#1066: interpolated strings are not implicit functions", ->
|
||||
cantCompile '"int#{er}polated" arg'
|
||||
|
||||
test "#2846: while with empty body", ->
|
||||
CoffeeScript.compile 'while 1 then', {sourceMap: true}
|
||||
CoffeeScript.compile 'while 1 then', {sourceMap: true}
|
||||
|
||||
test "#2944: implicit call with a regex argument", ->
|
||||
CoffeeScript.compile 'o[key] /regex/'
|
||||
Reference in New Issue
Block a user