/** * @fileoverview Rule to flag the use of empty character classes in regular expressions * @author Ian Christian Myers */ 'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ const { RegExpParser, visitRegExpAST } = require('@eslint-community/regexpp'); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ const parser = new RegExpParser(); const QUICK_TEST_REGEX = /\[\]/u; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ /** @type {import('../types').Rule.RuleModule} */ module.exports = { meta: { type: 'problem', docs: { description: 'Disallow empty character classes in regular expressions', recommended: true, url: 'https://eslint.org/docs/latest/rules/no-empty-character-class', }, schema: [], messages: { unexpected: 'Empty class.', }, }, create(context) { return { 'Literal[regex]'(node) { const { pattern, flags } = node.regex; if (!QUICK_TEST_REGEX.test(pattern)) { return; } let regExpAST; try { regExpAST = parser.parsePattern(pattern, 0, pattern.length, { unicode: flags.includes('u'), unicodeSets: flags.includes('v'), }); } catch { // Ignore regular expressions that regexpp cannot parse return; } visitRegExpAST(regExpAST, { onCharacterClassEnter(characterClass) { if ( !characterClass.negate && characterClass.elements.length === 0 ) { context.report({ node, messageId: 'unexpected' }); } }, }); }, }; }, };