Skip to content

Commit c683d1e

Browse files
authored
refactor(fmt,html,internal,regexp,text,uuid,xml,yaml): add CONSTANT_CASE RegExp name lint check (#6994)
1 parent 030ac5c commit c683d1e

27 files changed

+165
-115
lines changed

_tools/check_docs.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ type DocNodeWithJsDoc<T = DocNodeBase> = T & {
3030
jsDoc: JsDoc;
3131
};
3232

33-
const TS_SNIPPET = /```ts[\s\S]*?```/g;
34-
const ASSERTION_IMPORT =
33+
const TS_SNIPPET_REGEXP = /```ts[\s\S]*?```/g;
34+
const ASSERTION_IMPORT_REGEXP =
3535
/from "@std\/(assert(\/[a-z-]+)?|expect(\/[a-z-]+)?|testing\/(mock|snapshot|types))"/g;
3636
const NEWLINE = "\n";
3737
const diagnostics: DocumentError[] = [];
@@ -142,7 +142,7 @@ function assertHasSnippets(
142142
doc: string,
143143
document: { jsDoc: JsDoc; location: Location },
144144
) {
145-
const snippets = doc.match(TS_SNIPPET);
145+
const snippets = doc.match(TS_SNIPPET_REGEXP);
146146
assert(
147147
snippets !== null,
148148
"@example tag must have a TypeScript code snippet",
@@ -155,7 +155,7 @@ function assertHasSnippets(
155155
snippet = snippet.split(NEWLINE).slice(1, -1).join(NEWLINE);
156156
if (!(delim?.includes("no-assert") || delim?.includes("ignore"))) {
157157
assert(
158-
snippet.match(ASSERTION_IMPORT) !== null,
158+
snippet.match(ASSERTION_IMPORT_REGEXP) !== null,
159159
"Snippet must contain assertion from `@std/assert`, `@std/expect` or `@std/testing`",
160160
document,
161161
);

_tools/lint_plugin.ts

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ import { toFileUrl } from "@std/path/to-file-url";
1111
import { resolve } from "@std/path/resolve";
1212

1313
const PASCAL_CASE_REGEXP = /^_?(?:[A-Z][a-z0-9]*)*_?$/;
14-
const UPPER_CASE_ONLY = /^_?[A-Z]{2,}$/;
14+
const UPPER_CASE_ONLY_REGEXP = /^_?[A-Z]{2,}$/;
1515
function isPascalCase(string: string): boolean {
16-
return PASCAL_CASE_REGEXP.test(string) && !UPPER_CASE_ONLY.test(string);
16+
return PASCAL_CASE_REGEXP.test(string) &&
17+
!UPPER_CASE_ONLY_REGEXP.test(string);
1718
}
1819

1920
const CAMEL_CASE_REGEXP = /^[_a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)*_?$/;
@@ -233,6 +234,38 @@ export default {
233234
if (id.type !== "Identifier") return;
234235
const name = id.name;
235236
if (!name) return;
237+
if (isConstantCase(name)) {
238+
if (
239+
declaration.init?.type === "NewExpression" &&
240+
declaration.init.callee.type === "Identifier"
241+
) {
242+
switch (declaration.init.callee.name) {
243+
case "RegExp": {
244+
if (name !== "REGEXP" && !name.endsWith("_REGEXP")) {
245+
context.report({
246+
node: id,
247+
message:
248+
`RegExp variable name '${name}' must end with _REGEXP.`,
249+
fix: (fixer) =>
250+
fixer.replaceText(id, `${name}_REGEXP`),
251+
});
252+
}
253+
break;
254+
}
255+
}
256+
} else if (
257+
declaration.init?.type === "Literal" &&
258+
declaration.init.value instanceof RegExp &&
259+
name !== "REGEXP" && !name.endsWith("_REGEXP")
260+
) {
261+
context.report({
262+
node: id,
263+
message:
264+
`RegExp variable name '${name}' must end with _REGEXP.`,
265+
fix: (fixer) => fixer.replaceText(id, `${name}_REGEXP`),
266+
});
267+
}
268+
}
236269
if (
237270
!isConstantCase(name) && !isCamelCase(name) &&
238271
!isPascalCase(name)

fmt/colors.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,7 @@ export function bgRgb24(str: string, color: number | Rgb): string {
976976
}
977977

978978
// https://github.com/chalk/ansi-regex/blob/02fa893d619d3da85411acc8fd4e2eea0e95a9d9/index.js
979-
const ANSI_PATTERN = new RegExp(
979+
const ANSI_REGEXP = new RegExp(
980980
[
981981
"[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
982982
"(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TXZcf-nq-uy=><~]))",
@@ -998,5 +998,5 @@ const ANSI_PATTERN = new RegExp(
998998
* @returns The text without ANSI escape codes
999999
*/
10001000
export function stripAnsiCode(string: string): string {
1001-
return string.replace(ANSI_PATTERN, "");
1001+
return string.replace(ANSI_REGEXP, "");
10021002
}

html/entities.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ const defaultUnescapeOptions: UnescapeOptions = {
5353

5454
const MAX_CODE_POINT = 0x10ffff;
5555

56-
const RX_DEC_ENTITY = /&#([0-9]+);/g;
57-
const RX_HEX_ENTITY = /&#x(\p{AHex}+);/gu;
56+
const DEC_ENTITY_REGEXP = /&#([0-9]+);/g;
57+
const HEX_ENTITY_REGEXP = /&#x(\p{AHex}+);/gu;
5858

5959
const entityListRegexCache = new WeakMap<EntityList, RegExp>();
6060

@@ -111,8 +111,8 @@ export function unescape(
111111

112112
return str
113113
.replaceAll(entityRe, (m) => entityList[m]!)
114-
.replaceAll(RX_DEC_ENTITY, (_, dec) => codePointStrToChar(dec, 10))
115-
.replaceAll(RX_HEX_ENTITY, (_, hex) => codePointStrToChar(hex, 16));
114+
.replaceAll(DEC_ENTITY_REGEXP, (_, dec) => codePointStrToChar(dec, 10))
115+
.replaceAll(HEX_ENTITY_REGEXP, (_, hex) => codePointStrToChar(hex, 16));
116116
}
117117

118118
function codePointStrToChar(codePointStr: string, radix: number) {

html/unstable_is_valid_custom_element_name.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const FORBIDDEN_CUSTOM_ELEMENT_NAMES: string[] = [
1212
"missing-glyph",
1313
] as const;
1414

15-
const CUSTOM_ELEMENT_NAME_CHARS =
15+
const CUSTOM_ELEMENT_NAME_CHARS_REGEXP =
1616
/^[a-z](?:[-.0-9_a-z\xB7\xC0-\xD6\xD8-\xF6\xF8-\u037D\u037F-\u1FFF\u200C\u200D\u203F\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]|[\uD800-\uDB7F][\uDC00-\uDFFF]|[\u{10000}-\u{EFFFF}])*-(?:[-.0-9_a-z\xB7\xC0-\xD6\xD8-\xF6\xF8-\u037D\u037F-\u1FFF\u200C\u200D\u203F\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]|[\uD800-\uDB7F][\uDC00-\uDFFF]|[\u{10000}-\u{EFFFF}])*$/u;
1717

1818
/**
@@ -50,5 +50,5 @@ const CUSTOM_ELEMENT_NAME_CHARS =
5050
*/
5151
export function isValidCustomElementName(elementName: string): boolean {
5252
return !FORBIDDEN_CUSTOM_ELEMENT_NAMES.includes(elementName) &&
53-
CUSTOM_ELEMENT_NAME_CHARS.test(elementName);
53+
CUSTOM_ELEMENT_NAME_CHARS_REGEXP.test(elementName);
5454
}

internal/diff_str.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export function unescape(string: string): string {
3535
);
3636
}
3737

38-
const WHITESPACE_SYMBOLS =
38+
const WHITESPACE_SYMBOLS_REGEXP =
3939
/((?:\\[bftv]|[^\S\r\n])+|\\[rn\\]|[()[\]{}'"\r\n]|\b)/;
4040

4141
/**
@@ -57,7 +57,7 @@ const WHITESPACE_SYMBOLS =
5757
export function tokenize(string: string, wordDiff = false): string[] {
5858
if (wordDiff) {
5959
return string
60-
.split(WHITESPACE_SYMBOLS)
60+
.split(WHITESPACE_SYMBOLS_REGEXP)
6161
.filter((token) => token);
6262
}
6363
const tokens: string[] = [];

internal/styles.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ export function bgGreen(str: string): string {
204204
}
205205

206206
// https://github.com/chalk/ansi-regex/blob/02fa893d619d3da85411acc8fd4e2eea0e95a9d9/index.js
207-
const ANSI_PATTERN = new RegExp(
207+
const ANSI_REGEXP = new RegExp(
208208
[
209209
"[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
210210
"(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TXZcf-nq-uy=><~]))",
@@ -227,5 +227,5 @@ const ANSI_PATTERN = new RegExp(
227227
* ```
228228
*/
229229
export function stripAnsiCode(string: string): string {
230-
return string.replace(ANSI_PATTERN, "");
230+
return string.replace(ANSI_REGEXP, "");
231231
}

path/posix/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ export const SEPARATOR = "/" as const;
1212
/**
1313
* A regular expression that matches one or more path separators.
1414
*/
15+
// deno-lint-ignore deno-style-guide/naming-convention
1516
export const SEPARATOR_PATTERN = /\/+/;

path/windows/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ export const SEPARATOR = "\\" as const;
1212
/**
1313
* A regular expression that matches one or more path separators.
1414
*/
15+
// deno-lint-ignore deno-style-guide/naming-convention
1516
export const SEPARATOR_PATTERN = /[\\/]+/;

regexp/escape.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ const RESERVED_CHARS = {
6565
"|": "\\|",
6666
} as const;
6767

68-
const RX_REGEXP_ESCAPE = new RegExp(
68+
const ESCAPE_REGEXP = new RegExp(
6969
`[${Object.values(RESERVED_CHARS).join("")}]`,
7070
"gu",
7171
);
@@ -91,7 +91,7 @@ const RX_REGEXP_ESCAPE = new RegExp(
9191
*/
9292
export function escape(str: string): string {
9393
return str.replaceAll(
94-
RX_REGEXP_ESCAPE,
94+
ESCAPE_REGEXP,
9595
(m) => RESERVED_CHARS[m as keyof typeof RESERVED_CHARS],
9696
).replace(/^[0-9a-zA-Z]/, (m) => `\\x${m.codePointAt(0)!.toString(16)}`);
9797
}

0 commit comments

Comments
 (0)