Skip to content

Commit af1c21a

Browse files
committed
fix(indent-binary-ops): improve nested handling, close #530
1 parent 7b92cfd commit af1c21a

2 files changed

Lines changed: 70 additions & 14 deletions

File tree

‎packages/eslint-plugin/rules/indent-binary-ops/indent-binary-ops._plus_.test.ts‎

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,26 @@ run({
3535
type === 'srenque'
3636
));
3737
`,
38+
$`
39+
if (a
40+
&& b
41+
&& c
42+
&& (d
43+
|| e
44+
|| f
45+
)
46+
) {
47+
foo()
48+
}
49+
`,
3850
],
3951
invalid: [],
4052
})
4153

4254
it('snapshots', async () => {
4355
const { fix } = createLinter('indent-binary-ops', rule)
4456

45-
expect(
57+
expect.soft(
4658
fix($`
4759
if (
4860
a && (
@@ -64,7 +76,7 @@ it('snapshots', async () => {
6476
`,
6577
)
6678

67-
expect(
79+
expect.soft(
6880
fix($`
6981
const a =
7082
x +
@@ -77,7 +89,7 @@ it('snapshots', async () => {
7789
y * z"
7890
`,
7991
)
80-
expect(
92+
expect.soft(
8193
fix($`
8294
if (
8395
aaaaaa >
@@ -93,7 +105,7 @@ it('snapshots', async () => {
93105
`,
94106
)
95107

96-
expect(
108+
expect.soft(
97109
fix($`
98110
function foo() {
99111
if (a
@@ -119,7 +131,7 @@ it('snapshots', async () => {
119131
`,
120132
)
121133

122-
expect(
134+
expect.soft(
123135
fix($`
124136
type Foo = A | B
125137
| C | D
@@ -133,7 +145,7 @@ it('snapshots', async () => {
133145
`,
134146
)
135147

136-
expect(
148+
expect.soft(
137149
fix($`
138150
type Foo =
139151
| A | C
@@ -147,7 +159,7 @@ it('snapshots', async () => {
147159
`,
148160
)
149161

150-
expect(
162+
expect.soft(
151163
fix($`
152164
type T =
153165
& A
@@ -160,12 +172,12 @@ it('snapshots', async () => {
160172
"type T =
161173
& A
162174
& (B
163-
| A
164-
| D)"
175+
| A
176+
| D)"
165177
`,
166178
)
167179

168-
expect(
180+
expect.soft(
169181
fix($`
170182
type T =
171183
a
@@ -181,7 +193,7 @@ it('snapshots', async () => {
181193
`,
182194
)
183195

184-
expect(
196+
expect.soft(
185197
fix($`
186198
function TSPropertySignatureToProperty(
187199
node:
@@ -207,7 +219,7 @@ it('snapshots', async () => {
207219
`,
208220
)
209221

210-
expect(
222+
expect.soft(
211223
fix($`
212224
type Foo = Merge<
213225
A
@@ -225,7 +237,7 @@ it('snapshots', async () => {
225237
`,
226238
)
227239

228-
expect(
240+
expect.soft(
229241
fix($`
230242
if (
231243
typeof woof === 'string' &&
@@ -250,4 +262,40 @@ it('snapshots', async () => {
250262
}"
251263
`,
252264
)
265+
266+
expect.soft(
267+
fix($`
268+
const a = () => b
269+
|| c
270+
271+
const a = (
272+
p,
273+
) => (b
274+
|| c)
275+
276+
const a = b
277+
+ c;
278+
const a = {
279+
p: b
280+
+ c,
281+
};
282+
`),
283+
).toMatchInlineSnapshot(
284+
`
285+
"const a = () => b
286+
|| c
287+
288+
const a = (
289+
p,
290+
) => (b
291+
|| c)
292+
293+
const a = b
294+
+ c;
295+
const a = {
296+
p: b
297+
+ c,
298+
};"
299+
`,
300+
)
253301
})

‎packages/eslint-plugin/rules/indent-binary-ops/indent-binary-ops._plus_.ts‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export default createRule<RuleOptions, MessageIds>({
6262
if (tokenOperator.range[0] <= right.parent!.range[0])
6363
return
6464
}
65+
const tokenBeforeAll = sourceCode.getTokenBefore(node)
6566
const tokenLeft = sourceCode.getTokenBefore(tokenOperator)!
6667

6768
const isMultiline = tokenRight.loc.start.line !== tokenLeft.loc.start.line
@@ -73,9 +74,16 @@ export default createRule<RuleOptions, MessageIds>({
7374
// we bump the indentation level by one.
7475
const firstTokenOfLineLeft = firstTokenOfLine(tokenLeft.loc.start.line)
7576
const lastTokenOfLineLeft = lastTokenOfLine(tokenLeft.loc.start.line)
76-
const needAdditionIndent = (firstTokenOfLineLeft?.type === 'Keyword' && !['typeof', 'instanceof', 'this'].includes(firstTokenOfLineLeft.value))
77+
const needAdditionIndent = false
78+
// First line is a keyword (but exclude `typeof`, `instanceof`, `this`)
79+
|| (firstTokenOfLineLeft?.type === 'Keyword' && !['typeof', 'instanceof', 'this'].includes(firstTokenOfLineLeft.value))
80+
// First line is a `type` keyword in a type alias declaration
7781
|| (firstTokenOfLineLeft?.type === 'Identifier' && firstTokenOfLineLeft.value === 'type' && node.parent?.type === 'TSTypeAliasDeclaration')
82+
// End of line is a opening bracket
7883
|| [':', '[', '(', '<', '='].includes(lastTokenOfLineLeft?.value || '')
84+
// Before the left token is a opening bracket
85+
|| (['[', '(', '=>', ':'].includes(tokenBeforeAll?.value || '') && firstTokenOfLineLeft?.loc.start.line === tokenBeforeAll?.loc.start.line)
86+
// Chain of `||` or `&&` operators
7987
|| (['||', '&&'].includes(lastTokenOfLineLeft?.value || '') && node.loc.start.line === tokenLeft.loc.start.line && node.loc.start.column !== getIndentOfLine(node.loc.start.line).length)
8088

8189
const indentTarget = getIndentOfLine(tokenLeft.loc.start.line) + (needAdditionIndent ? indentStr : '')

0 commit comments

Comments
 (0)