Website Structure
This commit is contained in:
parent
62812f2090
commit
71f0676a62
22365 changed files with 4265753 additions and 791 deletions
209
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-misleading-unicode-character.js
generated
vendored
Normal file
209
Frontend-Learner/node_modules/eslint-plugin-regexp/dist/rules/no-misleading-unicode-character.js
generated
vendored
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("../utils");
|
||||
const mention_1 = require("../utils/mention");
|
||||
const regex_syntax_1 = require("../utils/regex-syntax");
|
||||
const segmenter = new Intl.Segmenter();
|
||||
function startsWithSurrogate(s) {
|
||||
if (s.length < 2) {
|
||||
return false;
|
||||
}
|
||||
const h = s.charCodeAt(0);
|
||||
const l = s.charCodeAt(1);
|
||||
return h >= 0xd800 && h <= 0xdbff && l >= 0xdc00 && l <= 0xdfff;
|
||||
}
|
||||
function getProblem(grapheme, flags) {
|
||||
if (grapheme.length > 2 ||
|
||||
(grapheme.length === 2 && !startsWithSurrogate(grapheme))) {
|
||||
return "Multi";
|
||||
}
|
||||
else if (!flags.unicode &&
|
||||
!flags.unicodeSets &&
|
||||
startsWithSurrogate(grapheme)) {
|
||||
return "Surrogate";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function getGraphemeBeforeQuant(quant) {
|
||||
const alt = quant.parent;
|
||||
let start = quant.start;
|
||||
for (let i = alt.elements.indexOf(quant) - 1; i >= 0; i--) {
|
||||
const e = alt.elements[i];
|
||||
if (e.type === "Character" && !(0, regex_syntax_1.isEscapeSequence)(e.raw)) {
|
||||
start = e.start;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
const before = alt.raw.slice(start - alt.start, quant.element.end - alt.start);
|
||||
const segments = [...segmenter.segment(before)];
|
||||
const segment = segments[segments.length - 1];
|
||||
return segment.segment;
|
||||
}
|
||||
function getGraphemeProblems(cc, flags) {
|
||||
const offset = cc.negate ? 2 : 1;
|
||||
const ignoreElements = cc.elements.filter((element) => element.type === "CharacterClass" ||
|
||||
element.type === "ExpressionCharacterClass" ||
|
||||
element.type === "ClassStringDisjunction");
|
||||
const problems = [];
|
||||
for (const { segment, index } of segmenter.segment(cc.raw.slice(offset, -1))) {
|
||||
const problem = getProblem(segment, flags);
|
||||
if (problem !== null) {
|
||||
const start = offset + index + cc.start;
|
||||
const end = start + segment.length;
|
||||
if (ignoreElements.some((ignore) => ignore.start <= start && end <= ignore.end)) {
|
||||
continue;
|
||||
}
|
||||
problems.push({
|
||||
grapheme: segment,
|
||||
problem,
|
||||
start,
|
||||
end,
|
||||
elements: cc.elements.filter((e) => e.start < end && e.end > start),
|
||||
});
|
||||
}
|
||||
}
|
||||
return problems;
|
||||
}
|
||||
function getGraphemeProblemsFix(problems, cc, flags) {
|
||||
if (cc.negate) {
|
||||
return null;
|
||||
}
|
||||
if (!problems.every((p) => p.start === p.elements[0].start &&
|
||||
p.end === p.elements[p.elements.length - 1].end)) {
|
||||
return null;
|
||||
}
|
||||
const prefixGraphemes = problems.map((p) => p.grapheme);
|
||||
let ccRaw = cc.raw;
|
||||
for (let i = problems.length - 1; i >= 0; i--) {
|
||||
const { start, end } = problems[i];
|
||||
ccRaw = ccRaw.slice(0, start - cc.start) + ccRaw.slice(end - cc.start);
|
||||
}
|
||||
if (flags.unicodeSets) {
|
||||
const prefix = prefixGraphemes.join("|");
|
||||
return `[\\q{${prefix}}${ccRaw.slice(1, -1)}]`;
|
||||
}
|
||||
if (ccRaw.startsWith("[^")) {
|
||||
ccRaw = `[\\${ccRaw.slice(1)}`;
|
||||
}
|
||||
const prefix = prefixGraphemes.sort((a, b) => b.length - a.length).join("|");
|
||||
let fix = prefix;
|
||||
let singleAlternative = problems.length === 1;
|
||||
if (ccRaw !== "[]") {
|
||||
fix += `|${ccRaw}`;
|
||||
singleAlternative = false;
|
||||
}
|
||||
if (singleAlternative && cc.parent.type === "Alternative") {
|
||||
return fix;
|
||||
}
|
||||
if (cc.parent.type === "Alternative" && cc.parent.elements.length === 1) {
|
||||
return fix;
|
||||
}
|
||||
return `(?:${fix})`;
|
||||
}
|
||||
exports.default = (0, utils_1.createRule)("no-misleading-unicode-character", {
|
||||
meta: {
|
||||
docs: {
|
||||
description: "disallow multi-code-point characters in character classes and quantifiers",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
fixable: { type: "boolean" },
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
fixable: "code",
|
||||
hasSuggestions: true,
|
||||
messages: {
|
||||
characterClass: "The character(s) {{ graphemes }} are all represented using multiple {{ unit }}.{{ uFlag }}",
|
||||
quantifierMulti: "The character {{ grapheme }} is represented using multiple Unicode code points. The quantifier only applies to the last code point {{ last }} and not to the whole character.",
|
||||
quantifierSurrogate: "The character {{ grapheme }} is represented using a surrogate pair. The quantifier only applies to the tailing surrogate {{ last }} and not to the whole character.",
|
||||
fixCharacterClass: "Move the character(s) {{ graphemes }} outside the character class.",
|
||||
fixQuantifier: "Wrap a group around {{ grapheme }}.",
|
||||
},
|
||||
type: "problem",
|
||||
},
|
||||
create(context) {
|
||||
var _a, _b;
|
||||
const fixable = (_b = (_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.fixable) !== null && _b !== void 0 ? _b : false;
|
||||
function makeFix(fix, messageId, data) {
|
||||
if (fixable) {
|
||||
return { fix };
|
||||
}
|
||||
return {
|
||||
suggest: [{ messageId, data, fix }],
|
||||
};
|
||||
}
|
||||
function createVisitor(regexpContext) {
|
||||
const { node, patternSource, flags, getRegexpLocation, fixReplaceNode, } = regexpContext;
|
||||
return {
|
||||
onCharacterClassEnter(ccNode) {
|
||||
const problems = getGraphemeProblems(ccNode, flags);
|
||||
if (problems.length === 0) {
|
||||
return;
|
||||
}
|
||||
const range = {
|
||||
start: problems[0].start,
|
||||
end: problems[problems.length - 1].end,
|
||||
};
|
||||
const fix = getGraphemeProblemsFix(problems, ccNode, flags);
|
||||
const graphemes = problems
|
||||
.map((p) => (0, mention_1.mention)(p.grapheme))
|
||||
.join(", ");
|
||||
const uFlag = problems.every((p) => p.problem === "Surrogate");
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(range),
|
||||
messageId: "characterClass",
|
||||
data: {
|
||||
graphemes,
|
||||
unit: flags.unicode || flags.unicodeSets
|
||||
? "code points"
|
||||
: "char codes",
|
||||
uFlag: uFlag ? " Use the `u` flag." : "",
|
||||
},
|
||||
...makeFix(fixReplaceNode(ccNode, () => fix), "fixCharacterClass", { graphemes }),
|
||||
});
|
||||
},
|
||||
onQuantifierEnter(qNode) {
|
||||
if (qNode.element.type !== "Character") {
|
||||
return;
|
||||
}
|
||||
const grapheme = getGraphemeBeforeQuant(qNode);
|
||||
const problem = getProblem(grapheme, flags);
|
||||
if (problem === null) {
|
||||
return;
|
||||
}
|
||||
context.report({
|
||||
node,
|
||||
loc: getRegexpLocation(qNode),
|
||||
messageId: `quantifier${problem}`,
|
||||
data: {
|
||||
grapheme: (0, mention_1.mention)(grapheme),
|
||||
last: (0, mention_1.mentionChar)(qNode.element),
|
||||
},
|
||||
...makeFix((fixer) => {
|
||||
const range = patternSource.getReplaceRange({
|
||||
start: qNode.element.end - grapheme.length,
|
||||
end: qNode.element.end,
|
||||
});
|
||||
if (!range) {
|
||||
return null;
|
||||
}
|
||||
return range.replace(fixer, `(?:${grapheme})`);
|
||||
}, "fixQuantifier", { grapheme: (0, mention_1.mention)(grapheme) }),
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
return (0, utils_1.defineRegexpVisitor)(context, {
|
||||
createVisitor,
|
||||
});
|
||||
},
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue