@@ -34,7 +34,7 @@ namespace ts.formatting {
34
34
* the first token in line so it should be indented
35
35
*/
36
36
interface DynamicIndentation {
37
- getIndentationForToken ( tokenLine : number , tokenKind : SyntaxKind , container : Node ) : number ;
37
+ getIndentationForToken ( tokenLine : number , tokenKind : SyntaxKind , container : Node , suppressDelta ?: boolean ) : number ;
38
38
getIndentationForComment ( owningToken : SyntaxKind , tokenIndentation : number , container : Node ) : number ;
39
39
/**
40
40
* Indentation for open and close tokens of the node if it is block or another node that needs special indentation
@@ -399,7 +399,7 @@ namespace ts.formatting {
399
399
let previousRangeStartLine : number ;
400
400
401
401
let lastIndentedLine : number ;
402
- let indentationOnLastIndentedLine : number ;
402
+ let indentationOnLastIndentedLine = Constants . Unknown ;
403
403
404
404
const edits : TextChange [ ] = [ ] ;
405
405
@@ -540,8 +540,18 @@ namespace ts.formatting {
540
540
}
541
541
return tokenIndentation !== Constants . Unknown ? tokenIndentation : indentation ;
542
542
} ,
543
- getIndentationForToken : ( line , kind , container ) =>
544
- shouldAddDelta ( line , kind , container ) ? indentation + getDelta ( container ) : indentation ,
543
+ // if list end token is LessThanToken '>' then its delta should be explicitly suppressed
544
+ // so that LessThanToken as a binary operator can still be indented.
545
+ // foo.then
546
+ // <
547
+ // number,
548
+ // string,
549
+ // >();
550
+ // vs
551
+ // var a = xValue
552
+ // > yValue;
553
+ getIndentationForToken : ( line , kind , container , suppressDelta ) =>
554
+ ! suppressDelta && shouldAddDelta ( line , kind , container ) ? indentation + getDelta ( container ) : indentation ,
545
555
getIndentation : ( ) => indentation ,
546
556
getDelta,
547
557
recomputeIndentation : lineAdded => {
@@ -557,7 +567,6 @@ namespace ts.formatting {
557
567
// open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent
558
568
case SyntaxKind . OpenBraceToken :
559
569
case SyntaxKind . CloseBraceToken :
560
- case SyntaxKind . OpenParenToken :
561
570
case SyntaxKind . CloseParenToken :
562
571
case SyntaxKind . ElseKeyword :
563
572
case SyntaxKind . WhileKeyword :
@@ -726,6 +735,7 @@ namespace ts.formatting {
726
735
727
736
let listDynamicIndentation = parentDynamicIndentation ;
728
737
let startLine = parentStartLine ;
738
+ let indentationOnListStartToken = parentDynamicIndentation . getIndentation ( ) ;
729
739
730
740
if ( listStartToken !== SyntaxKind . Unknown ) {
731
741
// introduce a new indentation scope for lists (including list start and end tokens)
@@ -738,11 +748,22 @@ namespace ts.formatting {
738
748
else if ( tokenInfo . token . kind === listStartToken ) {
739
749
// consume list start token
740
750
startLine = sourceFile . getLineAndCharacterOfPosition ( tokenInfo . token . pos ) . line ;
741
- const indentation =
742
- computeIndentation ( tokenInfo . token , startLine , Constants . Unknown , parent , parentDynamicIndentation , parentStartLine ) ;
743
751
744
- listDynamicIndentation = getDynamicIndentation ( parent , parentStartLine , indentation . indentation , indentation . delta ) ;
745
- consumeTokenAndAdvanceScanner ( tokenInfo , parent , listDynamicIndentation , parent ) ;
752
+ consumeTokenAndAdvanceScanner ( tokenInfo , parent , parentDynamicIndentation , parent ) ;
753
+
754
+ if ( indentationOnLastIndentedLine !== Constants . Unknown ) {
755
+ // scanner just processed list start token so consider last indentation as list indentation
756
+ // function foo(): { // last indentation was 0, list item will be indented based on this value
757
+ // foo: number;
758
+ // }: {};
759
+ indentationOnListStartToken = indentationOnLastIndentedLine ;
760
+ }
761
+ else {
762
+ const startLinePosition = getLineStartPositionForPosition ( tokenInfo . token . pos , sourceFile ) ;
763
+ indentationOnListStartToken = SmartIndenter . findFirstNonWhitespaceColumn ( startLinePosition , tokenInfo . token . pos , sourceFile , options ) ;
764
+ }
765
+
766
+ listDynamicIndentation = getDynamicIndentation ( parent , parentStartLine , indentationOnListStartToken , options . indentSize ! ) ; // TODO: GH#18217
746
767
}
747
768
else {
748
769
// consume any tokens that precede the list as child elements of 'node' using its indentation scope
@@ -771,12 +792,12 @@ namespace ts.formatting {
771
792
// without this check close paren will be interpreted as list end token for function expression which is wrong
772
793
if ( tokenInfo && tokenInfo . token . kind === listEndToken && rangeContainsRange ( parent , tokenInfo . token ) ) {
773
794
// consume list end token
774
- consumeTokenAndAdvanceScanner ( tokenInfo , parent , listDynamicIndentation , parent ) ;
795
+ consumeTokenAndAdvanceScanner ( tokenInfo , parent , listDynamicIndentation , parent , /*isListEndToken*/ true ) ;
775
796
}
776
797
}
777
798
}
778
799
779
- function consumeTokenAndAdvanceScanner ( currentTokenInfo : TokenInfo , parent : Node , dynamicIndentation : DynamicIndentation , container : Node ) : void {
800
+ function consumeTokenAndAdvanceScanner ( currentTokenInfo : TokenInfo , parent : Node , dynamicIndentation : DynamicIndentation , container : Node , isListEndToken ?: boolean ) : void {
780
801
Debug . assert ( rangeContainsRange ( parent , currentTokenInfo . token ) ) ;
781
802
782
803
const lastTriviaWasNewLine = formattingScanner . lastTrailingTriviaWasNewLine ( ) ;
@@ -814,7 +835,7 @@ namespace ts.formatting {
814
835
815
836
if ( indentToken ) {
816
837
const tokenIndentation = ( isTokenInRange && ! rangeContainsError ( currentTokenInfo . token ) ) ?
817
- dynamicIndentation . getIndentationForToken ( tokenStart . line , currentTokenInfo . token . kind , container ) :
838
+ dynamicIndentation . getIndentationForToken ( tokenStart . line , currentTokenInfo . token . kind , container , isListEndToken ) :
818
839
Constants . Unknown ;
819
840
820
841
let indentNextTokenOrTrivia = true ;
@@ -1228,6 +1249,9 @@ namespace ts.formatting {
1228
1249
if ( ( < TypeReferenceNode > node ) . typeArguments === list ) {
1229
1250
return SyntaxKind . LessThanToken ;
1230
1251
}
1252
+ break ;
1253
+ case SyntaxKind . TypeLiteral :
1254
+ return SyntaxKind . OpenBraceToken ;
1231
1255
}
1232
1256
1233
1257
return SyntaxKind . Unknown ;
@@ -1239,6 +1263,8 @@ namespace ts.formatting {
1239
1263
return SyntaxKind . CloseParenToken ;
1240
1264
case SyntaxKind . LessThanToken :
1241
1265
return SyntaxKind . GreaterThanToken ;
1266
+ case SyntaxKind . OpenBraceToken :
1267
+ return SyntaxKind . CloseBraceToken ;
1242
1268
}
1243
1269
1244
1270
return SyntaxKind . Unknown ;
0 commit comments