UNPKG

eslint-plugin-regexp

Version:

ESLint plugin for finding RegExp mistakes and RegExp style guide violations.

170 lines (169 loc) 5.63 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isEqualNodes = void 0; const regexp_ast_analysis_1 = require("regexp-ast-analysis"); function isEqualChar(a, b, flags) { if (a.type === "Character") { if (b.type === "Character") { if (a.value === b.value) { return true; } } else if (b.type === "CharacterSet") { return false; } } else if (a.type === "CharacterSet") { if (b.type === "Character") { return false; } else if (b.type === "CharacterSet") { return a.raw === b.raw; } } else if (a.type === "CharacterClassRange") { if (b.type === "CharacterClassRange") { return a.min.value === b.min.value && a.max.value === b.max.value; } } if (a.raw === b.raw) { return true; } return (0, regexp_ast_analysis_1.toUnicodeSet)(a, flags).equals((0, regexp_ast_analysis_1.toUnicodeSet)(b, flags)); } const EQUALS_CHECKER = { Alternative(a, b, flags, shortCircuit) { return isEqualConcatenation(a.elements, b.elements, flags, shortCircuit); }, Assertion(a, b, flags, shortCircuit) { if (a.kind === "start" || a.kind === "end") { return a.kind === b.kind; } if (a.kind === "word") { return b.kind === "word" && a.negate === b.negate; } if (a.kind === "lookahead" || a.kind === "lookbehind") { if (b.kind === a.kind && a.negate === b.negate) { return isEqualSet(a.alternatives, b.alternatives, flags, shortCircuit); } return false; } return false; }, Backreference(a, b) { return a.ref === b.ref; }, CapturingGroup(a, b, flags, shortCircuit) { return (a.name === b.name && isEqualSet(a.alternatives, b.alternatives, flags, shortCircuit)); }, Character(a, b, flags) { return isEqualChar(a, b, flags); }, CharacterClass(a, b, flags) { return isEqualChar(a, b, flags); }, CharacterClassRange(a, b, flags) { return isEqualChar(a, b, flags); }, CharacterSet(a, b, flags) { return isEqualChar(a, b, flags); }, ClassIntersection(a, b, flags, shortCircuit) { return isEqualSet([a.left, a.right], [b.left, b.right], flags, shortCircuit); }, ClassStringDisjunction(a, b, flags, shortCircuit) { return isEqualSet(a.alternatives, b.alternatives, flags, shortCircuit); }, ClassSubtraction(a, b, flags, shortCircuit) { return (isEqualNodes(a.left, b.left, flags, shortCircuit) && isEqualNodes(a.right, b.right, flags, shortCircuit)); }, ExpressionCharacterClass(a, b, flags) { return (a.negate === b.negate && isEqualNodes(a.expression, b.expression, flags)); }, Flags(a, b) { return (a.dotAll === b.dotAll && a.global === b.global && a.ignoreCase === b.ignoreCase && a.multiline === b.multiline && a.hasIndices === b.hasIndices && a.sticky === b.sticky && a.unicode === b.unicode && a.unicodeSets === b.unicodeSets); }, Group(a, b, flags, shortCircuit) { return isEqualSet(a.alternatives, b.alternatives, flags, shortCircuit); }, Pattern(a, b, flags, shortCircuit) { return isEqualSet(a.alternatives, b.alternatives, flags, shortCircuit); }, Quantifier(a, b, flags, shortCircuit) { return (a.min === b.min && a.max === b.max && a.greedy === b.greedy && isEqualNodes(a.element, b.element, flags, shortCircuit)); }, RegExpLiteral(a, b, flags, shortCircuit) { return (isEqualNodes(a.pattern, b.pattern, flags, shortCircuit) && isEqualNodes(a.flags, b.flags, flags, shortCircuit)); }, StringAlternative(a, b, flags, shortCircuit) { return isEqualConcatenation(a.elements, b.elements, flags, shortCircuit); }, }; function isToCharSetElement(node) { return (node.type === "Character" || node.type === "CharacterClass" || node.type === "CharacterClassRange" || node.type === "CharacterSet"); } function isEqualNodes(a, b, flags, shortCircuit) { if (isToCharSetElement(a) && isToCharSetElement(b)) { return isEqualChar(a, b, flags); } if (a.type !== b.type) { return false; } if (shortCircuit) { const kind = shortCircuit(a, b); if (kind != null) { return kind; } } if (/[(*+?[\\{|]/u.test(a.raw) || /[(*+?[\\{|]/u.test(b.raw)) { return EQUALS_CHECKER[a.type](a, b, flags, shortCircuit); } return a.raw === b.raw; } exports.isEqualNodes = isEqualNodes; function isEqualConcatenation(a, b, flags, shortCircuit) { if (a.length !== b.length) { return false; } for (let index = 0; index < a.length; index++) { const ae = a[index]; const be = b[index]; if (!isEqualNodes(ae, be, flags, shortCircuit)) { return false; } } return true; } function isEqualSet(a, b, flags, shortCircuit) { if (a.length !== b.length) { return false; } const beList = [...b]; for (const ae of a) { const bIndex = beList.findIndex((be) => isEqualNodes(ae, be, flags, shortCircuit)); if (bIndex >= 0) { beList.splice(bIndex, 1); } else { return false; } } return true; }