diff --git a/lib/coffee-script/command.js b/lib/coffee-script/command.js index 63d918ce2d..d0081d8dff 100644 --- a/lib/coffee-script/command.js +++ b/lib/coffee-script/command.js @@ -458,7 +458,7 @@ mkdirp = function(dir, fn) { var mkdirs, mode; - mode = 0x1ff & ~process.umask(); + mode = 0o777 & ~process.umask(); return (mkdirs = function(p, fn) { return fs.exists(p, function(exists) { if (exists) { diff --git a/lib/coffee-script/lexer.js b/lib/coffee-script/lexer.js index d27a07261f..5bb21270f9 100644 --- a/lib/coffee-script/lexer.js +++ b/lib/coffee-script/lexer.js @@ -22,6 +22,7 @@ this.indebt = 0; this.outdebt = 0; this.indents = []; + this.indentLiteral = ''; this.ends = []; this.tokens = []; this.seenFor = false; @@ -174,7 +175,7 @@ }; Lexer.prototype.numberToken = function() { - var base, lexedLength, match, number, numberValue, ref2, tag; + var base, lexedLength, match, number, numberValue, tag; if (!(match = NUMBER.exec(this.chunk))) { return 0; } @@ -214,9 +215,6 @@ } })(); numberValue = base != null ? parseInt(number.slice(2), base) : parseFloat(number); - if ((ref2 = number.charAt(1)) === 'b' || ref2 === 'o') { - number = "0x" + (numberValue.toString(16)); - } tag = numberValue === 2e308 ? 'INFINITY' : 'NUMBER'; this.token(tag, number, 0, lexedLength); return lexedLength; @@ -408,7 +406,7 @@ }; Lexer.prototype.lineToken = function() { - var diff, indent, match, noNewlines, size; + var diff, indent, match, minLiteralLength, newIndentLiteral, noNewlines, size; if (!(match = MULTI_DENT.exec(this.chunk))) { return 0; } @@ -416,6 +414,20 @@ this.seenFor = false; size = indent.length - 1 - indent.lastIndexOf('\n'); noNewlines = this.unfinished(); + newIndentLiteral = size > 0 ? indent.slice(-size) : ''; + if (!/^(.?)\1*$/.exec(newIndentLiteral)) { + this.error('mixed indentation', { + offset: indent.length + }); + return indent.length; + } + minLiteralLength = Math.min(newIndentLiteral.length, this.indentLiteral.length); + if (newIndentLiteral.slice(0, minLiteralLength) !== this.indentLiteral.slice(0, minLiteralLength)) { + this.error('indentation mismatch', { + offset: indent.length + }); + return indent.length; + } if (size - this.indebt === this.indent) { if (noNewlines) { this.suppressNewlines(); @@ -432,6 +444,7 @@ } if (!this.tokens.length) { this.baseIndent = this.indent = size; + this.indentLiteral = newIndentLiteral; return indent.length; } diff = size - this.indent + this.outdebt; @@ -442,6 +455,7 @@ }); this.outdebt = this.indebt = 0; this.indent = size; + this.indentLiteral = newIndentLiteral; } else if (size < this.baseIndent) { this.error('missing indentation', { offset: indent.length @@ -488,6 +502,7 @@ this.token('TERMINATOR', '\n', outdentLength, 0); } this.indent = decreasedIndent; + this.indentLiteral = this.indentLiteral.slice(0, decreasedIndent); return this; }; diff --git a/lib/coffee-script/nodes.js b/lib/coffee-script/nodes.js index ce8f0f2afe..f5eb07723a 100644 --- a/lib/coffee-script/nodes.js +++ b/lib/coffee-script/nodes.js @@ -2516,12 +2516,14 @@ o.scope.parameter(fragmentsToText(params[i])); } uniqs = []; - this.eachParamName(function(name, node) { - if (indexOf.call(uniqs, name) >= 0) { - node.error("multiple parameters named " + name); - } - return uniqs.push(name); - }); + this.eachParamName((function(_this) { + return function(name, node) { + if (indexOf.call(uniqs, name) >= 0) { + node.error("multiple parameters named '" + name + "'"); + } + return uniqs.push(name); + }; + })(this)); if (!(wasEmpty || this.noReturn)) { this.body.makeReturn(); }