From ae45c3d562354b208c12077163e0fcc7e0ce668d Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 6 Dec 2023 18:49:51 -0500 Subject: [PATCH 1/3] Add tests for Stage 3 Decorator Metadata --- features.txt | 4 ++ .../Function/prototype/Symbol.metadata.js | 19 ++++++ test/built-ins/Symbol/metadata/cross-realm.js | 14 +++++ test/built-ins/Symbol/metadata/prop-desc.js | 17 ++++++ .../metadata/context-metadata-prop-desc.js | 25 ++++++++ .../decorator/metadata/context-metadata.js | 59 +++++++++++++++++++ ...tadata-attached-when-class-is-decorated.js | 43 ++++++++++++++ ...e-not-affected-by-setPrototype-on-class.js | 45 ++++++++++++++ ...ot-affected-when-base-metadata-replaced.js | 45 ++++++++++++++ .../metadata/metadata-inheritance.js | 42 +++++++++++++ .../metadata/metadata-is-plain-object.js | 32 ++++++++++ .../metadata-is-same-as-context-metadata.js | 47 +++++++++++++++ .../decorator/metadata/metadata-prop-desc.js | 25 ++++++++ .../metadata/context-metadata-prop-desc.js | 25 ++++++++ .../decorator/metadata/context-metadata.js | 59 +++++++++++++++++++ ...tadata-attached-when-class-is-decorated.js | 43 ++++++++++++++ ...e-not-affected-by-setPrototype-on-class.js | 45 ++++++++++++++ ...ot-affected-when-base-metadata-replaced.js | 45 ++++++++++++++ .../metadata/metadata-inheritance.js | 42 +++++++++++++ .../metadata/metadata-is-plain-object.js | 32 ++++++++++ .../metadata-is-same-as-context-metadata.js | 47 +++++++++++++++ .../decorator/metadata/metadata-prop-desc.js | 25 ++++++++ 22 files changed, 780 insertions(+) create mode 100644 test/built-ins/Function/prototype/Symbol.metadata.js create mode 100644 test/built-ins/Symbol/metadata/cross-realm.js create mode 100644 test/built-ins/Symbol/metadata/prop-desc.js create mode 100644 test/language/expressions/class/decorator/metadata/context-metadata-prop-desc.js create mode 100644 test/language/expressions/class/decorator/metadata/context-metadata.js create mode 100644 test/language/expressions/class/decorator/metadata/metadata-attached-when-class-is-decorated.js create mode 100644 test/language/expressions/class/decorator/metadata/metadata-inheritance-not-affected-by-setPrototype-on-class.js create mode 100644 test/language/expressions/class/decorator/metadata/metadata-inheritance-not-affected-when-base-metadata-replaced.js create mode 100644 test/language/expressions/class/decorator/metadata/metadata-inheritance.js create mode 100644 test/language/expressions/class/decorator/metadata/metadata-is-plain-object.js create mode 100644 test/language/expressions/class/decorator/metadata/metadata-is-same-as-context-metadata.js create mode 100644 test/language/expressions/class/decorator/metadata/metadata-prop-desc.js create mode 100644 test/language/statements/class/decorator/metadata/context-metadata-prop-desc.js create mode 100644 test/language/statements/class/decorator/metadata/context-metadata.js create mode 100644 test/language/statements/class/decorator/metadata/metadata-attached-when-class-is-decorated.js create mode 100644 test/language/statements/class/decorator/metadata/metadata-inheritance-not-affected-by-setPrototype-on-class.js create mode 100644 test/language/statements/class/decorator/metadata/metadata-inheritance-not-affected-when-base-metadata-replaced.js create mode 100644 test/language/statements/class/decorator/metadata/metadata-inheritance.js create mode 100644 test/language/statements/class/decorator/metadata/metadata-is-plain-object.js create mode 100644 test/language/statements/class/decorator/metadata/metadata-is-same-as-context-metadata.js create mode 100644 test/language/statements/class/decorator/metadata/metadata-prop-desc.js diff --git a/features.txt b/features.txt index 6004cca4bf8..d911d88a4d4 100644 --- a/features.txt +++ b/features.txt @@ -77,6 +77,10 @@ regexp-v-flag # https://github.com/tc39/proposal-decorators decorators +# Decorator Metadata +# https://github.com/tc39/proposal-decorator-metadata +decorator-metadata + # Duplicate named capturing groups # https://github.com/tc39/proposal-duplicate-named-capturing-groups regexp-duplicate-named-groups diff --git a/test/built-ins/Function/prototype/Symbol.metadata.js b/test/built-ins/Function/prototype/Symbol.metadata.js new file mode 100644 index 00000000000..f604ae19b49 --- /dev/null +++ b/test/built-ins/Function/prototype/Symbol.metadata.js @@ -0,0 +1,19 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-function.prototype-@@metadata +description: Function.prototype[Symbol.metadata] property descriptor +info: | + The initial value of the @@metadata property is null. + This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: false }. +includes: [propertyHelper.js] +features: [decorator-metadata] +---*/ + +verifyProperty(Function.prototype, Symbol.metadata, { + value: null, + writable: false, + enumerable: false, + configurable: false +}); diff --git a/test/built-ins/Symbol/metadata/cross-realm.js b/test/built-ins/Symbol/metadata/cross-realm.js new file mode 100644 index 00000000000..59e4c0ddedc --- /dev/null +++ b/test/built-ins/Symbol/metadata/cross-realm.js @@ -0,0 +1,14 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-symbol.metadata +description: Value shared by all realms +info: | + Unless otherwise specified, well-known symbols values are shared by all + realms. +features: [cross-realm, decorator-metadata] +---*/ + +var OSymbol = $262.createRealm().global.Symbol; + +assert.sameValue(Symbol.metadata, OSymbol.metadata); diff --git a/test/built-ins/Symbol/metadata/prop-desc.js b/test/built-ins/Symbol/metadata/prop-desc.js new file mode 100644 index 00000000000..897f9a9ecd8 --- /dev/null +++ b/test/built-ins/Symbol/metadata/prop-desc.js @@ -0,0 +1,17 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-symbol.metadata +description: > + `Symbol.metadata` property descriptor +info: | + This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: false }. +includes: [propertyHelper.js] +features: [decorator-metadata] +---*/ + +assert.sameValue(typeof Symbol.metadata, 'symbol'); +verifyNotEnumerable(Symbol, 'metadata'); +verifyNotWritable(Symbol, 'metadata'); +verifyNotConfigurable(Symbol, 'metadata'); diff --git a/test/language/expressions/class/decorator/metadata/context-metadata-prop-desc.js b/test/language/expressions/class/decorator/metadata/context-metadata-prop-desc.js new file mode 100644 index 00000000000..44278f0152b --- /dev/null +++ b/test/language/expressions/class/decorator/metadata/context-metadata-prop-desc.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-createdecoratorcontextobject +description: > + Property descriptor for metadata property of decorator context object. +info: | + CreateDecoratorContextObject ( kind, name, initializers, decorationState, metadataObj [ , isStatic ] ) + [...] + 13. Perform ! CreateDataPropertyOrThrow(contextObj, "metadata", metadata). + 14. Return contextObj. +includes: [propertyHelper.js] +features: [decorators, decorator-metadata] +---*/ + +var contextObj; +function dec(_, context) { + contextObj = context; +} + +void @dec class C {}; +assert.sameValue(typeof contextObj.metadata, "object"); +verifyNotEnumerable(contextObj, "metadata"); +verifyWritable(contextObj, "metadata"); +verifyConfigurable(contextObj, "metadata"); diff --git a/test/language/expressions/class/decorator/metadata/context-metadata.js b/test/language/expressions/class/decorator/metadata/context-metadata.js new file mode 100644 index 00000000000..12146481d39 --- /dev/null +++ b/test/language/expressions/class/decorator/metadata/context-metadata.js @@ -0,0 +1,59 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-createdecoratorcontextobject +description: > + Property descriptor for metadata property of decorator context object. +info: | + CreateDecoratorContextObject ( kind, name, initializers, decorationState, metadataObj [ , isStatic ] ) + [...] + 13. Perform ! CreateDataPropertyOrThrow(contextObj, "metadata", metadata). + 14. Return contextObj. +includes: [deepEqual.js] +features: [decorators, decorator-metadata] +---*/ + +var kinds = { + "class": false, + "public method": false, + "public getter": false, + "public setter": false, + "public field": false, + "public accessor": false, + "private method": false, + "private getter": false, + "private setter": false, + "private field": false, + "private accessor": false, +}; +function dec(_, context) { + const key = `${context.private ? "private" : "public"} ${context.kind}`; + kinds[key] = typeof context.metadata === "object"; +} + +void @dec class C { + @dec method() {} + @dec get getter() {} + @dec set setter(x) {} + @dec field; + @dec accessor accessor; + @dec #method() {} + @dec get #getter() {} + @dec set #setter(x) {} + @dec #field; + @dec accessor #accessor; +}; + +assert.deepEqual(kinds, { + "class": true, + "public method": true, + "public getter": true, + "public setter": true, + "public field": true, + "public accessor": true, + "private method": true, + "private getter": true, + "private setter": true, + "private field": true, + "private accessor": true, +}); diff --git a/test/language/expressions/class/decorator/metadata/metadata-attached-when-class-is-decorated.js b/test/language/expressions/class/decorator/metadata/metadata-attached-when-class-is-decorated.js new file mode 100644 index 00000000000..558ea5c6f47 --- /dev/null +++ b/test/language/expressions/class/decorator/metadata/metadata-attached-when-class-is-decorated.js @@ -0,0 +1,43 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-runtime-semantics-classdefinitionevaluation +description: > + Metadata is only attached when a class or class element is decorated. +info: | + ClassTail : ClassHeritage_opt { ClassBody_opt } + 21. Let hasDecorators be false. + 22. If decorators is not empty, set hasDecorators to true. + [...] + 25. For each ClassElement e of elements, do + [...] + e. If element is a ClassElementDefinition Record, then + i. If e.[[Decorators]] is not empty, set hasDecorators to true. + [...] + [...] + 29. Let metadataObj be empty. + 30. If hasDecorators is true, then + a. If ClassHeritage is present, [...] + b. Else, let metadataParent be null. + c. Set metadataObj to OrdinaryObjectCreate(metadataParent). + [...] + 41. If metadataObj is not empty, then + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + 1. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 1. Return ? _setMetadataResult_. + [...] +features: [decorators, decorator-metadata] +---*/ + +function dec() {} + +let C1 = @dec class C1 {}; +assert.sameValue(typeof C1[Symbol.metadata], "object"); + +let C2 = class C2 { @dec method() {} }; +assert.sameValue(typeof C2[Symbol.metadata], "object"); + +let C3 = class C3 {}; +assert.sameValue(typeof C3[Symbol.metadata], "undefined"); diff --git a/test/language/expressions/class/decorator/metadata/metadata-inheritance-not-affected-by-setPrototype-on-class.js b/test/language/expressions/class/decorator/metadata/metadata-inheritance-not-affected-by-setPrototype-on-class.js new file mode 100644 index 00000000000..4d133108e8c --- /dev/null +++ b/test/language/expressions/class/decorator/metadata/metadata-inheritance-not-affected-by-setPrototype-on-class.js @@ -0,0 +1,45 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-runtime-semantics-classdefinitionevaluation +description: > + Metadata on a derived class inherits from the metadata of the declared super class. +info: | + ClassTail : ClassHeritage_opt { ClassBody_opt } + 21. Let hasDecorators be false. + 22. If decorators is not empty, set hasDecorators to true. + [...] + 25. For each ClassElement e of elements, do + [...] + e. If element is a ClassElementDefinition Record, then + i. If e.[[Decorators]] is not empty, set hasDecorators to true. + [...] + [...] + 29. Let metadataObj be empty. + 30. If hasDecorators is true, then + a. If ClassHeritage is present, [...] + b. Else, let metadataParent be null. + c. Set metadataObj to OrdinaryObjectCreate(metadataParent). + [...] + 41. If metadataObj is not empty, then + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + 1. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 1. Return ? _setMetadataResult_. + [...] +features: [decorators, decorator-metadata] +---*/ + +function dec() {} + +class UndecoratedBase {} + +let Base = @dec class Base {}; +const baseMetadata = Base[Symbol.metadata]; + +let Derived = @dec class Derived extends Base { }; +Object.setPrototypeOf(Derived, UndecoratedBase); + +const derivedMetadata = Derived[Symbol.metadata]; +assert.sameValue(Object.getPrototypeOf(derivedMetadata), baseMetadata); diff --git a/test/language/expressions/class/decorator/metadata/metadata-inheritance-not-affected-when-base-metadata-replaced.js b/test/language/expressions/class/decorator/metadata/metadata-inheritance-not-affected-when-base-metadata-replaced.js new file mode 100644 index 00000000000..458bd0d65c3 --- /dev/null +++ b/test/language/expressions/class/decorator/metadata/metadata-inheritance-not-affected-when-base-metadata-replaced.js @@ -0,0 +1,45 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-runtime-semantics-classdefinitionevaluation +description: > + Metadata on a derived class inherits from the metadata of the declared super class. +info: | + ClassTail : ClassHeritage_opt { ClassBody_opt } + 21. Let hasDecorators be false. + 22. If decorators is not empty, set hasDecorators to true. + [...] + 25. For each ClassElement e of elements, do + [...] + e. If element is a ClassElementDefinition Record, then + i. If e.[[Decorators]] is not empty, set hasDecorators to true. + [...] + [...] + 29. Let metadataObj be empty. + 30. If hasDecorators is true, then + a. If ClassHeritage is present, [...] + b. Else, let metadataParent be null. + c. Set metadataObj to OrdinaryObjectCreate(metadataParent). + [...] + 41. If metadataObj is not empty, then + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + 1. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 1. Return ? _setMetadataResult_. + [...] +features: [decorators, decorator-metadata] +---*/ + +function dec() {} + +class UndecoratedBase {} + +let Base = @dec class Base {}; +const baseMetadata = Base[Symbol.metadata]; + +let Derived = @dec class Derived extends Base { }; +Base[Symbol.metadata] = {}; + +const derivedMetadata = Derived[Symbol.metadata]; +assert.sameValue(Object.getPrototypeOf(derivedMetadata), baseMetadata); diff --git a/test/language/expressions/class/decorator/metadata/metadata-inheritance.js b/test/language/expressions/class/decorator/metadata/metadata-inheritance.js new file mode 100644 index 00000000000..3af3b9fd88a --- /dev/null +++ b/test/language/expressions/class/decorator/metadata/metadata-inheritance.js @@ -0,0 +1,42 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-runtime-semantics-classdefinitionevaluation +description: > + Metadata is only attached when a class or class element is decorated. +info: | + ClassTail : ClassHeritage_opt { ClassBody_opt } + 21. Let hasDecorators be false. + 22. If decorators is not empty, set hasDecorators to true. + [...] + 25. For each ClassElement e of elements, do + [...] + e. If element is a ClassElementDefinition Record, then + i. If e.[[Decorators]] is not empty, set hasDecorators to true. + [...] + [...] + 29. Let metadataObj be empty. + 30. If hasDecorators is true, then + a. If ClassHeritage is present, [...] + b. Else, let metadataParent be null. + c. Set metadataObj to OrdinaryObjectCreate(metadataParent). + [...] + 41. If metadataObj is not empty, then + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + 1. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 1. Return ? _setMetadataResult_. + [...] +features: [decorators, decorator-metadata] +---*/ + +function dec() {} + +let Base = @dec class Base {}; +const baseMetadata = Base[Symbol.metadata]; +assert.sameValue(Object.getPrototypeOf(baseMetadata), null); + +let Derived = @dec class Derived extends Base { }; +const derivedMetadata = Derived[Symbol.metadata]; +assert.sameValue(Object.getPrototypeOf(derivedMetadata), baseMetadata); diff --git a/test/language/expressions/class/decorator/metadata/metadata-is-plain-object.js b/test/language/expressions/class/decorator/metadata/metadata-is-plain-object.js new file mode 100644 index 00000000000..ba795e7266e --- /dev/null +++ b/test/language/expressions/class/decorator/metadata/metadata-is-plain-object.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-runtime-semantics-classdefinitionevaluation +description: > + The metadata object is a regular, extensible JS object. +info: | + ClassTail : ClassHeritage_opt { ClassBody_opt } + 21. Let hasDecorators be false. + 22. If decorators is not empty, set hasDecorators to true. + [...] + 25. For each ClassElement e of elements, do + [...] + e. If element is a ClassElementDefinition Record, then + i. If e.[[Decorators]] is not empty, set hasDecorators to true. + [...] + [...] + 29. Let metadataObj be empty. + 30. If hasDecorators is true, then + a. If ClassHeritage is present, [...] + b. Else, let metadataParent be null. + c. Set metadataObj to OrdinaryObjectCreate(metadataParent). + [...] +features: [decorators, decorator-metadata] +---*/ + +function dec() {} + +let C = @dec class C {}; +const metadata = C[Symbol.metadata]; +assert(Object.isExtensible(metadata)); diff --git a/test/language/expressions/class/decorator/metadata/metadata-is-same-as-context-metadata.js b/test/language/expressions/class/decorator/metadata/metadata-is-same-as-context-metadata.js new file mode 100644 index 00000000000..53fce57f722 --- /dev/null +++ b/test/language/expressions/class/decorator/metadata/metadata-is-same-as-context-metadata.js @@ -0,0 +1,47 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-runtime-semantics-classdefinitionevaluation +description: > + The metadata object provided to a decorator is the same one installed on the class. +info: | + CreateDecoratorContextObject ( kind, name, initializers, decorationState, metadataObj [ , isStatic ] ) + + [...] + 13. Perform ! CreateDataPropertyOrThrow(contextObj, "metadata", metadata). + 14. Return contextObj. + + ClassDefinitionEvaluation + ClassTail : ClassHeritage_opt { ClassBody_opt } + + 21. Let hasDecorators be false. + 22. If decorators is not empty, set hasDecorators to true. + [...] + 25. For each ClassElement e of elements, do + [...] + e. If element is a ClassElementDefinition Record, then + i. If e.[[Decorators]] is not empty, set hasDecorators to true. + [...] + [...] + 29. Let metadataObj be empty. + 30. If hasDecorators is true, then + a. If ClassHeritage is present, [...] + b. Else, let metadataParent be null. + c. Set metadataObj to OrdinaryObjectCreate(metadataParent). + [...] + 41. If metadataObj is not empty, then + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + 1. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 1. Return ? _setMetadataResult_. + [...] +features: [decorators, decorator-metadata] +---*/ + +var contextObj; +function dec(_, context) { + contextObj = context; +} + +let C = @dec class C {}; +assert.sameValue(C[Symbol.metadata], contextObj.metadata); diff --git a/test/language/expressions/class/decorator/metadata/metadata-prop-desc.js b/test/language/expressions/class/decorator/metadata/metadata-prop-desc.js new file mode 100644 index 00000000000..41c95e0f1fe --- /dev/null +++ b/test/language/expressions/class/decorator/metadata/metadata-prop-desc.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-createdecoratorcontextobject +description: > + Property descriptor for metadata property of decorator context object. +info: | + CreateDecoratorContextObject ( kind, name, initializers, decorationState, metadataObj [ , isStatic ] ) + [...] + 13. Perform ! CreateDataPropertyOrThrow(contextObj, "metadata", metadata). + 14. Return contextObj. +includes: [propertyHelper.js] +features: [decorators, decorator-metadata] +---*/ + +var contextObj; +function dec(_, context) { + contextObj = context; +} + +let C = @dec class C {}; +assert.sameValue(typeof contextObj.metadata, "object"); +verifyNotEnumerable(contextObj, "metadata"); +verifyWritable(contextObj, "metadata"); +verifyConfigurable(contextObj, "metadata"); diff --git a/test/language/statements/class/decorator/metadata/context-metadata-prop-desc.js b/test/language/statements/class/decorator/metadata/context-metadata-prop-desc.js new file mode 100644 index 00000000000..2113eceb0fa --- /dev/null +++ b/test/language/statements/class/decorator/metadata/context-metadata-prop-desc.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-createdecoratorcontextobject +description: > + Property descriptor for metadata property of decorator context object. +info: | + CreateDecoratorContextObject ( kind, name, initializers, decorationState, metadataObj [ , isStatic ] ) + [...] + 13. Perform ! CreateDataPropertyOrThrow(contextObj, "metadata", metadata). + 14. Return contextObj. +includes: [propertyHelper.js] +features: [decorators, decorator-metadata] +---*/ + +var contextObj; +function dec(_, context) { + contextObj = context; +} + +@dec class C {} +assert.sameValue(typeof contextObj.metadata, "object"); +verifyNotEnumerable(contextObj, "metadata"); +verifyWritable(contextObj, "metadata"); +verifyConfigurable(contextObj, "metadata"); diff --git a/test/language/statements/class/decorator/metadata/context-metadata.js b/test/language/statements/class/decorator/metadata/context-metadata.js new file mode 100644 index 00000000000..0ba77765569 --- /dev/null +++ b/test/language/statements/class/decorator/metadata/context-metadata.js @@ -0,0 +1,59 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-createdecoratorcontextobject +description: > + Property descriptor for metadata property of decorator context object. +info: | + CreateDecoratorContextObject ( kind, name, initializers, decorationState, metadataObj [ , isStatic ] ) + [...] + 13. Perform ! CreateDataPropertyOrThrow(contextObj, "metadata", metadata). + 14. Return contextObj. +includes: [deepEqual.js] +features: [decorators, decorator-metadata] +---*/ + +var kinds = { + "class": false, + "public method": false, + "public getter": false, + "public setter": false, + "public field": false, + "public accessor": false, + "private method": false, + "private getter": false, + "private setter": false, + "private field": false, + "private accessor": false, +}; +function dec(_, context) { + const key = `${context.private ? "private" : "public"} ${context.kind}`; + kinds[key] = typeof context.metadata === "object"; +} + +@dec class C { + @dec method() {} + @dec get getter() {} + @dec set setter(x) {} + @dec field; + @dec accessor accessor; + @dec #method() {} + @dec get #getter() {} + @dec set #setter(x) {} + @dec #field; + @dec accessor #accessor; +} + +assert.deepEqual(kinds, { + "class": true, + "public method": true, + "public getter": true, + "public setter": true, + "public field": true, + "public accessor": true, + "private method": true, + "private getter": true, + "private setter": true, + "private field": true, + "private accessor": true, +}); diff --git a/test/language/statements/class/decorator/metadata/metadata-attached-when-class-is-decorated.js b/test/language/statements/class/decorator/metadata/metadata-attached-when-class-is-decorated.js new file mode 100644 index 00000000000..5136d41bf38 --- /dev/null +++ b/test/language/statements/class/decorator/metadata/metadata-attached-when-class-is-decorated.js @@ -0,0 +1,43 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-runtime-semantics-classdefinitionevaluation +description: > + Metadata is only attached when a class or class element is decorated. +info: | + ClassTail : ClassHeritage_opt { ClassBody_opt } + 21. Let hasDecorators be false. + 22. If decorators is not empty, set hasDecorators to true. + [...] + 25. For each ClassElement e of elements, do + [...] + e. If element is a ClassElementDefinition Record, then + i. If e.[[Decorators]] is not empty, set hasDecorators to true. + [...] + [...] + 29. Let metadataObj be empty. + 30. If hasDecorators is true, then + a. If ClassHeritage is present, [...] + b. Else, let metadataParent be null. + c. Set metadataObj to OrdinaryObjectCreate(metadataParent). + [...] + 41. If metadataObj is not empty, then + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + 1. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 1. Return ? _setMetadataResult_. + [...] +features: [decorators, decorator-metadata] +---*/ + +function dec() {} + +@dec class C1 {} +assert.sameValue(typeof C1[Symbol.metadata], "object"); + +class C2 { @dec method() {} } +assert.sameValue(typeof C2[Symbol.metadata], "object"); + +class C3 {} +assert.sameValue(typeof C3[Symbol.metadata], "undefined"); diff --git a/test/language/statements/class/decorator/metadata/metadata-inheritance-not-affected-by-setPrototype-on-class.js b/test/language/statements/class/decorator/metadata/metadata-inheritance-not-affected-by-setPrototype-on-class.js new file mode 100644 index 00000000000..daf2793204e --- /dev/null +++ b/test/language/statements/class/decorator/metadata/metadata-inheritance-not-affected-by-setPrototype-on-class.js @@ -0,0 +1,45 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-runtime-semantics-classdefinitionevaluation +description: > + Metadata on a derived class inherits from the metadata of the declared super class. +info: | + ClassTail : ClassHeritage_opt { ClassBody_opt } + 21. Let hasDecorators be false. + 22. If decorators is not empty, set hasDecorators to true. + [...] + 25. For each ClassElement e of elements, do + [...] + e. If element is a ClassElementDefinition Record, then + i. If e.[[Decorators]] is not empty, set hasDecorators to true. + [...] + [...] + 29. Let metadataObj be empty. + 30. If hasDecorators is true, then + a. If ClassHeritage is present, [...] + b. Else, let metadataParent be null. + c. Set metadataObj to OrdinaryObjectCreate(metadataParent). + [...] + 41. If metadataObj is not empty, then + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + 1. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 1. Return ? _setMetadataResult_. + [...] +features: [decorators, decorator-metadata] +---*/ + +function dec() {} + +class UndecoratedBase {} + +@dec class Base {} +const baseMetadata = Base[Symbol.metadata]; + +@dec class Derived extends Base { } +Object.setPrototypeOf(Derived, UndecoratedBase); + +const derivedMetadata = Derived[Symbol.metadata]; +assert.sameValue(Object.getPrototypeOf(derivedMetadata), baseMetadata); diff --git a/test/language/statements/class/decorator/metadata/metadata-inheritance-not-affected-when-base-metadata-replaced.js b/test/language/statements/class/decorator/metadata/metadata-inheritance-not-affected-when-base-metadata-replaced.js new file mode 100644 index 00000000000..8a2a464c0a3 --- /dev/null +++ b/test/language/statements/class/decorator/metadata/metadata-inheritance-not-affected-when-base-metadata-replaced.js @@ -0,0 +1,45 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-runtime-semantics-classdefinitionevaluation +description: > + Metadata on a derived class inherits from the metadata of the declared super class. +info: | + ClassTail : ClassHeritage_opt { ClassBody_opt } + 21. Let hasDecorators be false. + 22. If decorators is not empty, set hasDecorators to true. + [...] + 25. For each ClassElement e of elements, do + [...] + e. If element is a ClassElementDefinition Record, then + i. If e.[[Decorators]] is not empty, set hasDecorators to true. + [...] + [...] + 29. Let metadataObj be empty. + 30. If hasDecorators is true, then + a. If ClassHeritage is present, [...] + b. Else, let metadataParent be null. + c. Set metadataObj to OrdinaryObjectCreate(metadataParent). + [...] + 41. If metadataObj is not empty, then + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + 1. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 1. Return ? _setMetadataResult_. + [...] +features: [decorators, decorator-metadata] +---*/ + +function dec() {} + +class UndecoratedBase {} + +@dec class Base {} +const baseMetadata = Base[Symbol.metadata]; + +@dec class Derived extends Base { } +Base[Symbol.metadata] = {}; + +const derivedMetadata = Derived[Symbol.metadata]; +assert.sameValue(Object.getPrototypeOf(derivedMetadata), baseMetadata); diff --git a/test/language/statements/class/decorator/metadata/metadata-inheritance.js b/test/language/statements/class/decorator/metadata/metadata-inheritance.js new file mode 100644 index 00000000000..8c1f2ec5f5e --- /dev/null +++ b/test/language/statements/class/decorator/metadata/metadata-inheritance.js @@ -0,0 +1,42 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-runtime-semantics-classdefinitionevaluation +description: > + Metadata is only attached when a class or class element is decorated. +info: | + ClassTail : ClassHeritage_opt { ClassBody_opt } + 21. Let hasDecorators be false. + 22. If decorators is not empty, set hasDecorators to true. + [...] + 25. For each ClassElement e of elements, do + [...] + e. If element is a ClassElementDefinition Record, then + i. If e.[[Decorators]] is not empty, set hasDecorators to true. + [...] + [...] + 29. Let metadataObj be empty. + 30. If hasDecorators is true, then + a. If ClassHeritage is present, [...] + b. Else, let metadataParent be null. + c. Set metadataObj to OrdinaryObjectCreate(metadataParent). + [...] + 41. If metadataObj is not empty, then + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + 1. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 1. Return ? _setMetadataResult_. + [...] +features: [decorators, decorator-metadata] +---*/ + +function dec() {} + +@dec class Base {} +const baseMetadata = Base[Symbol.metadata]; +assert.sameValue(Object.getPrototypeOf(baseMetadata), null); + +@dec class Derived extends Base { } +const derivedMetadata = Derived[Symbol.metadata]; +assert.sameValue(Object.getPrototypeOf(derivedMetadata), baseMetadata); diff --git a/test/language/statements/class/decorator/metadata/metadata-is-plain-object.js b/test/language/statements/class/decorator/metadata/metadata-is-plain-object.js new file mode 100644 index 00000000000..b5e176e48e1 --- /dev/null +++ b/test/language/statements/class/decorator/metadata/metadata-is-plain-object.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-runtime-semantics-classdefinitionevaluation +description: > + The metadata object is a regular, extensible JS object. +info: | + ClassTail : ClassHeritage_opt { ClassBody_opt } + 21. Let hasDecorators be false. + 22. If decorators is not empty, set hasDecorators to true. + [...] + 25. For each ClassElement e of elements, do + [...] + e. If element is a ClassElementDefinition Record, then + i. If e.[[Decorators]] is not empty, set hasDecorators to true. + [...] + [...] + 29. Let metadataObj be empty. + 30. If hasDecorators is true, then + a. If ClassHeritage is present, [...] + b. Else, let metadataParent be null. + c. Set metadataObj to OrdinaryObjectCreate(metadataParent). + [...] +features: [decorators, decorator-metadata] +---*/ + +function dec() {} + +@dec class C {} +const metadata = C[Symbol.metadata]; +assert(Object.isExtensible(metadata)); diff --git a/test/language/statements/class/decorator/metadata/metadata-is-same-as-context-metadata.js b/test/language/statements/class/decorator/metadata/metadata-is-same-as-context-metadata.js new file mode 100644 index 00000000000..020f3a1bc07 --- /dev/null +++ b/test/language/statements/class/decorator/metadata/metadata-is-same-as-context-metadata.js @@ -0,0 +1,47 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-runtime-semantics-classdefinitionevaluation +description: > + The metadata object provided to a decorator is the same one installed on the class. +info: | + CreateDecoratorContextObject ( kind, name, initializers, decorationState, metadataObj [ , isStatic ] ) + + [...] + 13. Perform ! CreateDataPropertyOrThrow(contextObj, "metadata", metadata). + 14. Return contextObj. + + ClassDefinitionEvaluation + ClassTail : ClassHeritage_opt { ClassBody_opt } + + 21. Let hasDecorators be false. + 22. If decorators is not empty, set hasDecorators to true. + [...] + 25. For each ClassElement e of elements, do + [...] + e. If element is a ClassElementDefinition Record, then + i. If e.[[Decorators]] is not empty, set hasDecorators to true. + [...] + [...] + 29. Let metadataObj be empty. + 30. If hasDecorators is true, then + a. If ClassHeritage is present, [...] + b. Else, let metadataParent be null. + c. Set metadataObj to OrdinaryObjectCreate(metadataParent). + [...] + 41. If metadataObj is not empty, then + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + 1. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 1. Return ? _setMetadataResult_. + [...] +features: [decorators, decorator-metadata] +---*/ + +var contextObj; +function dec(_, context) { + contextObj = context; +} + +@dec class C {} +assert.sameValue(C[Symbol.metadata], contextObj.metadata); diff --git a/test/language/statements/class/decorator/metadata/metadata-prop-desc.js b/test/language/statements/class/decorator/metadata/metadata-prop-desc.js new file mode 100644 index 00000000000..2113eceb0fa --- /dev/null +++ b/test/language/statements/class/decorator/metadata/metadata-prop-desc.js @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-createdecoratorcontextobject +description: > + Property descriptor for metadata property of decorator context object. +info: | + CreateDecoratorContextObject ( kind, name, initializers, decorationState, metadataObj [ , isStatic ] ) + [...] + 13. Perform ! CreateDataPropertyOrThrow(contextObj, "metadata", metadata). + 14. Return contextObj. +includes: [propertyHelper.js] +features: [decorators, decorator-metadata] +---*/ + +var contextObj; +function dec(_, context) { + contextObj = context; +} + +@dec class C {} +assert.sameValue(typeof contextObj.metadata, "object"); +verifyNotEnumerable(contextObj, "metadata"); +verifyWritable(contextObj, "metadata"); +verifyConfigurable(contextObj, "metadata"); From 0f4987c2e7da3b008a2fc58556edfd0a8bdaae75 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 7 Dec 2023 12:07:57 -0500 Subject: [PATCH 2/3] PR feedback and corrections for metadata-prop-desc.js tests --- test/built-ins/Symbol/metadata/prop-desc.js | 9 ++++-- .../metadata/context-metadata-prop-desc.js | 8 +++-- .../decorator/metadata/context-metadata.js | 1 + ...tadata-attached-when-class-is-decorated.js | 4 ++- .../decorator/metadata/metadata-prop-desc.js | 26 +++++++++-------- .../metadata/context-metadata-prop-desc.js | 8 +++-- .../decorator/metadata/context-metadata.js | 1 + ...tadata-attached-when-class-is-decorated.js | 4 ++- .../decorator/metadata/metadata-prop-desc.js | 29 ++++++++++--------- 9 files changed, 54 insertions(+), 36 deletions(-) diff --git a/test/built-ins/Symbol/metadata/prop-desc.js b/test/built-ins/Symbol/metadata/prop-desc.js index 897f9a9ecd8..95201ae1513 100644 --- a/test/built-ins/Symbol/metadata/prop-desc.js +++ b/test/built-ins/Symbol/metadata/prop-desc.js @@ -12,6 +12,9 @@ features: [decorator-metadata] ---*/ assert.sameValue(typeof Symbol.metadata, 'symbol'); -verifyNotEnumerable(Symbol, 'metadata'); -verifyNotWritable(Symbol, 'metadata'); -verifyNotConfigurable(Symbol, 'metadata'); +verifyProperty(Symbol, 'metadata', { + writable: false, + enumerable: false, + configurable: false, +}); + diff --git a/test/language/expressions/class/decorator/metadata/context-metadata-prop-desc.js b/test/language/expressions/class/decorator/metadata/context-metadata-prop-desc.js index 44278f0152b..3b3a68c9d25 100644 --- a/test/language/expressions/class/decorator/metadata/context-metadata-prop-desc.js +++ b/test/language/expressions/class/decorator/metadata/context-metadata-prop-desc.js @@ -20,6 +20,8 @@ function dec(_, context) { void @dec class C {}; assert.sameValue(typeof contextObj.metadata, "object"); -verifyNotEnumerable(contextObj, "metadata"); -verifyWritable(contextObj, "metadata"); -verifyConfigurable(contextObj, "metadata"); +verifyProperty(contextObj, 'metadata', { + enumerable: false, + writable: true, + configurable: true, +}); diff --git a/test/language/expressions/class/decorator/metadata/context-metadata.js b/test/language/expressions/class/decorator/metadata/context-metadata.js index 12146481d39..b026dc21626 100644 --- a/test/language/expressions/class/decorator/metadata/context-metadata.js +++ b/test/language/expressions/class/decorator/metadata/context-metadata.js @@ -14,6 +14,7 @@ features: [decorators, decorator-metadata] ---*/ var kinds = { + __proto__: null, "class": false, "public method": false, "public getter": false, diff --git a/test/language/expressions/class/decorator/metadata/metadata-attached-when-class-is-decorated.js b/test/language/expressions/class/decorator/metadata/metadata-attached-when-class-is-decorated.js index 558ea5c6f47..26862ec7224 100644 --- a/test/language/expressions/class/decorator/metadata/metadata-attached-when-class-is-decorated.js +++ b/test/language/expressions/class/decorator/metadata/metadata-attached-when-class-is-decorated.js @@ -35,9 +35,11 @@ function dec() {} let C1 = @dec class C1 {}; assert.sameValue(typeof C1[Symbol.metadata], "object"); +assert.notSameValue(C1[Symbol.metadata], null); let C2 = class C2 { @dec method() {} }; assert.sameValue(typeof C2[Symbol.metadata], "object"); +assert.notSameValue(C2[Symbol.metadata], null); let C3 = class C3 {}; -assert.sameValue(typeof C3[Symbol.metadata], "undefined"); +assert.sameValue(C3[Symbol.metadata], null); // inherited from Function.prototype[Symbol.metadata] diff --git a/test/language/expressions/class/decorator/metadata/metadata-prop-desc.js b/test/language/expressions/class/decorator/metadata/metadata-prop-desc.js index 41c95e0f1fe..9d2068e6fa9 100644 --- a/test/language/expressions/class/decorator/metadata/metadata-prop-desc.js +++ b/test/language/expressions/class/decorator/metadata/metadata-prop-desc.js @@ -1,25 +1,27 @@ // Copyright (C) 2023 Ron Buckton. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -esid: sec-createdecoratorcontextobject +esid: sec-runtime-semantics-classdefinitionevaluation description: > - Property descriptor for metadata property of decorator context object. + Property descriptor for Symbol.metadata property of decorated class expression. info: | CreateDecoratorContextObject ( kind, name, initializers, decorationState, metadataObj [ , isStatic ] ) [...] - 13. Perform ! CreateDataPropertyOrThrow(contextObj, "metadata", metadata). - 14. Return contextObj. + 41. If metadataObj is not empty, then + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + 1. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 1. Return ? _setMetadataResult_. + [...] includes: [propertyHelper.js] features: [decorators, decorator-metadata] ---*/ -var contextObj; -function dec(_, context) { - contextObj = context; -} +function dec() {} let C = @dec class C {}; -assert.sameValue(typeof contextObj.metadata, "object"); -verifyNotEnumerable(contextObj, "metadata"); -verifyWritable(contextObj, "metadata"); -verifyConfigurable(contextObj, "metadata"); +verifyProperty(C, Symbol.metadata, { + enumerable: false, + writable: true, + configurable: true, +}); diff --git a/test/language/statements/class/decorator/metadata/context-metadata-prop-desc.js b/test/language/statements/class/decorator/metadata/context-metadata-prop-desc.js index 2113eceb0fa..06f66bc18d7 100644 --- a/test/language/statements/class/decorator/metadata/context-metadata-prop-desc.js +++ b/test/language/statements/class/decorator/metadata/context-metadata-prop-desc.js @@ -20,6 +20,8 @@ function dec(_, context) { @dec class C {} assert.sameValue(typeof contextObj.metadata, "object"); -verifyNotEnumerable(contextObj, "metadata"); -verifyWritable(contextObj, "metadata"); -verifyConfigurable(contextObj, "metadata"); +verifyProperty(contextObj, 'metadata', { + enumerable: false, + writable: true, + configurable: true, +}); diff --git a/test/language/statements/class/decorator/metadata/context-metadata.js b/test/language/statements/class/decorator/metadata/context-metadata.js index 0ba77765569..8ba984bc0f1 100644 --- a/test/language/statements/class/decorator/metadata/context-metadata.js +++ b/test/language/statements/class/decorator/metadata/context-metadata.js @@ -14,6 +14,7 @@ features: [decorators, decorator-metadata] ---*/ var kinds = { + __proto__: null, "class": false, "public method": false, "public getter": false, diff --git a/test/language/statements/class/decorator/metadata/metadata-attached-when-class-is-decorated.js b/test/language/statements/class/decorator/metadata/metadata-attached-when-class-is-decorated.js index 5136d41bf38..3a18fce5f33 100644 --- a/test/language/statements/class/decorator/metadata/metadata-attached-when-class-is-decorated.js +++ b/test/language/statements/class/decorator/metadata/metadata-attached-when-class-is-decorated.js @@ -35,9 +35,11 @@ function dec() {} @dec class C1 {} assert.sameValue(typeof C1[Symbol.metadata], "object"); +assert.notSameValue(C1[Symbol.metadata], null); class C2 { @dec method() {} } assert.sameValue(typeof C2[Symbol.metadata], "object"); +assert.notSameValue(C2[Symbol.metadata], null); class C3 {} -assert.sameValue(typeof C3[Symbol.metadata], "undefined"); +assert.sameValue(C3[Symbol.metadata], null); // inherited from Function.prototype[Symbol.metadata] diff --git a/test/language/statements/class/decorator/metadata/metadata-prop-desc.js b/test/language/statements/class/decorator/metadata/metadata-prop-desc.js index 2113eceb0fa..6cb9bd53081 100644 --- a/test/language/statements/class/decorator/metadata/metadata-prop-desc.js +++ b/test/language/statements/class/decorator/metadata/metadata-prop-desc.js @@ -1,25 +1,28 @@ // Copyright (C) 2023 Ron Buckton. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -esid: sec-createdecoratorcontextobject +esid: sec-runtime-semantics-classdefinitionevaluation description: > - Property descriptor for metadata property of decorator context object. + Property descriptor for Symbol.metadata property of decorated class declaration. info: | CreateDecoratorContextObject ( kind, name, initializers, decorationState, metadataObj [ , isStatic ] ) + + [...] + 41. If metadataObj is not empty, then + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + 1. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 1. Return ? _setMetadataResult_. [...] - 13. Perform ! CreateDataPropertyOrThrow(contextObj, "metadata", metadata). - 14. Return contextObj. includes: [propertyHelper.js] features: [decorators, decorator-metadata] ---*/ -var contextObj; -function dec(_, context) { - contextObj = context; -} +function dec() {} -@dec class C {} -assert.sameValue(typeof contextObj.metadata, "object"); -verifyNotEnumerable(contextObj, "metadata"); -verifyWritable(contextObj, "metadata"); -verifyConfigurable(contextObj, "metadata"); +@dec class C {}; +verifyProperty(C, Symbol.metadata, { + enumerable: false, + writable: true, + configurable: true, +}); From 1505f2a245af8f364bb60554586f88a44533c5ed Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 7 Dec 2023 12:11:48 -0500 Subject: [PATCH 3/3] clean up algorithm steps in comments --- .../metadata-attached-when-class-is-decorated.js | 9 +++++---- ...-inheritance-not-affected-by-setPrototype-on-class.js | 9 +++++---- ...heritance-not-affected-when-base-metadata-replaced.js | 9 +++++---- .../class/decorator/metadata/metadata-inheritance.js | 9 +++++---- .../metadata/metadata-is-same-as-context-metadata.js | 9 +++++---- .../class/decorator/metadata/metadata-prop-desc.js | 9 +++++---- ...-inheritance-not-affected-by-setPrototype-on-class.js | 9 +++++---- ...heritance-not-affected-when-base-metadata-replaced.js | 9 +++++---- .../class/decorator/metadata/metadata-inheritance.js | 9 +++++---- .../metadata/metadata-is-same-as-context-metadata.js | 9 +++++---- .../class/decorator/metadata/metadata-prop-desc.js | 9 +++++---- 11 files changed, 55 insertions(+), 44 deletions(-) diff --git a/test/language/expressions/class/decorator/metadata/metadata-attached-when-class-is-decorated.js b/test/language/expressions/class/decorator/metadata/metadata-attached-when-class-is-decorated.js index 26862ec7224..a921fabda06 100644 --- a/test/language/expressions/class/decorator/metadata/metadata-attached-when-class-is-decorated.js +++ b/test/language/expressions/class/decorator/metadata/metadata-attached-when-class-is-decorated.js @@ -23,10 +23,11 @@ info: | c. Set metadataObj to OrdinaryObjectCreate(metadataParent). [...] 41. If metadataObj is not empty, then - a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). - 1. If _setMetadataResult_ is an abrupt completion, then - 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. - 1. Return ? _setMetadataResult_. + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { + [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + i. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 2. Return ? _setMetadataResult_. [...] features: [decorators, decorator-metadata] ---*/ diff --git a/test/language/expressions/class/decorator/metadata/metadata-inheritance-not-affected-by-setPrototype-on-class.js b/test/language/expressions/class/decorator/metadata/metadata-inheritance-not-affected-by-setPrototype-on-class.js index 4d133108e8c..bb47ea83150 100644 --- a/test/language/expressions/class/decorator/metadata/metadata-inheritance-not-affected-by-setPrototype-on-class.js +++ b/test/language/expressions/class/decorator/metadata/metadata-inheritance-not-affected-by-setPrototype-on-class.js @@ -23,10 +23,11 @@ info: | c. Set metadataObj to OrdinaryObjectCreate(metadataParent). [...] 41. If metadataObj is not empty, then - a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). - 1. If _setMetadataResult_ is an abrupt completion, then - 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. - 1. Return ? _setMetadataResult_. + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { + [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + i. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 2. Return ? _setMetadataResult_. [...] features: [decorators, decorator-metadata] ---*/ diff --git a/test/language/expressions/class/decorator/metadata/metadata-inheritance-not-affected-when-base-metadata-replaced.js b/test/language/expressions/class/decorator/metadata/metadata-inheritance-not-affected-when-base-metadata-replaced.js index 458bd0d65c3..a74ff5bdab4 100644 --- a/test/language/expressions/class/decorator/metadata/metadata-inheritance-not-affected-when-base-metadata-replaced.js +++ b/test/language/expressions/class/decorator/metadata/metadata-inheritance-not-affected-when-base-metadata-replaced.js @@ -23,10 +23,11 @@ info: | c. Set metadataObj to OrdinaryObjectCreate(metadataParent). [...] 41. If metadataObj is not empty, then - a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). - 1. If _setMetadataResult_ is an abrupt completion, then - 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. - 1. Return ? _setMetadataResult_. + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { + [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + i. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 2. Return ? _setMetadataResult_. [...] features: [decorators, decorator-metadata] ---*/ diff --git a/test/language/expressions/class/decorator/metadata/metadata-inheritance.js b/test/language/expressions/class/decorator/metadata/metadata-inheritance.js index 3af3b9fd88a..46f99ee3d1f 100644 --- a/test/language/expressions/class/decorator/metadata/metadata-inheritance.js +++ b/test/language/expressions/class/decorator/metadata/metadata-inheritance.js @@ -23,10 +23,11 @@ info: | c. Set metadataObj to OrdinaryObjectCreate(metadataParent). [...] 41. If metadataObj is not empty, then - a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). - 1. If _setMetadataResult_ is an abrupt completion, then - 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. - 1. Return ? _setMetadataResult_. + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { + [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + i. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 2. Return ? _setMetadataResult_. [...] features: [decorators, decorator-metadata] ---*/ diff --git a/test/language/expressions/class/decorator/metadata/metadata-is-same-as-context-metadata.js b/test/language/expressions/class/decorator/metadata/metadata-is-same-as-context-metadata.js index 53fce57f722..c63cdf1ae74 100644 --- a/test/language/expressions/class/decorator/metadata/metadata-is-same-as-context-metadata.js +++ b/test/language/expressions/class/decorator/metadata/metadata-is-same-as-context-metadata.js @@ -30,10 +30,11 @@ info: | c. Set metadataObj to OrdinaryObjectCreate(metadataParent). [...] 41. If metadataObj is not empty, then - a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). - 1. If _setMetadataResult_ is an abrupt completion, then - 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. - 1. Return ? _setMetadataResult_. + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { + [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + i. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 2. Return ? _setMetadataResult_. [...] features: [decorators, decorator-metadata] ---*/ diff --git a/test/language/expressions/class/decorator/metadata/metadata-prop-desc.js b/test/language/expressions/class/decorator/metadata/metadata-prop-desc.js index 9d2068e6fa9..ed7a9dfd82f 100644 --- a/test/language/expressions/class/decorator/metadata/metadata-prop-desc.js +++ b/test/language/expressions/class/decorator/metadata/metadata-prop-desc.js @@ -8,10 +8,11 @@ info: | CreateDecoratorContextObject ( kind, name, initializers, decorationState, metadataObj [ , isStatic ] ) [...] 41. If metadataObj is not empty, then - a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). - 1. If _setMetadataResult_ is an abrupt completion, then - 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. - 1. Return ? _setMetadataResult_. + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { + [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + i. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 2. Return ? _setMetadataResult_. [...] includes: [propertyHelper.js] features: [decorators, decorator-metadata] diff --git a/test/language/statements/class/decorator/metadata/metadata-inheritance-not-affected-by-setPrototype-on-class.js b/test/language/statements/class/decorator/metadata/metadata-inheritance-not-affected-by-setPrototype-on-class.js index daf2793204e..27eb86ffbf4 100644 --- a/test/language/statements/class/decorator/metadata/metadata-inheritance-not-affected-by-setPrototype-on-class.js +++ b/test/language/statements/class/decorator/metadata/metadata-inheritance-not-affected-by-setPrototype-on-class.js @@ -23,10 +23,11 @@ info: | c. Set metadataObj to OrdinaryObjectCreate(metadataParent). [...] 41. If metadataObj is not empty, then - a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). - 1. If _setMetadataResult_ is an abrupt completion, then - 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. - 1. Return ? _setMetadataResult_. + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { + [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + i. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 2. Return ? _setMetadataResult_. [...] features: [decorators, decorator-metadata] ---*/ diff --git a/test/language/statements/class/decorator/metadata/metadata-inheritance-not-affected-when-base-metadata-replaced.js b/test/language/statements/class/decorator/metadata/metadata-inheritance-not-affected-when-base-metadata-replaced.js index 8a2a464c0a3..c46972796d5 100644 --- a/test/language/statements/class/decorator/metadata/metadata-inheritance-not-affected-when-base-metadata-replaced.js +++ b/test/language/statements/class/decorator/metadata/metadata-inheritance-not-affected-when-base-metadata-replaced.js @@ -23,10 +23,11 @@ info: | c. Set metadataObj to OrdinaryObjectCreate(metadataParent). [...] 41. If metadataObj is not empty, then - a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). - 1. If _setMetadataResult_ is an abrupt completion, then - 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. - 1. Return ? _setMetadataResult_. + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { + [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + i. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 2. Return ? _setMetadataResult_. [...] features: [decorators, decorator-metadata] ---*/ diff --git a/test/language/statements/class/decorator/metadata/metadata-inheritance.js b/test/language/statements/class/decorator/metadata/metadata-inheritance.js index 8c1f2ec5f5e..af80781c240 100644 --- a/test/language/statements/class/decorator/metadata/metadata-inheritance.js +++ b/test/language/statements/class/decorator/metadata/metadata-inheritance.js @@ -23,10 +23,11 @@ info: | c. Set metadataObj to OrdinaryObjectCreate(metadataParent). [...] 41. If metadataObj is not empty, then - a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). - 1. If _setMetadataResult_ is an abrupt completion, then - 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. - 1. Return ? _setMetadataResult_. + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { + [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + i. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 2. Return ? _setMetadataResult_. [...] features: [decorators, decorator-metadata] ---*/ diff --git a/test/language/statements/class/decorator/metadata/metadata-is-same-as-context-metadata.js b/test/language/statements/class/decorator/metadata/metadata-is-same-as-context-metadata.js index 020f3a1bc07..91c22d9b3f8 100644 --- a/test/language/statements/class/decorator/metadata/metadata-is-same-as-context-metadata.js +++ b/test/language/statements/class/decorator/metadata/metadata-is-same-as-context-metadata.js @@ -30,10 +30,11 @@ info: | c. Set metadataObj to OrdinaryObjectCreate(metadataParent). [...] 41. If metadataObj is not empty, then - a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). - 1. If _setMetadataResult_ is an abrupt completion, then - 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. - 1. Return ? _setMetadataResult_. + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { + [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + i. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 2. Return ? _setMetadataResult_. [...] features: [decorators, decorator-metadata] ---*/ diff --git a/test/language/statements/class/decorator/metadata/metadata-prop-desc.js b/test/language/statements/class/decorator/metadata/metadata-prop-desc.js index 6cb9bd53081..495cc38863d 100644 --- a/test/language/statements/class/decorator/metadata/metadata-prop-desc.js +++ b/test/language/statements/class/decorator/metadata/metadata-prop-desc.js @@ -9,10 +9,11 @@ info: | [...] 41. If metadataObj is not empty, then - a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). - 1. If _setMetadataResult_ is an abrupt completion, then - 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. - 1. Return ? _setMetadataResult_. + a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { + [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })). + i. If _setMetadataResult_ is an abrupt completion, then + 1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_. + 2. Return ? _setMetadataResult_. [...] includes: [propertyHelper.js] features: [decorators, decorator-metadata]