| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 | 'use strict';var GetIntrinsic = require('get-intrinsic');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://ecma-international.org/ecma-262/6.0/#sec-validateandapplypropertydescriptor// https://ecma-international.org/ecma-262/8.0/#sec-validateandapplypropertydescriptor// eslint-disable-next-line max-lines-per-function, max-statements, max-paramsmodule.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;};
 |