mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-02-18 03:21:20 -05:00
nodes: soaking Call now converts to If using the same logic as soaking Accessor
This commit is contained in:
113
lib/nodes.js
113
lib/nodes.js
@@ -105,7 +105,7 @@
|
||||
}
|
||||
return _result;
|
||||
}).call(this).join('');
|
||||
klass = override || this.constructor.name + (this.soakNode || this.exist ? '?' : '');
|
||||
klass = override || this.constructor.name + (this.soakNode ? '?' : '');
|
||||
return '\n' + idt + klass + children;
|
||||
};
|
||||
Base.prototype.eachChild = function(func) {
|
||||
@@ -152,6 +152,7 @@
|
||||
Base.prototype.isPureStatement = NO;
|
||||
Base.prototype.isComplex = YES;
|
||||
Base.prototype.topSensitive = NO;
|
||||
Base.prototype.unfoldSoak = NO;
|
||||
Base.prototype.assigns = NO;
|
||||
return Base;
|
||||
})();
|
||||
@@ -391,9 +392,9 @@
|
||||
return !o.top || this.properties.length ? Value.__super__.compile.call(this, o) : this.base.compile(o);
|
||||
};
|
||||
Value.prototype.compileNode = function(o) {
|
||||
var _i, _len, code, ex, prop, props;
|
||||
if (ex = this.unfoldSoak(o)) {
|
||||
return ex.compile(o);
|
||||
var _i, _len, code, ifn, prop, props;
|
||||
if (ifn = this.unfoldSoak(o)) {
|
||||
return ifn.compile(o);
|
||||
}
|
||||
props = this.properties;
|
||||
if (this.parenthetical && !props.length) {
|
||||
@@ -411,9 +412,9 @@
|
||||
};
|
||||
Value.prototype.unfoldSoak = function(o) {
|
||||
var _len, _ref2, fst, i, ifn, prop, ref, snd;
|
||||
if (this.base.soakNode) {
|
||||
Array.prototype.push.apply(this.base.body.properties, this.properties);
|
||||
return this.base;
|
||||
if (ifn = this.base.unfoldSoak(o)) {
|
||||
Array.prototype.push.apply(ifn.body.properties, this.properties);
|
||||
return ifn;
|
||||
}
|
||||
for (i = 0, _len = (_ref2 = this.properties).length; i < _len; i++) {
|
||||
prop = _ref2[i];
|
||||
@@ -427,28 +428,21 @@
|
||||
snd.base = ref;
|
||||
}
|
||||
ifn = new If(new Existence(fst), snd, {
|
||||
operation: true
|
||||
soak: true
|
||||
});
|
||||
ifn.soakNode = true;
|
||||
return ifn;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
Value.unfoldSoak = function(o, parent, name) {
|
||||
var ifnode, node;
|
||||
node = parent[name];
|
||||
if (node instanceof If && node.soakNode) {
|
||||
ifnode = node;
|
||||
} else if (node instanceof Value) {
|
||||
ifnode = node.unfoldSoak(o);
|
||||
}
|
||||
if (!ifnode) {
|
||||
var ifn;
|
||||
if (!(ifn = parent[name].unfoldSoak(o))) {
|
||||
return;
|
||||
}
|
||||
parent[name] = ifnode.body;
|
||||
ifnode.body = new Value(parent);
|
||||
return ifnode;
|
||||
parent[name] = ifn.body;
|
||||
ifn.body = new Value(parent);
|
||||
return ifn;
|
||||
};
|
||||
return Value;
|
||||
}).call(this);
|
||||
@@ -472,7 +466,7 @@
|
||||
exports.Call = (function() {
|
||||
Call = (function() {
|
||||
function Call(variable, _arg, _arg2) {
|
||||
this.exist = _arg2;
|
||||
this.soakNode = _arg2;
|
||||
this.args = _arg;
|
||||
Call.__super__.constructor.call(this);
|
||||
this.isNew = false;
|
||||
@@ -508,7 +502,25 @@
|
||||
return method.klass ? ("" + (method.klass) + ".__super__." + name) : ("" + name + ".__super__.constructor");
|
||||
};
|
||||
Call.prototype.unfoldSoak = function(o) {
|
||||
var _i, _len, _ref2, call, list, node;
|
||||
var _i, _len, _ref2, _ref3, call, ifn, left, list, rite, val;
|
||||
if (this.soakNode) {
|
||||
if (val = this.variable) {
|
||||
if (!(val instanceof Value)) {
|
||||
val = new Value(val);
|
||||
}
|
||||
_ref2 = val.cacheReference(o), left = _ref2[0], rite = _ref2[1];
|
||||
} else {
|
||||
left = new Literal(this.superReference(o));
|
||||
rite = new Value(left);
|
||||
}
|
||||
rite = new Call(rite, this.args);
|
||||
rite.isNew = this.isNew;
|
||||
left = new Literal("typeof " + (left.compile(o)) + " === \"function\"");
|
||||
ifn = new If(left, new Value(rite), {
|
||||
soak: true
|
||||
});
|
||||
return ifn;
|
||||
}
|
||||
call = this;
|
||||
list = [];
|
||||
while (true) {
|
||||
@@ -525,51 +537,35 @@
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (_i = 0, _len = (_ref2 = list.reverse()).length; _i < _len; _i++) {
|
||||
call = _ref2[_i];
|
||||
if (node) {
|
||||
for (_i = 0, _len = (_ref3 = list.reverse()).length; _i < _len; _i++) {
|
||||
call = _ref3[_i];
|
||||
if (ifn) {
|
||||
if (call.variable instanceof Call) {
|
||||
call.variable = node;
|
||||
call.variable = ifn;
|
||||
} else {
|
||||
call.variable.base = node;
|
||||
call.variable.base = ifn;
|
||||
}
|
||||
}
|
||||
node = Value.unfoldSoak(o, call, 'variable');
|
||||
ifn = Value.unfoldSoak(o, call, 'variable');
|
||||
}
|
||||
return node;
|
||||
return ifn;
|
||||
};
|
||||
Call.prototype.compileNode = function(o) {
|
||||
var _i, _j, _len, _len2, _ref2, _ref3, _ref4, _ref5, _result, arg, args, left, node, rite, val;
|
||||
if (node = this.unfoldSoak(o)) {
|
||||
return node.compile(o);
|
||||
var _i, _j, _len, _len2, _ref2, _ref3, _ref4, _result, arg, args, ifn;
|
||||
if (ifn = this.unfoldSoak(o)) {
|
||||
return ifn.compile(o);
|
||||
}
|
||||
(((_ref2 = this.variable) != null) ? (_ref2.tags.front = this.tags.front) : undefined);
|
||||
if (this.exist) {
|
||||
if (val = this.variable) {
|
||||
if (!(val instanceof Value)) {
|
||||
val = new Value(val);
|
||||
}
|
||||
_ref3 = val.cacheReference(o), left = _ref3[0], rite = _ref3[1];
|
||||
rite = new Call(rite, this.args);
|
||||
} else {
|
||||
left = new Literal(this.superReference(o));
|
||||
rite = new Call(new Value(left), this.args);
|
||||
rite.isNew = this.isNew;
|
||||
}
|
||||
left = ("typeof " + (left.compile(o)) + " !== \"function\"");
|
||||
rite = rite.compile(o);
|
||||
return ("(" + left + " ? undefined : " + rite + ")");
|
||||
}
|
||||
for (_i = 0, _len = (_ref4 = this.args).length; _i < _len; _i++) {
|
||||
arg = _ref4[_i];
|
||||
for (_i = 0, _len = (_ref3 = this.args).length; _i < _len; _i++) {
|
||||
arg = _ref3[_i];
|
||||
if (arg instanceof Splat) {
|
||||
return this.compileSplat(o);
|
||||
}
|
||||
}
|
||||
args = (function() {
|
||||
_result = [];
|
||||
for (_j = 0, _len2 = (_ref5 = this.args).length; _j < _len2; _j++) {
|
||||
arg = _ref5[_j];
|
||||
for (_j = 0, _len2 = (_ref4 = this.args).length; _j < _len2; _j++) {
|
||||
arg = _ref4[_j];
|
||||
_result.push((arg.parenthetical = true) && arg.compile(o));
|
||||
}
|
||||
return _result;
|
||||
@@ -1816,11 +1812,11 @@
|
||||
})();
|
||||
exports.If = (function() {
|
||||
If = (function() {
|
||||
function If(condition, _arg, _arg2) {
|
||||
this.tags = _arg2;
|
||||
function If(condition, _arg, tags) {
|
||||
this.body = _arg;
|
||||
this.tags || (this.tags = {});
|
||||
this.condition = this.tags.invert ? condition.invert() : condition;
|
||||
this.tags = tags || (tags = {});
|
||||
this.condition = tags.invert ? condition.invert() : condition;
|
||||
this.soakNode = tags.soak;
|
||||
this.elseBody = null;
|
||||
this.isChain = false;
|
||||
return this;
|
||||
@@ -1898,7 +1894,10 @@
|
||||
ifPart = this.condition.compile(o) + ' ? ' + this.bodyNode().compile(o);
|
||||
elsePart = this.elseBody ? this.elseBodyNode().compile(o) : 'undefined';
|
||||
code = ("" + ifPart + " : " + elsePart);
|
||||
return this.tags.operation ? ("(" + code + ")") : code;
|
||||
return this.tags.operation || this.soakNode ? ("(" + code + ")") : code;
|
||||
};
|
||||
If.prototype.unfoldSoak = function() {
|
||||
return this.soakNode && this;
|
||||
};
|
||||
return If;
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user