-
-
Notifications
You must be signed in to change notification settings - Fork 388
/
named-tuple-spacing.ts
83 lines (74 loc) · 2.34 KB
/
named-tuple-spacing.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import { createEslintRule } from '../utils'
export const RULE_NAME = 'named-tuple-spacing'
export type MessageIds = 'expectedSpaceAfter' | 'unexpectedSpaceBetween' | 'unexpectedSpaceBefore'
export type Options = []
const RE = /^([\w_$]+)(\s*)(\?\s*)?:(\s*)(.*)$/
export default createEslintRule<Options, MessageIds>({
name: RULE_NAME,
meta: {
type: 'suggestion',
docs: {
description: 'Expect space before type declaration in named tuple',
recommended: 'stylistic',
},
fixable: 'code',
schema: [],
messages: {
expectedSpaceAfter: 'Expected a space after the \':\'.',
unexpectedSpaceBetween: 'Unexpected space between \'?\' and the \':\'.',
unexpectedSpaceBefore: 'Unexpected space before the \':\'.',
},
},
defaultOptions: [],
create: (context) => {
const sourceCode = context.getSourceCode()
return {
TSNamedTupleMember: (node: any) => {
const code = sourceCode.text.slice(node.range[0], node.range[1])
const match = code.match(RE)
if (!match)
return
const labelName = node.label.name
const spaceBeforeColon = match[2]
const optionalMark = match[3]
const spacesAfterColon = match[4]
const elementType = match[5]
function getReplaceValue() {
let ret = labelName
if (node.optional)
ret += '?'
ret += ': '
ret += elementType
return ret
}
if (optionalMark?.length > 1) {
context.report({
node,
messageId: 'unexpectedSpaceBetween',
*fix(fixer) {
yield fixer.replaceTextRange(node.range, code.replace(RE, getReplaceValue()))
},
})
}
if (spaceBeforeColon?.length) {
context.report({
node,
messageId: 'unexpectedSpaceBefore',
*fix(fixer) {
yield fixer.replaceTextRange(node.range, code.replace(RE, getReplaceValue()))
},
})
}
if (spacesAfterColon != null && spacesAfterColon.length !== 1) {
context.report({
node,
messageId: 'expectedSpaceAfter',
*fix(fixer) {
yield fixer.replaceTextRange(node.range, code.replace(RE, getReplaceValue()))
},
})
}
},
}
},
})