eslint-plugin-regexp
Version:
ESLint plugin for finding RegExp mistakes and RegExp style guide violations.
118 lines (117 loc) • 4.54 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("../utils");
const get_usage_of_pattern_1 = require("../utils/get-usage-of-pattern");
function isTopLevel(group) {
const parent = group.parent;
if (parent.type === "Alternative" && parent.elements.length === 1) {
const parentParent = parent.parent;
if (parentParent.type === "Pattern" &&
parentParent.alternatives.length === 1) {
return true;
}
}
return false;
}
exports.default = (0, utils_1.createRule)("no-useless-non-capturing-group", {
meta: {
docs: {
description: "disallow unnecessary non-capturing group",
category: "Stylistic Issues",
recommended: true,
},
fixable: "code",
schema: [
{
type: "object",
properties: {
allowTop: {
anyOf: [
{
type: "boolean",
},
{ enum: ["always", "never", "partial"] },
],
},
},
additionalProperties: false,
},
],
messages: {
unexpected: "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.",
},
type: "suggestion",
},
create(context) {
var _a, _b, _c, _d;
const allowTop = ((_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.allowTop) === true
? "always"
: ((_b = context.options[0]) === null || _b === void 0 ? void 0 : _b.allowTop) === false
? "never"
: (_d = (_c = context.options[0]) === null || _c === void 0 ? void 0 : _c.allowTop) !== null && _d !== void 0 ? _d : "partial";
function createVisitor({ node, getRegexpLocation, fixReplaceNode, getUsageOfPattern, }) {
let isIgnored;
if (allowTop === "always") {
isIgnored = isTopLevel;
}
else if (allowTop === "partial") {
if (getUsageOfPattern() !== get_usage_of_pattern_1.UsageOfPattern.whole) {
isIgnored = isTopLevel;
}
else {
isIgnored = () => false;
}
}
else {
isIgnored = () => false;
}
return {
onGroupEnter(gNode) {
if (isIgnored(gNode)) {
return;
}
if (gNode.alternatives.length === 1) {
const alt = gNode.alternatives[0];
if (alt.elements.length === 0) {
return;
}
const parent = gNode.parent;
if (parent.type === "Quantifier" &&
(alt.elements.length > 1 ||
alt.elements[0].type === "Quantifier")) {
return;
}
if (!(0, utils_1.canUnwrapped)(gNode, alt.raw)) {
return;
}
}
else {
const parent = gNode.parent;
if (parent.type !== "Alternative") {
return;
}
if (parent.elements.length !== 1) {
return;
}
}
context.report({
node,
loc: getRegexpLocation(gNode, [0, 3]),
messageId: "unexpected",
fix: fixReplaceNode(gNode, () => {
if (allowTop === "never" &&
isTopLevel(gNode) &&
getUsageOfPattern() !== get_usage_of_pattern_1.UsageOfPattern.whole) {
return null;
}
return gNode.raw.slice(3, -1);
}),
});
},
};
}
return (0, utils_1.defineRegexpVisitor)(context, {
createVisitor,
});
},
});
;