Ensuring constructors invoked with splats behave correctly, along with caching.

This commit is contained in:
Timothy Jones
2010-09-12 01:28:22 +12:00
parent 4af41e9bfb
commit d1f31c5143
3 changed files with 19 additions and 4 deletions

View File

@@ -524,7 +524,7 @@
return "" + (this.superReference(o)) + ".call(this" + (args.length ? ', ' : '') + (args) + ")"; return "" + (this.superReference(o)) + ".call(this" + (args.length ? ', ' : '') + (args) + ")";
}; };
CallNode.prototype.compileSplat = function(o) { CallNode.prototype.compileSplat = function(o) {
var _b, _c, _d, mentionsArgs, meth, obj, temp; var _b, _c, _d, a, b, c, mentionsArgs, meth, obj, temp;
meth = this.meth || this.superReference(o); meth = this.meth || this.superReference(o);
obj = this.variable && this.variable.source || 'this'; obj = this.variable && this.variable.source || 'this';
if (obj.match(/\(/)) { if (obj.match(/\(/)) {
@@ -544,7 +544,10 @@
})(); })();
} }
utility('extends'); utility('extends');
return "" + (this.first) + "(function() {\n" + (this.idt(1)) + "var ctor = function(){};\n" + (this.idt(1)) + "__extends(ctor, " + (meth) + ");\n" + (this.idt(1)) + "return " + (meth) + ".apply(new ctor, " + (this.compileSplatArguments(o)) + ");\n" + (this.tab) + "})." + (mentionsArgs ? 'apply(this, arguments)' : 'call(this)') + (this.last); a = o.scope.freeVariable();
b = o.scope.freeVariable();
c = o.scope.freeVariable();
return "" + (this.first) + "(function() {\n" + (this.idt(1)) + "var ctor = function(){};\n" + (this.idt(1)) + "__extends(ctor, " + (a) + " = " + (meth) + ");\n" + (this.idt(1)) + "return typeof (" + (b) + " = " + (meth) + ".apply(" + (c) + " = new ctor, " + (this.compileSplatArguments(o)) + ")) === \"object\" ? " + (b) + " : " + (c) + ";\n" + (this.tab) + "})." + (mentionsArgs ? 'apply(this, arguments)' : 'call(this)') + (this.last);
} else { } else {
return "" + (this.first) + (this.prefix()) + (meth) + ".apply(" + (obj) + ", " + (this.compileSplatArguments(o)) + ")" + (this.last); return "" + (this.first) + (this.prefix()) + (meth) + ".apply(" + (obj) + ", " + (this.compileSplatArguments(o)) + ")" + (this.last);
} }

View File

@@ -479,11 +479,14 @@ exports.CallNode = class CallNode extends BaseNode
for arg in @args for arg in @args
arg.contains (n) -> mentionsArgs or= n instanceof LiteralNode and (n.value is 'arguments') arg.contains (n) -> mentionsArgs or= n instanceof LiteralNode and (n.value is 'arguments')
utility 'extends' utility 'extends'
a = o.scope.freeVariable()
b = o.scope.freeVariable()
c = o.scope.freeVariable()
""" """
#{@first}(function() { #{@first}(function() {
#{@idt(1)}var ctor = function(){}; #{@idt(1)}var ctor = function(){};
#{@idt(1)}__extends(ctor, #{meth}); #{@idt(1)}__extends(ctor, #{a} = #{meth});
#{@idt(1)}return #{meth}.apply(new ctor, #{ @compileSplatArguments(o) }); #{@idt(1)}return typeof (#{b} = #{meth}.apply(#{c} = new ctor, #{ @compileSplatArguments(o) })) === "object" ? #{b} : #{c};
#{@tab}}).#{ if mentionsArgs then 'apply(this, arguments)' else 'call(this)'}#{@last} #{@tab}}).#{ if mentionsArgs then 'apply(this, arguments)' else 'call(this)'}#{@last}
""" """
else else

View File

@@ -229,3 +229,12 @@ func.withThis = -> this true
func.withAt() func.withAt()
func.withThis() func.withThis()
# Ensure that constructors invoked with splats return a new object.
args = [1, 2, 3]
Type = (@args) ->
type = new Type args...
ok type and type instanceof Type
ok v is args[i] for v, i in type.args