diff --git a/lib/nodes.js b/lib/nodes.js index 9939ccfd..bcf03246 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -497,40 +497,49 @@ })()); }; CallNode.prototype.compileNode = function(o) { - var _b, _c, _d, _e, _f, _g, _h, _i, arg, args, code, op; + var _b, _c, _d, _e, _f, _g, _h, _i, _j, arg, args, code, methodAccessor, op; if (!(o.chainRoot)) { o.chainRoot = this; } op = this.tags.operation; if (this.exist) { - _b = this.variable.compileReference(o, { - precompile: true - }); - this.first = _b[0]; - this.meth = _b[1]; + if (this.variable instanceof ValueNode && this.variable.properties[this.variable.properties.length - 1] instanceof AccessorNode) { + methodAccessor = this.variable.properties.pop(); + _b = this.variable.compileReference(o); + this.first = _b[0]; + this.meth = _b[1]; + this.first = new ValueNode(this.first, [methodAccessor]).compile(o); + this.meth = new ValueNode(this.meth, [methodAccessor]).compile(o); + } else { + _c = this.variable.compileReference(o, { + precompile: true + }); + this.first = _c[0]; + this.meth = _c[1]; + } this.first = ("(typeof " + (this.first) + " === \"function\" ? "); this.last = " : undefined)"; } else if (this.variable) { this.meth = this.variable.compile(o); } - _d = this.args; - for (_c = 0, _e = _d.length; _c < _e; _c++) { - arg = _d[_c]; + _e = this.args; + for (_d = 0, _f = _e.length; _d < _f; _d++) { + arg = _e[_d]; if (arg instanceof SplatNode) { code = this.compileSplat(o); } } if (!code) { args = (function() { - _f = []; _h = this.args; - for (_g = 0, _i = _h.length; _g < _i; _g++) { - arg = _h[_g]; - _f.push((function() { + _g = []; _i = this.args; + for (_h = 0, _j = _i.length; _h < _j; _h++) { + arg = _i[_h]; + _g.push((function() { arg.parenthetical = true; return arg.compile(o); })()); } - return _f; + return _g; }).call(this); code = this.isSuper ? this.compileSuper(args.join(', '), o) : ("" + (this.first) + (this.prefix()) + (this.meth) + "(" + (args.join(', ')) + ")" + (this.last)); } diff --git a/src/nodes.coffee b/src/nodes.coffee index a7a29573..9a75e46c 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -452,7 +452,13 @@ exports.CallNode = class CallNode extends BaseNode o.chainRoot = this unless o.chainRoot op = @tags.operation if @exist - [@first, @meth] = @variable.compileReference o, precompile: yes + if @variable instanceof ValueNode and @variable.properties[@variable.properties.length - 1] instanceof AccessorNode + methodAccessor = @variable.properties.pop() + [@first, @meth] = @variable.compileReference o + @first = new ValueNode(@first, [methodAccessor]).compile o + @meth = new ValueNode(@meth, [methodAccessor]).compile o + else + [@first, @meth] = @variable.compileReference o, precompile: yes @first = "(typeof #{@first} === \"function\" ? " @last = " : undefined)" else if @variable then @meth = @variable.compile o diff --git a/test/test_existence.coffee b/test/test_existence.coffee index a74a2b30..8a5771a3 100644 --- a/test/test_existence.coffee +++ b/test/test_existence.coffee @@ -124,13 +124,17 @@ duration = if options?.animated then 150 else 0 ok duration is 0 -# function soak +# Function soaks. plus1 = (x) -> x + 1 +obj = { + returnThis: -> this +} ok plus1?(41) is 42 ok (plus1? 41) is 42 ok plus2?(41) is undefined ok (plus2? 41) is undefined +ok obj.returnThis?() is obj maybe_close = (f, arg) -> if typeof f is 'function' then () -> f(arg) else -1