added lint to check for empty and infinite matches
MODIFY
packages/@romejs/diagnostics/categories.ts
packages/@romejs/diagnostics/categories.ts
@@ -67,6 +67,7 @@ export type DiagnosticCategory =
| 'lint/undeclaredVariables'
| 'lint/unsafeNegation'
| 'lint/unusedVariables'
+ | 'lint/emptyMatches'
| 'lsp/parse'
| 'parse/js'
| 'parse/json'

MODIFY
packages/@romejs/diagnostics/descriptions.ts
packages/@romejs/diagnostics/descriptions.ts
@@ -490,6 +490,10 @@ export const descriptions = createMessages({
category: 'lint/noEmptyCharacterClass',
message: 'Empty character classes in regular expressions are not allowed',
},
+ EMPTY_MATCHES: {
+ category: 'lint/emptyMatches',
+ message: 'The expression can return empty matches, and may match infinitely in some use cases',
+ },
NO_DUPLICATE_KEYS: (key: string) => ({
category: 'lint/noDuplicateKeys',
message: markup`Duplicate key <emphasis>${key}</emphasis>`,

ADD
packages/@romejs/js-compiler/lint/rules/emptyMatches.test.ts
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import {test} from 'rome';
+import {testLintMultiple} from '../testHelpers';
+
+test(
+ 'empty matches; may match infinitely',
+ async (t) => {
+ await testLintMultiple(
+ t,
+ [
+ // infinite match possible
+ 'let a = /a*/',
+ 'let b = /a*(abc)?[1,2,3]*/',
+
+ // valid regexes
+ 'let a = /a*(abc)+[1,2,3]?/',
+ 'let b = /a+(abc)*/',
+ ],
+ {category: 'lint/emptyMatches'},
+ );
+ },
+);

ADD
packages/@romejs/js-compiler/lint/rules/emptyMatches.ts
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import {Path, TransformExitResult} from '@romejs/js-compiler';
+import {descriptions} from '@romejs/diagnostics';
+
+export default {
+ name: 'noEmptyCharacterClass',
+ enter(path: Path): TransformExitResult {
+ const {context, node} = path;
+ if (node.type === 'RegExpSubExpression') {
+ let isQuantifiedMinZero = el => el.type === 'RegExpQuantified' && el.min == 0;
+ if (node.body.every(isQuantifiedMinZero)) {
+ context.addNodeDiagnostic(node, descriptions.LINT.EMPTY_MATCHES);
+ }
+ }
+ return node;
+ },
+};

MODIFY
packages/@romejs/js-compiler/lint/rules/index.ts
packages/@romejs/js-compiler/lint/rules/index.ts
@@ -51,6 +51,7 @@ import sparseArray from './sparseArray';
import undeclaredVariables from './undeclaredVariables';
import unsafeNegation from './unsafeNegation';
import unusedVariables from './unusedVariables';
+import emptyMatches from './emptyMatches';
// Add transforms in alphabetical order.
export const lintTransforms = [
@@ -99,4 +100,5 @@ export const lintTransforms = [
undeclaredVariables,
unsafeNegation,
unusedVariables,
+ emptyMatches,
];

added lint to check for empty and infinite matches