From 53426d23618f465c2284d3349726ac14dd19dfd0 Mon Sep 17 00:00:00 2001 From: Dan Harper Date: Sun, 2 Oct 2016 01:04:02 +0100 Subject: [PATCH] fix error when constructor default arg refers to own static property or self (closes #4253) (closes #4442) --- .../src/default.js | 12 +++++++++--- .../fixtures/parameters/default-iife-4253/actual.js | 6 ++++++ .../fixtures/parameters/default-iife-4253/exec.js | 9 +++++++++ .../parameters/default-iife-4253/expected.js | 8 ++++++++ .../fixtures/parameters/default-iife-self/actual.js | 11 +++++++++++ .../fixtures/parameters/default-iife-self/exec.js | 7 +++++++ .../parameters/default-iife-self/expected.js | 13 +++++++++++++ 7 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-4253/actual.js create mode 100644 packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-4253/exec.js create mode 100644 packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-4253/expected.js create mode 100644 packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-self/actual.js create mode 100644 packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-self/exec.js create mode 100644 packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-self/expected.js diff --git a/packages/babel-plugin-transform-es2015-parameters/src/default.js b/packages/babel-plugin-transform-es2015-parameters/src/default.js index afcdba29b5ce..445000fadba6 100644 --- a/packages/babel-plugin-transform-es2015-parameters/src/default.js +++ b/packages/babel-plugin-transform-es2015-parameters/src/default.js @@ -24,10 +24,16 @@ function hasDefaults(node) { return false; } +function isSafeBinding(scope, node) { + if (!scope.hasOwnBinding(node.name)) return true; + const { kind } = scope.getOwnBinding(node.name); + return kind === "param" || kind === "local"; +} + let iifeVisitor = { ReferencedIdentifier(path, state) { - let name = path.node.name; - if (name === "eval" || (path.scope.hasOwnBinding(name) && path.scope.getOwnBinding(name).kind !== "param")) { + const { scope, node } = path; + if (node.name === "eval" || !isSafeBinding(scope, node)) { state.iife = true; path.stop(); } @@ -100,7 +106,7 @@ export let visitor = { // if (!state.iife) { - if (right.isIdentifier() && scope.hasOwnBinding(right.node.name) && scope.getOwnBinding(right.node.name).kind !== "param") { + if (right.isIdentifier() && !isSafeBinding(scope, right.node)) { // the right hand side references a parameter state.iife = true; } else { diff --git a/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-4253/actual.js b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-4253/actual.js new file mode 100644 index 000000000000..02d3c1128826 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-4253/actual.js @@ -0,0 +1,6 @@ +class Ref { + constructor(id = ++Ref.nextID) { + this.id = id + } +} +Ref.nextID = 0 \ No newline at end of file diff --git a/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-4253/exec.js b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-4253/exec.js new file mode 100644 index 000000000000..8e0a435f1198 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-4253/exec.js @@ -0,0 +1,9 @@ +class Ref { + static nextId = 0 + constructor(id = ++Ref.nextId, n = id) { + this.id = n + } +} + +assert.equal(1, new Ref().id) +assert.equal(2, new Ref().id) diff --git a/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-4253/expected.js b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-4253/expected.js new file mode 100644 index 000000000000..e442afadfa3f --- /dev/null +++ b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-4253/expected.js @@ -0,0 +1,8 @@ +var Ref = function Ref() { + var id = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ++Ref.nextID; + babelHelpers.classCallCheck(this, Ref); + + this.id = id; +}; + +Ref.nextID = 0; \ No newline at end of file diff --git a/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-self/actual.js b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-self/actual.js new file mode 100644 index 000000000000..d60443bb66ca --- /dev/null +++ b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-self/actual.js @@ -0,0 +1,11 @@ +class Ref { + constructor(ref = Ref) { + this.ref = ref + } +} + +class X { + constructor(x = foo) { + this.x = x + } +} diff --git a/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-self/exec.js b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-self/exec.js new file mode 100644 index 000000000000..f1ad98139db6 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-self/exec.js @@ -0,0 +1,7 @@ +class Ref { + constructor(ref = Ref) { + this.ref = ref + } +} + +assert.equal(Ref, new Ref().ref) diff --git a/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-self/expected.js b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-self/expected.js new file mode 100644 index 000000000000..08ab69096aac --- /dev/null +++ b/packages/babel-plugin-transform-es2015-parameters/test/fixtures/parameters/default-iife-self/expected.js @@ -0,0 +1,13 @@ +var Ref = function Ref() { + var ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Ref; + babelHelpers.classCallCheck(this, Ref); + + this.ref = ref; +}; + +var X = function X() { + var x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : foo; + babelHelpers.classCallCheck(this, X); + + this.x = x; +};