diff --git a/lib/coffee-script/nodes.js b/lib/coffee-script/nodes.js index 5eeaa7c7..9cf1c6a0 100644 --- a/lib/coffee-script/nodes.js +++ b/lib/coffee-script/nodes.js @@ -813,7 +813,7 @@ } if (this.isNew) { idt = this.tab + TAB; - return "(function(func, args, ctor) {\n" + idt + "ctor.prototype = func.prototype;\n" + idt + "var child = new ctor, result = func.apply(child, args);\n" + idt + "return typeof result === \"object\" && result !== null ? result : child;\n" + this.tab + "})(" + (this.variable.compile(o, LEVEL_LIST)) + ", " + splatArgs + ", function() {})"; + return "(function(func, args, ctor) {\n" + idt + "ctor.prototype = func.prototype;\n" + idt + "var child = new ctor, result = func.apply(child, args), t = typeof result;\n" + idt + "return t == \"object\" || t == \"function\" ? result || child : child;\n" + this.tab + "})(" + (this.variable.compile(o, LEVEL_LIST)) + ", " + splatArgs + ", function(){})"; } base = new Value(this.variable); if ((name = base.properties.pop()) && base.isComplex()) { diff --git a/src/nodes.coffee b/src/nodes.coffee index 0037f690..260f379d 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -586,9 +586,9 @@ exports.Call = class Call extends Base return """ (function(func, args, ctor) { #{idt}ctor.prototype = func.prototype; - #{idt}var child = new ctor, result = func.apply(child, args); - #{idt}return typeof result === "object" && result !== null ? result : child; - #{@tab}})(#{ @variable.compile o, LEVEL_LIST }, #{splatArgs}, function() {}) + #{idt}var child = new ctor, result = func.apply(child, args), t = typeof result; + #{idt}return t == "object" || t == "function" ? result || child : child; + #{@tab}})(#{ @variable.compile o, LEVEL_LIST }, #{splatArgs}, function(){}) """ base = new Value @variable if (name = base.properties.pop()) and base.isComplex() diff --git a/test/function_invocation.coffee b/test/function_invocation.coffee index 145f6ac1..c12a93e1 100644 --- a/test/function_invocation.coffee +++ b/test/function_invocation.coffee @@ -392,11 +392,17 @@ test "#1011: passing a splat to a method of a number", -> eq '1011', (131.0).toString [5]... -test "splats and the `new` operator: functions that return `null` should produce their instance", -> +test "splats and the `new` operator: functions that return `null` should construct their instance", -> args = [] child = new (constructor = -> null) args... ok child instanceof constructor +test "splats and the `new` operator: functions that return functions should construct their return value", -> + args = [] + fn = -> + child = new (constructor = -> fn) args... + ok child not instanceof constructor + eq fn, child test "implicit return", ->