| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 | 
							- 'use strict';
 
- const {getStaticValue} = require('@eslint-community/eslint-utils');
 
- // Copied from https://github.com/eslint/eslint/blob/94ba68d76a6940f68ff82eea7332c6505f93df76/lib/rules/utils/ast-utils.js#L392
 
- /**
 
- Gets the property name of a given node.
 
- The node can be a MemberExpression, a Property, or a MethodDefinition.
 
- If the name is dynamic, this returns `null`.
 
- For examples:
 
- 	a.b		   // => "b"
 
- 	a["b"]		// => "b"
 
- 	a['b']		// => "b"
 
- 	a[`b`]		// => "b"
 
- 	a[100]		// => "100"
 
- 	a[b]		  // => null
 
- 	a["a" + "b"]  // => null
 
- 	a[tag`b`]	 // => null
 
- 	a[`${b}`]	 // => null
 
- 	let a = {b: 1}			// => "b"
 
- 	let a = {["b"]: 1}		// => "b"
 
- 	let a = {['b']: 1}		// => "b"
 
- 	let a = {[`b`]: 1}		// => "b"
 
- 	let a = {[100]: 1}		// => "100"
 
- 	let a = {[b]: 1}		  // => null
 
- 	let a = {["a" + "b"]: 1}  // => null
 
- 	let a = {[tag`b`]: 1}	 // => null
 
- 	let a = {[`${b}`]: 1}	 // => null
 
- @param {ASTNode} node The node to get.
 
- @returns {string|undefined} The property name if static. Otherwise, undefined.
 
- */
 
- function getStaticPropertyName(node) {
 
- 	let property;
 
- 	switch (node?.type) {
 
- 		case 'MemberExpression': {
 
- 			property = node.property;
 
- 			break;
 
- 		}
 
- 		/* c8 ignore next 2 */
 
- 		case 'ChainExpression': {
 
- 			return getStaticPropertyName(node.expression);
 
- 		}
 
- 		// Only reachable when use this to get class/object member key
 
- 		/* c8 ignore next */
 
- 		case 'Property':
 
- 		case 'MethodDefinition': {
 
- 			/* c8 ignore next 2 */
 
- 			property = node.key;
 
- 			break;
 
- 		}
 
- 			// No default
 
- 	}
 
- 	if (property) {
 
- 		if (property.type === 'Identifier' && !node.computed) {
 
- 			return property.name;
 
- 		}
 
- 		const staticResult = getStaticValue(property);
 
- 		if (!staticResult) {
 
- 			return;
 
- 		}
 
- 		return String(staticResult.value);
 
- 	}
 
- }
 
- /**
 
- Check if two literal nodes are the same value.
 
- @param {ASTNode} left The Literal node to compare.
 
- @param {ASTNode} right The other Literal node to compare.
 
- @returns {boolean} `true` if the two literal nodes are the same value.
 
- */
 
- function equalLiteralValue(left, right) {
 
- 	// RegExp literal.
 
- 	if (left.regex || right.regex) {
 
- 		return Boolean(
 
- 			left.regex
 
- 			&& right.regex
 
- 			&& left.regex.pattern === right.regex.pattern
 
- 			&& left.regex.flags === right.regex.flags,
 
- 		);
 
- 	}
 
- 	// BigInt literal.
 
- 	if (left.bigint || right.bigint) {
 
- 		return left.bigint === right.bigint;
 
- 	}
 
- 	return left.value === right.value;
 
- }
 
- /**
 
- Check if two expressions reference the same value. For example:
 
- 	a = a
 
- 	a.b = a.b
 
- 	a[0] = a[0]
 
- 	a['b'] = a['b']
 
- @param {ASTNode} left The left side of the comparison.
 
- @param {ASTNode} right The right side of the comparison.
 
- @returns {boolean} `true` if both sides match and reference the same value.
 
- */
 
- function isSameReference(left, right) {
 
- 	if (left.type !== right.type) {
 
- 		// Handle `a.b` and `a?.b` are samely.
 
- 		if (left.type === 'ChainExpression') {
 
- 			return isSameReference(left.expression, right);
 
- 		}
 
- 		if (right.type === 'ChainExpression') {
 
- 			return isSameReference(left, right.expression);
 
- 		}
 
- 		return false;
 
- 	}
 
- 	switch (left.type) {
 
- 		case 'Super':
 
- 		case 'ThisExpression': {
 
- 			return true;
 
- 		}
 
- 		case 'Identifier':
 
- 		case 'PrivateIdentifier': {
 
- 			return left.name === right.name;
 
- 		}
 
- 		case 'Literal': {
 
- 			return equalLiteralValue(left, right);
 
- 		}
 
- 		case 'ChainExpression': {
 
- 			return isSameReference(left.expression, right.expression);
 
- 		}
 
- 		case 'MemberExpression': {
 
- 			const nameA = getStaticPropertyName(left);
 
- 			// `x.y = x["y"]`
 
- 			if (nameA !== undefined) {
 
- 				return (
 
- 					isSameReference(left.object, right.object)
 
- 					&& nameA === getStaticPropertyName(right)
 
- 				);
 
- 			}
 
- 			/*
 
- 			`x[0] = x[0]`
 
- 			`x[y] = x[y]`
 
- 			`x.y = x.y`
 
- 			*/
 
- 			return (
 
- 				left.computed === right.computed
 
- 				&& isSameReference(left.object, right.object)
 
- 				&& isSameReference(left.property, right.property)
 
- 			);
 
- 		}
 
- 		default: {
 
- 			return false;
 
- 		}
 
- 	}
 
- }
 
- module.exports = isSameReference;
 
 
  |