js-compiler: Update regex lints to use new AST nodes
MODIFY
packages/@romejs/js-compiler/transforms/lint/disallowMultipleSpacesInRegularExpressionLiterals.ts
packages/@romejs/js-compiler/transforms/lint/disallowMultipleSpacesInRegularExpressionLiterals.ts
* LICENSE file in the root directory of this source tree.
*/
-import {AnyNode} from '@romejs/js-ast';
+import {AnyNode, RegExpCharacter} from '@romejs/js-ast';
import {Path} from '@romejs/js-compiler';
-
-const multipleSpacesPattern = /( {2,})(?: [+*{?]|[^+*{?]|$)/gu;
+import {extractSourceLocationRangeFromNodes} from '@romejs/parser-core';
export default {
name: 'disallowMultipleSpacesInRegularExpressionLiterals',
enter(path: Path): AnyNode {
const {context, node} = path;
- if (
- (node.type === 'NewExpression' &&
- node.callee.type === 'ReferenceIdentifier' &&
- node.callee.name === 'RegExp' &&
- node.arguments.length > 0 &&
- node.arguments[0].type === 'StringLiteral' &&
- multipleSpacesPattern.test(node.arguments[0].value)) ||
- (node.type === 'RegExpLiteral' &&
- multipleSpacesPattern.test(node.pattern))
- ) {
- context.addNodeDiagnostic(node, {
- category: 'lint/disallowMultipleSpacesInRegularExpressionLiterals',
- message: 'Disallow multiple spaces in regular expression literals',
- });
+ if (node.type === 'RegExpSubExpression') {
+ for (let i = 0; i < node.body.length; i++) {
+ const spaceNodes: Array<RegExpCharacter> = [];
+
+ while (true) {
+ const item = node.body[i];
+ if (item.type === 'RegExpCharacter' && item.value === ' ') {
+ spaceNodes.push(item);
+ i++;
+ } else {
+ break;
+ }
+ }
+
+ if (spaceNodes.length > 1) {
+ context.addLocDiagnostic(
+ extractSourceLocationRangeFromNodes(spaceNodes),
+ {
+ category:
+ 'lint/disallowMultipleSpacesInRegularExpressionLiterals',
+ message:
+ "Multiple spaces aren't allowed in regular expression literals",
+ },
+ );
+ }
+ }
}
return node;

MODIFY
packages/@romejs/js-compiler/transforms/lint/noEmptyCharacterClass.ts
packages/@romejs/js-compiler/transforms/lint/noEmptyCharacterClass.ts
* LICENSE file in the root directory of this source tree.
*/
-import {AnyNode} from '@romejs/js-ast';
-import {Path} from '@romejs/js-compiler';
-
-/*
- * plain-English description of the following regexp:
- * 1. `^` fix the match at the beginning of the string
- * 2. `([^\\[]|\\.|\[([^\\\]]|\\.)+\])*`: regexp contents; 0 or more of the following
- * 2.0. `[^\\[]`: any character that's not a `\` or a `[` (anything but escape sequences and character classes)
- * 2.1. `\\.`: an escape sequence
- * 2.2. `\[([^\\\]]|\\.)+\]`: a character class that isn't empty
- * 3. `$`: fix the match at the end of the string
- */
-
-const regex = /^([^\\[]|\\.|\[([^\\\]]|\\.)+\])*$/u;
+import {Path, REDUCE_REMOVE, TransformExitResult} from '@romejs/js-compiler';
export default {
name: 'noEmptyCharacterClass',
- enter(path: Path): AnyNode {
+ enter(path: Path): TransformExitResult {
const {context, node} = path;
- if (node.type === 'RegExpLiteral' && !regex.test(node.pattern)) {
+ if (node.type === 'RegExpCharSet') {
+ if (node.body.length === 0) {
context.addNodeDiagnostic(node, {
category: 'lint/noEmptyCharacterClass',
message:
'Empty character classes in regular expressions are not allowed',
});
+ return REDUCE_REMOVE;
+ }
}
return node;

js-compiler: Update regex lints to use new AST nodes