UNPKG

2.15 kBJavaScriptView Raw
1'use strict';
2const cleanRegexp = require('clean-regexp');
3const {optimize} = require('regexp-tree');
4const getDocumentationUrl = require('./utils/get-documentation-url');
5const quoteString = require('./utils/quote-string');
6
7const message = '{{original}} can be optimized to {{optimized}}';
8
9const create = context => {
10 const {sortCharacterClasses} = context.options[0] || {};
11
12 const blacklist = [];
13
14 if (sortCharacterClasses === false) {
15 blacklist.push('charClassClassrangesMerge');
16 }
17
18 return {
19 'Literal[regex]': node => {
20 const {raw: original, regex} = node;
21
22 // Regular Expressions with `u` flag are not well handled by `regexp-tree`
23 // https://github.com/DmitrySoshnikov/regexp-tree/issues/162
24 if (regex.flags.includes('u')) {
25 return;
26 }
27
28 let optimized = original;
29
30 try {
31 optimized = optimize(original, undefined, {blacklist}).toString();
32 } catch (_) {}
33
34 if (original === optimized) {
35 return;
36 }
37
38 context.report({
39 node,
40 message,
41 data: {
42 original,
43 optimized
44 },
45 fix: fixer => fixer.replaceText(node, optimized)
46 });
47 },
48 'NewExpression[callee.type="Identifier"][callee.name="RegExp"][arguments.length>=1][arguments.0.type="Literal"]': node => {
49 const [patternNode, flagsNode] = node.arguments;
50
51 if (typeof patternNode.value !== 'string') {
52 return;
53 }
54
55 const oldPattern = patternNode.value;
56 const flags = flagsNode &&
57 flagsNode.type === 'Literal' &&
58 typeof flagsNode.value === 'string' ?
59 flagsNode.value :
60 '';
61
62 const newPattern = cleanRegexp(oldPattern, flags);
63
64 if (oldPattern !== newPattern) {
65 context.report({
66 node,
67 message,
68 data: {
69 original: oldPattern,
70 optimized: newPattern
71 },
72 fix: fixer => fixer.replaceText(
73 patternNode,
74 quoteString(newPattern)
75 )
76 });
77 }
78 }
79 };
80};
81
82const schema = [
83 {
84 type: 'object',
85 properties: {
86 sortCharacterClasses: {
87 type: 'boolean',
88 default: true
89 }
90 }
91 }
92];
93
94module.exports = {
95 create,
96 meta: {
97 type: 'suggestion',
98 docs: {
99 url: getDocumentationUrl(__filename)
100 },
101 fixable: 'code',
102 schema
103 }
104};