From 3fb17b00a63407e604b4dc773575069f0576a578 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sat, 11 Oct 2014 10:44:51 +1100 Subject: [PATCH] fix spread and super resolution - fixes #42 --- lib/6to5/transformers/classes.js | 18 +++++++++++------- lib/6to5/transformers/spread.js | 6 ++---- .../classes/accessing-super-class/actual.js | 10 ++++++++++ .../classes/accessing-super-class/expected.js | 14 ++++++++++++++ .../actual.js | 1 + .../expected.js | 4 ++++ .../contexted-method-call-single-arg/actual.js | 1 + .../expected.js | 1 + 8 files changed, 44 insertions(+), 11 deletions(-) diff --git a/lib/6to5/transformers/classes.js b/lib/6to5/transformers/classes.js index 765f030cef..fe1fac5bf7 100644 --- a/lib/6to5/transformers/classes.js +++ b/lib/6to5/transformers/classes.js @@ -133,19 +133,23 @@ var superIdentifier = function (superName, methodNode, methodName, node, parent) // super(); -> ClassName.prototype.MethodName.call(this); if (parent.type === "CallExpression" && parent.callee === node) { + parent.arguments.unshift(b.thisExpression()); + if (methodName === "constructor") { // constructor() { super(); } - node.name += ".call"; + return b.memberExpression(node, b.identifier("call"), false); } else { // foo() { super(); } - if (!methodNode.static) node.name += ".prototype"; - node.name += "." + methodName + ".call"; - } + if (!methodNode.static) { + node = b.memberExpression(node, b.identifier("prototype"), false); + } - parent.arguments.unshift(b.thisExpression()); + node = b.memberExpression(node, b.identifier(methodName), false); + return b.memberExpression(node, b.identifier("call"), false); + } } else if (parent.type === "MemberExpression") { // super.test -> ClassName.prototype.test - node.name += ".prototype"; + return b.memberExpression(node, b.identifier("prototype"), false); } }; @@ -154,7 +158,7 @@ var replaceInstanceSuperReferences = function (superName, method, methodNode, me traverse(method, function (node, parent) { if (node.type === "Identifier" && node.name === "super") { - superIdentifier(superName, methodNode, methodName, node, parent); + return superIdentifier(superName, methodNode, methodName, node, parent); } else if (node.type === "CallExpression") { var callee = node.callee; if (callee.type !== "MemberExpression") return; diff --git a/lib/6to5/transformers/spread.js b/lib/6to5/transformers/spread.js index ee8e1a2c4a..bf9aa31d05 100644 --- a/lib/6to5/transformers/spread.js +++ b/lib/6to5/transformers/spread.js @@ -3,8 +3,6 @@ var b = require("ast-types").builders; var _ = require("lodash"); exports.ArrayExpression = function (node) { - //if (node.ignoreSpread) return; - var elements = node.elements; if (!elements.length) return; @@ -51,9 +49,9 @@ exports.CallExpression = function (node) { if (callee.type === "MemberExpression") { contextLiteral = callee.object; - callee.property.name += ".apply"; + callee.property = b.memberExpression(callee.property, b.identifier("apply"), false); } else { - node.callee.name += ".apply"; + node.callee = b.memberExpression(node.callee, b.identifier("apply"), false); } node.arguments.unshift(contextLiteral); diff --git a/test/fixtures/classes/accessing-super-class/actual.js b/test/fixtures/classes/accessing-super-class/actual.js index b6c04c4c61..64b349152c 100644 --- a/test/fixtures/classes/accessing-super-class/actual.js +++ b/test/fixtures/classes/accessing-super-class/actual.js @@ -4,13 +4,23 @@ class Test extends Foo { super(); super.test(); foob(super); + + super(...arguments); + super("test", ...arguments); + + super.test(...arguments); + super.test("test", ...arguments); } test() { super(); + super(...arguments); + super("test", ...arguments); } static foo() { super(); + super(...arguments); + super("test", ...arguments); } } diff --git a/test/fixtures/classes/accessing-super-class/expected.js b/test/fixtures/classes/accessing-super-class/expected.js index 9aeb053d55..013063b60a 100644 --- a/test/fixtures/classes/accessing-super-class/expected.js +++ b/test/fixtures/classes/accessing-super-class/expected.js @@ -4,6 +4,13 @@ var Test = function (Foo) { Foo.call(this); Foo.prototype.test.call(this); foob(Foo); + Foo.call.apply(Foo, [this].concat(Array.prototype.slice.call(arguments))); + Foo.call.apply(Foo, [this, "test"].concat(Array.prototype.slice.call(arguments))); + Foo.prototype.test.call.apply(Foo.prototype, [this].concat(Array.prototype.slice.call(arguments))); + Foo.prototype.test.call.apply( + Foo.prototype, + [this, "test"].concat(Array.prototype.slice.call(arguments)) + ); } Test.prototype = Object.create(Foo.prototype, { constructor: { @@ -16,9 +23,16 @@ var Test = function (Foo) { Test.__proto__ = Foo; Test.prototype.test = function () { Foo.prototype.test.call(this); + Foo.prototype.test.call.apply(Foo.prototype.test, [this].concat(Array.prototype.slice.call(arguments))); + Foo.prototype.test.call.apply( + Foo.prototype.test, + [this, "test"].concat(Array.prototype.slice.call(arguments)) + ); }; Test.foo = function () { Foo.foo.call(this); + Foo.foo.call.apply(Foo.foo, [this].concat(Array.prototype.slice.call(arguments))); + Foo.foo.call.apply(Foo.foo, [this, "test"].concat(Array.prototype.slice.call(arguments))); }; return Test; }(Foo); diff --git a/test/fixtures/spread/contexted-method-call-multiple-args/actual.js b/test/fixtures/spread/contexted-method-call-multiple-args/actual.js index 112f046005..7dc7d142a1 100644 --- a/test/fixtures/spread/contexted-method-call-multiple-args/actual.js +++ b/test/fixtures/spread/contexted-method-call-multiple-args/actual.js @@ -1 +1,2 @@ foob.add(foo, bar, ...numbers); +foob.test.add(foo, bar, ...numbers); diff --git a/test/fixtures/spread/contexted-method-call-multiple-args/expected.js b/test/fixtures/spread/contexted-method-call-multiple-args/expected.js index eb6f7281d9..2a9d39f39b 100644 --- a/test/fixtures/spread/contexted-method-call-multiple-args/expected.js +++ b/test/fixtures/spread/contexted-method-call-multiple-args/expected.js @@ -2,3 +2,7 @@ foob.add.apply(foob, [ foo, bar ].concat(numbers)); +foob.test.add.apply(foob.test, [ + foo, + bar +].concat(numbers)); diff --git a/test/fixtures/spread/contexted-method-call-single-arg/actual.js b/test/fixtures/spread/contexted-method-call-single-arg/actual.js index 08a01b0c56..ef061e17a8 100644 --- a/test/fixtures/spread/contexted-method-call-single-arg/actual.js +++ b/test/fixtures/spread/contexted-method-call-single-arg/actual.js @@ -1 +1,2 @@ foob.add(...numbers); +foob.test.add(...numbers); diff --git a/test/fixtures/spread/contexted-method-call-single-arg/expected.js b/test/fixtures/spread/contexted-method-call-single-arg/expected.js index 2423ac1874..ce805e7f8d 100644 --- a/test/fixtures/spread/contexted-method-call-single-arg/expected.js +++ b/test/fixtures/spread/contexted-method-call-single-arg/expected.js @@ -1 +1,2 @@ foob.add.apply(foob, numbers); +foob.test.add.apply(foob.test, numbers);