diff --git a/lib/nodes.js b/lib/nodes.js index dedbacd6..c78c6d47 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -385,11 +385,26 @@ return !o.top || this.properties.length ? ValueNode.__super__.compile.call(this, o) : this.base.compile(o); }; ValueNode.prototype.compileNode = function(o) { - var _b, _c, baseline, complete, i, only, op, part, prop, props, temp; + var _b, _c, _d, _e, _f, _g, _h, baseline, complete, copy, hasSoak, i, me, only, op, p, part, prop, props, temp; only = del(o, 'onlyFirst'); op = this.tags.operation; props = only ? this.properties.slice(0, this.properties.length - 1) : this.properties; o.chainRoot || (o.chainRoot = this); + hasSoak = !!(function() { + _b = []; _d = props; + for (_c = 0, _e = _d.length; _c < _e; _c++) { + p = _d[_c]; + if (p.soakNode) { + _b.push(p); + } + } + return _b; + })().length; + if (hasSoak && this.containsType(CallNode)) { + _f = this.cacheIndexes(o); + me = _f[0]; + copy = _f[1]; + } if (this.parenthetical && !props.length) { this.base.parenthetical = true; } @@ -398,9 +413,9 @@ baseline = ("(" + (baseline) + ")"); } complete = (this.last = baseline); - _b = props; - for (i = 0, _c = _b.length; i < _c; i++) { - prop = _b[i]; + _g = props; + for (i = 0, _h = _g.length; i < _h; i++) { + prop = _g[i]; this.source = baseline; if (prop.soakNode) { if (this.base.containsType(CallNode) && i === 0) { @@ -411,7 +426,11 @@ complete += (baseline += prop.compile(o)); } else { part = prop.compile(o); - baseline += part; + if (hasSoak && prop.containsType(CallNode)) { + baseline += copy.properties[i].compile(o); + } else { + baseline += part; + } complete += part; this.last = part; } diff --git a/src/nodes.coffee b/src/nodes.coffee index 39991fdf..221f88f4 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -361,6 +361,9 @@ exports.ValueNode = class ValueNode extends BaseNode op = @tags.operation props = if only then @properties[0...@properties.length - 1] else @properties o.chainRoot or= this + hasSoak = !!(p for p in props when p.soakNode).length + if hasSoak and @containsType CallNode + [me, copy] = @cacheIndexes o @base.parenthetical = yes if @parenthetical and not props.length baseline = @base.compile o baseline = "(#{baseline})" if @hasProperties() and (@base instanceof ObjectNode or @isNumber()) @@ -379,7 +382,10 @@ exports.ValueNode = class ValueNode extends BaseNode complete += (baseline += prop.compile(o)) else part = prop.compile(o) - baseline += part + if hasSoak and prop.containsType CallNode + baseline += copy.properties[i].compile o + else + baseline += part complete += part @last = part diff --git a/test/test_existence.coffee b/test/test_existence.coffee index 6d0ee766..a74a2b30 100644 --- a/test/test_existence.coffee +++ b/test/test_existence.coffee @@ -77,6 +77,17 @@ ok result is '10' ok(process.exit.nothing?.property() or 101) +counter = 0 +func = -> + counter += 1 + 'prop' +obj = + prop: -> this + value: 25 + +ok obj[func()]()[func()]()[func()]()?.value is 25 +ok counter is 3 + # Soaks inner values. ident = (obj) -> obj