@so1ve/eslint-plugin 0.56.1 → 0.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,369 +1,12 @@
1
1
  'use strict';
2
2
 
3
3
  const utils = require('@typescript-eslint/utils');
4
- const reactivity = require('@vue/reactivity');
5
- const util = require('@typescript-eslint/utils/dist/ast-utils');
6
-
7
- function _interopNamespaceDefault(e) {
8
- const n = Object.create(null);
9
- if (e) {
10
- for (const k in e) {
11
- n[k] = e[k];
12
- }
13
- }
14
- n.default = e;
15
- return n;
16
- }
17
-
18
- const util__namespace = /*#__PURE__*/_interopNamespaceDefault(util);
19
4
 
20
5
  const createEslintRule = utils.ESLintUtils.RuleCreator((ruleName) => ruleName);
21
6
 
22
- const RULE_NAME$8 = "array-bracket-spacing";
23
- const arrayBracketSpacing = createEslintRule({
24
- name: RULE_NAME$8,
25
- meta: {
26
- type: "layout",
27
- docs: {
28
- description: "Array bracket spacing",
29
- recommended: "error"
30
- },
31
- fixable: "whitespace",
32
- schema: [],
33
- messages: {
34
- arrayBracketSpacing: "Array bracket spacing mismatch"
35
- }
36
- },
37
- defaultOptions: [],
38
- create: (context) => {
39
- const sourceCode = context.getSourceCode();
40
- const text = sourceCode.getText();
41
- const checkNode = (node) => {
42
- const elements = node.type === utils.AST_NODE_TYPES.TSTupleType ? node.elementTypes : node.elements;
43
- const firstElement = elements[0];
44
- const lastElement = elements[elements.length - 1];
45
- if (!firstElement) {
46
- return;
47
- }
48
- const leftToken = sourceCode.getTokenBefore(firstElement);
49
- const rightToken = reactivity.ref(sourceCode.getTokenAfter(lastElement));
50
- if (rightToken.value.value === ",") {
51
- rightToken.value = sourceCode.getTokenAfter(rightToken.value);
52
- }
53
- const textBetweenFirstAndToken = reactivity.computed(() => text.slice(leftToken.range[1], firstElement.range[0]));
54
- const isNewline = reactivity.computed(() => textBetweenFirstAndToken.value.includes("\n"));
55
- const textBetweenLastAndToken = reactivity.computed(() => text.slice(lastElement.range[1], rightToken.value.range[0]));
56
- const hasNewlineAfter = reactivity.computed(() => textBetweenLastAndToken.value.includes("\n"));
57
- if (sourceCode.isSpaceBetween(leftToken, firstElement) && !isNewline.value) {
58
- context.report({
59
- node,
60
- messageId: "arrayBracketSpacing",
61
- *fix(fixer) {
62
- yield fixer.removeRange([leftToken.range[1], firstElement.range[0]]);
63
- }
64
- });
65
- }
66
- if (sourceCode.isSpaceBetween(lastElement, rightToken.value)) {
67
- if (!isNewline.value) {
68
- context.report({
69
- node,
70
- messageId: "arrayBracketSpacing",
71
- *fix(fixer) {
72
- yield fixer.removeRange([lastElement.range[1], rightToken.value.range[0]]);
73
- }
74
- });
75
- }
76
- }
77
- if (isNewline.value && !hasNewlineAfter.value) {
78
- context.report({
79
- node,
80
- messageId: "arrayBracketSpacing",
81
- *fix(fixer) {
82
- yield fixer.replaceTextRange([lastElement.range[1], rightToken.value.range[0]], "\n");
83
- }
84
- });
85
- }
86
- };
87
- return {
88
- TSTupleType: checkNode,
89
- ArrayExpression: checkNode
90
- };
91
- }
92
- });
93
-
94
- const RULE_NAME$7 = "generic-spacing";
95
- const genericSpacing = createEslintRule({
96
- name: RULE_NAME$7,
97
- meta: {
98
- type: "layout",
99
- docs: {
100
- description: "Spaces around generic type parameters",
101
- recommended: "error"
102
- },
103
- fixable: "whitespace",
104
- schema: [],
105
- messages: {
106
- genericSpacingMismatch: "Generic spaces mismatch"
107
- }
108
- },
109
- defaultOptions: [],
110
- create: (context) => {
111
- const sourceCode = context.getSourceCode();
112
- const text = sourceCode.getText();
113
- return {
114
- TSTypeParameterDeclaration: (node) => {
115
- const params = node.params;
116
- for (const param of params) {
117
- const leftToken = sourceCode.getTokenBefore(param);
118
- const rightToken = sourceCode.getTokenAfter(param);
119
- const hasSpacingBeforeParam = sourceCode.isSpaceBetween(leftToken, param);
120
- const hasSpacingAfterParam = sourceCode.isSpaceBetween(param, rightToken);
121
- if (hasSpacingBeforeParam && param.loc.start.line === node.loc.start.line && leftToken.value === "<") {
122
- context.report({
123
- node,
124
- loc: {
125
- start: {
126
- line: leftToken.loc.end.line,
127
- column: leftToken.loc.end.column
128
- },
129
- end: {
130
- line: param.loc.start.line,
131
- column: param.loc.start.column - 1
132
- }
133
- },
134
- messageId: "genericSpacingMismatch",
135
- *fix(fixer) {
136
- yield fixer.removeRange([leftToken.range[1], param.range[0]]);
137
- }
138
- });
139
- }
140
- if (hasSpacingAfterParam && param.loc.end.line === node.loc.end.line) {
141
- context.report({
142
- loc: {
143
- start: {
144
- line: param.loc.end.line,
145
- column: param.loc.end.column
146
- },
147
- end: {
148
- line: rightToken.loc.start.line,
149
- column: rightToken.loc.start.column
150
- }
151
- },
152
- node,
153
- messageId: "genericSpacingMismatch",
154
- *fix(fixer) {
155
- yield fixer.removeRange([param.range[1], rightToken.range[0]]);
156
- }
157
- });
158
- }
159
- if (!hasSpacingBeforeParam && util__namespace.isCommaToken(leftToken)) {
160
- context.report({
161
- node,
162
- loc: {
163
- start: {
164
- line: leftToken.loc.end.line,
165
- column: leftToken.loc.end.column
166
- },
167
- end: {
168
- line: param.loc.start.line,
169
- column: param.loc.start.column - 1
170
- }
171
- },
172
- messageId: "genericSpacingMismatch",
173
- *fix(fixer) {
174
- yield fixer.replaceTextRange([leftToken.range[1], param.range[0]], " ");
175
- }
176
- });
177
- }
178
- }
179
- if (!["TSCallSignatureDeclaration", "ArrowFunctionExpression"].includes(node.parent.type)) {
180
- const leftToken = sourceCode.getTokenBefore(node);
181
- const hasSpacingBeforeNode = sourceCode.isSpaceBetween(leftToken, node);
182
- const lastParam = params[params.length - 1];
183
- const endBracket = sourceCode.getTokenAfter(lastParam);
184
- const rightToken = sourceCode.getTokenAfter(endBracket, util__namespace.isOpeningParenToken);
185
- if (!rightToken) {
186
- return;
187
- }
188
- const hasSpacingAfterParam = sourceCode.isSpaceBetween(endBracket, rightToken);
189
- if (hasSpacingBeforeNode && node.parent.type !== utils.AST_NODE_TYPES.TSFunctionType) {
190
- context.report({
191
- node,
192
- loc: {
193
- start: {
194
- line: leftToken.loc.end.line,
195
- column: leftToken.loc.end.column
196
- },
197
- end: {
198
- line: node.loc.start.line,
199
- column: node.loc.start.column
200
- }
201
- },
202
- messageId: "genericSpacingMismatch",
203
- *fix(fixer) {
204
- yield fixer.removeRange([leftToken.range[1], node.range[0]]);
205
- }
206
- });
207
- }
208
- if (hasSpacingAfterParam && [utils.AST_NODE_TYPES.TSFunctionType, utils.AST_NODE_TYPES.FunctionDeclaration, utils.AST_NODE_TYPES.FunctionExpression].includes(node.parent.type)) {
209
- context.report({
210
- node,
211
- loc: {
212
- start: {
213
- line: endBracket.loc.end.line,
214
- column: endBracket.loc.end.column
215
- },
216
- end: {
217
- line: rightToken.loc.start.line,
218
- column: rightToken.loc.start.column
219
- }
220
- },
221
- messageId: "genericSpacingMismatch",
222
- *fix(fixer) {
223
- yield fixer.removeRange([endBracket.range[1], rightToken.range[0]]);
224
- }
225
- });
226
- }
227
- }
228
- },
229
- // add space around = in type Foo<T = true>
230
- TSTypeParameter: (node) => {
231
- if (!node.default) {
232
- return;
233
- }
234
- const endNode = node.constraint ?? node.name;
235
- const from = endNode.range[1];
236
- const to = node.default.range[0];
237
- const spaceAndEqual = sourceCode.text.slice(from, to);
238
- if (spaceAndEqual !== " = ") {
239
- const preSpace = spaceAndEqual.match(/^(\s*)/)?.[0];
240
- const postSpace = spaceAndEqual.match(/(\s*)$/)?.[0];
241
- if (preSpace.length !== 1) {
242
- context.report({
243
- *fix(fixer) {
244
- yield fixer.replaceTextRange([from, from + preSpace.length], " ");
245
- },
246
- loc: {
247
- start: {
248
- line: node.loc.start.line,
249
- column: node.loc.start.column + 1
250
- },
251
- end: {
252
- line: node.loc.end.line,
253
- column: node.loc.end.column - 2 - postSpace.length
254
- }
255
- },
256
- node,
257
- messageId: "genericSpacingMismatch"
258
- });
259
- }
260
- if (postSpace.length !== 1) {
261
- context.report({
262
- *fix(fixer) {
263
- yield fixer.replaceTextRange([to - postSpace.length, to], " ");
264
- },
265
- loc: {
266
- start: {
267
- line: node.loc.start.line,
268
- column: node.loc.start.column + 2 + preSpace.length
269
- },
270
- end: {
271
- line: node.loc.end.line,
272
- column: node.loc.end.column - 1
273
- }
274
- },
275
- messageId: "genericSpacingMismatch"
276
- });
277
- }
278
- }
279
- },
280
- // type T = Generic< any >
281
- TSTypeParameterInstantiation: (node) => {
282
- const params = node.params;
283
- for (const param of params) {
284
- const leftToken = sourceCode.getTokenBefore(param);
285
- const rightToken = sourceCode.getTokenAfter(param);
286
- const hasSpacingBeforeParam = leftToken.value === "<" ? sourceCode.isSpaceBetween(leftToken, param) : false;
287
- const hasSpacingAfterParam = rightToken.value === ">" ? sourceCode.isSpaceBetween(param, rightToken) : false;
288
- if (hasSpacingBeforeParam && leftToken.loc.end.line === param.loc.start.line) {
289
- context.report({
290
- node,
291
- loc: {
292
- start: {
293
- line: leftToken.loc.end.line,
294
- column: leftToken.loc.end.column
295
- },
296
- end: {
297
- line: param.loc.start.line,
298
- column: param.loc.start.column
299
- }
300
- },
301
- messageId: "genericSpacingMismatch",
302
- *fix(fixer) {
303
- yield fixer.removeRange([leftToken.range[1], param.range[0]]);
304
- }
305
- });
306
- }
307
- if (hasSpacingAfterParam && param.loc.end.line === rightToken.loc.start.line) {
308
- context.report({
309
- node,
310
- loc: {
311
- start: {
312
- line: param.loc.end.line,
313
- column: param.loc.end.column
314
- },
315
- end: {
316
- line: rightToken.loc.start.line,
317
- column: rightToken.loc.start.column
318
- }
319
- },
320
- messageId: "genericSpacingMismatch",
321
- *fix(fixer) {
322
- yield fixer.removeRange([param.range[1], rightToken.range[0]]);
323
- }
324
- });
325
- }
326
- }
327
- },
328
- // Add spaces before extends
329
- // interface a {}
330
- // interface A<B extends 1>extends a {}
331
- // Fix to: interface A<B extends 1> extends a {}
332
- TSInterfaceDeclaration: (node) => {
333
- if (!node.extends || !node.typeParameters) {
334
- return;
335
- }
336
- const { typeParameters } = node;
337
- const extendsKeywordStart = typeParameters.range[1];
338
- const extendsKeywordEnd = node.extends[0].range[0];
339
- const extendsText = text.slice(extendsKeywordStart, extendsKeywordEnd);
340
- if (!/^\s+/.test(extendsText)) {
341
- context.report({
342
- loc: {
343
- start: {
344
- line: typeParameters.loc.end.line,
345
- column: typeParameters.loc.end.column
346
- },
347
- end: {
348
- line: typeParameters.loc.end.line,
349
- column: typeParameters.loc.end.column + 7
350
- }
351
- },
352
- node,
353
- messageId: "genericSpacingMismatch",
354
- *fix(fixer) {
355
- yield fixer.replaceTextRange([extendsKeywordStart, extendsKeywordEnd - 8], " ");
356
- }
357
- });
358
- }
359
- }
360
- };
361
- }
362
- });
363
-
364
- const RULE_NAME$6 = "import-dedupe";
7
+ const RULE_NAME$2 = "import-dedupe";
365
8
  const importDedupe = createEslintRule({
366
- name: RULE_NAME$6,
9
+ name: RULE_NAME$2,
367
10
  meta: {
368
11
  type: "problem",
369
12
  docs: {
@@ -411,9 +54,9 @@ const importDedupe = createEslintRule({
411
54
  }
412
55
  });
413
56
 
414
- const RULE_NAME$5 = "no-inline-type-import";
57
+ const RULE_NAME$1 = "no-inline-type-import";
415
58
  const noInlineTypeImport = createEslintRule({
416
- name: RULE_NAME$5,
59
+ name: RULE_NAME$1,
417
60
  meta: {
418
61
  type: "layout",
419
62
  docs: {
@@ -463,450 +106,34 @@ import { ${valueSpecifiersText} } from "${node.source.value}";`
463
106
  }
464
107
  });
465
108
 
466
- const RULE_NAME$4 = "no-space-before-paren";
467
- const noSpaceBeforeParen = createEslintRule({
468
- name: RULE_NAME$4,
469
- meta: {
470
- type: "layout",
471
- docs: {
472
- description: "Space before paren",
473
- recommended: "error"
474
- },
475
- fixable: "whitespace",
476
- schema: [],
477
- messages: {
478
- noSpaceBeforeParen: "Expected no space before paren"
479
- }
480
- },
481
- defaultOptions: [],
482
- create: (context) => {
483
- const sourceCode = context.getSourceCode();
484
- const text = sourceCode.getText();
485
- return {
486
- ImportExpression(node) {
487
- const sourceRange = node.source.range;
488
- const parenStart = sourceRange[0] - 1;
489
- const importEnd = node.range[0] + 6;
490
- const textBetweenImportAndParenRange = [importEnd, parenStart];
491
- const textBetweenImportAndParen = text.slice(...textBetweenImportAndParenRange);
492
- if (textBetweenImportAndParen.length > 0) {
493
- context.report({
494
- node,
495
- messageId: "noSpaceBeforeParen",
496
- *fix(fixer) {
497
- yield fixer.removeRange(textBetweenImportAndParenRange);
498
- }
499
- });
500
- }
501
- },
502
- CallExpression(node) {
503
- let caller = "property" in node.callee ? node.callee.property : node.callee;
504
- if (caller.type === utils.AST_NODE_TYPES.TSInstantiationExpression && "property" in caller.expression) {
505
- caller = caller.expression.property;
506
- }
507
- const callerEnd = reactivity.ref(caller.range[1]);
508
- const textAfterCaller = reactivity.computed(() => text.slice(callerEnd.value));
509
- const parenStart = reactivity.ref(callerEnd.value + textAfterCaller.value.indexOf("("));
510
- const textBetweenFunctionNameAndParenRange = reactivity.computed(
511
- () => [callerEnd.value, parenStart.value]
512
- );
513
- const textBetweenFunctionNameAndParen = reactivity.computed(
514
- () => text.slice(...textBetweenFunctionNameAndParenRange.value)
515
- );
516
- const hasGenerics = reactivity.computed(() => /^\s*</.test(textBetweenFunctionNameAndParen.value));
517
- const hasIndex = reactivity.computed(() => textBetweenFunctionNameAndParen.value.startsWith("]"));
518
- if (hasIndex.value) {
519
- callerEnd.value += 1;
520
- }
521
- if (node.optional) {
522
- parenStart.value = callerEnd.value + textAfterCaller.value.indexOf("(");
523
- }
524
- const spaces = /(\s*)$/.exec(textBetweenFunctionNameAndParen.value)[1];
525
- if (!hasGenerics.value) {
526
- if (spaces.length > 0 && textBetweenFunctionNameAndParen.value !== "?.") {
527
- const textBeforeSpaces = textBetweenFunctionNameAndParen.value.slice(
528
- 0,
529
- textBetweenFunctionNameAndParen.value.length - spaces.length
530
- );
531
- context.report({
532
- node,
533
- messageId: "noSpaceBeforeParen",
534
- *fix(fixer) {
535
- yield fixer.replaceTextRange(
536
- textBetweenFunctionNameAndParenRange.value,
537
- textBeforeSpaces + (node.optional ? "?." : "")
538
- );
539
- }
540
- });
541
- }
542
- } else {
543
- const preSpaces = /^(\s*)/.exec(textBetweenFunctionNameAndParen.value)[1];
544
- const postSpaces = /(\s*)$/.exec(textBetweenFunctionNameAndParen.value)[1];
545
- const spacesBeforeOptionalMark = /(\s*)\?\./.exec(textBetweenFunctionNameAndParen.value)?.[1] ?? "";
546
- if (preSpaces.length > 0) {
547
- context.report({
548
- node,
549
- messageId: "noSpaceBeforeParen",
550
- *fix(fixer) {
551
- yield fixer.removeRange([callerEnd.value, callerEnd.value + preSpaces.length]);
552
- }
553
- });
554
- }
555
- if (postSpaces.length > 0) {
556
- context.report({
557
- node,
558
- messageId: "noSpaceBeforeParen",
559
- *fix(fixer) {
560
- yield fixer.removeRange([parenStart.value - postSpaces.length, parenStart.value]);
561
- }
562
- });
563
- }
564
- if (spacesBeforeOptionalMark.length > 0 && !textBetweenFunctionNameAndParen.value.endsWith(" ")) {
565
- context.report({
566
- node,
567
- messageId: "noSpaceBeforeParen",
568
- *fix(fixer) {
569
- yield fixer.removeRange([parenStart.value - spacesBeforeOptionalMark.length - 2, parenStart.value - 2]);
570
- }
571
- });
572
- }
573
- }
574
- },
575
- NewExpression(node) {
576
- const calleeEnd = node.callee.range[1];
577
- const textAfterCallee = text.slice(calleeEnd);
578
- const parenStart = calleeEnd + textAfterCallee.indexOf("(");
579
- const textBetweenCalleeAndParenRange = [calleeEnd, parenStart];
580
- const textBetweenCalleeAndParen = text.slice(...textBetweenCalleeAndParenRange);
581
- const hasGenerics = /^\s*</.test(textBetweenCalleeAndParen);
582
- if (!hasGenerics && textBetweenCalleeAndParen.length > 0) {
583
- context.report({
584
- node,
585
- messageId: "noSpaceBeforeParen",
586
- *fix(fixer) {
587
- yield fixer.removeRange(textBetweenCalleeAndParenRange);
588
- }
589
- });
590
- } else if (hasGenerics) {
591
- const preSpaces = /^(\s*)/.exec(textBetweenCalleeAndParen)[1];
592
- const postSpaces = /(\s*)$/.exec(textBetweenCalleeAndParen)[1];
593
- if (preSpaces.length > 0) {
594
- context.report({
595
- node,
596
- messageId: "noSpaceBeforeParen",
597
- *fix(fixer) {
598
- yield fixer.removeRange([calleeEnd, calleeEnd + preSpaces.length]);
599
- }
600
- });
601
- }
602
- if (postSpaces.length > 0) {
603
- context.report({
604
- node,
605
- messageId: "noSpaceBeforeParen",
606
- *fix(fixer) {
607
- yield fixer.removeRange([parenStart - postSpaces.length, parenStart]);
608
- }
609
- });
610
- }
611
- }
612
- }
613
- };
614
- }
615
- });
616
-
617
- const RULE_NAME$3 = "semi-spacing";
618
- const semiSpacing = createEslintRule({
619
- name: RULE_NAME$3,
620
- meta: {
621
- type: "layout",
622
- docs: {
623
- description: "Semicolon spacing in types",
624
- recommended: "error"
625
- },
626
- fixable: "whitespace",
627
- schema: [],
628
- messages: {
629
- noSpaceBeforeSemi: "Expected no space before semicolon"
630
- }
631
- },
632
- defaultOptions: [],
633
- create: (context) => {
634
- const sourceCode = context.getSourceCode();
635
- return {
636
- TSTypeAliasDeclaration(node) {
637
- const leftToken = node.typeAnnotation;
638
- const rightToken = sourceCode.getTokenAfter(node.typeAnnotation);
639
- if (!rightToken || rightToken.type !== utils.AST_TOKEN_TYPES.Punctuator || rightToken.value !== ";") {
640
- return;
641
- }
642
- const hasSpacing = sourceCode.isSpaceBetween(leftToken, rightToken);
643
- if (hasSpacing) {
644
- context.report({
645
- loc: {
646
- start: {
647
- line: leftToken.loc.end.line,
648
- column: leftToken.loc.end.column
649
- },
650
- end: {
651
- line: rightToken.loc.start.line,
652
- column: rightToken.loc.start.column
653
- }
654
- },
655
- node,
656
- messageId: "noSpaceBeforeSemi",
657
- *fix(fixer) {
658
- yield fixer.removeRange([leftToken.range[1], rightToken.range[0]]);
659
- }
660
- });
661
- }
662
- }
663
- };
664
- }
665
- });
666
-
667
- const RULE_NAME$2 = "space-before-function-paren";
668
- const spaceBeforeFunctionParen = createEslintRule({
669
- name: RULE_NAME$2,
670
- meta: {
671
- type: "layout",
672
- docs: {
673
- description: "Enforce consistent spacing before function parenthesis",
674
- recommended: false,
675
- extendsBaseRule: true
676
- },
677
- fixable: "whitespace",
678
- schema: [
679
- {
680
- oneOf: [
681
- {
682
- enum: ["always", "never"]
683
- },
684
- {
685
- type: "object",
686
- properties: {
687
- anonymous: {
688
- enum: ["always", "never", "ignore"]
689
- },
690
- named: {
691
- enum: ["always", "never", "ignore"]
692
- },
693
- asyncArrow: {
694
- enum: ["always", "never", "ignore"]
695
- }
696
- },
697
- additionalProperties: false
698
- }
699
- ]
700
- }
701
- ],
702
- messages: {
703
- unexpected: "Unexpected space before function parentheses.",
704
- missing: "Missing space before function parentheses."
705
- }
706
- },
707
- defaultOptions: ["always"],
708
- create(context, [firstOption]) {
709
- const sourceCode = context.getSourceCode();
710
- const baseConfig = typeof firstOption === "string" ? firstOption : "always";
711
- const overrideConfig = typeof firstOption === "object" ? firstOption : {};
712
- function isNamedFunction(node) {
713
- if (node.id != null) {
714
- return true;
715
- }
716
- const parent = node.parent;
717
- return parent.type === utils.AST_NODE_TYPES.MethodDefinition || parent.type === utils.AST_NODE_TYPES.TSAbstractMethodDefinition || parent.type === utils.AST_NODE_TYPES.Property && (parent.kind === "get" || parent.kind === "set" || parent.method);
718
- }
719
- function getConfigForFunction(node) {
720
- if (node.type === utils.AST_NODE_TYPES.ArrowFunctionExpression) {
721
- if (node.async && util__namespace.isOpeningParenToken(sourceCode.getFirstToken(node, { skip: 1 }))) {
722
- return overrideConfig.asyncArrow ?? baseConfig;
723
- }
724
- } else if (isNamedFunction(node)) {
725
- return overrideConfig.named ?? baseConfig;
726
- } else if (!node.generator) {
727
- return overrideConfig.anonymous ?? baseConfig;
728
- }
729
- return "ignore";
730
- }
731
- function checkFunction(node) {
732
- const functionConfig = getConfigForFunction(node);
733
- if (functionConfig === "ignore") {
734
- return;
735
- }
736
- let leftToken, rightToken;
737
- if (node.typeParameters) {
738
- leftToken = sourceCode.getLastToken(node.typeParameters);
739
- rightToken = sourceCode.getTokenAfter(leftToken);
740
- } else {
741
- rightToken = sourceCode.getFirstToken(node, util__namespace.isOpeningParenToken);
742
- leftToken = sourceCode.getTokenBefore(rightToken);
743
- }
744
- const hasSpacing = sourceCode.isSpaceBetween(leftToken, rightToken);
745
- if (hasSpacing && functionConfig === "never") {
746
- context.report({
747
- node,
748
- loc: {
749
- start: leftToken.loc.end,
750
- end: rightToken.loc.start
751
- },
752
- messageId: "unexpected",
753
- fix: (fixer) => fixer.removeRange([leftToken.range[1], rightToken.range[0]])
754
- });
755
- } else if (!hasSpacing && functionConfig === "always" && !node.typeParameters) {
756
- context.report({
757
- node,
758
- loc: rightToken.loc,
759
- messageId: "missing",
760
- fix: (fixer) => fixer.insertTextAfter(leftToken, " ")
761
- });
762
- }
763
- }
764
- return {
765
- ArrowFunctionExpression: checkFunction,
766
- FunctionDeclaration: checkFunction,
767
- FunctionExpression: checkFunction,
768
- TSEmptyBodyFunctionExpression: checkFunction,
769
- TSDeclareFunction: checkFunction
770
- };
771
- }
772
- });
773
-
774
- const operatorOrAnyBracketOrKeywordRE = /^(\||&|\*|\+|\-|\/|%|<|>|<=|>=|==|!=|===|!==|\[|\(|\{|as|extends|implements|keyof|new|readonly|typeof|unique|unknown)/;
775
- const RULE_NAME$1 = "space-between-generic-and-paren";
776
- const spaceBetweenGenericAndParen = createEslintRule({
777
- name: RULE_NAME$1,
778
- meta: {
779
- type: "layout",
780
- docs: {
781
- description: "Spaces between generic type parameters and paren",
782
- recommended: "error"
783
- },
784
- fixable: "whitespace",
785
- schema: [],
786
- messages: {
787
- noSpaceBetweenGenericAndParen: "Expected no space between generic type parameters and paren"
788
- }
789
- },
790
- defaultOptions: [],
791
- create: (context) => {
792
- const sourceCode = context.getSourceCode();
793
- const text = sourceCode.text;
794
- return {
795
- TSTypeParameter: (node) => {
796
- const spaceStartRange = node.range[1] + 1;
797
- const post = text.slice(spaceStartRange);
798
- const postSpace = post.match(/^(\s*)/)?.[0];
799
- const postEqual = post.slice(postSpace.length).match(/^(=)/)?.[0];
800
- const postComma = text.slice(node.range[1]).match(/^(,)/)?.[0];
801
- const postQuestionMark = text.slice(spaceStartRange + postSpace.length).match(/^(\?)/)?.[0];
802
- const postOperatorOrAnyBracketOrKeyword = text.slice(spaceStartRange + postSpace.length).match(operatorOrAnyBracketOrKeywordRE)?.[0];
803
- if (postSpace?.length && !postEqual && !postComma && !postQuestionMark && !postOperatorOrAnyBracketOrKeyword && node.parent.type !== utils.AST_NODE_TYPES.TSInferType) {
804
- context.report({
805
- loc: {
806
- start: {
807
- line: node.loc.end.line,
808
- column: node.loc.end.column + 1
809
- },
810
- end: {
811
- line: node.loc.end.line,
812
- column: node.loc.end.column + 1 + postSpace.length
813
- }
814
- },
815
- node,
816
- messageId: "noSpaceBetweenGenericAndParen",
817
- *fix(fixer) {
818
- yield fixer.replaceTextRange([spaceStartRange, spaceStartRange + postSpace.length], "");
819
- }
820
- });
821
- }
822
- if (node.parent?.parent.type === utils.AST_NODE_TYPES.FunctionDeclaration) {
823
- const spaceEndRange = node.range[0] - 1;
824
- const pre = sourceCode.text.slice(0, spaceEndRange);
825
- const preSpace = pre.match(/(\s+)$/)?.[0];
826
- if (preSpace?.length) {
827
- context.report({
828
- loc: {
829
- start: {
830
- line: node.loc.start.line,
831
- column: node.loc.start.column - preSpace.length
832
- },
833
- end: {
834
- line: node.loc.start.line,
835
- column: node.loc.start.column - 1
836
- }
837
- },
838
- node,
839
- messageId: "noSpaceBetweenGenericAndParen",
840
- *fix(fixer) {
841
- yield fixer.replaceTextRange([spaceEndRange - preSpace.length, spaceEndRange], "");
842
- }
843
- });
844
- }
845
- }
846
- }
847
- };
848
- }
849
- });
850
-
851
- const RULE_NAME = "space-in-empty-block";
852
- const spaceInEmptyBlock = createEslintRule({
109
+ const RULE_NAME = "no-useless-template-string";
110
+ const noUselessTemplateString = createEslintRule({
853
111
  name: RULE_NAME,
854
112
  meta: {
855
- type: "layout",
113
+ type: "problem",
856
114
  docs: {
857
- description: "Disallow spaces in empty block",
115
+ description: "No useless template string",
858
116
  recommended: "error"
859
117
  },
860
- fixable: "whitespace",
118
+ fixable: "code",
861
119
  schema: [],
862
120
  messages: {
863
- noSpaceInEmptyBlock: "Expected no space in empty block"
121
+ noUselessTemplateString: "No useless template string"
864
122
  }
865
123
  },
866
124
  defaultOptions: [],
867
125
  create: (context) => {
868
- const sourceCode = context.getSourceCode();
869
126
  return {
870
- BlockStatement: (node) => {
871
- if (node.body.length || sourceCode.getCommentsInside(node).length) {
872
- return;
873
- }
874
- const spaceStartRange = node.range[1] - 2;
875
- const post = sourceCode.text.slice(spaceStartRange);
876
- const postSpace = post.match(/^(\s*)/)?.[0];
877
- if (postSpace?.length) {
127
+ TemplateLiteral(node) {
128
+ const hasNewline = node.quasis.some((n) => n.value.raw.includes("\n"));
129
+ if (node.expressions.length === 0 && !hasNewline) {
878
130
  context.report({
879
- loc: {
880
- start: node.loc.start,
881
- end: {
882
- line: node.loc.end.line,
883
- column: node.loc.end.column - 1 + postSpace.length
884
- }
885
- },
886
- messageId: "noSpaceInEmptyBlock",
887
- *fix(fixer) {
888
- yield fixer.replaceTextRange([node.range[0] + 1, spaceStartRange + postSpace.length], "");
889
- }
890
- });
891
- }
892
- const spaceEndRange = node.range[0] + 1;
893
- const pre = sourceCode.text.slice(0, spaceEndRange);
894
- const preSpace = pre.match(/(\s+)$/)?.[0];
895
- if (preSpace?.length) {
896
- context.report({
897
- loc: {
898
- start: {
899
- line: node.loc.start.line,
900
- column: node.loc.start.column - preSpace.length
901
- },
902
- end: {
903
- line: node.loc.start.line,
904
- column: node.loc.start.column
905
- }
906
- },
907
- messageId: "noSpaceInEmptyBlock",
908
- *fix(fixer) {
909
- yield fixer.replaceTextRange([spaceEndRange - preSpace.length, spaceEndRange], "");
131
+ node,
132
+ messageId: "noUselessTemplateString",
133
+ fix(fixer) {
134
+ const s = node.range[0];
135
+ const e = node.range[1];
136
+ return fixer.replaceTextRange([s, e], `"${node.quasis[0].value.raw}"`);
910
137
  }
911
138
  });
912
139
  }
@@ -918,14 +145,8 @@ const spaceInEmptyBlock = createEslintRule({
918
145
  const index = {
919
146
  rules: {
920
147
  "import-dedupe": importDedupe,
921
- "generic-spacing": genericSpacing,
922
- "space-between-generic-and-paren": spaceBetweenGenericAndParen,
923
- "space-in-empty-block": spaceInEmptyBlock,
924
- "semi-spacing": semiSpacing,
925
148
  "no-inline-type-import": noInlineTypeImport,
926
- "no-space-before-paren": noSpaceBeforeParen,
927
- "space-before-function-paren": spaceBeforeFunctionParen,
928
- "array-bracket-spacing": arrayBracketSpacing
149
+ "no-useless-template-string": noUselessTemplateString
929
150
  }
930
151
  };
931
152