diff --git a/packages/babel-plugin-transform-optional-chaining/src/index.js b/packages/babel-plugin-transform-optional-chaining/src/index.js index 826a5b8a4c..ff14c27467 100644 --- a/packages/babel-plugin-transform-optional-chaining/src/index.js +++ b/packages/babel-plugin-transform-optional-chaining/src/index.js @@ -97,6 +97,9 @@ export default function ({ types: t }) { if (path.key == "callee" && (parentPath.isCallExpression() || parentPath.isNewExpression())) { return false; } + if (path.key == "argument" && parentPath.isUnaryExpression({ operator: "delete"})) { + return false; + } return true; }); diff --git a/packages/babel-plugin-transform-optional-chaining/test/fixtures/execute/assignment-left.js b/packages/babel-plugin-transform-optional-chaining/test/fixtures/execute/assignment-left.js new file mode 100644 index 0000000000..631cb72fcd --- /dev/null +++ b/packages/babel-plugin-transform-optional-chaining/test/fixtures/execute/assignment-left.js @@ -0,0 +1,14 @@ +const obj = { + a: { + b: 0, + }, +}; + +obj?.a.b = 1; +assert.equal(obj.a.b, 1); + +obj?.a?.b = 2; +assert.equal(obj.a.b, 2); + +obj?.b?.b = 3; +assert.equal(obj.b, undefined); diff --git a/packages/babel-plugin-transform-optional-chaining/test/fixtures/execute/assignment-right.js b/packages/babel-plugin-transform-optional-chaining/test/fixtures/execute/assignment-right.js new file mode 100644 index 0000000000..d2299449ff --- /dev/null +++ b/packages/babel-plugin-transform-optional-chaining/test/fixtures/execute/assignment-right.js @@ -0,0 +1,26 @@ +const obj = { + a: { + b: { + c: { + d: 2, + }, + }, + }, +}; + +const a = obj?.a; +assert.equal(a, obj.a); + +const b = obj?.a?.b; +assert.equal(b, obj.a.b); + +const bad = obj?.b?.b; +assert.equal(bad, undefined); + +let val; +val = obj?.a?.b; +assert.equal(val, obj.a.b); + +assert.throws(() => { + const bad = obj?.b.b; +}); diff --git a/packages/babel-plugin-transform-optional-chaining/test/fixtures/execute/call.js b/packages/babel-plugin-transform-optional-chaining/test/fixtures/execute/call.js new file mode 100644 index 0000000000..846b15d7dc --- /dev/null +++ b/packages/babel-plugin-transform-optional-chaining/test/fixtures/execute/call.js @@ -0,0 +1,61 @@ +let calls = 0; +const obj = { + a: { + b(val) { + assert.equal(val, 1); + assert.equal(this, obj.a); + return calls++; + }, + }, + c(val) { + assert.equal(val, 1); + assert.equal(this, obj); + return calls++; + }, +}; + +let ab = obj?.a?.b(1); +assert.equal(ab, 0); + +ab = obj?.a.b(1); +assert.equal(ab, 1); + +ab = obj?.a?.b?.(1); +assert.equal(ab, 2); + +ab = obj?.a.b?.(1); +assert.equal(ab, 3); + +ab = obj?.b?.b(1); +assert.equal(ab, undefined); + +ab = obj?.b?.b?.(1); +assert.equal(ab, undefined); + +let c = obj?.c(1); +assert.equal(c, 4); + +c = obj?.c?.(1); +assert.equal(c, 5); + +c = obj?.d?.(1); +assert.equal(c, undefined); + +obj?.a.b(1); +assert.equal(calls, 7); + +obj?.a?.b(1); +assert.equal(calls, 8); + +obj?.a?.b?.(1); +assert.equal(calls, 9); + +obj?.a.b?.(1); +assert.equal(calls, 10); + +obj?.c?.(1); +assert.equal(calls, 11); + +obj?.b?.b(1); +obj?.b?.b?.(1); +obj?.d?.(1); diff --git a/packages/babel-plugin-transform-optional-chaining/test/fixtures/execute/delete.js b/packages/babel-plugin-transform-optional-chaining/test/fixtures/execute/delete.js new file mode 100644 index 0000000000..cbb890e5fe --- /dev/null +++ b/packages/babel-plugin-transform-optional-chaining/test/fixtures/execute/delete.js @@ -0,0 +1,20 @@ +const obj = { + a: { + b: 0, + }, +}; + +let test = delete obj?.a?.b; +assert.equal(obj.a.b, undefined); +assert.equal(test, true); + +test = delete obj?.a.b; +assert.equal(obj.a.b, undefined); +assert.equal(test, true); + +test = delete obj?.b?.b; +assert.equal(obj.b, undefined); +assert.equal(test, undefined); + +delete obj?.a; +assert.equal(obj.a, undefined); diff --git a/packages/babel-plugin-transform-optional-chaining/test/fixtures/execute/new.js b/packages/babel-plugin-transform-optional-chaining/test/fixtures/execute/new.js new file mode 100644 index 0000000000..bef413aa6e --- /dev/null +++ b/packages/babel-plugin-transform-optional-chaining/test/fixtures/execute/new.js @@ -0,0 +1,65 @@ +let calls = 0; +const obj = { + a: { + b: class { + constructor(val) { + assert.equal(val, 1); + assert(this instanceof obj.a.b); + calls++; + } + }, + }, + c: class { + constructor(val) { + assert.equal(val, 1); + assert(this instanceof obj.c); + calls++; + } + }, +}; + +let ab = new obj?.a?.b(1); +assert(ab instanceof obj.a.b); + +ab = new obj?.a.b(1); +assert(ab instanceof obj.a.b); + +ab = new obj?.a?.b?.(1); +assert(ab instanceof obj.a.b); + +ab = new obj?.a.b?.(1); +assert(ab instanceof obj.a.b); + +ab = new obj?.b?.b(1); +assert.equal(ab, undefined); + +ab = new obj?.b?.b?.(1); +assert.equal(ab, undefined); + +let c = new obj?.c(1); +assert(c instanceof obj.c); + +c = new obj?.c?.(1); +assert(c instanceof obj.c); + +c = new obj?.d?.(1); +assert.equal(c, undefined); + +new obj?.a.b(1); +assert.equal(calls, 7); + +new obj?.a?.b(1); +assert.equal(calls, 8); + +new obj?.a?.b?.(1); +assert.equal(calls, 9); + +new obj?.a.b?.(1); +assert.equal(calls, 10); + +new obj?.c?.(1); +assert.equal(calls, 11); + +new obj?.b?.b(1); +new obj?.b?.b?.(1); +new obj?.d?.(1); diff --git a/packages/babel-plugin-transform-optional-chaining/test/fixtures/general/delete/expected.js b/packages/babel-plugin-transform-optional-chaining/test/fixtures/general/delete/expected.js index d1c9cb8617..a005adc52f 100644 --- a/packages/babel-plugin-transform-optional-chaining/test/fixtures/general/delete/expected.js +++ b/packages/babel-plugin-transform-optional-chaining/test/fixtures/general/delete/expected.js @@ -1,5 +1,5 @@ var _a, _a2, _a2$b, _a2$b$c; -delete ((_a = a) == null ? void 0 : _a.b); +(_a = a) == null ? void 0 : delete _a.b; -delete ((_a2 = a) == null ? void 0 : (_a2$b = _a2.b) == null ? void 0 : (_a2$b$c = _a2$b.c) == null ? void 0 : _a2$b$c.d); \ No newline at end of file +(_a2 = a) == null ? void 0 : (_a2$b = _a2.b) == null ? void 0 : (_a2$b$c = _a2$b.c) == null ? void 0 : delete _a2$b$c.d; diff --git a/packages/babel-plugin-transform-optional-chaining/test/fixtures/general/options.json b/packages/babel-plugin-transform-optional-chaining/test/fixtures/options.json similarity index 100% rename from packages/babel-plugin-transform-optional-chaining/test/fixtures/general/options.json rename to packages/babel-plugin-transform-optional-chaining/test/fixtures/options.json