Improving double-parentheses suppression. Issue #587
This commit is contained in:
parent
129e950c59
commit
9894eeb8e9
|
@ -37,7 +37,7 @@
|
|||
return path.exists('Cakefile', function(exists) {
|
||||
var _a, _b, _c, _d, arg, args;
|
||||
if (!(exists)) {
|
||||
throw new Error(("Cakefile not found in " + (process.cwd())));
|
||||
throw new Error("Cakefile not found in " + (process.cwd()));
|
||||
}
|
||||
args = process.argv.slice(2, process.argv.length);
|
||||
CoffeeScript.run(fs.readFileSync('Cakefile').toString(), {
|
||||
|
@ -71,14 +71,14 @@
|
|||
return _b;
|
||||
})().join('') : '';
|
||||
desc = task.description ? ("# " + (task.description)) : '';
|
||||
puts(("cake " + (name) + (spaces) + " " + (desc)));
|
||||
puts("cake " + (name) + (spaces) + " " + (desc));
|
||||
}
|
||||
if (switches.length) {
|
||||
return puts(oparse.help());
|
||||
}
|
||||
};
|
||||
missingTask = function(task) {
|
||||
puts(("No such task: \"" + (task) + "\""));
|
||||
puts("No such task: \"" + (task) + "\"");
|
||||
return process.exit(1);
|
||||
};
|
||||
})();
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
compile = function(source, topLevel) {
|
||||
return path.exists(source, function(exists) {
|
||||
if (!(exists)) {
|
||||
throw new Error(("File not found: " + (source)));
|
||||
throw new Error("File not found: " + (source));
|
||||
}
|
||||
return fs.stat(source, function(err, stats) {
|
||||
if (stats.isDirectory()) {
|
||||
|
@ -179,12 +179,12 @@
|
|||
}
|
||||
return fs.writeFile(jsPath, js, function(err) {
|
||||
if (options.compile && options.watch) {
|
||||
return puts(("Compiled " + (source)));
|
||||
return puts("Compiled " + (source));
|
||||
}
|
||||
});
|
||||
};
|
||||
return path.exists(dir, function(exists) {
|
||||
return exists ? compile() : exec(("mkdir -p " + (dir)), compile);
|
||||
return exists ? compile() : exec("mkdir -p " + (dir), compile);
|
||||
});
|
||||
};
|
||||
lint = function(js) {
|
||||
|
@ -238,7 +238,7 @@
|
|||
return process.exit(0);
|
||||
};
|
||||
version = function() {
|
||||
puts(("CoffeeScript version " + (CoffeeScript.VERSION)));
|
||||
puts("CoffeeScript version " + (CoffeeScript.VERSION));
|
||||
return process.exit(0);
|
||||
};
|
||||
})();
|
||||
|
|
|
@ -539,13 +539,13 @@
|
|||
Operation: [
|
||||
o("UNARY Expression", function() {
|
||||
return new OpNode($1, $2);
|
||||
}), o("- Expression", (function() {
|
||||
}), o("- Expression", function() {
|
||||
return new OpNode('-', $2);
|
||||
}), {
|
||||
}, {
|
||||
prec: 'UNARY'
|
||||
}), o("+ Expression", (function() {
|
||||
}), o("+ Expression", function() {
|
||||
return new OpNode('+', $2);
|
||||
}), {
|
||||
}, {
|
||||
prec: 'UNARY'
|
||||
}), o("-- Expression", function() {
|
||||
return new OpNode('--', $2);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
(function() {
|
||||
var compact, count, del, ends, extend, flatten, helpers, include, indexOf, merge, starts;
|
||||
if (!((typeof process !== "undefined" && process !== null))) {
|
||||
if (!(typeof process !== "undefined" && process !== null)) {
|
||||
this.exports = this;
|
||||
}
|
||||
helpers = (exports.helpers = {});
|
||||
|
@ -72,7 +72,7 @@
|
|||
_a = []; _b = properties;
|
||||
for (key in _b) {
|
||||
val = _b[key];
|
||||
_a.push((object[key] = val));
|
||||
_a.push(object[key] = val);
|
||||
}
|
||||
return _a;
|
||||
});
|
||||
|
|
14
lib/lexer.js
14
lib/lexer.js
|
@ -216,7 +216,7 @@
|
|||
return '\\' + escaped;
|
||||
});
|
||||
this.tokens = this.tokens.concat([['(', '('], ['NEW', 'new'], ['IDENTIFIER', 'RegExp'], ['CALL_START', '(']]);
|
||||
this.interpolateString(("\"" + (str) + "\""), {
|
||||
this.interpolateString("\"" + (str) + "\"", {
|
||||
escapeQuotes: true
|
||||
});
|
||||
if (flags) {
|
||||
|
@ -400,7 +400,7 @@
|
|||
if (options.herecomment) {
|
||||
return doc;
|
||||
}
|
||||
return doc.replace(MULTILINER, "\\n").replace(new RegExp(options.quote, 'g'), ("\\" + (options.quote)));
|
||||
return doc.replace(MULTILINER, "\\n").replace(new RegExp(options.quote, 'g'), "\\" + (options.quote));
|
||||
};
|
||||
Lexer.prototype.tagParameters = function() {
|
||||
var _d, i, tok;
|
||||
|
@ -428,10 +428,10 @@
|
|||
return this.outdentToken(this.indent);
|
||||
};
|
||||
Lexer.prototype.identifierError = function(word) {
|
||||
throw new Error(("SyntaxError: Reserved word \"" + (word) + "\" on line " + (this.line + 1)));
|
||||
throw new Error("SyntaxError: Reserved word \"" + (word) + "\" on line " + (this.line + 1));
|
||||
};
|
||||
Lexer.prototype.assignmentError = function() {
|
||||
throw new Error(("SyntaxError: Reserved word \"" + (this.value()) + "\" on line " + (this.line + 1) + " can't be assigned"));
|
||||
throw new Error("SyntaxError: Reserved word \"" + (this.value()) + "\" on line " + (this.line + 1) + " can't be assigned");
|
||||
};
|
||||
Lexer.prototype.balancedString = function(str, delimited, options) {
|
||||
var _d, _e, _f, _g, close, i, levels, open, pair, slash;
|
||||
|
@ -472,7 +472,7 @@
|
|||
if (slash) {
|
||||
return false;
|
||||
}
|
||||
throw new Error(("SyntaxError: Unterminated " + (levels.pop()[0]) + " starting on line " + (this.line + 1)));
|
||||
throw new Error("SyntaxError: Unterminated " + (levels.pop()[0]) + " starting on line " + (this.line + 1));
|
||||
}
|
||||
return !i ? false : str.substring(0, i);
|
||||
};
|
||||
|
@ -500,7 +500,7 @@
|
|||
if (options.heredoc) {
|
||||
inner = inner.replace(new RegExp('\\\\' + quote, 'g'), quote);
|
||||
}
|
||||
nested = lexer.tokenize(("(" + (inner) + ")"), {
|
||||
nested = lexer.tokenize("(" + (inner) + ")", {
|
||||
line: this.line
|
||||
});
|
||||
_e = nested;
|
||||
|
@ -540,7 +540,7 @@
|
|||
this.tokens = this.tokens.concat(value);
|
||||
} else if (tag === 'STRING' && options.escapeQuotes) {
|
||||
escaped = value.substring(1, value.length - 1).replace(/"/g, '\\"');
|
||||
this.token(tag, ("\"" + (escaped) + "\""));
|
||||
this.token(tag, "\"" + (escaped) + "\"");
|
||||
} else {
|
||||
this.token(tag, value);
|
||||
}
|
||||
|
|
61
lib/nodes.js
61
lib/nodes.js
|
@ -383,6 +383,9 @@
|
|||
op = del(o, 'operation');
|
||||
props = only ? this.properties.slice(0, this.properties.length - 1) : this.properties;
|
||||
o.chainRoot = o.chainRoot || this;
|
||||
if (this.parenthetical && !props.length) {
|
||||
this.base.parenthetical = true;
|
||||
}
|
||||
baseline = this.base.compile(o);
|
||||
if (this.hasProperties() && (this.base instanceof ObjectNode || this.isNumber())) {
|
||||
baseline = ("(" + (baseline) + ")");
|
||||
|
@ -483,18 +486,21 @@
|
|||
compilation = this.compileSplat(o);
|
||||
}
|
||||
}
|
||||
if (!(compilation)) {
|
||||
if (!compilation) {
|
||||
args = (function() {
|
||||
_e = []; _g = this.args;
|
||||
for (_f = 0, _h = _g.length; _f < _h; _f++) {
|
||||
arg = _g[_f];
|
||||
_e.push(arg.compile(o));
|
||||
_e.push((function() {
|
||||
arg.parenthetical = true;
|
||||
return arg.compile(o);
|
||||
})());
|
||||
}
|
||||
return _e;
|
||||
}).call(this).join(', ');
|
||||
compilation = this.isSuper ? this.compileSuper(args, o) : ("" + (this.prefix()) + (this.variable.compile(o)) + "(" + (args) + ")");
|
||||
}).call(this);
|
||||
compilation = this.isSuper ? this.compileSuper(args.join(', '), o) : ("" + (this.prefix()) + (this.variable.compile(o)) + "(" + (args.join(', ')) + ")");
|
||||
}
|
||||
return o.operation && this.wrapped ? ("(" + (compilation) + ")") : compilation;
|
||||
return compilation;
|
||||
};
|
||||
CallNode.prototype.compileSuper = function(args, o) {
|
||||
return "" + (this.superReference(o)) + ".call(this" + (args.length ? ', ' : '') + (args) + ")";
|
||||
|
@ -759,11 +765,11 @@
|
|||
if (obj instanceof SplatNode) {
|
||||
return this.compileSplatLiteral(o);
|
||||
} else if (obj instanceof CommentNode) {
|
||||
objects.push(("\n" + (code) + "\n" + (o.indent)));
|
||||
objects.push("\n" + (code) + "\n" + (o.indent));
|
||||
} else if (i === this.objects.length - 1) {
|
||||
objects.push(code);
|
||||
} else {
|
||||
objects.push(("" + (code) + ", "));
|
||||
objects.push("" + (code) + ", ");
|
||||
}
|
||||
}
|
||||
objects = objects.join('');
|
||||
|
@ -832,7 +838,7 @@
|
|||
if (constructor.body.empty()) {
|
||||
constructor.body.push(new ReturnNode(literal('this')));
|
||||
}
|
||||
constructor.body.unshift(literal(("this." + (pname) + " = function(){ return " + (className) + ".prototype." + (pname) + ".apply(" + (me) + ", arguments); }")));
|
||||
constructor.body.unshift(literal("this." + (pname) + " = function(){ return " + (className) + ".prototype." + (pname) + ".apply(" + (me) + ", arguments); }"));
|
||||
}
|
||||
if (pvar) {
|
||||
access = prop.context === 'this' ? pvar.base.properties[0] : new AccessorNode(pvar, 'prototype');
|
||||
|
@ -842,7 +848,7 @@
|
|||
props.push(prop);
|
||||
}
|
||||
if (me) {
|
||||
constructor.body.unshift(literal(("" + (me) + " = this")));
|
||||
constructor.body.unshift(literal("" + (me) + " = this"));
|
||||
}
|
||||
construct = this.idt() + (new AssignNode(this.variable, constructor)).compile(merge(o, {
|
||||
sharedScope: constScope
|
||||
|
@ -915,7 +921,7 @@
|
|||
if (stmt) {
|
||||
return ("" + (this.tab) + (val) + ";");
|
||||
}
|
||||
return top ? val : ("(" + (val) + ")");
|
||||
return top || this.parenthetical ? val : ("(" + (val) + ")");
|
||||
};
|
||||
AssignNode.prototype.compilePatternMatch = function(o) {
|
||||
var _b, _c, _d, accessClass, assigns, code, i, idx, isString, obj, oindex, olength, splat, val, valVar, value;
|
||||
|
@ -944,7 +950,7 @@
|
|||
isString = idx.value && idx.value.match(IS_STRING);
|
||||
accessClass = isString || this.variable.isArray() ? IndexNode : AccessorNode;
|
||||
if (obj instanceof SplatNode && !splat) {
|
||||
val = literal(obj.compileValue(o, valVar, (oindex = indexOf(this.variable.base.objects, obj)), (olength = this.variable.base.objects.length) - oindex - 1));
|
||||
val = literal(obj.compileValue(o, valVar, oindex = indexOf(this.variable.base.objects, obj), (olength = this.variable.base.objects.length) - oindex - 1));
|
||||
splat = true;
|
||||
} else {
|
||||
if (typeof idx !== 'object') {
|
||||
|
@ -1125,7 +1131,7 @@
|
|||
assign.value = trailing;
|
||||
}
|
||||
pos = this.trailings.length - idx;
|
||||
o.scope.assign(trailing.compile(o), ("arguments[" + (variadic) + " ? " + (len) + " - " + (pos) + " : " + (this.index + idx) + "]"));
|
||||
o.scope.assign(trailing.compile(o), "arguments[" + (variadic) + " ? " + (len) + " - " + (pos) + " : " + (this.index + idx) + "]");
|
||||
}
|
||||
}
|
||||
return "" + (name) + " = " + (utility('slice')) + ".call(arguments, " + (this.index) + (end) + ")";
|
||||
|
@ -1354,7 +1360,7 @@
|
|||
_b = []; _c = this.array.base.objects;
|
||||
for (i = 0, _d = _c.length; i < _d; i++) {
|
||||
item = _c[i];
|
||||
_b.push(("" + (item.compile(o)) + " === " + (i ? this.obj2 : this.obj1)));
|
||||
_b.push("" + (item.compile(o)) + " === " + (i ? this.obj2 : this.obj1));
|
||||
}
|
||||
return _b;
|
||||
}).call(this);
|
||||
|
@ -1438,7 +1444,9 @@
|
|||
ExistenceNode.prototype["class"] = 'ExistenceNode';
|
||||
ExistenceNode.prototype.children = ['expression'];
|
||||
ExistenceNode.prototype.compileNode = function(o) {
|
||||
return ExistenceNode.compileTest(o, this.expression)[0];
|
||||
var test;
|
||||
test = ExistenceNode.compileTest(o, this.expression)[0];
|
||||
return this.parenthetical ? test.substring(1, test.length - 1) : test;
|
||||
};
|
||||
ExistenceNode.compileTest = function(o, variable) {
|
||||
var _b, first, second;
|
||||
|
@ -1469,17 +1477,14 @@
|
|||
return true;
|
||||
};
|
||||
ParentheticalNode.prototype.compileNode = function(o) {
|
||||
var code, l, top;
|
||||
var code, top;
|
||||
top = del(o, 'top');
|
||||
this.expression.parenthetical = true;
|
||||
code = this.expression.compile(o);
|
||||
if (this.isStatement(o)) {
|
||||
return (top ? this.tab + code + ';' : code);
|
||||
if (this.parenthetical || this.isStatement(o)) {
|
||||
return top ? this.tab + code + ';' : code;
|
||||
}
|
||||
l = code.length;
|
||||
if (code.substr(l - 1, 1) === ';') {
|
||||
code = code.substr(o, l - 1);
|
||||
}
|
||||
return this.expression instanceof AssignNode ? code : ("(" + (code) + ")");
|
||||
return "(" + (code) + ")";
|
||||
};
|
||||
return ParentheticalNode;
|
||||
})();
|
||||
|
@ -1571,7 +1576,7 @@
|
|||
svar = scope.freeVariable();
|
||||
sourcePart = ("" + (svar) + " = " + (this.source.compile(o)) + ";");
|
||||
if (this.pattern) {
|
||||
namePart = new AssignNode(this.name, literal(("" + (svar) + "[" + (ivar) + "]"))).compile(merge(o, {
|
||||
namePart = new AssignNode(this.name, literal("" + (svar) + "[" + (ivar) + "]")).compile(merge(o, {
|
||||
indent: this.idt(1),
|
||||
top: true
|
||||
})) + '\n';
|
||||
|
@ -1597,13 +1602,13 @@
|
|||
}
|
||||
if (codeInBody) {
|
||||
if (range) {
|
||||
body.unshift(literal(("var " + (name) + " = " + (ivar))));
|
||||
body.unshift(literal("var " + (name) + " = " + (ivar)));
|
||||
}
|
||||
if (namePart) {
|
||||
body.unshift(literal(("var " + (namePart))));
|
||||
body.unshift(literal("var " + (namePart)));
|
||||
}
|
||||
if (index) {
|
||||
body.unshift(literal(("var " + (index) + " = " + (ivar))));
|
||||
body.unshift(literal("var " + (index) + " = " + (ivar)));
|
||||
}
|
||||
body = ClosureNode.wrap(body, true);
|
||||
} else {
|
||||
|
@ -1660,7 +1665,7 @@
|
|||
IfNode.prototype.rewriteSwitch = function(o) {
|
||||
var _b, _c, _d, cond, i, variable;
|
||||
this.assigner = this.switchSubject;
|
||||
if (!((this.switchSubject.unwrap() instanceof LiteralNode))) {
|
||||
if (!(this.switchSubject.unwrap() instanceof LiteralNode)) {
|
||||
variable = literal(o.scope.freeVariable());
|
||||
this.assigner = new AssignNode(variable, this.switchSubject);
|
||||
this.switchSubject = variable;
|
||||
|
@ -1673,7 +1678,7 @@
|
|||
if (cond instanceof OpNode) {
|
||||
cond = new ParentheticalNode(cond);
|
||||
}
|
||||
return new OpNode('==', (i === 0 ? this.assigner : this.switchSubject), cond);
|
||||
return new OpNode('==', i === 0 ? this.assigner : this.switchSubject, cond);
|
||||
}).call(this));
|
||||
}
|
||||
return _b;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
}
|
||||
}
|
||||
if (isOption && !matchedRule) {
|
||||
throw new Error(("unrecognized option: " + (arg)));
|
||||
throw new Error("unrecognized option: " + (arg));
|
||||
}
|
||||
if (!isOption) {
|
||||
options.arguments = args.slice(i, args.length);
|
||||
|
@ -41,7 +41,7 @@
|
|||
var _a, _b, _c, _d, i, letPart, lines, rule, spaces;
|
||||
lines = ['Available options:'];
|
||||
if (this.banner) {
|
||||
lines.unshift(("" + (this.banner) + "\n"));
|
||||
lines.unshift("" + (this.banner) + "\n");
|
||||
}
|
||||
_b = this.rules;
|
||||
for (_a = 0, _c = _b.length; _a < _c; _a++) {
|
||||
|
|
|
@ -275,7 +275,7 @@
|
|||
levels[open] -= 1;
|
||||
}
|
||||
if (levels[open] < 0) {
|
||||
throw new Error(("too many " + (token[1]) + " on line " + (token[2] + 1)));
|
||||
throw new Error("too many " + (token[1]) + " on line " + (token[2] + 1));
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
@ -294,7 +294,7 @@
|
|||
if (unclosed.length) {
|
||||
open = unclosed[0];
|
||||
line = openLine[open] + 1;
|
||||
throw new Error(("unclosed " + (open) + " on line " + (line)));
|
||||
throw new Error("unclosed " + (open) + " on line " + (line));
|
||||
}
|
||||
};
|
||||
Rewriter.prototype.rewriteClosingParens = function() {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
(function() {
|
||||
var Scope;
|
||||
var __hasProp = Object.prototype.hasOwnProperty;
|
||||
if (!((typeof process !== "undefined" && process !== null))) {
|
||||
if (!(typeof process !== "undefined" && process !== null)) {
|
||||
this.exports = this;
|
||||
}
|
||||
exports.Scope = (function() {
|
||||
|
@ -95,7 +95,7 @@
|
|||
if (!__hasProp.call(_b, key)) continue;
|
||||
val = _b[key];
|
||||
if (val.assigned) {
|
||||
_a.push(("" + (key) + " = " + (val.value)));
|
||||
_a.push("" + (key) + " = " + (val.value));
|
||||
}
|
||||
}
|
||||
return _a;
|
||||
|
|
|
@ -354,6 +354,7 @@ exports.ValueNode = class ValueNode extends BaseNode
|
|||
op = del o, 'operation'
|
||||
props = if only then @properties[0...@properties.length - 1] else @properties
|
||||
o.chainRoot or= this
|
||||
@base.parenthetical = yes if @parenthetical and not props.length
|
||||
baseline = @base.compile o
|
||||
baseline = "(#{baseline})" if @hasProperties() and (@base instanceof ObjectNode or @isNumber())
|
||||
complete = @last = baseline
|
||||
|
@ -434,11 +435,15 @@ exports.CallNode = class CallNode extends BaseNode
|
|||
o.chainRoot = this unless o.chainRoot
|
||||
for arg in @args when arg instanceof SplatNode
|
||||
compilation = @compileSplat(o)
|
||||
unless compilation
|
||||
args = (arg.compile(o) for arg in @args).join(', ')
|
||||
compilation = if @isSuper then @compileSuper(args, o)
|
||||
else "#{@prefix()}#{@variable.compile(o)}(#{args})"
|
||||
if o.operation and @wrapped then "(#{compilation})" else compilation
|
||||
if not compilation
|
||||
args = for arg in @args
|
||||
arg.parenthetical = true
|
||||
arg.compile o
|
||||
compilation = if @isSuper
|
||||
@compileSuper(args.join(', '), o)
|
||||
else
|
||||
"#{@prefix()}#{@variable.compile(o)}(#{ args.join(', ') })"
|
||||
compilation
|
||||
|
||||
# `super()` is converted into a call against the superclass's implementation
|
||||
# of the current function.
|
||||
|
@ -790,7 +795,7 @@ exports.AssignNode = class AssignNode extends BaseNode
|
|||
o.scope.find name unless @isValue() and (@variable.hasProperties() or @variable.namespaced)
|
||||
val = "#{name} = #{val}"
|
||||
return "#{@tab}#{val};" if stmt
|
||||
if top then val else "(#{val})"
|
||||
if top or @parenthetical then val else "(#{val})"
|
||||
|
||||
# Brief implementation of recursive pattern matching, when assigning array or
|
||||
# object literals to a value. Peeks at their properties to assign inner names.
|
||||
|
@ -1214,7 +1219,8 @@ exports.ExistenceNode = class ExistenceNode extends BaseNode
|
|||
constructor: (@expression) ->
|
||||
|
||||
compileNode: (o) ->
|
||||
ExistenceNode.compileTest(o, @expression)[0]
|
||||
test = ExistenceNode.compileTest(o, @expression)[0]
|
||||
if @parenthetical then test.substring(1, test.length - 1) else test
|
||||
|
||||
# The meat of the **ExistenceNode** is in this static `compileTest` method
|
||||
# because other nodes like to check the existence of their variables as well.
|
||||
|
@ -1248,12 +1254,11 @@ exports.ParentheticalNode = class ParentheticalNode extends BaseNode
|
|||
|
||||
compileNode: (o) ->
|
||||
top = del o, 'top'
|
||||
@expression.parenthetical = true
|
||||
code = @expression.compile(o)
|
||||
if @isStatement(o)
|
||||
return (if top then @tab + code + ';' else code)
|
||||
l = code.length
|
||||
code = code.substr(o, l-1) if code.substr(l-1, 1) is ';'
|
||||
if @expression instanceof AssignNode then code else "(#{code})"
|
||||
if @parenthetical or @isStatement o
|
||||
return if top then @tab + code + ';' else code
|
||||
"(#{code})"
|
||||
|
||||
#### ForNode
|
||||
|
||||
|
|
Loading…
Reference in New Issue