Private Class Methods Stage 3: Private Accessors (#9101)

* Add accessor loose support

* Add private accessors spec support

* Fix private dupe name check

* Changes from code review

* Add duplicated names tests

* Add get/set-only tests

* Move accessors tests

* Split out updates tests

* Add helper change tests

* Update test output

* Update test options
This commit is contained in:
Tim McClure
2019-01-21 16:05:37 -05:00
committed by Nicolò Ribaudo
parent 3ae5e79ec8
commit e8de6fa5d4
53 changed files with 1171 additions and 57 deletions

View File

@@ -0,0 +1,31 @@
class Cl {
#privateField = "top secret string";
constructor() {
this.publicField = "not secret string";
}
get #privateFieldValue() {
return this.#privateField;
}
set #privateFieldValue(newValue) {
this.#privateField = newValue;
}
publicGetPrivateField() {
return this.#privateFieldValue;
}
publicSetPrivateField(newValue) {
this.#privateFieldValue = newValue;
}
}
const cl = new Cl();
expect(cl.publicGetPrivateField()).toEqual("top secret string");
cl.publicSetPrivateField("new secret string");
expect(cl.publicGetPrivateField()).toEqual("new secret string");

View File

@@ -0,0 +1,23 @@
class Cl {
#privateField = "top secret string";
constructor() {
this.publicField = "not secret string";
}
get #privateFieldValue() {
return this.#privateField;
}
set #privateFieldValue(newValue) {
this.#privateField = newValue;
}
publicGetPrivateField() {
return this.#privateFieldValue;
}
publicSetPrivateField(newValue) {
this.#privateFieldValue = newValue;
}
}

View File

@@ -0,0 +1,43 @@
var Cl =
/*#__PURE__*/
function () {
"use strict";
function Cl() {
babelHelpers.classCallCheck(this, Cl);
Object.defineProperty(this, _privateFieldValue, {
get: _get_privateFieldValue,
set: _set_privateFieldValue
});
Object.defineProperty(this, _privateField, {
writable: true,
value: "top secret string"
});
this.publicField = "not secret string";
}
babelHelpers.createClass(Cl, [{
key: "publicGetPrivateField",
value: function publicGetPrivateField() {
return babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue];
}
}, {
key: "publicSetPrivateField",
value: function publicSetPrivateField(newValue) {
babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue] = newValue;
}
}]);
return Cl;
}();
var _privateField = babelHelpers.classPrivateFieldLooseKey("privateField");
var _privateFieldValue = babelHelpers.classPrivateFieldLooseKey("privateFieldValue");
var _get_privateFieldValue = function () {
return babelHelpers.classPrivateFieldLooseBase(this, _privateField)[_privateField];
};
var _set_privateFieldValue = function (newValue) {
babelHelpers.classPrivateFieldLooseBase(this, _privateField)[_privateField] = newValue;
};

View File

@@ -0,0 +1,13 @@
class Cl {
#privateField = 0;
set #privateFieldValue(newValue) {
this.#privateField = newValue;
}
constructor() {
expect(this.#privateFieldValue).toBeUndefined();
}
}
const cl = new Cl();

View File

@@ -0,0 +1,11 @@
class Cl {
#privateField = 0;
set #privateFieldValue(newValue) {
this.#privateField = newValue;
}
constructor() {
this.publicField = this.#privateFieldValue;
}
}

View File

@@ -0,0 +1,21 @@
var Cl = function Cl() {
"use strict";
babelHelpers.classCallCheck(this, Cl);
Object.defineProperty(this, _privateFieldValue, {
set: _set_privateFieldValue
});
Object.defineProperty(this, _privateField, {
writable: true,
value: 0
});
this.publicField = babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue];
};
var _privateField = babelHelpers.classPrivateFieldLooseKey("privateField");
var _privateFieldValue = babelHelpers.classPrivateFieldLooseKey("privateFieldValue");
var _set_privateFieldValue = function (newValue) {
babelHelpers.classPrivateFieldLooseBase(this, _privateField)[_privateField] = newValue;
};

View File

@@ -0,0 +1,11 @@
let foo;
class Cl {
set #foo(v) { return 1 }
test() {
foo = this.#foo = 2;
}
}
new Cl().test();
expect(foo).toBe(2);

View File

@@ -0,0 +1,15 @@
{
"plugins": [
[
"external-helpers",
{
"helperVersion": "7.1000.0"
}
],
["proposal-private-methods", { "loose": true }],
["proposal-class-properties", { "loose": true }],
"transform-classes",
"transform-block-scoping",
"syntax-class-properties"
]
}

View File

@@ -0,0 +1,13 @@
class Cl {
#privateField = 0;
get #privateFieldValue() {
return this.#privateField;
}
constructor() {
expect(() => this.#privateFieldValue = 1).toThrow(TypeError);
}
}
const cl = new Cl();

View File

@@ -0,0 +1,11 @@
class Cl {
#privateField = 0;
get #privateFieldValue() {
return this.#privateField;
}
constructor() {
this.#privateFieldValue = 1;
}
}

View File

@@ -0,0 +1,21 @@
var Cl = function Cl() {
"use strict";
babelHelpers.classCallCheck(this, Cl);
Object.defineProperty(this, _privateFieldValue, {
get: _get_privateFieldValue
});
Object.defineProperty(this, _privateField, {
writable: true,
value: 0
});
babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue] = 1;
};
var _privateField = babelHelpers.classPrivateFieldLooseKey("privateField");
var _privateFieldValue = babelHelpers.classPrivateFieldLooseKey("privateFieldValue");
var _get_privateFieldValue = function () {
return babelHelpers.classPrivateFieldLooseBase(this, _privateField)[_privateField];
};

View File

@@ -0,0 +1,50 @@
class Cl {
#privateField = "top secret string";
constructor() {
this.publicField = "not secret string";
}
get #privateFieldValue() {
return this.#privateField;
}
set #privateFieldValue(newValue) {
this.#privateField = newValue;
}
publicGetPrivateField() {
return this.#privateFieldValue;
}
publicSetPrivateField(newValue) {
this.#privateFieldValue = newValue;
}
get publicFieldValue() {
return this.publicField;
}
set publicFieldValue(newValue) {
this.publicField = newValue;
}
testUpdates() {
this.#privateField = 0;
this.publicField = 0;
this.#privateFieldValue = this.#privateFieldValue++;
this.publicFieldValue = this.publicFieldValue++;
expect(this.#privateField).toEqual(this.publicField);
++this.#privateFieldValue;
++this.publicFieldValue;
expect(this.#privateField).toEqual(this.publicField);
this.#privateFieldValue += 1;
this.publicFieldValue += 1;
expect(this.#privateField).toEqual(this.publicField);
}
}
const cl = new Cl();
cl.testUpdates();

View File

@@ -0,0 +1,47 @@
class Cl {
#privateField = "top secret string";
constructor() {
this.publicField = "not secret string";
}
get #privateFieldValue() {
return this.#privateField;
}
set #privateFieldValue(newValue) {
this.#privateField = newValue;
}
publicGetPrivateField() {
return this.#privateFieldValue;
}
publicSetPrivateField(newValue) {
this.#privateFieldValue = newValue;
}
get publicFieldValue() {
return this.publicField;
}
set publicFieldValue(newValue) {
this.publicField = newValue;
}
testUpdates() {
this.#privateField = 0;
this.publicField = 0;
this.#privateFieldValue = this.#privateFieldValue++;
this.publicFieldValue = this.publicFieldValue++;
++this.#privateFieldValue;
++this.publicFieldValue;
this.#privateFieldValue += 1;
this.publicFieldValue += 1;
this.#privateFieldValue = -(this.#privateFieldValue ** this.#privateFieldValue);
this.publicFieldValue = -(this.publicFieldValue ** this.publicFieldValue);
}
}

View File

@@ -0,0 +1,65 @@
var Cl =
/*#__PURE__*/
function () {
"use strict";
function Cl() {
babelHelpers.classCallCheck(this, Cl);
Object.defineProperty(this, _privateFieldValue, {
get: _get_privateFieldValue,
set: _set_privateFieldValue
});
Object.defineProperty(this, _privateField, {
writable: true,
value: "top secret string"
});
this.publicField = "not secret string";
}
babelHelpers.createClass(Cl, [{
key: "publicGetPrivateField",
value: function publicGetPrivateField() {
return babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue];
}
}, {
key: "publicSetPrivateField",
value: function publicSetPrivateField(newValue) {
babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue] = newValue;
}
}, {
key: "testUpdates",
value: function testUpdates() {
babelHelpers.classPrivateFieldLooseBase(this, _privateField)[_privateField] = 0;
this.publicField = 0;
babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue] = babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue]++;
this.publicFieldValue = this.publicFieldValue++;
++babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue];
++this.publicFieldValue;
babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue] += 1;
this.publicFieldValue += 1;
babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue] = -(babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue] ** babelHelpers.classPrivateFieldLooseBase(this, _privateFieldValue)[_privateFieldValue]);
this.publicFieldValue = -(this.publicFieldValue ** this.publicFieldValue);
}
}, {
key: "publicFieldValue",
get: function () {
return this.publicField;
},
set: function (newValue) {
this.publicField = newValue;
}
}]);
return Cl;
}();
var _privateField = babelHelpers.classPrivateFieldLooseKey("privateField");
var _privateFieldValue = babelHelpers.classPrivateFieldLooseKey("privateFieldValue");
var _get_privateFieldValue = function () {
return babelHelpers.classPrivateFieldLooseBase(this, _privateField)[_privateField];
};
var _set_privateFieldValue = function (newValue) {
babelHelpers.classPrivateFieldLooseBase(this, _privateField)[_privateField] = newValue;
};

View File

@@ -0,0 +1,31 @@
class Cl {
#privateField = "top secret string";
constructor() {
this.publicField = "not secret string";
}
get #privateFieldValue() {
return this.#privateField;
}
set #privateFieldValue(newValue) {
this.#privateField = newValue;
}
publicGetPrivateField() {
return this.#privateFieldValue;
}
publicSetPrivateField(newValue) {
this.#privateFieldValue = newValue;
}
}
const cl = new Cl();
expect(cl.publicGetPrivateField()).toEqual("top secret string");
cl.publicSetPrivateField("new secret string");
expect(cl.publicGetPrivateField()).toEqual("new secret string");

View File

@@ -0,0 +1,23 @@
class Cl {
#privateField = "top secret string";
constructor() {
this.publicField = "not secret string";
}
get #privateFieldValue() {
return this.#privateField;
}
set #privateFieldValue(newValue) {
this.#privateField = newValue;
}
publicGetPrivateField() {
return this.#privateFieldValue;
}
publicSetPrivateField(newValue) {
this.#privateFieldValue = newValue;
}
}

View File

@@ -0,0 +1,46 @@
var Cl =
/*#__PURE__*/
function () {
"use strict";
function Cl() {
babelHelpers.classCallCheck(this, Cl);
_privateFieldValue.set(this, {
get: _get_privateFieldValue,
set: _set_privateFieldValue
});
_privateField.set(this, {
writable: true,
value: "top secret string"
});
this.publicField = "not secret string";
}
babelHelpers.createClass(Cl, [{
key: "publicGetPrivateField",
value: function publicGetPrivateField() {
return babelHelpers.classPrivateFieldGet(this, _privateFieldValue);
}
}, {
key: "publicSetPrivateField",
value: function publicSetPrivateField(newValue) {
babelHelpers.classPrivateFieldSet(this, _privateFieldValue, newValue);
}
}]);
return Cl;
}();
var _privateField = new WeakMap();
var _privateFieldValue = new WeakMap();
var _get_privateFieldValue = function () {
return babelHelpers.classPrivateFieldGet(this, _privateField);
};
var _set_privateFieldValue = function (newValue) {
babelHelpers.classPrivateFieldSet(this, _privateField, newValue);
};

View File

@@ -0,0 +1,13 @@
class Cl {
#privateField = 0;
set #privateFieldValue(newValue) {
this.#privateField = newValue;
}
constructor() {
expect(this.#privateFieldValue).toBeUndefined();
}
}
const cl = new Cl();

View File

@@ -0,0 +1,11 @@
class Cl {
#privateField = 0;
set #privateFieldValue(newValue) {
this.#privateField = newValue;
}
constructor() {
this.publicField = this.#privateFieldValue;
}
}

View File

@@ -0,0 +1,24 @@
var Cl = function Cl() {
"use strict";
babelHelpers.classCallCheck(this, Cl);
_privateFieldValue.set(this, {
set: _set_privateFieldValue
});
_privateField.set(this, {
writable: true,
value: 0
});
this.publicField = babelHelpers.classPrivateFieldGet(this, _privateFieldValue);
};
var _privateField = new WeakMap();
var _privateFieldValue = new WeakMap();
var _set_privateFieldValue = function (newValue) {
babelHelpers.classPrivateFieldSet(this, _privateField, newValue);
};

View File

@@ -0,0 +1,11 @@
let foo;
class Cl {
set #foo(v) { return 1 }
test() {
foo = this.#foo = 2;
}
}
new Cl().test();
expect(foo).toBe(2);

View File

@@ -0,0 +1,15 @@
{
"plugins": [
[
"external-helpers",
{
"helperVersion": "7.1000.0"
}
],
"proposal-private-methods",
"proposal-class-properties",
"transform-classes",
"transform-block-scoping",
"syntax-class-properties"
]
}

View File

@@ -0,0 +1,13 @@
class Cl {
#privateField = 0;
get #privateFieldValue() {
return this.#privateField;
}
constructor() {
expect(() => this.#privateFieldValue = 1).toThrow(TypeError);
}
}
const cl = new Cl();

View File

@@ -0,0 +1,11 @@
class Cl {
#privateField = 0;
get #privateFieldValue() {
return this.#privateField;
}
constructor() {
this.#privateFieldValue = 1;
}
}

View File

@@ -0,0 +1,24 @@
var Cl = function Cl() {
"use strict";
babelHelpers.classCallCheck(this, Cl);
_privateFieldValue.set(this, {
get: _get_privateFieldValue
});
_privateField.set(this, {
writable: true,
value: 0
});
babelHelpers.classPrivateMethodSet();
};
var _privateField = new WeakMap();
var _privateFieldValue = new WeakMap();
var _get_privateFieldValue = function () {
return babelHelpers.classPrivateFieldGet(this, _privateField);
};

View File

@@ -0,0 +1,50 @@
class Cl {
#privateField = "top secret string";
constructor() {
this.publicField = "not secret string";
}
get #privateFieldValue() {
return this.#privateField;
}
set #privateFieldValue(newValue) {
this.#privateField = newValue;
}
publicGetPrivateField() {
return this.#privateFieldValue;
}
publicSetPrivateField(newValue) {
this.#privateFieldValue = newValue;
}
get publicFieldValue() {
return this.publicField;
}
set publicFieldValue(newValue) {
this.publicField = newValue;
}
testUpdates() {
this.#privateField = 0;
this.publicField = 0;
this.#privateFieldValue = this.#privateFieldValue++;
this.publicFieldValue = this.publicFieldValue++;
expect(this.#privateField).toEqual(this.publicField);
++this.#privateFieldValue;
++this.publicFieldValue;
expect(this.#privateField).toEqual(this.publicField);
this.#privateFieldValue += 1;
this.publicFieldValue += 1;
expect(this.#privateField).toEqual(this.publicField);
}
}
const cl = new Cl();
cl.testUpdates();

View File

@@ -0,0 +1,47 @@
class Cl {
#privateField = "top secret string";
constructor() {
this.publicField = "not secret string";
}
get #privateFieldValue() {
return this.#privateField;
}
set #privateFieldValue(newValue) {
this.#privateField = newValue;
}
publicGetPrivateField() {
return this.#privateFieldValue;
}
publicSetPrivateField(newValue) {
this.#privateFieldValue = newValue;
}
get publicFieldValue() {
return this.publicField;
}
set publicFieldValue(newValue) {
this.publicField = newValue;
}
testUpdates() {
this.#privateField = 0;
this.publicField = 0;
this.#privateFieldValue = this.#privateFieldValue++;
this.publicFieldValue = this.publicFieldValue++;
++this.#privateFieldValue;
++this.publicFieldValue;
this.#privateFieldValue += 1;
this.publicFieldValue += 1;
this.#privateFieldValue = -(this.#privateFieldValue ** this.#privateFieldValue);
this.publicFieldValue = -(this.publicFieldValue ** this.publicFieldValue);
}
}

View File

@@ -0,0 +1,70 @@
var Cl =
/*#__PURE__*/
function () {
"use strict";
function Cl() {
babelHelpers.classCallCheck(this, Cl);
_privateFieldValue.set(this, {
get: _get_privateFieldValue,
set: _set_privateFieldValue
});
_privateField.set(this, {
writable: true,
value: "top secret string"
});
this.publicField = "not secret string";
}
babelHelpers.createClass(Cl, [{
key: "publicGetPrivateField",
value: function publicGetPrivateField() {
return babelHelpers.classPrivateFieldGet(this, _privateFieldValue);
}
}, {
key: "publicSetPrivateField",
value: function publicSetPrivateField(newValue) {
babelHelpers.classPrivateFieldSet(this, _privateFieldValue, newValue);
}
}, {
key: "testUpdates",
value: function testUpdates() {
var _this$privateFieldVal, _this$privateFieldVal2;
babelHelpers.classPrivateFieldSet(this, _privateField, 0);
this.publicField = 0;
babelHelpers.classPrivateFieldSet(this, _privateFieldValue, (babelHelpers.classPrivateFieldSet(this, _privateFieldValue, (_this$privateFieldVal2 = +babelHelpers.classPrivateFieldGet(this, _privateFieldValue)) + 1), _this$privateFieldVal2));
this.publicFieldValue = this.publicFieldValue++;
babelHelpers.classPrivateFieldSet(this, _privateFieldValue, +babelHelpers.classPrivateFieldGet(this, _privateFieldValue) + 1);
++this.publicFieldValue;
babelHelpers.classPrivateFieldSet(this, _privateFieldValue, babelHelpers.classPrivateFieldGet(this, _privateFieldValue) + 1);
this.publicFieldValue += 1;
babelHelpers.classPrivateFieldSet(this, _privateFieldValue, -(babelHelpers.classPrivateFieldGet(this, _privateFieldValue) ** babelHelpers.classPrivateFieldGet(this, _privateFieldValue)));
this.publicFieldValue = -(this.publicFieldValue ** this.publicFieldValue);
}
}, {
key: "publicFieldValue",
get: function () {
return this.publicField;
},
set: function (newValue) {
this.publicField = newValue;
}
}]);
return Cl;
}();
var _privateField = new WeakMap();
var _privateFieldValue = new WeakMap();
var _get_privateFieldValue = function () {
return babelHelpers.classPrivateFieldGet(this, _privateField);
};
var _set_privateFieldValue = function (newValue) {
babelHelpers.classPrivateFieldSet(this, _privateField, newValue);
};

View File

@@ -0,0 +1,11 @@
class Cl {
#privateField = 0;
get #getSet() {
return this.#privateField;
}
get #getSet() {
return this.#privateField;
}
}

View File

@@ -0,0 +1,3 @@
{
"throws": "Duplicate private field"
}

View File

@@ -0,0 +1,11 @@
class Cl {
#privateField = 0;
get #foo() {
return this.#privateField;
}
#foo() {
return 'foo';
}
}

View File

@@ -0,0 +1,3 @@
{
"throws": "Duplicate private field"
}

View File

@@ -0,0 +1,11 @@
class Cl {
#privateField = 0;
get #getSet() {
return this.#privateField;
}
set #getSet(newValue) {
this.#privateField = newValue;
}
}

View File

@@ -0,0 +1,27 @@
var Cl = function Cl() {
"use strict";
babelHelpers.classCallCheck(this, Cl);
_getSet.set(this, {
get: _get_getSet,
set: _set_getSet
});
_privateField.set(this, {
writable: true,
value: 0
});
};
var _privateField = new WeakMap();
var _getSet = new WeakMap();
var _get_getSet = function () {
return babelHelpers.classPrivateFieldGet(this, _privateField);
};
var _set_getSet = function (newValue) {
babelHelpers.classPrivateFieldSet(this, _privateField, newValue);
};

View File

@@ -0,0 +1,11 @@
class Cl {
#privateField = 0;
#foo() {
return 'foo';
}
get #foo() {
return this.#privateField;
}
}

View File

@@ -0,0 +1,3 @@
{
"throws": "Duplicate private field"
}

View File

@@ -0,0 +1,10 @@
class Cl {
#dank() {
return 'foo';
}
#dank() {
return 'foo';
}
}

View File

@@ -0,0 +1,3 @@
{
"throws": "Duplicate private field"
}

View File

@@ -0,0 +1,11 @@
class Cl {
#privateField = 0;
#foo() {
return 'foo';
}
set #foo(newValue) {
this.#privateField = newValue;
}
}

View File

@@ -0,0 +1,3 @@
{
"throws": "Duplicate private field"
}

View File

@@ -0,0 +1,15 @@
{
"plugins": [
[
"external-helpers",
{
"helperVersion": "7.1000.0"
}
],
"proposal-private-methods",
"proposal-class-properties",
"transform-classes",
"transform-block-scoping",
"syntax-class-properties"
]
}

View File

@@ -0,0 +1,11 @@
class Cl {
#privateField = 0;
set #getSet(newValue) {
this.#privateField = newValue;
}
get #getSet() {
return this.#privateField;
}
}

View File

@@ -0,0 +1,27 @@
var Cl = function Cl() {
"use strict";
babelHelpers.classCallCheck(this, Cl);
_getSet.set(this, {
get: _get_getSet,
set: _set_getSet
});
_privateField.set(this, {
writable: true,
value: 0
});
};
var _privateField = new WeakMap();
var _getSet = new WeakMap();
var _set_getSet = function (newValue) {
babelHelpers.classPrivateFieldSet(this, _privateField, newValue);
};
var _get_getSet = function () {
return babelHelpers.classPrivateFieldGet(this, _privateField);
};

View File

@@ -0,0 +1,11 @@
class Cl {
#privateField = 0;
set #foo(newValue) {
this.#privateField = newValue;
}
#foo() {
return 'foo';
}
}

View File

@@ -0,0 +1,3 @@
{
"throws": "Duplicate private field"
}

View File

@@ -0,0 +1,11 @@
class Cl {
#privateField = 0;
set #getSet(newValue) {
return this.#privateField;
}
set #getSet(newValue) {
return this.#privateField;
}
}

View File

@@ -0,0 +1,3 @@
{
"throws": "Duplicate private field"
}

View File

@@ -3,7 +3,7 @@
[
"external-helpers",
{
"helperVersion": "7.1.6"
"helperVersion": "7.1000.0"
}
],
["proposal-private-methods", { "loose": true }],

View File

@@ -3,7 +3,7 @@
[
"external-helpers",
{
"helperVersion": "7.1.6"
"helperVersion": "7.1000.0"
}
],
"proposal-private-methods",