mirror of https://github.com/tc39/test262.git
[decorators] Support private auto-accessors
Support for the accessor keywords for private class fields as part of the decorators proposal. Changes to AST: - Add an AUTO_ACCESSOR value to the ClassLiteralProperty::Kind enum. - Add an AutoAccessorInfo class to be used in ClassLiteralProperty objects of kind AUTO_ACCESSOR to hold the information about the generated getters/setters and backing storage. - Add AutoAccessorGetterBody and AutoAccessorSetterBody statements to implement the logic of generated getters and setters. Changes to Parser: - Add logic to parse the "accessor" keyword and throw when used on non field class properties. - Add preparser logic to mock the function scopes and variable declarations required for the generated getters/setters. - Add parser logic to synthetically create statements for the generated setters/getters. Changes to the Bytecode Generator: - Add logic to BuildClassLiteral to build auto accessor storage private names. - Add logic to set the generated getters/setters in the accessor pair. - Add logic to initialize the accessor storage in BuildClassProperty. - Add AutoAccessorGetterBody and AutoAccessorSetterBody visitors. Tests: - Add parsing-unittests for parsing converage. - Add test262 tests for functionality coverage. - Add test-debug test for devtools support coverage. Bug: 42202709 Change-Id: Ibb9bee3bbd0c09341108856f969e0c22bbb8b9cc Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5547688 Reviewed-by: Seth Brenith <seth.brenith@microsoft.com> Commit-Queue: Luis Pardo <lpardosixtos@microsoft.com> Reviewed-by: Shu-yu Guo <syg@chromium.org> Cr-Commit-Position: refs/heads/main@{#95612}
This commit is contained in:
parent
bcb42e339d
commit
2020cfbe66
|
@ -0,0 +1,106 @@
|
|||
// Copyright 2024 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Test private auto-accessors.
|
||||
features: [decorators]
|
||||
---*/
|
||||
|
||||
(function TestUninitializedPrivateAccessor() {
|
||||
class C {
|
||||
accessor #x;
|
||||
assertFieldIsUndefined() {
|
||||
assert.sameValue(this.#x, undefined);
|
||||
}
|
||||
assertFieldMatchesValue(value) {
|
||||
assert.sameValue(this.#x, value);
|
||||
}
|
||||
setField(value) {
|
||||
this.#x = value;
|
||||
}
|
||||
}
|
||||
let c = new C();
|
||||
c.assertFieldIsUndefined();
|
||||
c.setField(42);
|
||||
c.assertFieldMatchesValue(42);
|
||||
})();
|
||||
|
||||
(function TestInitializedPrivateAccessor() {
|
||||
class C {
|
||||
accessor #x = 5;
|
||||
assertFieldMatchesValue(value) {
|
||||
assert.sameValue(this.#x, value);
|
||||
}
|
||||
setField(value) {
|
||||
this.#x = value;
|
||||
}
|
||||
}
|
||||
let c = new C();
|
||||
c.assertFieldMatchesValue(5);
|
||||
c.setField(42);
|
||||
c.assertFieldMatchesValue(42);
|
||||
})();
|
||||
|
||||
(function TestInitializedMultiplePrivateAccessor() {
|
||||
class C {
|
||||
accessor #x = 5;
|
||||
accessor #y = 42;
|
||||
assertFieldsMatcheValues(value_x, value_y) {
|
||||
assert.sameValue(this.#x, value_x);
|
||||
assert.sameValue(this.#y, value_y);
|
||||
}
|
||||
}
|
||||
let c = new C();
|
||||
c.assertFieldsMatcheValues(5, 42);
|
||||
})();
|
||||
|
||||
(function TestThrowOnDuplicatedName() {
|
||||
// Auto-accessors will instantiate private getter and setter with the same
|
||||
// name, which shouldn't collide with other private variables.
|
||||
let assertThrowsSyntaxError = (code_string) => {
|
||||
assert.throws(SyntaxError, () => {eval(code_string)});
|
||||
};
|
||||
assertThrowsSyntaxError('class C { accessor #x = 5; accessor #x = 42; }');
|
||||
assertThrowsSyntaxError('class C { accessor #x = 5; #x = 42; }');
|
||||
assertThrowsSyntaxError('class C { accessor #x = 5; get #x() {}; }');
|
||||
assertThrowsSyntaxError('class C { accessor #x = 5; set #x(value) {}; }');
|
||||
assertThrowsSyntaxError('class C { accessor #x = 5; #x() {}; }');
|
||||
assertThrowsSyntaxError('class C { accessor #x = 5; static #x = 42; }');
|
||||
assertThrowsSyntaxError('class C { static accessor #x = 5; #x = 42; }');
|
||||
assertThrowsSyntaxError(
|
||||
'class C { static accessor #x = 5; static #x = 42; }');
|
||||
})();
|
||||
|
||||
(function TestUninitializedStaticPrivateAccessor() {
|
||||
class C {
|
||||
static #x;
|
||||
static assertFieldIsUndefined() {
|
||||
assert.sameValue(C.#x, undefined);
|
||||
}
|
||||
static assertFieldMatchesValue(value) {
|
||||
assert.sameValue(C.#x, value);
|
||||
}
|
||||
static setField(value) {
|
||||
C.#x = value;
|
||||
}
|
||||
}
|
||||
C.assertFieldIsUndefined();
|
||||
C.setField(42);
|
||||
C.assertFieldMatchesValue(42);
|
||||
})();
|
||||
|
||||
(function TestInitializedStaticPrivateAccessor() {
|
||||
class C {
|
||||
static accessor #x = 5;
|
||||
static assertFieldMatchesValue(value) {
|
||||
assert.sameValue(C.#x, value);
|
||||
}
|
||||
static setField(value) {
|
||||
C.#x = value;
|
||||
}
|
||||
}
|
||||
C.assertFieldMatchesValue(5);
|
||||
C.setField(42);
|
||||
C.assertFieldMatchesValue(42);
|
||||
})();
|
Loading…
Reference in New Issue