@unix/eslint 1.1.1 → 1.2.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.
@@ -1,18 +1,13 @@
1
1
  const lineBreakFor = sourceCode => (sourceCode.text.includes('\r\n') ? '\r\n' : '\n')
2
2
 
3
- const LONG_BLOCK_MIN_LINES = 4
4
-
5
3
  const indentationFor = (sourceCode, token) => {
6
4
  const line = sourceCode.lines[token.loc.start.line - 1] ?? ''
7
5
 
8
6
  return line.slice(0, token.loc.start.column)
9
7
  }
10
8
 
11
- const spacingBefore = (sourceCode, token, blankLines) =>
12
- `${lineBreakFor(sourceCode).repeat(blankLines + 1)}${indentationFor(
13
- sourceCode,
14
- token,
15
- )}`
9
+ const spacingBefore = (sourceCode, token) =>
10
+ `${lineBreakFor(sourceCode)}${indentationFor(sourceCode, token)}`
16
11
 
17
12
  const paddingLineSequencesBetween = (sourceCode, leftToken, rightToken) => {
18
13
  const sequences = []
@@ -48,18 +43,36 @@ const hasTokensBetween = (sourceCode, leftToken, rightToken) =>
48
43
  sourceCode.getTokensBetween(leftToken, rightToken, { includeComments: true })
49
44
  .length > 0
50
45
 
51
- const reportPadding = (
46
+ const hasBlockBody = node => {
47
+ if (node.type === 'BlockStatement') return true
48
+ if (node.type === 'FunctionDeclaration') return true
49
+ if (node.type === 'SwitchStatement') return true
50
+ if (node.type === 'TryStatement') return true
51
+ if (node.type === 'IfStatement') {
52
+ if (hasBlockBody(node.consequent)) return true
53
+
54
+ return Boolean(node.alternate && hasBlockBody(node.alternate))
55
+ }
56
+
57
+ return node.body?.type === 'BlockStatement'
58
+ }
59
+
60
+ const isSingleLineStatement = node => node.loc.start.line === node.loc.end.line
61
+
62
+ const isRestrictedStatement = node =>
63
+ isSingleLineStatement(node) && !hasBlockBody(node)
64
+
65
+ const reportUnexpectedBlankLine = (
52
66
  context,
53
67
  sourceCode,
54
- node,
55
- leftToken,
56
- rightToken,
57
- maxBlankLines,
58
- messageId,
68
+ previousStatement,
69
+ nextStatement,
59
70
  ) => {
71
+ const leftToken = sourceCode.getLastToken(previousStatement)
72
+ const rightToken = sourceCode.getFirstToken(nextStatement)
60
73
  const sequences = paddingLineSequencesBetween(sourceCode, leftToken, rightToken)
61
74
 
62
- if (blankLineCount(sequences) <= maxBlankLines) return
75
+ if (blankLineCount(sequences) === 0) return
63
76
 
64
77
  const [firstSequence] = sequences
65
78
 
@@ -69,7 +82,7 @@ const reportPadding = (
69
82
 
70
83
  return fixer.replaceTextRange(
71
84
  [leftToken.range[1], rightToken.range[0]],
72
- spacingBefore(sourceCode, rightToken, maxBlankLines),
85
+ spacingBefore(sourceCode, rightToken),
73
86
  )
74
87
  },
75
88
  loc: {
@@ -79,126 +92,21 @@ const reportPadding = (
79
92
  line: firstSequence.leftToken.loc.end.line + 1,
80
93
  },
81
94
  },
82
- messageId,
83
- node,
95
+ messageId: 'unexpectedBlankLine',
96
+ node: nextStatement,
84
97
  })
85
98
  }
86
99
 
87
- const isReturnStatement = node => node.type === 'ReturnStatement'
88
-
89
- const lineCountFor = node => node.loc.end.line - node.loc.start.line + 1
90
-
91
- const hasBlockBody = node => {
92
- if (node.type === 'BlockStatement') return true
93
- if (node.type === 'FunctionDeclaration') return true
94
- if (node.type === 'SwitchStatement') return true
95
- if (node.type === 'TryStatement') return true
96
- if (node.type === 'IfStatement') {
97
- if (hasBlockBody(node.consequent)) return true
98
-
99
- return Boolean(node.alternate && hasBlockBody(node.alternate))
100
- }
101
-
102
- return node.body?.type === 'BlockStatement'
103
- }
104
-
105
- const isLongBlockStatement = node =>
106
- hasBlockBody(node) && lineCountFor(node) >= LONG_BLOCK_MIN_LINES
107
-
108
- const messageIdForStatementGap = (previousStatement, nextStatement) => {
109
- if (isReturnStatement(previousStatement)) return 'unexpectedBlankLineAfterReturn'
110
- if (isReturnStatement(nextStatement)) return 'tooManyBlankLinesBeforeReturn'
111
-
112
- return 'unexpectedBlankLine'
113
- }
114
-
115
- const maxBlankLinesForStatementGap = (previousStatement, nextStatement) => {
116
- if (isReturnStatement(previousStatement)) return 0
117
- if (isReturnStatement(nextStatement)) return 1
118
- if (isLongBlockStatement(previousStatement)) return 1
119
- if (isLongBlockStatement(nextStatement)) return 1
120
-
121
- return 0
122
- }
123
-
124
- const checkStatementList = (
125
- context,
126
- sourceCode,
127
- node,
128
- statements,
129
- leftToken,
130
- rightToken,
131
- ) => {
132
- if (statements.length === 0) {
133
- reportPadding(
134
- context,
135
- sourceCode,
136
- node,
137
- leftToken,
138
- rightToken,
139
- 0,
140
- 'unexpectedBlankLine',
141
- )
142
- return
143
- }
144
-
145
- const [firstStatement] = statements
146
- const lastStatement = statements[statements.length - 1]
147
-
148
- reportPadding(
149
- context,
150
- sourceCode,
151
- firstStatement,
152
- leftToken,
153
- sourceCode.getFirstToken(firstStatement),
154
- 0,
155
- 'unexpectedBlankLine',
156
- )
157
-
100
+ const checkStatementPairs = (context, sourceCode, statements) => {
158
101
  for (let index = 1; index < statements.length; index += 1) {
159
102
  const previousStatement = statements[index - 1]
160
103
  const nextStatement = statements[index]
161
104
 
162
- reportPadding(
163
- context,
164
- sourceCode,
165
- nextStatement,
166
- sourceCode.getLastToken(previousStatement),
167
- sourceCode.getFirstToken(nextStatement),
168
- maxBlankLinesForStatementGap(previousStatement, nextStatement),
169
- messageIdForStatementGap(previousStatement, nextStatement),
170
- )
171
- }
172
-
173
- reportPadding(
174
- context,
175
- sourceCode,
176
- lastStatement,
177
- sourceCode.getLastToken(lastStatement),
178
- rightToken,
179
- 0,
180
- isReturnStatement(lastStatement)
181
- ? 'unexpectedBlankLineAfterReturn'
182
- : 'unexpectedBlankLine',
183
- )
184
- }
185
-
186
- const caseColonToken = (sourceCode, node) => {
187
- const tokenBeforeConsequent = sourceCode.getTokenBefore(node.consequent[0])
188
-
189
- if (tokenBeforeConsequent?.value === ':') return tokenBeforeConsequent
105
+ if (!isRestrictedStatement(previousStatement)) continue
106
+ if (!isRestrictedStatement(nextStatement)) continue
190
107
 
191
- const firstToken = sourceCode.getFirstToken(node)
192
-
193
- return sourceCode.getTokenAfter(firstToken, {
194
- filter: token => token.value === ':',
195
- })
196
- }
197
-
198
- const caseEndToken = (sourceCode, node) => {
199
- const lastStatement = node.consequent[node.consequent.length - 1]
200
-
201
- return sourceCode.getTokenAfter(sourceCode.getLastToken(lastStatement))
108
+ reportUnexpectedBlankLine(context, sourceCode, previousStatement, nextStatement)
109
+ }
202
110
  }
203
111
 
204
112
  const functionBlankLines = {
@@ -206,14 +114,12 @@ const functionBlankLines = {
206
114
  type: 'layout',
207
115
  docs: {
208
116
  description:
209
- 'Disallow extra blank lines in functions except before return statements',
117
+ 'Disallow blank lines between adjacent single-line non-block statements',
210
118
  },
211
119
  fixable: 'whitespace',
212
120
  messages: {
213
- tooManyBlankLinesBeforeReturn:
214
- 'Return statements may have at most one blank line above them.',
215
- unexpectedBlankLine: 'Unexpected blank line inside function.',
216
- unexpectedBlankLineAfterReturn: 'Unexpected blank line after return.',
121
+ unexpectedBlankLine:
122
+ 'Unexpected blank line between adjacent single-line statements.',
217
123
  },
218
124
  schema: [],
219
125
  },
@@ -237,14 +143,7 @@ const functionBlankLines = {
237
143
  BlockStatement(node) {
238
144
  if (!isInsideFunction()) return
239
145
 
240
- checkStatementList(
241
- context,
242
- sourceCode,
243
- node,
244
- node.body,
245
- sourceCode.getFirstToken(node),
246
- sourceCode.getLastToken(node),
247
- )
146
+ checkStatementPairs(context, sourceCode, node.body)
248
147
  },
249
148
  FunctionDeclaration: enterFunction,
250
149
  'FunctionDeclaration:exit': exitFunction,
@@ -252,16 +151,8 @@ const functionBlankLines = {
252
151
  'FunctionExpression:exit': exitFunction,
253
152
  SwitchCase(node) {
254
153
  if (!isInsideFunction()) return
255
- if (node.consequent.length === 0) return
256
-
257
- checkStatementList(
258
- context,
259
- sourceCode,
260
- node,
261
- node.consequent,
262
- caseColonToken(sourceCode, node),
263
- caseEndToken(sourceCode, node),
264
- )
154
+
155
+ checkStatementPairs(context, sourceCode, node.consequent)
265
156
  },
266
157
  }
267
158
  },
package/configs/ts.js CHANGED
@@ -73,13 +73,6 @@ const classMemberOrder = [
73
73
  ],
74
74
  ]
75
75
 
76
- const recommendedTypeChecked = tseslint.configs.recommendedTypeChecked.map(
77
- config => ({
78
- ...config,
79
- files: config.files ?? tsFiles,
80
- }),
81
- )
82
-
83
76
  const withTsFiles = config => ({
84
77
  ...config,
85
78
  files: tsFiles,
@@ -91,7 +84,6 @@ export default tseslint.config(
91
84
  ...eslint.configs.recommended,
92
85
  files: tsFiles,
93
86
  },
94
- ...recommendedTypeChecked,
95
87
  {
96
88
  files: tsFiles,
97
89
  languageOptions: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unix/eslint",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "ESLint config for all @unix projects.",
5
5
  "type": "module",
6
6
  "main": "index.js",