Show More
Commit Description:
submission report
Commit Description:
submission report
References:
File last commit:
Show/Diff file:
Action:
node_modules/es-abstract/2017/ValidateAndApplyPropertyDescriptor.js
| 170 lines
| 5.1 KiB
| application/javascript
| JavascriptLexer
|
r789 | 'use strict'; | |||
var GetIntrinsic = require('../GetIntrinsic'); | ||||
var $TypeError = GetIntrinsic('%TypeError%'); | ||||
var DefineOwnProperty = require('../helpers/DefineOwnProperty'); | ||||
var isPropertyDescriptor = require('../helpers/isPropertyDescriptor'); | ||||
var isSamePropertyDescriptor = require('../helpers/isSamePropertyDescriptor'); | ||||
var FromPropertyDescriptor = require('./FromPropertyDescriptor'); | ||||
var IsAccessorDescriptor = require('./IsAccessorDescriptor'); | ||||
var IsDataDescriptor = require('./IsDataDescriptor'); | ||||
var IsGenericDescriptor = require('./IsGenericDescriptor'); | ||||
var IsPropertyKey = require('./IsPropertyKey'); | ||||
var SameValue = require('./SameValue'); | ||||
var Type = require('./Type'); | ||||
// https://www.ecma-international.org/ecma-262/6.0/#sec-validateandapplypropertydescriptor | ||||
// https://www.ecma-international.org/ecma-262/8.0/#sec-validateandapplypropertydescriptor | ||||
// eslint-disable-next-line max-lines-per-function, max-statements, max-params | ||||
module.exports = function ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current) { | ||||
// this uses the ES2017+ logic, since it fixes a number of bugs in the ES2015 logic. | ||||
var oType = Type(O); | ||||
if (oType !== 'Undefined' && oType !== 'Object') { | ||||
throw new $TypeError('Assertion failed: O must be undefined or an Object'); | ||||
} | ||||
if (Type(extensible) !== 'Boolean') { | ||||
throw new $TypeError('Assertion failed: extensible must be a Boolean'); | ||||
} | ||||
if (!isPropertyDescriptor({ | ||||
Type: Type, | ||||
IsDataDescriptor: IsDataDescriptor, | ||||
IsAccessorDescriptor: IsAccessorDescriptor | ||||
}, Desc)) { | ||||
throw new $TypeError('Assertion failed: Desc must be a Property Descriptor'); | ||||
} | ||||
if (Type(current) !== 'Undefined' && !isPropertyDescriptor({ | ||||
Type: Type, | ||||
IsDataDescriptor: IsDataDescriptor, | ||||
IsAccessorDescriptor: IsAccessorDescriptor | ||||
}, current)) { | ||||
throw new $TypeError('Assertion failed: current must be a Property Descriptor, or undefined'); | ||||
} | ||||
if (oType !== 'Undefined' && !IsPropertyKey(P)) { | ||||
throw new $TypeError('Assertion failed: if O is not undefined, P must be a Property Key'); | ||||
} | ||||
if (Type(current) === 'Undefined') { | ||||
if (!extensible) { | ||||
return false; | ||||
} | ||||
if (IsGenericDescriptor(Desc) || IsDataDescriptor(Desc)) { | ||||
if (oType !== 'Undefined') { | ||||
DefineOwnProperty( | ||||
IsDataDescriptor, | ||||
SameValue, | ||||
FromPropertyDescriptor, | ||||
O, | ||||
P, | ||||
{ | ||||
'[[Configurable]]': Desc['[[Configurable]]'], | ||||
'[[Enumerable]]': Desc['[[Enumerable]]'], | ||||
'[[Value]]': Desc['[[Value]]'], | ||||
'[[Writable]]': Desc['[[Writable]]'] | ||||
} | ||||
); | ||||
} | ||||
} else { | ||||
if (!IsAccessorDescriptor(Desc)) { | ||||
throw new $TypeError('Assertion failed: Desc is not an accessor descriptor'); | ||||
} | ||||
if (oType !== 'Undefined') { | ||||
return DefineOwnProperty( | ||||
IsDataDescriptor, | ||||
SameValue, | ||||
FromPropertyDescriptor, | ||||
O, | ||||
P, | ||||
Desc | ||||
); | ||||
} | ||||
} | ||||
return true; | ||||
} | ||||
if (IsGenericDescriptor(Desc) && !('[[Configurable]]' in Desc) && !('[[Enumerable]]' in Desc)) { | ||||
return true; | ||||
} | ||||
if (isSamePropertyDescriptor({ SameValue: SameValue }, Desc, current)) { | ||||
return true; // removed by ES2017, but should still be correct | ||||
} | ||||
// "if every field in Desc is absent, return true" can't really match the assertion that it's a Property Descriptor | ||||
if (!current['[[Configurable]]']) { | ||||
if (Desc['[[Configurable]]']) { | ||||
return false; | ||||
} | ||||
if ('[[Enumerable]]' in Desc && !Desc['[[Enumerable]]'] === !!current['[[Enumerable]]']) { | ||||
return false; | ||||
} | ||||
} | ||||
if (IsGenericDescriptor(Desc)) { | ||||
// no further validation is required. | ||||
} else if (IsDataDescriptor(current) !== IsDataDescriptor(Desc)) { | ||||
if (!current['[[Configurable]]']) { | ||||
return false; | ||||
} | ||||
if (IsDataDescriptor(current)) { | ||||
if (oType !== 'Undefined') { | ||||
DefineOwnProperty( | ||||
IsDataDescriptor, | ||||
SameValue, | ||||
FromPropertyDescriptor, | ||||
O, | ||||
P, | ||||
{ | ||||
'[[Configurable]]': current['[[Configurable]]'], | ||||
'[[Enumerable]]': current['[[Enumerable]]'], | ||||
'[[Get]]': undefined | ||||
} | ||||
); | ||||
} | ||||
} else if (oType !== 'Undefined') { | ||||
DefineOwnProperty( | ||||
IsDataDescriptor, | ||||
SameValue, | ||||
FromPropertyDescriptor, | ||||
O, | ||||
P, | ||||
{ | ||||
'[[Configurable]]': current['[[Configurable]]'], | ||||
'[[Enumerable]]': current['[[Enumerable]]'], | ||||
'[[Value]]': undefined | ||||
} | ||||
); | ||||
} | ||||
} else if (IsDataDescriptor(current) && IsDataDescriptor(Desc)) { | ||||
if (!current['[[Configurable]]'] && !current['[[Writable]]']) { | ||||
if ('[[Writable]]' in Desc && Desc['[[Writable]]']) { | ||||
return false; | ||||
} | ||||
if ('[[Value]]' in Desc && !SameValue(Desc['[[Value]]'], current['[[Value]]'])) { | ||||
return false; | ||||
} | ||||
return true; | ||||
} | ||||
} else if (IsAccessorDescriptor(current) && IsAccessorDescriptor(Desc)) { | ||||
if (!current['[[Configurable]]']) { | ||||
if ('[[Set]]' in Desc && !SameValue(Desc['[[Set]]'], current['[[Set]]'])) { | ||||
return false; | ||||
} | ||||
if ('[[Get]]' in Desc && !SameValue(Desc['[[Get]]'], current['[[Get]]'])) { | ||||
return false; | ||||
} | ||||
return true; | ||||
} | ||||
} else { | ||||
throw new $TypeError('Assertion failed: current and Desc are not both data, both accessors, or one accessor and one data.'); | ||||
} | ||||
if (oType !== 'Undefined') { | ||||
return DefineOwnProperty( | ||||
IsDataDescriptor, | ||||
SameValue, | ||||
FromPropertyDescriptor, | ||||
O, | ||||
P, | ||||
Desc | ||||
); | ||||
} | ||||
return true; | ||||
}; | ||||