@@ -19,6 +19,7 @@ const {
19
19
* @typedef { { type: string } & HasLocation } MaybeNode
20
20
*/
21
21
/**
22
+ * @typedef {import('@typescript-eslint/types').TSESTree.Node } TSESTreeNode
22
23
* @typedef {import('@typescript-eslint/types').TSESTree.ClassExpression } ClassExpression
23
24
* @typedef {import('@typescript-eslint/types').TSESTree.ClassDeclaration } ClassDeclaration
24
25
* @typedef {import('@typescript-eslint/types').TSESTree.TSTypeAliasDeclaration } TSTypeAliasDeclaration
@@ -125,6 +126,48 @@ function defineVisitor({
125
126
processSemicolons,
126
127
getFirstAndLastTokens
127
128
} ) {
129
+ /**
130
+ * Check whether a given token is the first token of:
131
+ *
132
+ * - A parameter of TSTypeParameterInstantiation
133
+ * - An element of TSTupleType
134
+ *
135
+ * @param {Token } token The token to check.
136
+ * @param {TSUnionType | TSIntersectionType } belongingNode The node that the token is belonging to.
137
+ * @returns {boolean } `true` if the token is the first token of an element.
138
+ */
139
+ function isBeginningOfElement ( token , belongingNode ) {
140
+ /** @type {TSESTreeNode | null } */
141
+ let node = belongingNode
142
+
143
+ while ( node != null && node . parent != null ) {
144
+ /** @type {TSESTreeNode } */
145
+ const parent = node . parent
146
+ if ( parent . type === 'TSTypeParameterInstantiation' ) {
147
+ return (
148
+ parent . params . length >= 2 &&
149
+ parent . params . some (
150
+ ( param ) =>
151
+ getFirstAndLastTokens ( param ) . firstToken . range [ 0 ] ===
152
+ token . range [ 0 ]
153
+ )
154
+ )
155
+ }
156
+ if ( parent . type === 'TSTupleType' ) {
157
+ return parent . elementTypes . some (
158
+ ( element ) =>
159
+ element != null &&
160
+ getFirstAndLastTokens ( element ) . firstToken . range [ 0 ] ===
161
+ token . range [ 0 ]
162
+ )
163
+ }
164
+
165
+ node = parent
166
+ }
167
+
168
+ return false
169
+ }
170
+
128
171
return {
129
172
// Support TypeScript
130
173
/** @param {ClassDeclaration | ClassExpression } node */
@@ -463,16 +506,34 @@ function defineVisitor({
463
506
// A | B
464
507
// A & B
465
508
const firstToken = tokenStore . getFirstToken ( node )
466
- const types = [ ...node . types ]
467
- if ( getFirstAndLastTokens ( types [ 0 ] ) . firstToken === firstToken ) {
468
- types . shift ( )
509
+
510
+ const prevToken = tokenStore . getTokenBefore ( firstToken )
511
+ const shouldIndent =
512
+ prevToken == null ||
513
+ prevToken . loc . end . line === firstToken . loc . start . line ||
514
+ isBeginningOfElement ( firstToken , node )
515
+ const offset = shouldIndent ? 1 : 0
516
+
517
+ const typeTokensList = node . types . map ( getFirstAndLastTokens )
518
+ const typeTokens = typeTokensList . shift ( )
519
+ if ( ! typeTokens ) {
520
+ return
521
+ }
522
+ let lastToken
523
+ if ( typeTokens . firstToken === firstToken ) {
524
+ lastToken = typeTokens . lastToken
525
+ } else {
526
+ typeTokensList . unshift ( typeTokens )
527
+ lastToken = firstToken
528
+ }
529
+ for ( const typeTokens of typeTokensList ) {
530
+ setOffset (
531
+ tokenStore . getTokensBetween ( lastToken , typeTokens . firstToken ) ,
532
+ offset ,
533
+ firstToken
534
+ )
535
+ setOffset ( typeTokens . firstToken , offset , firstToken )
469
536
}
470
- processNodeList (
471
- types ,
472
- firstToken ,
473
- null ,
474
- isBeginningOfLine ( firstToken ) ? 0 : 1
475
- )
476
537
} ,
477
538
TSParenthesizedType ( node ) {
478
539
// (T)
@@ -1253,12 +1314,4 @@ function defineVisitor({
1253
1314
// ----------------------------------------------------------------------
1254
1315
TSLiteralType ( ) { }
1255
1316
}
1256
- /**
1257
- * Check whether the given node or token is the beginning of a line.
1258
- * @param {MaybeNode } node
1259
- */
1260
- function isBeginningOfLine ( node ) {
1261
- const prevToken = tokenStore . getTokenBefore ( node , { includeComments : true } )
1262
- return ! prevToken || prevToken . loc . end . line < node . loc . start . line
1263
- }
1264
1317
}
0 commit comments