source: imaps-frontend/node_modules/es-abstract/2023/ValidateAndApplyPropertyDescriptor.js

main
Last change on this file was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 5.6 KB
Line 
1'use strict';
2
3var $TypeError = require('es-errors/type');
4
5var DefineOwnProperty = require('../helpers/DefineOwnProperty');
6var isFullyPopulatedPropertyDescriptor = require('../helpers/isFullyPopulatedPropertyDescriptor');
7var isPropertyDescriptor = require('../helpers/records/property-descriptor');
8
9var FromPropertyDescriptor = require('./FromPropertyDescriptor');
10var IsAccessorDescriptor = require('./IsAccessorDescriptor');
11var IsDataDescriptor = require('./IsDataDescriptor');
12var IsGenericDescriptor = require('./IsGenericDescriptor');
13var IsPropertyKey = require('./IsPropertyKey');
14var SameValue = require('./SameValue');
15var Type = require('./Type');
16
17// https://262.ecma-international.org/13.0/#sec-validateandapplypropertydescriptor
18
19// see https://github.com/tc39/ecma262/pull/2468 for ES2022 changes
20
21// eslint-disable-next-line max-lines-per-function, max-statements
22module.exports = function ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current) {
23 var oType = Type(O);
24 if (oType !== 'Undefined' && oType !== 'Object') {
25 throw new $TypeError('Assertion failed: O must be undefined or an Object');
26 }
27 if (!IsPropertyKey(P)) {
28 throw new $TypeError('Assertion failed: P must be a Property Key');
29 }
30 if (typeof extensible !== 'boolean') {
31 throw new $TypeError('Assertion failed: extensible must be a Boolean');
32 }
33 if (!isPropertyDescriptor(Desc)) {
34 throw new $TypeError('Assertion failed: Desc must be a Property Descriptor');
35 }
36 if (typeof current !== 'undefined' && !isPropertyDescriptor(current)) {
37 throw new $TypeError('Assertion failed: current must be a Property Descriptor, or undefined');
38 }
39
40 if (typeof current === 'undefined') { // step 2
41 if (!extensible) {
42 return false; // step 2.a
43 }
44 if (oType === 'Undefined') {
45 return true; // step 2.b
46 }
47 if (IsAccessorDescriptor(Desc)) { // step 2.c
48 return DefineOwnProperty(
49 IsDataDescriptor,
50 SameValue,
51 FromPropertyDescriptor,
52 O,
53 P,
54 Desc
55 );
56 }
57 // step 2.d
58 return DefineOwnProperty(
59 IsDataDescriptor,
60 SameValue,
61 FromPropertyDescriptor,
62 O,
63 P,
64 {
65 '[[Configurable]]': !!Desc['[[Configurable]]'],
66 '[[Enumerable]]': !!Desc['[[Enumerable]]'],
67 '[[Value]]': Desc['[[Value]]'],
68 '[[Writable]]': !!Desc['[[Writable]]']
69 }
70 );
71 }
72
73 // 3. Assert: current is a fully populated Property Descriptor.
74 if (
75 !isFullyPopulatedPropertyDescriptor(
76 {
77 IsAccessorDescriptor: IsAccessorDescriptor,
78 IsDataDescriptor: IsDataDescriptor
79 },
80 current
81 )
82 ) {
83 throw new $TypeError('`current`, when present, must be a fully populated and valid Property Descriptor');
84 }
85
86 // 4. If every field in Desc is absent, return true.
87 // this can't really match the assertion that it's a Property Descriptor in our JS implementation
88
89 // 5. If current.[[Configurable]] is false, then
90 if (!current['[[Configurable]]']) {
91 if ('[[Configurable]]' in Desc && Desc['[[Configurable]]']) {
92 // step 5.a
93 return false;
94 }
95 if ('[[Enumerable]]' in Desc && !SameValue(Desc['[[Enumerable]]'], current['[[Enumerable]]'])) {
96 // step 5.b
97 return false;
98 }
99 if (!IsGenericDescriptor(Desc) && !SameValue(IsAccessorDescriptor(Desc), IsAccessorDescriptor(current))) {
100 // step 5.c
101 return false;
102 }
103 if (IsAccessorDescriptor(current)) { // step 5.d
104 if ('[[Get]]' in Desc && !SameValue(Desc['[[Get]]'], current['[[Get]]'])) {
105 return false;
106 }
107 if ('[[Set]]' in Desc && !SameValue(Desc['[[Set]]'], current['[[Set]]'])) {
108 return false;
109 }
110 } else if (!current['[[Writable]]']) { // step 5.e
111 if ('[[Writable]]' in Desc && Desc['[[Writable]]']) {
112 return false;
113 }
114 if ('[[Value]]' in Desc && !SameValue(Desc['[[Value]]'], current['[[Value]]'])) {
115 return false;
116 }
117 }
118 }
119
120 // 6. If O is not undefined, then
121 if (oType !== 'Undefined') {
122 var configurable;
123 var enumerable;
124 if (IsDataDescriptor(current) && IsAccessorDescriptor(Desc)) { // step 6.a
125 configurable = ('[[Configurable]]' in Desc ? Desc : current)['[[Configurable]]'];
126 enumerable = ('[[Enumerable]]' in Desc ? Desc : current)['[[Enumerable]]'];
127 // Replace the property named P of object O with an accessor property having [[Configurable]] and [[Enumerable]] attributes as described by current and each other attribute set to its default value.
128 return DefineOwnProperty(
129 IsDataDescriptor,
130 SameValue,
131 FromPropertyDescriptor,
132 O,
133 P,
134 {
135 '[[Configurable]]': !!configurable,
136 '[[Enumerable]]': !!enumerable,
137 '[[Get]]': ('[[Get]]' in Desc ? Desc : current)['[[Get]]'],
138 '[[Set]]': ('[[Set]]' in Desc ? Desc : current)['[[Set]]']
139 }
140 );
141 } else if (IsAccessorDescriptor(current) && IsDataDescriptor(Desc)) {
142 configurable = ('[[Configurable]]' in Desc ? Desc : current)['[[Configurable]]'];
143 enumerable = ('[[Enumerable]]' in Desc ? Desc : current)['[[Enumerable]]'];
144 // i. Replace the property named P of object O with a data property having [[Configurable]] and [[Enumerable]] attributes as described by current and each other attribute set to its default value.
145 return DefineOwnProperty(
146 IsDataDescriptor,
147 SameValue,
148 FromPropertyDescriptor,
149 O,
150 P,
151 {
152 '[[Configurable]]': !!configurable,
153 '[[Enumerable]]': !!enumerable,
154 '[[Value]]': ('[[Value]]' in Desc ? Desc : current)['[[Value]]'],
155 '[[Writable]]': !!('[[Writable]]' in Desc ? Desc : current)['[[Writable]]']
156 }
157 );
158 }
159
160 // For each field of Desc that is present, set the corresponding attribute of the property named P of object O to the value of the field.
161 return DefineOwnProperty(
162 IsDataDescriptor,
163 SameValue,
164 FromPropertyDescriptor,
165 O,
166 P,
167 Desc
168 );
169 }
170
171 return true; // step 7
172};
Note: See TracBrowser for help on using the repository browser.