Merge remote-tracking branch 'refs/remotes/upstream/master'

This commit is contained in:
Marc Häfner
2013-04-29 05:27:13 +02:00
19 changed files with 106 additions and 178 deletions

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View File

@@ -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));

View File

@@ -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) : '.';

View File

@@ -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

View File

@@ -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);

View File

@@ -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'];

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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',

View File

@@ -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= {}

View File

@@ -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

View File

@@ -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

View File

@@ -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]

View File

@@ -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"

View File

@@ -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'] =

View File

@@ -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) ->

View File

@@ -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/'