139 lines
6.2 KiB
JavaScript
139 lines
6.2 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const utils_1 = require("../utils");
|
|
const get_usage_of_pattern_1 = require("../utils/get-usage-of-pattern");
|
|
function* extractLazyEndQuantifiers(alternatives) {
|
|
for (const { elements } of alternatives) {
|
|
if (elements.length > 0) {
|
|
const last = elements[elements.length - 1];
|
|
switch (last.type) {
|
|
case "Quantifier":
|
|
if (!last.greedy && last.min !== last.max) {
|
|
yield last;
|
|
}
|
|
else if (last.max === 1) {
|
|
const element = last.element;
|
|
if (element.type === "Group" ||
|
|
element.type === "CapturingGroup") {
|
|
yield* extractLazyEndQuantifiers(element.alternatives);
|
|
}
|
|
}
|
|
break;
|
|
case "CapturingGroup":
|
|
case "Group":
|
|
yield* extractLazyEndQuantifiers(last.alternatives);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
exports.default = (0, utils_1.createRule)("no-lazy-ends", {
|
|
meta: {
|
|
docs: {
|
|
description: "disallow lazy quantifiers at the end of an expression",
|
|
category: "Possible Errors",
|
|
recommended: true,
|
|
default: "warn",
|
|
},
|
|
schema: [
|
|
{
|
|
type: "object",
|
|
properties: {
|
|
ignorePartial: { type: "boolean" },
|
|
},
|
|
additionalProperties: false,
|
|
},
|
|
],
|
|
hasSuggestions: true,
|
|
messages: {
|
|
uselessElement: "The quantifier and the quantified element can be removed because the quantifier is lazy and has a minimum of 0.",
|
|
uselessQuantifier: "The quantifier can be removed because the quantifier is lazy and has a minimum of 1.",
|
|
uselessRange: "The quantifier can be replaced with '{{{min}}}' because the quantifier is lazy and has a minimum of {{min}}.",
|
|
suggestMakeGreedy: "Make the quantifier greedy. (This changes the behavior of the regex.)",
|
|
suggestRemoveElement: "Remove the quantified element. (This does not changes the behavior of the regex.)",
|
|
suggestRemoveQuantifier: "Remove the quantifier. (This does not changes the behavior of the regex.)",
|
|
suggestRange: "Replace the quantifier with '{{{min}}}'. (This does not changes the behavior of the regex.)",
|
|
},
|
|
type: "problem",
|
|
},
|
|
create(context) {
|
|
var _a, _b;
|
|
const ignorePartial = (_b = (_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.ignorePartial) !== null && _b !== void 0 ? _b : true;
|
|
function createVisitor({ node, getRegexpLocation, getUsageOfPattern, fixReplaceNode, }) {
|
|
if (ignorePartial) {
|
|
const usageOfPattern = getUsageOfPattern();
|
|
if (usageOfPattern !== get_usage_of_pattern_1.UsageOfPattern.whole) {
|
|
return {};
|
|
}
|
|
}
|
|
return {
|
|
onPatternEnter(pNode) {
|
|
for (const lazy of extractLazyEndQuantifiers(pNode.alternatives)) {
|
|
const makeGreedy = {
|
|
messageId: "suggestMakeGreedy",
|
|
fix: fixReplaceNode(lazy, lazy.raw.slice(0, -1)),
|
|
};
|
|
if (lazy.min === 0) {
|
|
const replacement = pNode.alternatives.length === 1 &&
|
|
pNode.alternatives[0].elements.length === 1 &&
|
|
pNode.alternatives[0].elements[0] === lazy
|
|
? "(?:)"
|
|
: "";
|
|
context.report({
|
|
node,
|
|
loc: getRegexpLocation(lazy),
|
|
messageId: "uselessElement",
|
|
suggest: [
|
|
{
|
|
messageId: "suggestRemoveElement",
|
|
fix: fixReplaceNode(lazy, replacement),
|
|
},
|
|
makeGreedy,
|
|
],
|
|
});
|
|
}
|
|
else if (lazy.min === 1) {
|
|
context.report({
|
|
node,
|
|
loc: getRegexpLocation(lazy),
|
|
messageId: "uselessQuantifier",
|
|
suggest: [
|
|
{
|
|
messageId: "suggestRemoveQuantifier",
|
|
fix: fixReplaceNode(lazy, lazy.element.raw),
|
|
},
|
|
makeGreedy,
|
|
],
|
|
});
|
|
}
|
|
else {
|
|
context.report({
|
|
node,
|
|
loc: getRegexpLocation(lazy),
|
|
messageId: "uselessRange",
|
|
data: {
|
|
min: String(lazy.min),
|
|
},
|
|
suggest: [
|
|
{
|
|
messageId: "suggestRange",
|
|
data: {
|
|
min: String(lazy.min),
|
|
},
|
|
fix: fixReplaceNode(lazy, `${lazy.element.raw}{${lazy.min}}`),
|
|
},
|
|
makeGreedy,
|
|
],
|
|
});
|
|
}
|
|
}
|
|
},
|
|
};
|
|
}
|
|
return (0, utils_1.defineRegexpVisitor)(context, {
|
|
createVisitor,
|
|
});
|
|
},
|
|
});
|