From 27c39c512dc13bd264f53111d093991d0756b6eb Mon Sep 17 00:00:00 2001 From: Justin Ridgewell Date: Fri, 18 May 2018 14:03:23 -0400 Subject: [PATCH] Class private properties (#7842) * Update member-expression-to-functions 1. Babel using British spellings, so `memoise` 2. Provide a helper `AssignmentMemoiser` class, which will assign the memo'd value with the `n`th access. * Private properties! * Fixes * Tests * Update helper name * Fix privates that reference other privates * Don't extend a builtin * Rebase --- .../README.md | 6 +- .../src/index.js | 56 +++- .../babel-helper-replace-supers/src/index.js | 83 +++--- packages/babel-helpers/src/helpers.js | 35 +++ .../package.json | 2 + .../src/index.js | 264 ++++++++++++++++-- .../private-loose/assignment/input.js | 10 + .../private-loose/assignment/output.js | 26 ++ .../test/fixtures/private-loose/call/exec.js | 15 + .../test/fixtures/private-loose/call/input.js | 10 + .../fixtures/private-loose/call/output.js | 27 ++ .../fixtures/private-loose/canonical/exec.js | 73 +++++ .../fixtures/private-loose/canonical/input.js | 20 ++ .../private-loose/canonical/options.json | 3 + .../private-loose/canonical/output.js | 52 ++++ .../constructor-collision/exec.js | 17 ++ .../constructor-collision/input.js | 9 + .../constructor-collision/output.js | 14 + .../private-loose/declaration-order/LICENSE | 28 ++ .../private-loose/declaration-order/exec.js | 8 + .../private-loose/declaration-order/input.js | 8 + .../private-loose/declaration-order/output.js | 16 ++ .../derived-multiple-supers/input.js | 11 + .../derived-multiple-supers/output.js | 32 +++ .../fixtures/private-loose/derived/exec.js | 22 ++ .../fixtures/private-loose/derived/input.js | 7 + .../fixtures/private-loose/derived/output.js | 32 +++ .../private-loose/extracted-this/input.js | 9 + .../private-loose/extracted-this/output.js | 19 ++ .../fixtures/private-loose/foobar/input.js | 9 + .../private-loose/foobar/options.json | 3 + .../fixtures/private-loose/foobar/output.js | 24 ++ .../private-loose/instance-undefined/exec.js | 9 + .../private-loose/instance-undefined/input.js | 3 + .../instance-undefined/output.js | 11 + .../fixtures/private-loose/instance/exec.js | 16 ++ .../fixtures/private-loose/instance/input.js | 3 + .../fixtures/private-loose/instance/output.js | 11 + .../fixtures/private-loose/multiple/exec.js | 11 + .../fixtures/private-loose/multiple/input.js | 4 + .../fixtures/private-loose/multiple/output.js | 17 ++ .../private-loose/native-classes/input.js | 18 ++ .../private-loose/native-classes/options.json | 3 + .../private-loose/native-classes/output.js | 18 ++ .../non-block-arrow-func/input.mjs | 11 + .../non-block-arrow-func/options.json | 3 + .../non-block-arrow-func/output.mjs | 25 ++ .../test/fixtures/private-loose/options.json | 3 + .../private-loose/private-in-derived/input.js | 8 + .../private-in-derived/output.js | 23 ++ .../private-loose/reevaluated/input.js | 43 +++ .../private-loose/reevaluated/options.json | 3 + .../private-loose/reevaluated/output.js | 18 ++ .../reference-in-other-property/input.js | 7 + .../reference-in-other-property/output.js | 25 ++ .../private-loose/static-export/input.mjs | 7 + .../private-loose/static-export/options.json | 3 + .../private-loose/static-export/output.mjs | 21 ++ .../private-loose/static-infer-name/input.js | 3 + .../static-infer-name/options.json | 3 + .../private-loose/static-infer-name/output.js | 8 + .../private-loose/static-inherited/input.js | 70 +++++ .../static-inherited/options.json | 3 + .../private-loose/static-inherited/output.js | 55 ++++ .../private-loose/static-undefined/input.js | 15 + .../static-undefined/options.json | 3 + .../private-loose/static-undefined/output.js | 11 + .../fixtures/private-loose/static/input.js | 15 + .../private-loose/static/options.json | 3 + .../fixtures/private-loose/static/output.js | 28 ++ .../private-loose/super-expression/input.js | 7 + .../private-loose/super-expression/output.js | 21 ++ .../private-loose/super-statement/input.js | 7 + .../private-loose/super-statement/output.js | 22 ++ .../fixtures/private-loose/update/exec.js | 27 ++ .../fixtures/private-loose/update/input.js | 10 + .../fixtures/private-loose/update/output.js | 26 ++ .../test/fixtures/private/assignment/input.js | 10 + .../fixtures/private/assignment/output.js | 26 ++ .../test/fixtures/private/call/exec.js | 15 + .../test/fixtures/private/call/input.js | 10 + .../test/fixtures/private/call/output.js | 26 ++ .../test/fixtures/private/canonical/exec.js | 73 +++++ .../test/fixtures/private/canonical/input.js | 20 ++ .../fixtures/private/canonical/options.json | 3 + .../test/fixtures/private/canonical/output.js | 49 ++++ .../private/constructor-collision/exec.js | 17 ++ .../private/constructor-collision/input.js | 9 + .../private/constructor-collision/output.js | 13 + .../private/declaration-order/LICENSE | 28 ++ .../private/declaration-order/exec.js | 8 + .../private/declaration-order/input.js | 8 + .../private/declaration-order/output.js | 14 + .../private/derived-multiple-supers/input.js | 11 + .../private/derived-multiple-supers/output.js | 28 ++ .../test/fixtures/private/derived/exec.js | 22 ++ .../test/fixtures/private/derived/input.js | 7 + .../test/fixtures/private/derived/output.js | 27 ++ .../fixtures/private/extracted-this/input.js | 9 + .../fixtures/private/extracted-this/output.js | 15 + .../test/fixtures/private/foobar/input.js | 9 + .../test/fixtures/private/foobar/output.js | 23 ++ .../private/instance-undefined/exec.js | 9 + .../private/instance-undefined/input.js | 3 + .../private/instance-undefined/output.js | 9 + .../test/fixtures/private/instance/exec.js | 35 +++ .../test/fixtures/private/instance/input.js | 3 + .../fixtures/private/instance/options.json | 3 + .../test/fixtures/private/instance/output.js | 9 + .../test/fixtures/private/multiple/exec.js | 11 + .../test/fixtures/private/multiple/input.js | 4 + .../test/fixtures/private/multiple/output.js | 13 + .../fixtures/private/native-classes/input.js | 18 ++ .../private/native-classes/options.json | 3 + .../fixtures/private/native-classes/output.js | 14 + .../private/non-block-arrow-func/input.mjs | 11 + .../private/non-block-arrow-func/options.json | 3 + .../private/non-block-arrow-func/output.mjs | 22 ++ .../test/fixtures/private/options.json | 3 + .../private/private-in-derived/input.js | 8 + .../private/private-in-derived/output.js | 21 ++ .../fixtures/private/reevaluated/input.js | 51 ++++ .../fixtures/private/reevaluated/options.json | 3 + .../fixtures/private/reevaluated/output.js | 15 + .../reference-in-other-property/input.js | 7 + .../reference-in-other-property/output.js | 20 ++ .../private/regression-T2983/input.mjs | 7 + .../private/regression-T2983/options.json | 3 + .../private/regression-T2983/output.mjs | 16 ++ .../private/regression-T6719/input.js | 14 + .../private/regression-T6719/options.json | 3 + .../private/regression-T6719/output.js | 22 ++ .../private/regression-T7364/input.mjs | 17 ++ .../private/regression-T7364/options.json | 3 + .../private/regression-T7364/output.mjs | 46 +++ .../fixtures/private/static-export/input.mjs | 7 + .../private/static-export/options.json | 3 + .../fixtures/private/static-export/output.mjs | 18 ++ .../private/static-infer-name/input.js | 3 + .../private/static-infer-name/options.json | 3 + .../private/static-infer-name/output.js | 5 + .../private/static-inherited/input.js | 70 +++++ .../private/static-inherited/options.json | 3 + .../private/static-inherited/output.js | 51 ++++ .../private/static-undefined/input.js | 15 + .../private/static-undefined/options.json | 3 + .../private/static-undefined/output.js | 9 + .../test/fixtures/private/static/input.js | 15 + .../test/fixtures/private/static/options.json | 3 + .../test/fixtures/private/static/output.js | 26 ++ .../test/fixtures/private/super-call/input.js | 9 + .../fixtures/private/super-call/output.js | 35 +++ .../private/super-expression/input.js | 7 + .../private/super-expression/output.js | 18 ++ .../fixtures/private/super-statement/input.js | 7 + .../private/super-statement/output.js | 21 ++ .../test/fixtures/private/update/exec.js | 27 ++ .../test/fixtures/private/update/input.js | 10 + .../test/fixtures/private/update/output.js | 26 ++ .../test/fixtures/public/assignment/input.js | 12 + .../test/fixtures/public/assignment/output.js | 23 ++ .../test/fixtures/public/call/exec.js | 15 + .../test/fixtures/public/call/input.js | 10 + .../test/fixtures/public/call/output.js | 21 ++ .../public/derived-multiple-supers/input.js | 11 + .../public/derived-multiple-supers/output.js | 24 ++ .../fixtures/public/extracted-this/input.js | 9 + .../fixtures/public/extracted-this/output.js | 9 + .../fixtures/public/native-classes/exec.js | 18 ++ .../fixtures/public/native-classes/input.js | 4 + .../public/native-classes/options.json | 4 + .../fixtures/public/native-classes/output.js | 8 + .../test/fixtures/public/numeric/input.js | 4 + .../test/fixtures/public/numeric/output.js | 7 + .../test/fixtures/public/update/exec.js | 27 ++ .../test/fixtures/public/update/input.js | 10 + .../test/fixtures/public/update/output.js | 21 ++ 177 files changed, 3056 insertions(+), 95 deletions(-) create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/assignment/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/assignment/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/call/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/call/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/call/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/constructor-collision/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/constructor-collision/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/constructor-collision/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/declaration-order/LICENSE create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/declaration-order/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/declaration-order/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/declaration-order/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived-multiple-supers/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived-multiple-supers/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/extracted-this/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/extracted-this/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/foobar/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/foobar/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/foobar/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance-undefined/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance-undefined/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance-undefined/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/multiple/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/multiple/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/multiple/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/input.mjs create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/output.mjs create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/private-in-derived/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/private-in-derived/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reference-in-other-property/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reference-in-other-property/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/input.mjs create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/output.mjs create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/super-expression/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/super-expression/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/super-statement/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/super-statement/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/update/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/update/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/update/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/assignment/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/assignment/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/call/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/call/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/call/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/constructor-collision/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/constructor-collision/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/constructor-collision/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/declaration-order/LICENSE create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/declaration-order/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/declaration-order/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/declaration-order/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived-multiple-supers/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived-multiple-supers/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/extracted-this/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/extracted-this/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/foobar/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/foobar/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance-undefined/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance-undefined/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance-undefined/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/multiple/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/multiple/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/multiple/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/input.mjs create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/output.mjs create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/private-in-derived/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/private-in-derived/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/reference-in-other-property/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/reference-in-other-property/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/input.mjs create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/output.mjs create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T7364/input.mjs create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T7364/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T7364/output.mjs create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/input.mjs create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/output.mjs create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-call/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-call/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-expression/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-expression/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-statement/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-statement/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/update/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/update/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/private/update/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/public/assignment/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/public/assignment/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/public/call/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/public/call/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/public/call/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/public/derived-multiple-supers/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/public/derived-multiple-supers/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/public/extracted-this/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/public/extracted-this/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/public/native-classes/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/public/native-classes/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/public/native-classes/options.json create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/public/native-classes/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/public/numeric/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/public/numeric/output.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/public/update/exec.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/public/update/input.js create mode 100644 packages/babel-plugin-proposal-class-properties/test/fixtures/public/update/output.js diff --git a/packages/babel-helper-member-expression-to-functions/README.md b/packages/babel-helper-member-expression-to-functions/README.md index 31dd4c3ce2..7bc38cf6d5 100644 --- a/packages/babel-helper-member-expression-to-functions/README.md +++ b/packages/babel-helper-member-expression-to-functions/README.md @@ -26,7 +26,7 @@ const visitor = { // The helper requires three special methods on state: `get`, `set`, and // `call`. -// Optionally, a special `memoize` method may be defined, which gets +// Optionally, a special `memoise` method may be defined, which gets // called if the member is in a self-referential update expression. // Everything else will be passed through as normal. const state = { @@ -55,10 +55,10 @@ const state = { ); }, - memoize(memberPath) { + memoise(memberPath) { const { node } = memberPath; if (node.computed) { - MEMOIZED.set(node, ...); + MEMOISED.set(node, ...); } }, diff --git a/packages/babel-helper-member-expression-to-functions/src/index.js b/packages/babel-helper-member-expression-to-functions/src/index.js index b57a5e0a7e..e44c3eb784 100644 --- a/packages/babel-helper-member-expression-to-functions/src/index.js +++ b/packages/babel-helper-member-expression-to-functions/src/index.js @@ -1,6 +1,39 @@ import * as t from "@babel/types"; +class AssignmentMemoiser { + constructor() { + this._map = new WeakMap(); + } + + has(key) { + return this._map.has(key); + } + + get(key) { + if (!this.has(key)) return; + + const record = this._map.get(key); + const { value } = record; + + record.count--; + if (record.count === 0) { + // The `count` access is the outermost function call (hopefully), so it + // does the assignment. + return t.assignmentExpression("=", value, key); + } + return value; + } + + set(key, value, count) { + return this._map.set(key, { count, value }); + } +} + const handle = { + memoise() { + // noop. + }, + handle(member) { const { node, parent, parentPath } = member; @@ -9,11 +42,10 @@ const handle = { if (parentPath.isUpdateExpression({ argument: node })) { const { operator, prefix } = parent; - // Give the state handler a chance to memoize the member, - // since we'll reference it twice. - if (this.memoize) { - this.memoize(member); - } + // Give the state handler a chance to memoise the member, since we'll + // reference it twice. The second access (the set) should do the memo + // assignment. + this.memoise(member, 2); const value = t.binaryExpression( operator[0], @@ -44,11 +76,10 @@ const handle = { let value = right; if (operator !== "=") { - // Give the state handler a chance to memoize the member, - // since we'll reference it twice. - if (this.memoize) { - this.memoize(member); - } + // Give the state handler a chance to memoise the member, since we'll + // reference it twice. The second access (the set) should do the memo + // assignment. + this.memoise(member, 2); value = t.binaryExpression( operator.slice(0, -1), @@ -79,11 +110,12 @@ const handle = { // it wishes to be transformed. // Additionally, the caller must pass in a state object with at least // get, set, and call methods. -// Optionally, a memoize method may be defined on the state, which will be +// Optionally, a memoise method may be defined on the state, which will be // called when the member is a self-referential update. export default function memberExpressionToFunctions(path, visitor, state) { path.traverse(visitor, { - ...state, ...handle, + ...state, + memoiser: new AssignmentMemoiser(), }); } diff --git a/packages/babel-helper-replace-supers/src/index.js b/packages/babel-helper-replace-supers/src/index.js index 58bfb0591d..d8da1f0409 100644 --- a/packages/babel-helper-replace-supers/src/index.js +++ b/packages/babel-helper-replace-supers/src/index.js @@ -70,9 +70,8 @@ const visitor = traverse.visitors.merge([ }, ]); -const memoized = new WeakMap(); const specHandlers = { - memoize(superMember) { + memoise(superMember, count) { const { scope, node } = superMember; const { computed, property } = node; if (!computed) { @@ -84,44 +83,34 @@ const specHandlers = { return; } - memoized.set(property, memo); + this.memoiser.set(property, memo, count); + }, + + prop(superMember) { + const { computed, property } = superMember.node; + if (this.memoiser.has(property)) { + return t.cloneNode(this.memoiser.get(property)); + } + + if (computed) { + return t.cloneNode(property); + } + + return t.stringLiteral(property.name); }, get(superMember) { - const { computed, property } = superMember.node; - const thisExpr = t.thisExpression(); - - let prop; - if (computed && memoized.has(property)) { - prop = t.cloneNode(memoized.get(property)); - } else { - prop = computed ? property : t.stringLiteral(property.name); - } - return t.callExpression(this.file.addHelper("get"), [ getPrototypeOfExpression(this.getObjectRef(), this.isStatic, this.file), - prop, - thisExpr, + this.prop(superMember), + t.thisExpression(), ]); }, set(superMember, value) { - const { computed, property } = superMember.node; - - let prop; - if (computed && memoized.has(property)) { - prop = t.assignmentExpression( - "=", - t.cloneNode(memoized.get(property)), - property, - ); - } else { - prop = computed ? property : t.stringLiteral(property.name); - } - return t.callExpression(this.file.addHelper("set"), [ getPrototypeOfExpression(this.getObjectRef(), this.isStatic, this.file), - prop, + this.prop(superMember), value, t.thisExpression(), t.booleanLiteral(superMember.isInStrictMode()), @@ -134,12 +123,21 @@ const specHandlers = { }; const looseHandlers = { - memoize: specHandlers.memoize, - call: specHandlers.call, + ...specHandlers, + + prop(superMember) { + const { property } = superMember.node; + if (this.memoiser.has(property)) { + return t.cloneNode(this.memoiser.get(property)); + } + + return t.cloneNode(property); + }, get(superMember) { const { isStatic, superRef } = this; - const { property, computed } = superMember.node; + const { computed } = superMember.node; + const prop = this.prop(superMember); let object; if (isStatic) { @@ -155,29 +153,12 @@ const looseHandlers = { : t.memberExpression(t.identifier("Object"), t.identifier("prototype")); } - let prop; - if (computed && memoized.has(property)) { - prop = t.cloneNode(memoized.get(property)); - } else { - prop = property; - } - return t.memberExpression(object, prop, computed); }, set(superMember, value) { - const { property, computed } = superMember.node; - - let prop; - if (computed && memoized.has(property)) { - prop = t.assignmentExpression( - "=", - t.cloneNode(memoized.get(property)), - property, - ); - } else { - prop = property; - } + const { computed } = superMember.node; + const prop = this.prop(superMember); return t.assignmentExpression( "=", diff --git a/packages/babel-helpers/src/helpers.js b/packages/babel-helpers/src/helpers.js index 647d1e46b2..122cc01485 100644 --- a/packages/babel-helpers/src/helpers.js +++ b/packages/babel-helpers/src/helpers.js @@ -967,3 +967,38 @@ helpers.applyDecoratedDescriptor = () => template.program.ast` return desc; } `; + +helpers.classPrivateFieldLooseKey = () => template.program.ast` + var id = 0; + export default function _classPrivateFieldKey(name) { + return "__private_" + (id++) + "_" + name; + } +`; + +helpers.classPrivateFieldLooseBase = () => template.program.ast` + export default function _classPrivateFieldBase(receiver, privateKey) { + if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { + throw new TypeError("attempted to use private field on non-instance"); + } + return receiver; + } +`; + +helpers.classPrivateFieldGet = () => template.program.ast` + export default function _classPrivateFieldGet(receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); + } +`; + +helpers.classPrivateFieldSet = () => template.program.ast` + export default function _classPrivateFieldSet(receiver, privateMap, value) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to set private field on non-instance"); + } + privateMap.set(receiver, value); + return value; + } +`; diff --git a/packages/babel-plugin-proposal-class-properties/package.json b/packages/babel-plugin-proposal-class-properties/package.json index 7dc7fffff9..88b4e5cd82 100644 --- a/packages/babel-plugin-proposal-class-properties/package.json +++ b/packages/babel-plugin-proposal-class-properties/package.json @@ -10,6 +10,8 @@ ], "dependencies": { "@babel/helper-function-name": "7.0.0-beta.47", + "@babel/helper-member-expression-to-functions": "7.0.0-beta.47", + "@babel/helper-optimise-call-expression": "7.0.0-beta.47", "@babel/helper-plugin-utils": "7.0.0-beta.47", "@babel/helper-replace-supers": "7.0.0-beta.47", "@babel/plugin-syntax-class-properties": "7.0.0-beta.47" diff --git a/packages/babel-plugin-proposal-class-properties/src/index.js b/packages/babel-plugin-proposal-class-properties/src/index.js index f15769ee37..7ae92b0514 100644 --- a/packages/babel-plugin-proposal-class-properties/src/index.js +++ b/packages/babel-plugin-proposal-class-properties/src/index.js @@ -3,6 +3,8 @@ import nameFunction from "@babel/helper-function-name"; import syntaxClassProperties from "@babel/plugin-syntax-class-properties"; import { template, traverse, types as t } from "@babel/core"; import { environmentVisitor } from "@babel/helper-replace-supers"; +import memberExpressionToFunctions from "@babel/helper-member-expression-to-functions"; +import optimiseCall from "@babel/helper-optimise-call-expression"; export default declare((api, options) => { api.assertVersion(7); @@ -51,36 +53,206 @@ export default declare((api, options) => { environmentVisitor, ]); - const buildClassPropertySpec = ( - ref, - { key, value, computed }, - scope, - state, - ) => { + // Traverses the class scope, handling private name references. If an inner + // class redeclares the same private name, it will hand off traversal to the + // restricted visitor (which doesn't traverse the inner class's inner scope). + const privateNameVisitor = { + PrivateName(path) { + const { name } = this; + const { node, parentPath } = path; + + if (!parentPath.isMemberExpression({ property: node })) return; + if (node.id.name !== name) return; + this.handle(parentPath); + }, + + Class(path) { + const { name } = this; + const body = path.get("body.body"); + + for (const prop of body) { + if (!prop.isClassPrivateProperty()) continue; + if (prop.node.key.id.name !== name) continue; + + // This class redeclares the private name. + // So, we can only evaluate the things in the outer scope. + path.traverse(privateNameInnerVisitor, this); + path.skip(); + break; + } + }, + }; + + // Traverses the outer portion of a class, without touching the class's inner + // scope, for private names. + const privateNameInnerVisitor = traverse.visitors.merge([ + { + PrivateName: privateNameVisitor.PrivateName, + }, + environmentVisitor, + ]); + + const privateNameHandlerSpec = { + memoise(member, count) { + const { scope } = member; + const { object } = member.node; + + const memo = scope.maybeGenerateMemoised(object); + if (!memo) { + return; + } + + this.memoiser.set(object, memo, count); + }, + + receiver(member) { + const { object } = member.node; + + if (this.memoiser.has(object)) { + return t.cloneNode(this.memoiser.get(object)); + } + + return t.cloneNode(object); + }, + + get(member) { + const { map, file } = this; + + return t.callExpression(file.addHelper("classPrivateFieldGet"), [ + this.receiver(member), + t.cloneNode(map), + ]); + }, + + set(member, value) { + const { map, file } = this; + + return t.callExpression(file.addHelper("classPrivateFieldSet"), [ + this.receiver(member), + t.cloneNode(map), + value, + ]); + }, + + call(member, args) { + // The first access (the get) should do the memo assignment. + this.memoise(member, 1); + + return optimiseCall(this.get(member), this.receiver(member), args); + }, + }; + + const privateNameHandlerLoose = { + handle(member) { + const { prop, file } = this; + const { object } = member.node; + + member.replaceWith( + template.expression`BASE(REF, PROP)[PROP]`({ + BASE: file.addHelper("classPrivateFieldLooseBase"), + REF: object, + PROP: prop, + }), + ); + }, + }; + + function buildClassPropertySpec(ref, path, state) { + const { scope } = path; + const { key, value, computed } = path.node; return t.expressionStatement( t.callExpression(state.addHelper("defineProperty"), [ ref, - t.isIdentifier(key) && !computed ? t.stringLiteral(key.name) : key, + computed || t.isLiteral(key) ? key : t.stringLiteral(key.name), value || scope.buildUndefinedNode(), ]), ); - }; + } - const buildClassPropertyLoose = (ref, { key, value, computed }, scope) => { - return template.statement`MEMBER = VALUE`({ - MEMBER: t.memberExpression( - t.cloneNode(ref), - key, - computed || t.isLiteral(key), + function buildClassPropertyLoose(ref, path) { + const { scope } = path; + const { key, value, computed } = path.node; + return t.expressionStatement( + t.assignmentExpression( + "=", + t.memberExpression(ref, key, computed || t.isLiteral(key)), + value || scope.buildUndefinedNode(), ), - VALUE: value || scope.buildUndefinedNode(), + ); + } + + function buildClassPrivatePropertySpec(ref, path, initNodes, state) { + const { parentPath, scope } = path; + const { name } = path.node.key.id; + + const map = scope.generateUidIdentifier(name); + memberExpressionToFunctions(parentPath, privateNameVisitor, { + name, + map, + file: state, + ...privateNameHandlerSpec, }); - }; + + initNodes.push( + template.statement`var MAP = new WeakMap();`({ + MAP: map, + }), + ); + + // Must be late evaluated in case it references another private field. + return () => + template.statement`MAP.set(REF, VALUE);`({ + MAP: map, + REF: ref, + VALUE: path.node.value || scope.buildUndefinedNode(), + }); + } + + function buildClassPrivatePropertyLoose(ref, path, initNodes, state) { + const { parentPath, scope } = path; + const { name } = path.node.key.id; + + const prop = scope.generateUidIdentifier(name); + + parentPath.traverse(privateNameVisitor, { + name, + prop, + file: state, + ...privateNameHandlerLoose, + }); + + initNodes.push( + template.statement`var PROP = HELPER(NAME);`({ + PROP: prop, + HELPER: state.addHelper("classPrivateFieldLooseKey"), + NAME: t.stringLiteral(name), + }), + ); + + // Must be late evaluated in case it references another private field. + return () => + template.statement` + Object.defineProperty(REF, PROP, { + // configurable is false by default + // enumerable is false by default + writable: true, + value: VALUE + }); + `({ + REF: ref, + PROP: prop, + VALUE: path.node.value || scope.buildUndefinedNode(), + }); + } const buildClassProperty = loose ? buildClassPropertyLoose : buildClassPropertySpec; + const buildClassPrivateProperty = loose + ? buildClassPrivatePropertyLoose + : buildClassPrivatePropertySpec; + return { inherits: syntaxClassProperties, @@ -90,14 +262,35 @@ export default declare((api, options) => { let constructor; const props = []; const computedPaths = []; + const privateNames = new Set(); const body = path.get("body"); for (const path of body.get("body")) { - if (path.node.computed) { + const { computed, decorators } = path.node; + if (computed) { computedPaths.push(path); } + if (decorators && decorators.length > 0) { + throw path.buildCodeFrameError( + "Decorators transform is necessary.", + ); + } - if (path.isClassProperty()) { + if (path.isClassPrivateProperty()) { + const { static: isStatic, key: { id: { name } } } = path.node; + + if (isStatic) { + throw path.buildCodeFrameError( + "Static class fields are not spec'ed yet.", + ); + } + if (privateNames.has(name)) { + throw path.buildCodeFrameError("Duplicate private field"); + } + privateNames.add(name); + } + + if (path.isProperty()) { props.push(path); } else if (path.isClassMethod({ kind: "constructor" })) { constructor = path; @@ -141,22 +334,31 @@ export default declare((api, options) => { } } + // Transform private props before publics. + const privateMaps = []; + const privateMapInits = []; for (const prop of props) { - const propNode = prop.node; - if (propNode.decorators && propNode.decorators.length > 0) continue; + if (prop.isPrivate()) { + const inits = []; + privateMapInits.push(inits); - if (propNode.static) { - staticNodes.push( - buildClassProperty(ref, propNode, path.scope, state), + privateMaps.push( + buildClassPrivateProperty(t.thisExpression(), prop, inits, state), ); + } + } + + let p = 0; + for (const prop of props) { + if (prop.node.static) { + staticNodes.push(buildClassProperty(t.cloneNode(ref), prop, state)); + } else if (prop.isPrivate()) { + instanceBody.push(privateMaps[p]()); + staticNodes.push(...privateMapInits[p]); + p++; } else { instanceBody.push( - buildClassProperty( - t.thisExpression(), - propNode, - path.scope, - state, - ), + buildClassProperty(t.thisExpression(), prop, state), ); } } @@ -220,6 +422,10 @@ export default declare((api, options) => { path.insertBefore(computedNodes); path.insertAfter(staticNodes); }, + + PrivateName(path) { + throw path.buildCodeFrameError(`Unknown PrivateName "${path}"`); + }, }, }; }); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/assignment/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/assignment/input.js new file mode 100644 index 0000000000..ff39a73a41 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/assignment/input.js @@ -0,0 +1,10 @@ +class Foo { + #foo = 0; + + test(other) { + this.#foo += 1; + this.#foo = 2; + other.obj.#foo += 1; + other.obj.#foo = 2; + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/assignment/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/assignment/output.js new file mode 100644 index 0000000000..00a33dc992 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/assignment/output.js @@ -0,0 +1,26 @@ +var Foo = +/*#__PURE__*/ +function () { + "use strict"; + + function Foo() { + babelHelpers.classCallCheck(this, Foo); + Object.defineProperty(this, _foo, { + writable: true, + value: 0 + }); + } + + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test(other) { + babelHelpers.classPrivateFieldLooseBase(this, _foo)[_foo] += 1; + babelHelpers.classPrivateFieldLooseBase(this, _foo)[_foo] = 2; + babelHelpers.classPrivateFieldLooseBase(other.obj, _foo)[_foo] += 1; + babelHelpers.classPrivateFieldLooseBase(other.obj, _foo)[_foo] = 2; + } + }]); + return Foo; +}(); + +var _foo = babelHelpers.classPrivateFieldLooseKey("foo"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/call/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/call/exec.js new file mode 100644 index 0000000000..1afcafc40b --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/call/exec.js @@ -0,0 +1,15 @@ +class Foo { + #foo = function() { + return this; + } + + test(other) { + return [this.#foo(), other.#foo()]; + } +} + +const f = new Foo; +const o = new Foo; +const test = f.test(o); +expect(test[0]).toBe(f); +expect(test[1]).toBe(o); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/call/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/call/input.js new file mode 100644 index 0000000000..b629496c3a --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/call/input.js @@ -0,0 +1,10 @@ +class Foo { + #foo = function() { + return this; + } + + test(other) { + this.#foo(); + other.obj.#foo(); + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/call/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/call/output.js new file mode 100644 index 0000000000..29515449ce --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/call/output.js @@ -0,0 +1,27 @@ +var Foo = +/*#__PURE__*/ +function () { + "use strict"; + + function Foo() { + babelHelpers.classCallCheck(this, Foo); + Object.defineProperty(this, _foo, { + writable: true, + value: function () { + return this; + } + }); + } + + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test(other) { + babelHelpers.classPrivateFieldLooseBase(this, _foo)[_foo](); + + babelHelpers.classPrivateFieldLooseBase(other.obj, _foo)[_foo](); + } + }]); + return Foo; +}(); + +var _foo = babelHelpers.classPrivateFieldLooseKey("foo"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/exec.js new file mode 100644 index 0000000000..197513bb77 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/exec.js @@ -0,0 +1,73 @@ +class Point { + #x; + #y; + + constructor(x = 0, y = 0) { + this.#x = +x; + this.#y = +y; + } + + get x() { return this.#x } + set x(value) { this.#x = +value } + + get y() { return this.#y } + set y(value) { this.#y = +value } + + equals(p) { return this.#x === p.#x && this.#y === p.#y } + + toString() { return `Point<${ this.#x },${ this.#y }>` } + +} + +const p1 = new Point(1, 2); +const p2 = new Point(2, 3); +const p3 = new Point(1, 2); + +expect(p1.x).toBe(1); +expect(p1.y).toBe(2); +expect(p2.x).toBe(2); +expect(p2.y).toBe(3); +expect(p3.x).toBe(1); +expect(p3.y).toBe(2); + +expect(p1.equals(p1)).toBe(true) +expect(p1.equals(p2)).toBe(false) +expect(p1.equals(p3)).toBe(true) +expect(p2.equals(p1)).toBe(false) +expect(p2.equals(p2)).toBe(true) +expect(p2.equals(p3)).toBe(false) +expect(p3.equals(p1)).toBe(true) +expect(p3.equals(p2)).toBe(false) +expect(p3.equals(p3)).toBe(true) + +expect(p1.toString()).toBe("Point<1,2>") +expect(p2.toString()).toBe("Point<2,3>") +expect(p3.toString()).toBe("Point<1,2>") + +p1.x += 1; +p1.y = 3; +p2.x -= 1; +p2.y = 3; +p3.x = 0; +p3.y = 0; + +expect(p1.x).toBe(2); +expect(p1.y).toBe(3); +expect(p2.x).toBe(1); +expect(p2.y).toBe(3); +expect(p3.x).toBe(0); +expect(p3.y).toBe(0); + +expect(p1.equals(p1)).toBe(true) +expect(p1.equals(p2)).toBe(false) +expect(p1.equals(p3)).toBe(false) +expect(p2.equals(p1)).toBe(false) +expect(p2.equals(p2)).toBe(true) +expect(p2.equals(p3)).toBe(false) +expect(p3.equals(p1)).toBe(false) +expect(p3.equals(p2)).toBe(false) +expect(p3.equals(p3)).toBe(true) + +expect(p1.toString()).toBe("Point<2,3>") +expect(p2.toString()).toBe("Point<1,3>") +expect(p3.toString()).toBe("Point<0,0>") diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/input.js new file mode 100644 index 0000000000..1d9fbab199 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/input.js @@ -0,0 +1,20 @@ +class Point { + #x; + #y; + + constructor(x = 0, y = 0) { + this.#x = +x; + this.#y = +y; + } + + get x() { return this.#x } + set x(value) { this.#x = +value } + + get y() { return this.#y } + set y(value) { this.#y = +value } + + equals(p) { return this.#x === p.#x && this.#y === p.#y } + + toString() { return `Point<${ this.#x },${ this.#y }>` } + +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/options.json new file mode 100644 index 0000000000..7d8c3c204c --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/options.json @@ -0,0 +1,3 @@ +{ + "minNodeVersion": "6.0.0" +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/output.js new file mode 100644 index 0000000000..899fff2341 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/output.js @@ -0,0 +1,52 @@ +var Point = +/*#__PURE__*/ +function () { + "use strict"; + + function Point(_x2 = 0, _y2 = 0) { + babelHelpers.classCallCheck(this, Point); + Object.defineProperty(this, _x, { + writable: true, + value: void 0 + }); + Object.defineProperty(this, _y, { + writable: true, + value: void 0 + }); + babelHelpers.classPrivateFieldLooseBase(this, _x)[_x] = +_x2; + babelHelpers.classPrivateFieldLooseBase(this, _y)[_y] = +_y2; + } + + babelHelpers.createClass(Point, [{ + key: "equals", + value: function equals(p) { + return babelHelpers.classPrivateFieldLooseBase(this, _x)[_x] === babelHelpers.classPrivateFieldLooseBase(p, _x)[_x] && babelHelpers.classPrivateFieldLooseBase(this, _y)[_y] === babelHelpers.classPrivateFieldLooseBase(p, _y)[_y]; + } + }, { + key: "toString", + value: function toString() { + return `Point<${babelHelpers.classPrivateFieldLooseBase(this, _x)[_x]},${babelHelpers.classPrivateFieldLooseBase(this, _y)[_y]}>`; + } + }, { + key: "x", + get: function () { + return babelHelpers.classPrivateFieldLooseBase(this, _x)[_x]; + }, + set: function (value) { + babelHelpers.classPrivateFieldLooseBase(this, _x)[_x] = +value; + } + }, { + key: "y", + get: function () { + return babelHelpers.classPrivateFieldLooseBase(this, _y)[_y]; + }, + set: function (value) { + babelHelpers.classPrivateFieldLooseBase(this, _y)[_y] = +value; + } + }]); + return Point; +}(); + +var _x = babelHelpers.classPrivateFieldLooseKey("x"); + +var _y = babelHelpers.classPrivateFieldLooseKey("y"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/constructor-collision/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/constructor-collision/exec.js new file mode 100644 index 0000000000..0b0e9382bf --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/constructor-collision/exec.js @@ -0,0 +1,17 @@ +var foo = "bar"; + +class Foo { + #bar = foo; + + constructor() { + var foo = "foo"; + } + + test() { + return this.#bar; + } +} + +const f = new Foo; +expect(f.test()).toBe(foo); +expect("bar" in f).toBe(false); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/constructor-collision/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/constructor-collision/input.js new file mode 100644 index 0000000000..f7894f436d --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/constructor-collision/input.js @@ -0,0 +1,9 @@ +var foo = "bar"; + +class Foo { + #bar = foo; + + constructor() { + var foo = "foo"; + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/constructor-collision/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/constructor-collision/output.js new file mode 100644 index 0000000000..e7583b3836 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/constructor-collision/output.js @@ -0,0 +1,14 @@ +var foo = "bar"; + +var Foo = function Foo() { + "use strict"; + + babelHelpers.classCallCheck(this, Foo); + Object.defineProperty(this, _bar, { + writable: true, + value: foo + }); + var _foo = "foo"; +}; + +var _bar = babelHelpers.classPrivateFieldLooseKey("bar"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/declaration-order/LICENSE b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/declaration-order/LICENSE new file mode 100644 index 0000000000..18e9c1a0e2 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/declaration-order/LICENSE @@ -0,0 +1,28 @@ +The << Software identified by reference to the Ecma Standard* ("Software)">> is protected by copyright and is being +made available under the "BSD License", included below. This Software may be subject to third party rights (rights +from parties other than Ecma International), including patent rights, and no licenses under such third party rights +are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA +CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT http://www.ecma-international.org/memento/codeofconduct.htm FOR +INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS*. + +Copyright (C) 2012-2013 Ecma International +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +following conditions are met: +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other materials provided with the distribution. +3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. + +* Ecma International Standards hereafter means Ecma International Standards as well as Ecma Technical Reports diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/declaration-order/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/declaration-order/exec.js new file mode 100644 index 0000000000..a19c579e36 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/declaration-order/exec.js @@ -0,0 +1,8 @@ +class C { + y = this.#x; + #x; +} + +expect(() => { + new C(); +}).toThrow(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/declaration-order/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/declaration-order/input.js new file mode 100644 index 0000000000..a19c579e36 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/declaration-order/input.js @@ -0,0 +1,8 @@ +class C { + y = this.#x; + #x; +} + +expect(() => { + new C(); +}).toThrow(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/declaration-order/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/declaration-order/output.js new file mode 100644 index 0000000000..8d162c369b --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/declaration-order/output.js @@ -0,0 +1,16 @@ +var C = function C() { + "use strict"; + + babelHelpers.classCallCheck(this, C); + this.y = babelHelpers.classPrivateFieldLooseBase(this, _x)[_x]; + Object.defineProperty(this, _x, { + writable: true, + value: void 0 + }); +}; + +var _x = babelHelpers.classPrivateFieldLooseKey("x"); + +expect(() => { + new C(); +}).toThrow(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived-multiple-supers/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived-multiple-supers/input.js new file mode 100644 index 0000000000..44777df6c3 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived-multiple-supers/input.js @@ -0,0 +1,11 @@ +class Foo extends Bar { + #bar = "foo"; + + constructor() { + if (condition) { + super(); + } else { + super(); + } + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived-multiple-supers/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived-multiple-supers/output.js new file mode 100644 index 0000000000..d2b6a8fb88 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived-multiple-supers/output.js @@ -0,0 +1,32 @@ +var Foo = +/*#__PURE__*/ +function (_Bar) { + "use strict"; + + function Foo() { + var _this; + + babelHelpers.classCallCheck(this, Foo); + + if (condition) { + _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this)); + Object.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this))), _bar, { + writable: true, + value: "foo" + }); + } else { + _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this)); + Object.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this))), _bar, { + writable: true, + value: "foo" + }); + } + + return babelHelpers.possibleConstructorReturn(_this); + } + + babelHelpers.inherits(Foo, _Bar); + return Foo; +}(Bar); + +var _bar = babelHelpers.classPrivateFieldLooseKey("bar"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived/exec.js new file mode 100644 index 0000000000..e6bb119953 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived/exec.js @@ -0,0 +1,22 @@ +class Foo { + #prop = "foo"; + + foo() { + return this.#prop; + } +} + +class Bar extends Foo { + #prop = "bar"; + + bar() { + return this.#prop; + } +} + +const f = new Foo; +expect(f.foo()).toBe("foo"); + +const b = new Bar; +expect(b.foo()).toBe("foo"); +expect(b.bar()).toBe("bar"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived/input.js new file mode 100644 index 0000000000..a274845176 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived/input.js @@ -0,0 +1,7 @@ +class Foo { + #prop = "foo"; +} + +class Bar extends Foo { + #prop = "bar"; +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived/output.js new file mode 100644 index 0000000000..5eb8b76e9c --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived/output.js @@ -0,0 +1,32 @@ +var Foo = function Foo() { + "use strict"; + + babelHelpers.classCallCheck(this, Foo); + Object.defineProperty(this, _prop, { + writable: true, + value: "foo" + }); +}; + +var _prop = babelHelpers.classPrivateFieldLooseKey("prop"); + +var Bar = +/*#__PURE__*/ +function (_Foo) { + "use strict"; + + function Bar(...args) { + var _temp, _this; + + babelHelpers.classCallCheck(this, Bar); + return babelHelpers.possibleConstructorReturn(_this, (_temp = _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Bar).call(this, ...args)), Object.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), _prop2, { + writable: true, + value: "bar" + }), _temp)); + } + + babelHelpers.inherits(Bar, _Foo); + return Bar; +}(Foo); + +var _prop2 = babelHelpers.classPrivateFieldLooseKey("prop"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/extracted-this/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/extracted-this/input.js new file mode 100644 index 0000000000..7d1f81581a --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/extracted-this/input.js @@ -0,0 +1,9 @@ +var foo = "bar"; + +class Foo { + #bar = this; + #baz = foo; + + constructor(foo) { + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/extracted-this/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/extracted-this/output.js new file mode 100644 index 0000000000..1dcdbcb1fb --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/extracted-this/output.js @@ -0,0 +1,19 @@ +var foo = "bar"; + +var Foo = function Foo(_foo) { + "use strict"; + + babelHelpers.classCallCheck(this, Foo); + Object.defineProperty(this, _bar, { + writable: true, + value: this + }); + Object.defineProperty(this, _baz, { + writable: true, + value: foo + }); +}; + +var _bar = babelHelpers.classPrivateFieldLooseKey("bar"); + +var _baz = babelHelpers.classPrivateFieldLooseKey("baz"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/foobar/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/foobar/input.js new file mode 100644 index 0000000000..552a575dab --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/foobar/input.js @@ -0,0 +1,9 @@ +class Child extends Parent { + constructor() { + super(); + } + + #scopedFunctionWithThis = () => { + this.name = {}; + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/foobar/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/foobar/options.json new file mode 100644 index 0000000000..8110be628e --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/foobar/options.json @@ -0,0 +1,3 @@ +{ + "presets": [["stage-0", { "decoratorsLegacy": true }], "es2015"] +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/foobar/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/foobar/output.js new file mode 100644 index 0000000000..8dc9f1f2a3 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/foobar/output.js @@ -0,0 +1,24 @@ +var Child = +/*#__PURE__*/ +function (_Parent) { + "use strict"; + + function Child() { + var _this; + + babelHelpers.classCallCheck(this, Child); + _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Child).call(this)); + Object.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), _scopedFunctionWithThis, { + writable: true, + value: function value() { + _this.name = {}; + } + }); + return _this; + } + + babelHelpers.inherits(Child, _Parent); + return Child; +}(Parent); + +var _scopedFunctionWithThis = babelHelpers.classPrivateFieldLooseKey("scopedFunctionWithThis"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance-undefined/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance-undefined/exec.js new file mode 100644 index 0000000000..ccc0973482 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance-undefined/exec.js @@ -0,0 +1,9 @@ +class Foo { + #bar; + + test() { + return this.#bar; + } +} + +expect(new Foo().test()).toBe(undefined); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance-undefined/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance-undefined/input.js new file mode 100644 index 0000000000..dcb865ec4a --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance-undefined/input.js @@ -0,0 +1,3 @@ +class Foo { + #bar; +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance-undefined/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance-undefined/output.js new file mode 100644 index 0000000000..2a6d4bf233 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance-undefined/output.js @@ -0,0 +1,11 @@ +var Foo = function Foo() { + "use strict"; + + babelHelpers.classCallCheck(this, Foo); + Object.defineProperty(this, _bar, { + writable: true, + value: void 0 + }); +}; + +var _bar = babelHelpers.classPrivateFieldLooseKey("bar"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance/exec.js new file mode 100644 index 0000000000..606196bb0d --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance/exec.js @@ -0,0 +1,16 @@ +class Foo { + #bar = "foo"; + + test() { + return this.#bar; + } + + static test(foo) { + return foo.#bar; + } +} + +const f = new Foo(); +expect(f.test()).toBe("foo"); +expect(Foo.test(f)).toBe("foo"); +expect("bar" in f).toBe(false); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance/input.js new file mode 100644 index 0000000000..9c3d29eb81 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance/input.js @@ -0,0 +1,3 @@ +class Foo { + #bar = "foo"; +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance/output.js new file mode 100644 index 0000000000..c3c531e93f --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance/output.js @@ -0,0 +1,11 @@ +var Foo = function Foo() { + "use strict"; + + babelHelpers.classCallCheck(this, Foo); + Object.defineProperty(this, _bar, { + writable: true, + value: "foo" + }); +}; + +var _bar = babelHelpers.classPrivateFieldLooseKey("bar"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/multiple/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/multiple/exec.js new file mode 100644 index 0000000000..3c45eec1e4 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/multiple/exec.js @@ -0,0 +1,11 @@ +class Foo { + #x = 0; + #y = this.#x + 1; + + test() { + return this.#y; + } +} + +const f = new Foo(); +expect(f.test()).toBe(1); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/multiple/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/multiple/input.js new file mode 100644 index 0000000000..1e01f81502 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/multiple/input.js @@ -0,0 +1,4 @@ +class Foo { + #x = 0; + #y = this.#x; +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/multiple/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/multiple/output.js new file mode 100644 index 0000000000..e630441e09 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/multiple/output.js @@ -0,0 +1,17 @@ +var Foo = function Foo() { + "use strict"; + + babelHelpers.classCallCheck(this, Foo); + Object.defineProperty(this, _x, { + writable: true, + value: 0 + }); + Object.defineProperty(this, _y, { + writable: true, + value: babelHelpers.classPrivateFieldLooseBase(this, _x)[_x] + }); +}; + +var _x = babelHelpers.classPrivateFieldLooseKey("x"); + +var _y = babelHelpers.classPrivateFieldLooseKey("y"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/input.js new file mode 100644 index 0000000000..e0c4dfe70b --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/input.js @@ -0,0 +1,18 @@ +class Foo { + static #foo = "foo"; + #bar = "bar"; + + static test() { + return Foo.#foo; + } + + test() { + return this.#bar; + } +} + +const f = new Foo(); +expect("foo" in Foo).toBe(false) +expect("bar" in f).toBe(false) +expect(Foo.test()).toBe("foo") +expect(f.test()).toBe("bar") diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/options.json new file mode 100644 index 0000000000..03872554af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Static class fields are not spec'ed yet." +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/output.js new file mode 100644 index 0000000000..b5e753c186 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/native-classes/output.js @@ -0,0 +1,18 @@ +var _foo, _bar; + +class Foo { + constructor() { + Object.defineProperty(this, _bar, { + writable: true, + value: "bar" + }); + } + +} + +_foo = babelHelpers.classPrivateFieldKey("foo"); +Object.defineProperty(Foo, _foo, { + writable: true, + value: "foo" +}); +_bar = babelHelpers.classPrivateFieldKey("bar"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/input.mjs b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/input.mjs new file mode 100644 index 0000000000..cd1cfaa283 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/input.mjs @@ -0,0 +1,11 @@ +export default param => + class App { + static #props = { + prop1: 'prop1', + prop2: 'prop2' + } + + getParam() { + return param; + } + } diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/options.json new file mode 100644 index 0000000000..03872554af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Static class fields are not spec'ed yet." +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/output.mjs b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/output.mjs new file mode 100644 index 0000000000..784e0909f5 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/non-block-arrow-func/output.mjs @@ -0,0 +1,25 @@ +export default (param => { + var _props, _class, _temp; + + return _temp = _class = + /*#__PURE__*/ + function () { + function App() { + babelHelpers.classCallCheck(this, App); + } + + babelHelpers.createClass(App, [{ + key: "getParam", + value: function getParam() { + return param; + } + }]); + return App; + }(), _props = babelHelpers.classPrivateFieldKey("props"), Object.defineProperty(_class, _props, { + writable: true, + value: { + prop1: 'prop1', + prop2: 'prop2' + } + }), _temp; +}); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/options.json new file mode 100644 index 0000000000..38f1a44c55 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["external-helpers",["proposal-class-properties", { "loose": true }], "transform-classes", "transform-block-scoping", "syntax-class-properties"] +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/private-in-derived/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/private-in-derived/input.js new file mode 100644 index 0000000000..03754e8a4a --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/private-in-derived/input.js @@ -0,0 +1,8 @@ +class Outer { + #outer; + + constructor() { + class Test extends this.#outer { + } + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/private-in-derived/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/private-in-derived/output.js new file mode 100644 index 0000000000..39a984b0e8 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/private-in-derived/output.js @@ -0,0 +1,23 @@ +var Outer = function Outer() { + "use strict"; + + babelHelpers.classCallCheck(this, Outer); + Object.defineProperty(this, _outer, { + writable: true, + value: void 0 + }); + + var Test = + /*#__PURE__*/ + function (_babelHelpers$classPr) { + function Test() { + babelHelpers.classCallCheck(this, Test); + return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Test).apply(this, arguments)); + } + + babelHelpers.inherits(Test, _babelHelpers$classPr); + return Test; + }(babelHelpers.classPrivateFieldLooseBase(this, _outer)[_outer]); +}; + +var _outer = babelHelpers.classPrivateFieldLooseKey("outer"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/input.js new file mode 100644 index 0000000000..e542f2f49b --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/input.js @@ -0,0 +1,43 @@ +function classFactory() { + return class Foo { + #foo = "foo"; + static #bar = "bar"; + + instance() { + return this.#foo; + } + + static() { + return Foo.#bar; + } + + static instance(inst) { + return inst.#foo; + } + + static static() { + return Foo.#bar; + } + } +} + +const Foo1 = classFactory(); +const Foo2 = classFactory(); + +const f1 = new Foo1; +const f2 = new Foo2; + +expect(f1.instance()).toBe("foo"); +expect(f1.static()).toBe("bar"); +expect(f2.instance()).toBe("foo"); +expect(f2.static()).toBe("bar"); + +expect(Foo1.instance(f1)).toBe("foo"); +expect(Foo1.static()).toBe("bar"); +expect(Foo2.instance(f2)).toBe("foo"); +expect(Foo2.static()).toBe("bar"); + +assert.throws(() => f1.instance.call(f2)); +assert.throws(() => f2.instance.call(f1)); +assert.throws(() => Foo1.instance(f2)); +assert.throws(() => Foo2.instance(f1)); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/options.json new file mode 100644 index 0000000000..03872554af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Static class fields are not spec'ed yet." +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/output.js new file mode 100644 index 0000000000..87651fcca8 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/output.js @@ -0,0 +1,18 @@ +function classFactory() { + var _bar, _foo; + + var Foo = function Foo() { + babelHelpers.classCallCheck(this, Foo); + Object.defineProperty(this, _foo, { + writable: true, + value: "foo" + }); + }; + + _bar = babelHelpers.classPrivateFieldKey("bar"); + Object.defineProperty(Foo, _bar, { + writable: true, + value: "bar" + }); + _foo = babelHelpers.classPrivateFieldKey("foo"); +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reference-in-other-property/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reference-in-other-property/input.js new file mode 100644 index 0000000000..63c7e41999 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reference-in-other-property/input.js @@ -0,0 +1,7 @@ +class Foo { + one = this.#private; + #two = this.#private; + #private = 0; + three = this.#private; + #four = this.#private; +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reference-in-other-property/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reference-in-other-property/output.js new file mode 100644 index 0000000000..0199c1f064 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reference-in-other-property/output.js @@ -0,0 +1,25 @@ +var Foo = function Foo() { + "use strict"; + + babelHelpers.classCallCheck(this, Foo); + this.one = babelHelpers.classPrivateFieldLooseBase(this, _private)[_private]; + Object.defineProperty(this, _two, { + writable: true, + value: babelHelpers.classPrivateFieldLooseBase(this, _private)[_private] + }); + Object.defineProperty(this, _private, { + writable: true, + value: 0 + }); + this.three = babelHelpers.classPrivateFieldLooseBase(this, _private)[_private]; + Object.defineProperty(this, _four, { + writable: true, + value: babelHelpers.classPrivateFieldLooseBase(this, _private)[_private] + }); +}; + +var _two = babelHelpers.classPrivateFieldLooseKey("two"); + +var _private = babelHelpers.classPrivateFieldLooseKey("private"); + +var _four = babelHelpers.classPrivateFieldLooseKey("four"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/input.mjs b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/input.mjs new file mode 100644 index 0000000000..8da62e5b2b --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/input.mjs @@ -0,0 +1,7 @@ +export class MyClass { + static #property = value; +} + +export default class MyClass2 { + static #property = value; +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/options.json new file mode 100644 index 0000000000..03872554af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Static class fields are not spec'ed yet." +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/output.mjs b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/output.mjs new file mode 100644 index 0000000000..133132192b --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-export/output.mjs @@ -0,0 +1,21 @@ +var _property, _property2; + +export var MyClass = function MyClass() { + babelHelpers.classCallCheck(this, MyClass); +}; +_property = babelHelpers.classPrivateFieldKey("property"); +Object.defineProperty(MyClass, _property, { + writable: true, + value: value +}); + +var MyClass2 = function MyClass2() { + babelHelpers.classCallCheck(this, MyClass2); +}; + +_property2 = babelHelpers.classPrivateFieldKey("property"); +Object.defineProperty(MyClass2, _property2, { + writable: true, + value: value +}); +export { MyClass2 as default }; diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/input.js new file mode 100644 index 0000000000..4fa2273cf6 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/input.js @@ -0,0 +1,3 @@ +var Foo = class { + static #num = 0; +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/options.json new file mode 100644 index 0000000000..03872554af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Static class fields are not spec'ed yet." +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/output.js new file mode 100644 index 0000000000..4b8ed2958b --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-infer-name/output.js @@ -0,0 +1,8 @@ +var _num, _class, _temp; + +var Foo = (_temp = _class = function Foo() { + babelHelpers.classCallCheck(this, Foo); +}, _num = babelHelpers.classPrivateFieldKey("num"), Object.defineProperty(_class, _num, { + writable: true, + value: 0 +}), _temp); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/input.js new file mode 100644 index 0000000000..66202d9f9d --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/input.js @@ -0,0 +1,70 @@ +class Base { + static #foo = 1; + + static getThis() { + return this.#foo; + } + + static updateThis(val) { + return this.#foo = val; + } + + static getClass() { + return Base.#foo; + } + + static updateClass(val) { + return Base.#foo = val; + } +} + +class Sub1 extends Base { + static #foo = 2; + + static update(val) { + return this.#foo = val; + } +} + +class Sub2 extends Base { +} + +expect(Base.getThis()).toBe(1); +expect(Base.getClass()).toBe(1); +assert.throws(() => Sub1.getThis()); +expect(Sub1.getClass()).toBe(1); +assert.throws(() => Sub2.getThis()); +expect(Sub2.getClass()).toBe(1); + +expect(Sub1.update(3)).toBe(3); +expect(Base.getThis()).toBe(1); +expect(Base.getClass()).toBe(1); +assert.throws(() => Sub1.getThis()); +expect(Sub1.getClass()).toBe(1); +assert.throws(() => Sub2.getThis()); +expect(Sub2.getClass()).toBe(1); + +expect(Base.updateThis(4)).toBe(4); +expect(Base.getThis()).toBe(4); +expect(Base.getClass()).toBe(4); +assert.throws(() => Sub1.getThis()); +expect(Sub1.getClass()).toBe(4); +assert.throws(() => Sub2.getThis()); +expect(Sub2.getClass()).toBe(4); + +expect(Base.updateClass(5)).toBe(5); +expect(Base.getThis()).toBe(5); +expect(Base.getClass()).toBe(5); +assert.throws(() => Sub1.getThis()); +expect(Sub1.getClass()).toBe(5); +assert.throws(() => Sub2.getThis()); +expect(Sub2.getClass()).toBe(5); + +assert.throws(() => Sub2.updateThis(6)); +expect(Sub2.updateClass(7)).toBe(7); +expect(Base.getThis()).toBe(7); +expect(Base.getClass()).toBe(7); +assert.throws(() => Sub1.getThis()); +expect(Sub1.getClass()).toBe(7); +assert.throws(() => Sub2.getThis()); +expect(Sub2.getClass()).toBe(7); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/options.json new file mode 100644 index 0000000000..03872554af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Static class fields are not spec'ed yet." +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/output.js new file mode 100644 index 0000000000..5510c2aa9e --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-inherited/output.js @@ -0,0 +1,55 @@ +var _foo, _foo2; + +var Base = +/*#__PURE__*/ +function () { + function Base() { + babelHelpers.classCallCheck(this, Base); + } + + babelHelpers.createClass(Base, null, [{ + key: "m", + value: function m() { + return babelHelpers.classPrivateFieldBase(this, _foo)[_foo]; + } + }]); + return Base; +}(); + +_foo = babelHelpers.classPrivateFieldKey("foo"); +Object.defineProperty(Base, _foo, { + writable: true, + value: 1 +}); + +var Sub1 = +/*#__PURE__*/ +function (_Base) { + babelHelpers.inherits(Sub1, _Base); + + function Sub1() { + babelHelpers.classCallCheck(this, Sub1); + return babelHelpers.possibleConstructorReturn(this, (Sub1.__proto__ || Object.getPrototypeOf(Sub1)).apply(this, arguments)); + } + + return Sub1; +}(Base); + +_foo2 = babelHelpers.classPrivateFieldKey("foo"); +Object.defineProperty(Sub1, _foo2, { + writable: true, + value: 2 +}); + +var Sub2 = +/*#__PURE__*/ +function (_Base2) { + babelHelpers.inherits(Sub2, _Base2); + + function Sub2() { + babelHelpers.classCallCheck(this, Sub2); + return babelHelpers.possibleConstructorReturn(this, (Sub2.__proto__ || Object.getPrototypeOf(Sub2)).apply(this, arguments)); + } + + return Sub2; +}(Base); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/input.js new file mode 100644 index 0000000000..d639688898 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/input.js @@ -0,0 +1,15 @@ +class Foo { + static #bar; + + static test() { + return Foo.#bar; + } + + test() { + return Foo.#bar; + } +} + +expect("bar" in Foo).toBe(false) +expect(Foo.test()).toBe(undefined) +expect(Foo.test()).toBe(undefined) diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/options.json new file mode 100644 index 0000000000..03872554af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Static class fields are not spec'ed yet." +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/output.js new file mode 100644 index 0000000000..4db5076cd4 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static-undefined/output.js @@ -0,0 +1,11 @@ +var _bar; + +var Foo = function Foo() { + babelHelpers.classCallCheck(this, Foo); +}; + +_bar = babelHelpers.classPrivateFieldKey("bar"); +Object.defineProperty(Foo, _bar, { + writable: true, + value: void 0 +}); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/input.js new file mode 100644 index 0000000000..c905fa85d5 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/input.js @@ -0,0 +1,15 @@ +class Foo { + static #bar = "foo"; + + static test() { + return Foo.#bar; + } + + test() { + return Foo.#bar; + } +} + +expect("bar" in Foo).toBe(false) +expect(Foo.test()).toBe("foo") +expect(Foo.test()).toBe("foo") diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/options.json new file mode 100644 index 0000000000..03872554af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Static class fields are not spec'ed yet." +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/output.js new file mode 100644 index 0000000000..5ef62d69ad --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/output.js @@ -0,0 +1,28 @@ +var _bar; + +var Foo = +/*#__PURE__*/ +function () { + function Foo() { + babelHelpers.classCallCheck(this, Foo); + } + + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test() { + return babelHelpers.classPrivateFieldBase(Foo, _bar)[_bar]; + } + }], [{ + key: "test", + value: function test() { + return babelHelpers.classPrivateFieldBase(Foo, _bar)[_bar]; + } + }]); + return Foo; +}(); + +_bar = babelHelpers.classPrivateFieldKey("bar"); +Object.defineProperty(Foo, _bar, { + writable: true, + value: "foo" +}); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/super-expression/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/super-expression/input.js new file mode 100644 index 0000000000..617776acc9 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/super-expression/input.js @@ -0,0 +1,7 @@ +class Foo extends Bar { + #bar = "foo"; + + constructor() { + foo(super()); + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/super-expression/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/super-expression/output.js new file mode 100644 index 0000000000..d00fe5e1a0 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/super-expression/output.js @@ -0,0 +1,21 @@ +var Foo = +/*#__PURE__*/ +function (_Bar) { + "use strict"; + + function Foo() { + var _temp, _this; + + babelHelpers.classCallCheck(this, Foo); + foo((_temp = _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this)), Object.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), _bar, { + writable: true, + value: "foo" + }), _temp)); + return _this; + } + + babelHelpers.inherits(Foo, _Bar); + return Foo; +}(Bar); + +var _bar = babelHelpers.classPrivateFieldLooseKey("bar"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/super-statement/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/super-statement/input.js new file mode 100644 index 0000000000..4bef6ef21b --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/super-statement/input.js @@ -0,0 +1,7 @@ +class Foo extends Bar { + #bar = "foo"; + + constructor() { + super(); + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/super-statement/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/super-statement/output.js new file mode 100644 index 0000000000..b4aaadf736 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/super-statement/output.js @@ -0,0 +1,22 @@ +var Foo = +/*#__PURE__*/ +function (_Bar) { + "use strict"; + + function Foo() { + var _this; + + babelHelpers.classCallCheck(this, Foo); + _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this)); + Object.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), _bar, { + writable: true, + value: "foo" + }); + return _this; + } + + babelHelpers.inherits(Foo, _Bar); + return Foo; +}(Bar); + +var _bar = babelHelpers.classPrivateFieldLooseKey("bar"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/update/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/update/exec.js new file mode 100644 index 0000000000..ff92564c81 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/update/exec.js @@ -0,0 +1,27 @@ +class Foo { + #foo = 0; + + test(other) { + return [ + this.#foo++, + this.#foo, + ++this.#foo, + this.#foo, + other.obj.#foo++, + other.obj.#foo, + ++other.obj.#foo, + other.obj.#foo, + ]; + } +} + +const f = new Foo; +const results = f.test({ obj: f }); +expect(results[0]).toBe(0); +expect(results[1]).toBe(1); +expect(results[2]).toBe(2); +expect(results[3]).toBe(2); +expect(results[4]).toBe(2); +expect(results[5]).toBe(3); +expect(results[6]).toBe(4); +expect(results[7]).toBe(4); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/update/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/update/input.js new file mode 100644 index 0000000000..0ff8b74927 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/update/input.js @@ -0,0 +1,10 @@ +class Foo { + #foo = 0; + + test(other) { + this.#foo++; + ++this.#foo; + other.obj.#foo++; + ++other.obj.#foo; + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/update/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/update/output.js new file mode 100644 index 0000000000..dde814f54d --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/update/output.js @@ -0,0 +1,26 @@ +var Foo = +/*#__PURE__*/ +function () { + "use strict"; + + function Foo() { + babelHelpers.classCallCheck(this, Foo); + Object.defineProperty(this, _foo, { + writable: true, + value: 0 + }); + } + + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test(other) { + babelHelpers.classPrivateFieldLooseBase(this, _foo)[_foo]++; + ++babelHelpers.classPrivateFieldLooseBase(this, _foo)[_foo]; + babelHelpers.classPrivateFieldLooseBase(other.obj, _foo)[_foo]++; + ++babelHelpers.classPrivateFieldLooseBase(other.obj, _foo)[_foo]; + } + }]); + return Foo; +}(); + +var _foo = babelHelpers.classPrivateFieldLooseKey("foo"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/assignment/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/assignment/input.js new file mode 100644 index 0000000000..ff39a73a41 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/assignment/input.js @@ -0,0 +1,10 @@ +class Foo { + #foo = 0; + + test(other) { + this.#foo += 1; + this.#foo = 2; + other.obj.#foo += 1; + other.obj.#foo = 2; + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/assignment/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/assignment/output.js new file mode 100644 index 0000000000..bf56ee4e34 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/assignment/output.js @@ -0,0 +1,26 @@ +var Foo = +/*#__PURE__*/ +function () { + "use strict"; + + function Foo() { + babelHelpers.classCallCheck(this, Foo); + + _foo.set(this, 0); + } + + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test(other) { + var _other$obj; + + babelHelpers.classPrivateFieldSet(this, _foo, babelHelpers.classPrivateFieldGet(this, _foo) + 1); + babelHelpers.classPrivateFieldSet(this, _foo, 2); + babelHelpers.classPrivateFieldSet(_other$obj = other.obj, _foo, babelHelpers.classPrivateFieldGet(_other$obj, _foo) + 1); + babelHelpers.classPrivateFieldSet(other.obj, _foo, 2); + } + }]); + return Foo; +}(); + +var _foo = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/call/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/call/exec.js new file mode 100644 index 0000000000..1afcafc40b --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/call/exec.js @@ -0,0 +1,15 @@ +class Foo { + #foo = function() { + return this; + } + + test(other) { + return [this.#foo(), other.#foo()]; + } +} + +const f = new Foo; +const o = new Foo; +const test = f.test(o); +expect(test[0]).toBe(f); +expect(test[1]).toBe(o); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/call/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/call/input.js new file mode 100644 index 0000000000..b629496c3a --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/call/input.js @@ -0,0 +1,10 @@ +class Foo { + #foo = function() { + return this; + } + + test(other) { + this.#foo(); + other.obj.#foo(); + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/call/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/call/output.js new file mode 100644 index 0000000000..cc609c1f73 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/call/output.js @@ -0,0 +1,26 @@ +var Foo = +/*#__PURE__*/ +function () { + "use strict"; + + function Foo() { + babelHelpers.classCallCheck(this, Foo); + + _foo.set(this, function () { + return this; + }); + } + + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test(other) { + var _other$obj; + + babelHelpers.classPrivateFieldGet(this, _foo).call(this); + babelHelpers.classPrivateFieldGet(_other$obj = other.obj, _foo).call(_other$obj); + } + }]); + return Foo; +}(); + +var _foo = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/exec.js new file mode 100644 index 0000000000..197513bb77 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/exec.js @@ -0,0 +1,73 @@ +class Point { + #x; + #y; + + constructor(x = 0, y = 0) { + this.#x = +x; + this.#y = +y; + } + + get x() { return this.#x } + set x(value) { this.#x = +value } + + get y() { return this.#y } + set y(value) { this.#y = +value } + + equals(p) { return this.#x === p.#x && this.#y === p.#y } + + toString() { return `Point<${ this.#x },${ this.#y }>` } + +} + +const p1 = new Point(1, 2); +const p2 = new Point(2, 3); +const p3 = new Point(1, 2); + +expect(p1.x).toBe(1); +expect(p1.y).toBe(2); +expect(p2.x).toBe(2); +expect(p2.y).toBe(3); +expect(p3.x).toBe(1); +expect(p3.y).toBe(2); + +expect(p1.equals(p1)).toBe(true) +expect(p1.equals(p2)).toBe(false) +expect(p1.equals(p3)).toBe(true) +expect(p2.equals(p1)).toBe(false) +expect(p2.equals(p2)).toBe(true) +expect(p2.equals(p3)).toBe(false) +expect(p3.equals(p1)).toBe(true) +expect(p3.equals(p2)).toBe(false) +expect(p3.equals(p3)).toBe(true) + +expect(p1.toString()).toBe("Point<1,2>") +expect(p2.toString()).toBe("Point<2,3>") +expect(p3.toString()).toBe("Point<1,2>") + +p1.x += 1; +p1.y = 3; +p2.x -= 1; +p2.y = 3; +p3.x = 0; +p3.y = 0; + +expect(p1.x).toBe(2); +expect(p1.y).toBe(3); +expect(p2.x).toBe(1); +expect(p2.y).toBe(3); +expect(p3.x).toBe(0); +expect(p3.y).toBe(0); + +expect(p1.equals(p1)).toBe(true) +expect(p1.equals(p2)).toBe(false) +expect(p1.equals(p3)).toBe(false) +expect(p2.equals(p1)).toBe(false) +expect(p2.equals(p2)).toBe(true) +expect(p2.equals(p3)).toBe(false) +expect(p3.equals(p1)).toBe(false) +expect(p3.equals(p2)).toBe(false) +expect(p3.equals(p3)).toBe(true) + +expect(p1.toString()).toBe("Point<2,3>") +expect(p2.toString()).toBe("Point<1,3>") +expect(p3.toString()).toBe("Point<0,0>") diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/input.js new file mode 100644 index 0000000000..1d9fbab199 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/input.js @@ -0,0 +1,20 @@ +class Point { + #x; + #y; + + constructor(x = 0, y = 0) { + this.#x = +x; + this.#y = +y; + } + + get x() { return this.#x } + set x(value) { this.#x = +value } + + get y() { return this.#y } + set y(value) { this.#y = +value } + + equals(p) { return this.#x === p.#x && this.#y === p.#y } + + toString() { return `Point<${ this.#x },${ this.#y }>` } + +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/options.json new file mode 100644 index 0000000000..7d8c3c204c --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/options.json @@ -0,0 +1,3 @@ +{ + "minNodeVersion": "6.0.0" +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/output.js new file mode 100644 index 0000000000..1075fa4c44 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/output.js @@ -0,0 +1,49 @@ +var Point = +/*#__PURE__*/ +function () { + "use strict"; + + function Point(_x2 = 0, _y2 = 0) { + babelHelpers.classCallCheck(this, Point); + + _x.set(this, void 0); + + _y.set(this, void 0); + + babelHelpers.classPrivateFieldSet(this, _x, +_x2); + babelHelpers.classPrivateFieldSet(this, _y, +_y2); + } + + babelHelpers.createClass(Point, [{ + key: "equals", + value: function equals(p) { + return babelHelpers.classPrivateFieldGet(this, _x) === babelHelpers.classPrivateFieldGet(p, _x) && babelHelpers.classPrivateFieldGet(this, _y) === babelHelpers.classPrivateFieldGet(p, _y); + } + }, { + key: "toString", + value: function toString() { + return `Point<${babelHelpers.classPrivateFieldGet(this, _x)},${babelHelpers.classPrivateFieldGet(this, _y)}>`; + } + }, { + key: "x", + get: function () { + return babelHelpers.classPrivateFieldGet(this, _x); + }, + set: function (value) { + babelHelpers.classPrivateFieldSet(this, _x, +value); + } + }, { + key: "y", + get: function () { + return babelHelpers.classPrivateFieldGet(this, _y); + }, + set: function (value) { + babelHelpers.classPrivateFieldSet(this, _y, +value); + } + }]); + return Point; +}(); + +var _x = new WeakMap(); + +var _y = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/constructor-collision/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/constructor-collision/exec.js new file mode 100644 index 0000000000..0b0e9382bf --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/constructor-collision/exec.js @@ -0,0 +1,17 @@ +var foo = "bar"; + +class Foo { + #bar = foo; + + constructor() { + var foo = "foo"; + } + + test() { + return this.#bar; + } +} + +const f = new Foo; +expect(f.test()).toBe(foo); +expect("bar" in f).toBe(false); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/constructor-collision/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/constructor-collision/input.js new file mode 100644 index 0000000000..f7894f436d --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/constructor-collision/input.js @@ -0,0 +1,9 @@ +var foo = "bar"; + +class Foo { + #bar = foo; + + constructor() { + var foo = "foo"; + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/constructor-collision/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/constructor-collision/output.js new file mode 100644 index 0000000000..2bdbd6dd6b --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/constructor-collision/output.js @@ -0,0 +1,13 @@ +var foo = "bar"; + +var Foo = function Foo() { + "use strict"; + + babelHelpers.classCallCheck(this, Foo); + + _bar.set(this, foo); + + var _foo = "foo"; +}; + +var _bar = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/declaration-order/LICENSE b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/declaration-order/LICENSE new file mode 100644 index 0000000000..18e9c1a0e2 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/declaration-order/LICENSE @@ -0,0 +1,28 @@ +The << Software identified by reference to the Ecma Standard* ("Software)">> is protected by copyright and is being +made available under the "BSD License", included below. This Software may be subject to third party rights (rights +from parties other than Ecma International), including patent rights, and no licenses under such third party rights +are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA +CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT http://www.ecma-international.org/memento/codeofconduct.htm FOR +INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS*. + +Copyright (C) 2012-2013 Ecma International +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +following conditions are met: +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other materials provided with the distribution. +3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. + +* Ecma International Standards hereafter means Ecma International Standards as well as Ecma Technical Reports diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/declaration-order/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/declaration-order/exec.js new file mode 100644 index 0000000000..a19c579e36 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/declaration-order/exec.js @@ -0,0 +1,8 @@ +class C { + y = this.#x; + #x; +} + +expect(() => { + new C(); +}).toThrow(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/declaration-order/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/declaration-order/input.js new file mode 100644 index 0000000000..a19c579e36 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/declaration-order/input.js @@ -0,0 +1,8 @@ +class C { + y = this.#x; + #x; +} + +expect(() => { + new C(); +}).toThrow(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/declaration-order/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/declaration-order/output.js new file mode 100644 index 0000000000..641d0e5370 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/declaration-order/output.js @@ -0,0 +1,14 @@ +var C = function C() { + "use strict"; + + babelHelpers.classCallCheck(this, C); + babelHelpers.defineProperty(this, "y", babelHelpers.classPrivateFieldGet(this, _x)); + + _x.set(this, void 0); +}; + +var _x = new WeakMap(); + +expect(() => { + new C(); +}).toThrow(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived-multiple-supers/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived-multiple-supers/input.js new file mode 100644 index 0000000000..44777df6c3 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived-multiple-supers/input.js @@ -0,0 +1,11 @@ +class Foo extends Bar { + #bar = "foo"; + + constructor() { + if (condition) { + super(); + } else { + super(); + } + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived-multiple-supers/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived-multiple-supers/output.js new file mode 100644 index 0000000000..bcdd59a906 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived-multiple-supers/output.js @@ -0,0 +1,28 @@ +var Foo = +/*#__PURE__*/ +function (_Bar) { + "use strict"; + + function Foo() { + var _this; + + babelHelpers.classCallCheck(this, Foo); + + if (condition) { + _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this)); + + _bar.set(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this))), "foo"); + } else { + _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this)); + + _bar.set(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this))), "foo"); + } + + return babelHelpers.possibleConstructorReturn(_this); + } + + babelHelpers.inherits(Foo, _Bar); + return Foo; +}(Bar); + +var _bar = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived/exec.js new file mode 100644 index 0000000000..e6bb119953 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived/exec.js @@ -0,0 +1,22 @@ +class Foo { + #prop = "foo"; + + foo() { + return this.#prop; + } +} + +class Bar extends Foo { + #prop = "bar"; + + bar() { + return this.#prop; + } +} + +const f = new Foo; +expect(f.foo()).toBe("foo"); + +const b = new Bar; +expect(b.foo()).toBe("foo"); +expect(b.bar()).toBe("bar"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived/input.js new file mode 100644 index 0000000000..a274845176 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived/input.js @@ -0,0 +1,7 @@ +class Foo { + #prop = "foo"; +} + +class Bar extends Foo { + #prop = "bar"; +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived/output.js new file mode 100644 index 0000000000..82a177fb33 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived/output.js @@ -0,0 +1,27 @@ +var Foo = function Foo() { + "use strict"; + + babelHelpers.classCallCheck(this, Foo); + + _prop.set(this, "foo"); +}; + +var _prop = new WeakMap(); + +var Bar = +/*#__PURE__*/ +function (_Foo) { + "use strict"; + + function Bar(...args) { + var _temp, _this; + + babelHelpers.classCallCheck(this, Bar); + return babelHelpers.possibleConstructorReturn(_this, (_temp = _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Bar).call(this, ...args)), _prop2.set(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), "bar"), _temp)); + } + + babelHelpers.inherits(Bar, _Foo); + return Bar; +}(Foo); + +var _prop2 = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/extracted-this/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/extracted-this/input.js new file mode 100644 index 0000000000..7d1f81581a --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/extracted-this/input.js @@ -0,0 +1,9 @@ +var foo = "bar"; + +class Foo { + #bar = this; + #baz = foo; + + constructor(foo) { + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/extracted-this/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/extracted-this/output.js new file mode 100644 index 0000000000..1da67d41c1 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/extracted-this/output.js @@ -0,0 +1,15 @@ +var foo = "bar"; + +var Foo = function Foo(_foo) { + "use strict"; + + babelHelpers.classCallCheck(this, Foo); + + _bar.set(this, this); + + _baz.set(this, foo); +}; + +var _bar = new WeakMap(); + +var _baz = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/foobar/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/foobar/input.js new file mode 100644 index 0000000000..552a575dab --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/foobar/input.js @@ -0,0 +1,9 @@ +class Child extends Parent { + constructor() { + super(); + } + + #scopedFunctionWithThis = () => { + this.name = {}; + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/foobar/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/foobar/output.js new file mode 100644 index 0000000000..3c1a891774 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/foobar/output.js @@ -0,0 +1,23 @@ +var Child = +/*#__PURE__*/ +function (_Parent) { + "use strict"; + + function Child() { + var _this; + + babelHelpers.classCallCheck(this, Child); + _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Child).call(this)); + + _scopedFunctionWithThis.set(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), () => { + _this.name = {}; + }); + + return _this; + } + + babelHelpers.inherits(Child, _Parent); + return Child; +}(Parent); + +var _scopedFunctionWithThis = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance-undefined/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance-undefined/exec.js new file mode 100644 index 0000000000..ccc0973482 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance-undefined/exec.js @@ -0,0 +1,9 @@ +class Foo { + #bar; + + test() { + return this.#bar; + } +} + +expect(new Foo().test()).toBe(undefined); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance-undefined/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance-undefined/input.js new file mode 100644 index 0000000000..dcb865ec4a --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance-undefined/input.js @@ -0,0 +1,3 @@ +class Foo { + #bar; +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance-undefined/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance-undefined/output.js new file mode 100644 index 0000000000..883eae5647 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance-undefined/output.js @@ -0,0 +1,9 @@ +var Foo = function Foo() { + "use strict"; + + babelHelpers.classCallCheck(this, Foo); + + _bar.set(this, void 0); +}; + +var _bar = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance/exec.js new file mode 100644 index 0000000000..799eadae54 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance/exec.js @@ -0,0 +1,35 @@ +class Foo { + #bar = "foo"; + + test() { + return this.#bar; + } + + update() { + this.#bar++; + } + + set(val) { + this.#bar = val; + } + + static test(foo) { + return foo.#bar; + } + + static update(foo) { + foo.#bar **= 2; + } +} + +const f = new Foo(); +expect(f.test()).toBe("foo"); +expect(Foo.test(f)).toBe("foo"); +expect("bar" in f).toBe(false); + +f.set(1); +expect(f.test()).toBe(1); +f.update(); +expect(Foo.test(f)).toBe(2); +Foo.update(f); +expect(f.test()).toBe(4); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance/input.js new file mode 100644 index 0000000000..9c3d29eb81 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance/input.js @@ -0,0 +1,3 @@ +class Foo { + #bar = "foo"; +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance/options.json new file mode 100644 index 0000000000..da21c5605a --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["external-helpers", "proposal-class-properties", "transform-classes", "transform-block-scoping", "syntax-class-properties", "transform-exponentiation-operator"] +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance/output.js new file mode 100644 index 0000000000..33c04bf680 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/instance/output.js @@ -0,0 +1,9 @@ +var Foo = function Foo() { + "use strict"; + + babelHelpers.classCallCheck(this, Foo); + + _bar.set(this, "foo"); +}; + +var _bar = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/multiple/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/multiple/exec.js new file mode 100644 index 0000000000..3c45eec1e4 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/multiple/exec.js @@ -0,0 +1,11 @@ +class Foo { + #x = 0; + #y = this.#x + 1; + + test() { + return this.#y; + } +} + +const f = new Foo(); +expect(f.test()).toBe(1); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/multiple/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/multiple/input.js new file mode 100644 index 0000000000..1e01f81502 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/multiple/input.js @@ -0,0 +1,4 @@ +class Foo { + #x = 0; + #y = this.#x; +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/multiple/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/multiple/output.js new file mode 100644 index 0000000000..6b96ca95f7 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/multiple/output.js @@ -0,0 +1,13 @@ +var Foo = function Foo() { + "use strict"; + + babelHelpers.classCallCheck(this, Foo); + + _x.set(this, 0); + + _y.set(this, babelHelpers.classPrivateFieldGet(this, _x)); +}; + +var _x = new WeakMap(); + +var _y = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/input.js new file mode 100644 index 0000000000..e0c4dfe70b --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/input.js @@ -0,0 +1,18 @@ +class Foo { + static #foo = "foo"; + #bar = "bar"; + + static test() { + return Foo.#foo; + } + + test() { + return this.#bar; + } +} + +const f = new Foo(); +expect("foo" in Foo).toBe(false) +expect("bar" in f).toBe(false) +expect(Foo.test()).toBe("foo") +expect(f.test()).toBe("bar") diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/options.json new file mode 100644 index 0000000000..03872554af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Static class fields are not spec'ed yet." +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/output.js new file mode 100644 index 0000000000..f90dee5679 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/native-classes/output.js @@ -0,0 +1,14 @@ +var _foo, _bar; + +class Foo { + constructor() { + _bar.set(this, "bar"); + } + +} + +_foo = new WeakMap(); + +_foo.set(Foo, "foo"); + +_bar = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/input.mjs b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/input.mjs new file mode 100644 index 0000000000..cd1cfaa283 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/input.mjs @@ -0,0 +1,11 @@ +export default param => + class App { + static #props = { + prop1: 'prop1', + prop2: 'prop2' + } + + getParam() { + return param; + } + } diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/options.json new file mode 100644 index 0000000000..03872554af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Static class fields are not spec'ed yet." +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/output.mjs b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/output.mjs new file mode 100644 index 0000000000..e69c069b88 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/non-block-arrow-func/output.mjs @@ -0,0 +1,22 @@ +export default (param => { + var _props, _class, _temp; + + return _temp = _class = + /*#__PURE__*/ + function () { + function App() { + babelHelpers.classCallCheck(this, App); + } + + babelHelpers.createClass(App, [{ + key: "getParam", + value: function getParam() { + return param; + } + }]); + return App; + }(), _props = new WeakMap(), _props.set(_class, { + prop1: 'prop1', + prop2: 'prop2' + }), _temp; +}); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/options.json new file mode 100644 index 0000000000..9aefe6206b --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["external-helpers", "proposal-class-properties", "transform-classes", "transform-block-scoping", "syntax-class-properties"] +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/private-in-derived/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/private-in-derived/input.js new file mode 100644 index 0000000000..03754e8a4a --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/private-in-derived/input.js @@ -0,0 +1,8 @@ +class Outer { + #outer; + + constructor() { + class Test extends this.#outer { + } + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/private-in-derived/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/private-in-derived/output.js new file mode 100644 index 0000000000..beeacf11ce --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/private-in-derived/output.js @@ -0,0 +1,21 @@ +var Outer = function Outer() { + "use strict"; + + babelHelpers.classCallCheck(this, Outer); + + _outer.set(this, void 0); + + var Test = + /*#__PURE__*/ + function (_babelHelpers$classPr) { + function Test() { + babelHelpers.classCallCheck(this, Test); + return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Test).apply(this, arguments)); + } + + babelHelpers.inherits(Test, _babelHelpers$classPr); + return Test; + }(babelHelpers.classPrivateFieldGet(this, _outer)); +}; + +var _outer = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/input.js new file mode 100644 index 0000000000..9e8222eb71 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/input.js @@ -0,0 +1,51 @@ +function classFactory() { + return class Foo { + #foo = "foo"; + static #bar = "bar"; + + instance() { + return this.#foo; + } + + static() { + return Foo.#bar; + } + + static instance(inst) { + return inst.#foo; + } + + static static() { + return Foo.#bar; + } + } +} + +const Foo1 = classFactory(); +const Foo2 = classFactory(); + +const f1 = new Foo1; +const f2 = new Foo2; + +expect(f1.instance()).toBe("foo"); +expect(f1.static()).toBe("bar"); +expect(f2.instance()).toBe("foo"); +expect(f2.static()).toBe("bar"); + +expect(Foo1.instance(f1)).toBe("foo"); +expect(Foo1.static()).toBe("bar"); +expect(Foo2.instance(f2)).toBe("foo"); +expect(Foo2.static()).toBe("bar"); + +assert.throws(() => { + f1.instance.call(f2), undefined; +}); +assert.throws(() => { + f2.instance.call(f1), undefined; +}); +assert.throws(() => { + Foo1.instance(f2), undefined; +}); +assert.throws(() => { + Foo2.instance(f1), undefined; +}); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/options.json new file mode 100644 index 0000000000..03872554af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Static class fields are not spec'ed yet." +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/output.js new file mode 100644 index 0000000000..abfb86e72f --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reevaluated/output.js @@ -0,0 +1,15 @@ +function classFactory() { + var _bar, _foo; + + var Foo = function Foo() { + babelHelpers.classCallCheck(this, Foo); + + _foo.set(this, "foo"); + }; + + _bar = new WeakMap(); + + _bar.set(Foo, "bar"); + + _foo = new WeakMap(); +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reference-in-other-property/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reference-in-other-property/input.js new file mode 100644 index 0000000000..63c7e41999 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reference-in-other-property/input.js @@ -0,0 +1,7 @@ +class Foo { + one = this.#private; + #two = this.#private; + #private = 0; + three = this.#private; + #four = this.#private; +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reference-in-other-property/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reference-in-other-property/output.js new file mode 100644 index 0000000000..890181b195 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/reference-in-other-property/output.js @@ -0,0 +1,20 @@ +var Foo = function Foo() { + "use strict"; + + babelHelpers.classCallCheck(this, Foo); + babelHelpers.defineProperty(this, "one", babelHelpers.classPrivateFieldGet(this, _private)); + + _two.set(this, babelHelpers.classPrivateFieldGet(this, _private)); + + _private.set(this, 0); + + babelHelpers.defineProperty(this, "three", babelHelpers.classPrivateFieldGet(this, _private)); + + _four.set(this, babelHelpers.classPrivateFieldGet(this, _private)); +}; + +var _two = new WeakMap(); + +var _private = new WeakMap(); + +var _four = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/input.mjs b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/input.mjs new file mode 100644 index 0000000000..4d9a6a7c51 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/input.mjs @@ -0,0 +1,7 @@ +call(class { + static #test = true +}); + +export default class { + static #test = true +}; diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/options.json new file mode 100644 index 0000000000..03872554af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Static class fields are not spec'ed yet." +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/output.mjs b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/output.mjs new file mode 100644 index 0000000000..ea8020b0be --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T2983/output.mjs @@ -0,0 +1,16 @@ +var _test, _class, _temp, _test2; + +call((_temp = _class = function _class() { + babelHelpers.classCallCheck(this, _class); +}, _test = new WeakMap(), _test.set(_class, true), _temp)); + +var _default = function _default() { + babelHelpers.classCallCheck(this, _default); +}; + +_test2 = new WeakMap(); + +_test2.set(_default, true); + +export { _default as default }; +; diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/input.js new file mode 100644 index 0000000000..a8efa1abaa --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/input.js @@ -0,0 +1,14 @@ +function withContext(ComposedComponent) { + return class WithContext extends Component { + + static #propTypes = { + context: PropTypes.shape( + { + addCss: PropTypes.func, + setTitle: PropTypes.func, + setMeta: PropTypes.func, + } + ), + }; + }; +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/options.json new file mode 100644 index 0000000000..03872554af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Static class fields are not spec'ed yet." +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/output.js new file mode 100644 index 0000000000..553fcaf28a --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T6719/output.js @@ -0,0 +1,22 @@ +function withContext(ComposedComponent) { + var _propTypes, _class, _temp; + + return _temp = _class = + /*#__PURE__*/ + function (_Component) { + babelHelpers.inherits(WithContext, _Component); + + function WithContext() { + babelHelpers.classCallCheck(this, WithContext); + return babelHelpers.possibleConstructorReturn(this, (WithContext.__proto__ || Object.getPrototypeOf(WithContext)).apply(this, arguments)); + } + + return WithContext; + }(Component), _propTypes = new WeakMap(), _propTypes.set(_class, { + context: PropTypes.shape({ + addCss: PropTypes.func, + setTitle: PropTypes.func, + setMeta: PropTypes.func + }) + }), _temp; +} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T7364/input.mjs b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T7364/input.mjs new file mode 100644 index 0000000000..c5b2815a96 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T7364/input.mjs @@ -0,0 +1,17 @@ +class MyClass { + #myAsyncMethod = async () => { + console.log(this); + } +} + +(class MyClass2 { + #myAsyncMethod = async () => { + console.log(this); + } +}) + +export default class MyClass3 { + #myAsyncMethod = async () => { + console.log(this); + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T7364/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T7364/options.json new file mode 100644 index 0000000000..70ad9aef82 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T7364/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["external-helpers", "proposal-class-properties", "transform-block-scoping", "syntax-class-properties", "transform-async-to-generator"] +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T7364/output.mjs b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T7364/output.mjs new file mode 100644 index 0000000000..d56a5d7366 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/regression-T7364/output.mjs @@ -0,0 +1,46 @@ +var _class; + +class MyClass { + constructor() { + var _this = this; + + _myAsyncMethod.set(this, + /*#__PURE__*/ + babelHelpers.asyncToGenerator(function* () { + console.log(_this); + })); + } + +} + +var _myAsyncMethod = new WeakMap(); + +_class = class MyClass2 { + constructor() { + var _this2 = this; + + _myAsyncMethod2.set(this, + /*#__PURE__*/ + babelHelpers.asyncToGenerator(function* () { + console.log(_this2); + })); + } + +}; + +var _myAsyncMethod2 = new WeakMap(); + +export default class MyClass3 { + constructor() { + var _this3 = this; + + _myAsyncMethod3.set(this, + /*#__PURE__*/ + babelHelpers.asyncToGenerator(function* () { + console.log(_this3); + })); + } + +} + +var _myAsyncMethod3 = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/input.mjs b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/input.mjs new file mode 100644 index 0000000000..8da62e5b2b --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/input.mjs @@ -0,0 +1,7 @@ +export class MyClass { + static #property = value; +} + +export default class MyClass2 { + static #property = value; +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/options.json new file mode 100644 index 0000000000..03872554af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Static class fields are not spec'ed yet." +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/output.mjs b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/output.mjs new file mode 100644 index 0000000000..39d6c7cdd5 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-export/output.mjs @@ -0,0 +1,18 @@ +var _property, _property2; + +export var MyClass = function MyClass() { + babelHelpers.classCallCheck(this, MyClass); +}; +_property = new WeakMap(); + +_property.set(MyClass, value); + +var MyClass2 = function MyClass2() { + babelHelpers.classCallCheck(this, MyClass2); +}; + +_property2 = new WeakMap(); + +_property2.set(MyClass2, value); + +export { MyClass2 as default }; diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/input.js new file mode 100644 index 0000000000..4fa2273cf6 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/input.js @@ -0,0 +1,3 @@ +var Foo = class { + static #num = 0; +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/options.json new file mode 100644 index 0000000000..03872554af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Static class fields are not spec'ed yet." +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/output.js new file mode 100644 index 0000000000..16272497af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-infer-name/output.js @@ -0,0 +1,5 @@ +var _num, _class, _temp; + +var Foo = (_temp = _class = function Foo() { + babelHelpers.classCallCheck(this, Foo); +}, _num = new WeakMap(), _num.set(_class, 0), _temp); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/input.js new file mode 100644 index 0000000000..66202d9f9d --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/input.js @@ -0,0 +1,70 @@ +class Base { + static #foo = 1; + + static getThis() { + return this.#foo; + } + + static updateThis(val) { + return this.#foo = val; + } + + static getClass() { + return Base.#foo; + } + + static updateClass(val) { + return Base.#foo = val; + } +} + +class Sub1 extends Base { + static #foo = 2; + + static update(val) { + return this.#foo = val; + } +} + +class Sub2 extends Base { +} + +expect(Base.getThis()).toBe(1); +expect(Base.getClass()).toBe(1); +assert.throws(() => Sub1.getThis()); +expect(Sub1.getClass()).toBe(1); +assert.throws(() => Sub2.getThis()); +expect(Sub2.getClass()).toBe(1); + +expect(Sub1.update(3)).toBe(3); +expect(Base.getThis()).toBe(1); +expect(Base.getClass()).toBe(1); +assert.throws(() => Sub1.getThis()); +expect(Sub1.getClass()).toBe(1); +assert.throws(() => Sub2.getThis()); +expect(Sub2.getClass()).toBe(1); + +expect(Base.updateThis(4)).toBe(4); +expect(Base.getThis()).toBe(4); +expect(Base.getClass()).toBe(4); +assert.throws(() => Sub1.getThis()); +expect(Sub1.getClass()).toBe(4); +assert.throws(() => Sub2.getThis()); +expect(Sub2.getClass()).toBe(4); + +expect(Base.updateClass(5)).toBe(5); +expect(Base.getThis()).toBe(5); +expect(Base.getClass()).toBe(5); +assert.throws(() => Sub1.getThis()); +expect(Sub1.getClass()).toBe(5); +assert.throws(() => Sub2.getThis()); +expect(Sub2.getClass()).toBe(5); + +assert.throws(() => Sub2.updateThis(6)); +expect(Sub2.updateClass(7)).toBe(7); +expect(Base.getThis()).toBe(7); +expect(Base.getClass()).toBe(7); +assert.throws(() => Sub1.getThis()); +expect(Sub1.getClass()).toBe(7); +assert.throws(() => Sub2.getThis()); +expect(Sub2.getClass()).toBe(7); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/options.json new file mode 100644 index 0000000000..03872554af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Static class fields are not spec'ed yet." +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/output.js new file mode 100644 index 0000000000..e395c0915f --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-inherited/output.js @@ -0,0 +1,51 @@ +var _foo, _foo2; + +var Base = +/*#__PURE__*/ +function () { + function Base() { + babelHelpers.classCallCheck(this, Base); + } + + babelHelpers.createClass(Base, null, [{ + key: "m", + value: function m() { + return babelHelpers.classPrivateFieldGet(this, _foo); + } + }]); + return Base; +}(); + +_foo = new WeakMap(); + +_foo.set(Base, 1); + +var Sub1 = +/*#__PURE__*/ +function (_Base) { + babelHelpers.inherits(Sub1, _Base); + + function Sub1() { + babelHelpers.classCallCheck(this, Sub1); + return babelHelpers.possibleConstructorReturn(this, (Sub1.__proto__ || Object.getPrototypeOf(Sub1)).apply(this, arguments)); + } + + return Sub1; +}(Base); + +_foo2 = new WeakMap(); + +_foo2.set(Sub1, 2); + +var Sub2 = +/*#__PURE__*/ +function (_Base2) { + babelHelpers.inherits(Sub2, _Base2); + + function Sub2() { + babelHelpers.classCallCheck(this, Sub2); + return babelHelpers.possibleConstructorReturn(this, (Sub2.__proto__ || Object.getPrototypeOf(Sub2)).apply(this, arguments)); + } + + return Sub2; +}(Base); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/input.js new file mode 100644 index 0000000000..d639688898 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/input.js @@ -0,0 +1,15 @@ +class Foo { + static #bar; + + static test() { + return Foo.#bar; + } + + test() { + return Foo.#bar; + } +} + +expect("bar" in Foo).toBe(false) +expect(Foo.test()).toBe(undefined) +expect(Foo.test()).toBe(undefined) diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/options.json new file mode 100644 index 0000000000..03872554af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Static class fields are not spec'ed yet." +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/output.js new file mode 100644 index 0000000000..1891916984 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static-undefined/output.js @@ -0,0 +1,9 @@ +var _bar; + +var Foo = function Foo() { + babelHelpers.classCallCheck(this, Foo); +}; + +_bar = new WeakMap(); + +_bar.set(Foo, void 0); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/input.js new file mode 100644 index 0000000000..c905fa85d5 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/input.js @@ -0,0 +1,15 @@ +class Foo { + static #bar = "foo"; + + static test() { + return Foo.#bar; + } + + test() { + return Foo.#bar; + } +} + +expect("bar" in Foo).toBe(false) +expect(Foo.test()).toBe("foo") +expect(Foo.test()).toBe("foo") diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/options.json new file mode 100644 index 0000000000..03872554af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Static class fields are not spec'ed yet." +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/output.js new file mode 100644 index 0000000000..47430af8af --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/static/output.js @@ -0,0 +1,26 @@ +var _bar; + +var Foo = +/*#__PURE__*/ +function () { + function Foo() { + babelHelpers.classCallCheck(this, Foo); + } + + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test() { + return babelHelpers.classPrivateFieldGet(Foo, _bar); + } + }], [{ + key: "test", + value: function test() { + return babelHelpers.classPrivateFieldGet(Foo, _bar); + } + }]); + return Foo; +}(); + +_bar = new WeakMap(); + +_bar.set(Foo, "foo"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-call/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-call/input.js new file mode 100644 index 0000000000..eb001db941 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-call/input.js @@ -0,0 +1,9 @@ +class A { + foo() { + return "bar"; + } +} + +class B extends A { + #foo = super.foo(); +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-call/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-call/output.js new file mode 100644 index 0000000000..f036cceacd --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-call/output.js @@ -0,0 +1,35 @@ +var A = +/*#__PURE__*/ +function () { + "use strict"; + + function A() { + babelHelpers.classCallCheck(this, A); + } + + babelHelpers.createClass(A, [{ + key: "foo", + value: function foo() { + return "bar"; + } + }]); + return A; +}(); + +var B = +/*#__PURE__*/ +function (_A) { + "use strict"; + + function B(...args) { + var _temp, _this; + + babelHelpers.classCallCheck(this, B); + return babelHelpers.possibleConstructorReturn(_this, (_temp = _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(B).call(this, ...args)), _foo.set(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), babelHelpers.get(babelHelpers.getPrototypeOf(B.prototype), "foo", babelHelpers.assertThisInitialized(_this)).call(babelHelpers.assertThisInitialized(_this))), _temp)); + } + + babelHelpers.inherits(B, _A); + return B; +}(A); + +var _foo = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-expression/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-expression/input.js new file mode 100644 index 0000000000..617776acc9 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-expression/input.js @@ -0,0 +1,7 @@ +class Foo extends Bar { + #bar = "foo"; + + constructor() { + foo(super()); + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-expression/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-expression/output.js new file mode 100644 index 0000000000..5cef63bf76 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-expression/output.js @@ -0,0 +1,18 @@ +var Foo = +/*#__PURE__*/ +function (_Bar) { + "use strict"; + + function Foo() { + var _temp, _this; + + babelHelpers.classCallCheck(this, Foo); + foo((_temp = _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this)), _bar.set(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), "foo"), _temp)); + return _this; + } + + babelHelpers.inherits(Foo, _Bar); + return Foo; +}(Bar); + +var _bar = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-statement/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-statement/input.js new file mode 100644 index 0000000000..4bef6ef21b --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-statement/input.js @@ -0,0 +1,7 @@ +class Foo extends Bar { + #bar = "foo"; + + constructor() { + super(); + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-statement/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-statement/output.js new file mode 100644 index 0000000000..3d03522a31 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/super-statement/output.js @@ -0,0 +1,21 @@ +var Foo = +/*#__PURE__*/ +function (_Bar) { + "use strict"; + + function Foo() { + var _this; + + babelHelpers.classCallCheck(this, Foo); + _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this)); + + _bar.set(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), "foo"); + + return _this; + } + + babelHelpers.inherits(Foo, _Bar); + return Foo; +}(Bar); + +var _bar = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/update/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/update/exec.js new file mode 100644 index 0000000000..ff92564c81 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/update/exec.js @@ -0,0 +1,27 @@ +class Foo { + #foo = 0; + + test(other) { + return [ + this.#foo++, + this.#foo, + ++this.#foo, + this.#foo, + other.obj.#foo++, + other.obj.#foo, + ++other.obj.#foo, + other.obj.#foo, + ]; + } +} + +const f = new Foo; +const results = f.test({ obj: f }); +expect(results[0]).toBe(0); +expect(results[1]).toBe(1); +expect(results[2]).toBe(2); +expect(results[3]).toBe(2); +expect(results[4]).toBe(2); +expect(results[5]).toBe(3); +expect(results[6]).toBe(4); +expect(results[7]).toBe(4); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/update/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/update/input.js new file mode 100644 index 0000000000..0ff8b74927 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/update/input.js @@ -0,0 +1,10 @@ +class Foo { + #foo = 0; + + test(other) { + this.#foo++; + ++this.#foo; + other.obj.#foo++; + ++other.obj.#foo; + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/private/update/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/update/output.js new file mode 100644 index 0000000000..ae86f6bdba --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/private/update/output.js @@ -0,0 +1,26 @@ +var Foo = +/*#__PURE__*/ +function () { + "use strict"; + + function Foo() { + babelHelpers.classCallCheck(this, Foo); + + _foo.set(this, 0); + } + + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test(other) { + var _this$foo, _other$obj, _other$obj$foo, _other$obj2; + + babelHelpers.classPrivateFieldSet(this, _foo, (_this$foo = +babelHelpers.classPrivateFieldGet(this, _foo)) + 1), _this$foo; + babelHelpers.classPrivateFieldSet(this, _foo, +babelHelpers.classPrivateFieldGet(this, _foo) + 1); + babelHelpers.classPrivateFieldSet(_other$obj = other.obj, _foo, (_other$obj$foo = +babelHelpers.classPrivateFieldGet(_other$obj, _foo)) + 1), _other$obj$foo; + babelHelpers.classPrivateFieldSet(_other$obj2 = other.obj, _foo, +babelHelpers.classPrivateFieldGet(_other$obj2, _foo) + 1); + } + }]); + return Foo; +}(); + +var _foo = new WeakMap(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/public/assignment/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/assignment/input.js new file mode 100644 index 0000000000..3d0cee7f7f --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/assignment/input.js @@ -0,0 +1,12 @@ +class Foo { + foo = 0; + + test(other) { + this.foo++; + this.foo += 1; + this.foo = 2; + other.obj.foo++; + other.obj.foo += 1; + other.obj.foo = 2; + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/public/assignment/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/assignment/output.js new file mode 100644 index 0000000000..83a710d33e --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/assignment/output.js @@ -0,0 +1,23 @@ +var Foo = +/*#__PURE__*/ +function () { + "use strict"; + + function Foo() { + babelHelpers.classCallCheck(this, Foo); + babelHelpers.defineProperty(this, "foo", 0); + } + + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test(other) { + this.foo++; + this.foo += 1; + this.foo = 2; + other.obj.foo++; + other.obj.foo += 1; + other.obj.foo = 2; + } + }]); + return Foo; +}(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/public/call/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/call/exec.js new file mode 100644 index 0000000000..e6fc4d2d19 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/call/exec.js @@ -0,0 +1,15 @@ +class Foo { + foo = function() { + return this; + } + + test(other) { + return [this.foo(), other.foo()]; + } +} + +const f = new Foo; +const o = new Foo; +const test = f.test(o); +expect(test[0]).toBe(f); +expect(test[1]).toBe(o); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/public/call/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/call/input.js new file mode 100644 index 0000000000..55e56ff5d6 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/call/input.js @@ -0,0 +1,10 @@ +class Foo { + foo = function() { + return this; + } + + test(other) { + this.foo(); + other.obj.foo(); + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/public/call/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/call/output.js new file mode 100644 index 0000000000..b58e59b5fb --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/call/output.js @@ -0,0 +1,21 @@ +var Foo = +/*#__PURE__*/ +function () { + "use strict"; + + function Foo() { + babelHelpers.classCallCheck(this, Foo); + babelHelpers.defineProperty(this, "foo", function () { + return this; + }); + } + + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test(other) { + this.foo(); + other.obj.foo(); + } + }]); + return Foo; +}(); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/public/derived-multiple-supers/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/derived-multiple-supers/input.js new file mode 100644 index 0000000000..c4ff39116e --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/derived-multiple-supers/input.js @@ -0,0 +1,11 @@ +class Foo extends Bar { + bar = "foo"; + + constructor() { + if (condition) { + super(); + } else { + super(); + } + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/public/derived-multiple-supers/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/derived-multiple-supers/output.js new file mode 100644 index 0000000000..ee3a2517eb --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/derived-multiple-supers/output.js @@ -0,0 +1,24 @@ +var Foo = +/*#__PURE__*/ +function (_Bar) { + "use strict"; + + function Foo() { + var _this; + + babelHelpers.classCallCheck(this, Foo); + + if (condition) { + _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this)); + babelHelpers.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this))), "bar", "foo"); + } else { + _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this)); + babelHelpers.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this))), "bar", "foo"); + } + + return babelHelpers.possibleConstructorReturn(_this); + } + + babelHelpers.inherits(Foo, _Bar); + return Foo; +}(Bar); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/public/extracted-this/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/extracted-this/input.js new file mode 100644 index 0000000000..0f284976fb --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/extracted-this/input.js @@ -0,0 +1,9 @@ +var foo = "bar"; + +class Foo { + bar = this; + baz = foo; + + constructor(foo) { + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/public/extracted-this/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/extracted-this/output.js new file mode 100644 index 0000000000..9864802fd4 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/extracted-this/output.js @@ -0,0 +1,9 @@ +var foo = "bar"; + +var Foo = function Foo(_foo) { + "use strict"; + + babelHelpers.classCallCheck(this, Foo); + babelHelpers.defineProperty(this, "bar", this); + babelHelpers.defineProperty(this, "baz", foo); +}; diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/public/native-classes/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/native-classes/exec.js new file mode 100644 index 0000000000..6741d135b9 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/native-classes/exec.js @@ -0,0 +1,18 @@ +class Foo { + static foo = "foo"; + bar = "bar"; + + static test() { + return Foo.foo; + } + + test() { + return this.bar; + } +} + +const f = new Foo(); +expect("foo" in Foo).toBe(true) +expect("bar" in f).toBe(true) +expect(Foo.test()).toBe("foo") +expect(f.test()).toBe("bar") diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/public/native-classes/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/native-classes/input.js new file mode 100644 index 0000000000..3a8db96669 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/native-classes/input.js @@ -0,0 +1,4 @@ +class Foo { + static foo = "foo"; + bar = "bar"; +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/public/native-classes/options.json b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/native-classes/options.json new file mode 100644 index 0000000000..c19c65ddf9 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/native-classes/options.json @@ -0,0 +1,4 @@ +{ + "minNodeVersion": "6.0.0", + "plugins": ["external-helpers", "proposal-class-properties", "transform-block-scoping", "syntax-class-properties"] +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/public/native-classes/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/native-classes/output.js new file mode 100644 index 0000000000..427fcd4585 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/native-classes/output.js @@ -0,0 +1,8 @@ +class Foo { + constructor() { + babelHelpers.defineProperty(this, "bar", "bar"); + } + +} + +babelHelpers.defineProperty(Foo, "foo", "foo"); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/public/numeric/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/numeric/input.js new file mode 100644 index 0000000000..3b4db96aa1 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/numeric/input.js @@ -0,0 +1,4 @@ +class Foo { + 0 = "foo"; + 1 = "bar"; +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/public/numeric/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/numeric/output.js new file mode 100644 index 0000000000..9b8d3ba70d --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/numeric/output.js @@ -0,0 +1,7 @@ +var Foo = function Foo() { + "use strict"; + + babelHelpers.classCallCheck(this, Foo); + babelHelpers.defineProperty(this, 0, "foo"); + babelHelpers.defineProperty(this, 1, "bar"); +}; diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/public/update/exec.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/update/exec.js new file mode 100644 index 0000000000..592b96aa96 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/update/exec.js @@ -0,0 +1,27 @@ +class Foo { + foo = 0; + + test(other) { + return [ + this.foo++, + this.foo, + ++this.foo, + this.foo, + other.obj.foo++, + other.obj.foo, + ++other.obj.foo, + other.obj.foo, + ]; + } +} + +const f = new Foo; +const results = f.test({ obj: f }); +expect(results[0]).toBe(0); +expect(results[1]).toBe(1); +expect(results[2]).toBe(2); +expect(results[3]).toBe(2); +expect(results[4]).toBe(2); +expect(results[5]).toBe(3); +expect(results[6]).toBe(4); +expect(results[7]).toBe(4); diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/public/update/input.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/update/input.js new file mode 100644 index 0000000000..d6350282c4 --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/update/input.js @@ -0,0 +1,10 @@ +class Foo { + foo = 0; + + test(other) { + this.foo++; + ++this.foo; + other.obj.foo++; + ++other.obj.foo; + } +} diff --git a/packages/babel-plugin-proposal-class-properties/test/fixtures/public/update/output.js b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/update/output.js new file mode 100644 index 0000000000..c2c2a6927e --- /dev/null +++ b/packages/babel-plugin-proposal-class-properties/test/fixtures/public/update/output.js @@ -0,0 +1,21 @@ +var Foo = +/*#__PURE__*/ +function () { + "use strict"; + + function Foo() { + babelHelpers.classCallCheck(this, Foo); + babelHelpers.defineProperty(this, "foo", 0); + } + + babelHelpers.createClass(Foo, [{ + key: "test", + value: function test(other) { + this.foo++; + ++this.foo; + other.obj.foo++; + ++other.obj.foo; + } + }]); + return Foo; +}();