@@ -34,7 +34,7 @@ namespace ts.formatting {
3434 * the first token in line so it should be indented
3535 */
3636 interface DynamicIndentation {
37- getIndentationForToken ( tokenLine : number , tokenKind : SyntaxKind , container : Node ) : number ;
37+ getIndentationForToken ( tokenLine : number , tokenKind : SyntaxKind , container : Node , suppressDelta : boolean ) : number ;
3838 getIndentationForComment ( owningToken : SyntaxKind , tokenIndentation : number , container : Node ) : number ;
3939 /**
4040 * Indentation for open and close tokens of the node if it is block or another node that needs special indentation
@@ -398,7 +398,7 @@ namespace ts.formatting {
398398 let previousRangeStartLine : number ;
399399
400400 let lastIndentedLine : number ;
401- let indentationOnLastIndentedLine : number ;
401+ let indentationOnLastIndentedLine = Constants . Unknown ;
402402
403403 const edits : TextChange [ ] = [ ] ;
404404
@@ -539,8 +539,18 @@ namespace ts.formatting {
539539 }
540540 return tokenIndentation !== Constants . Unknown ? tokenIndentation : indentation ;
541541 } ,
542- getIndentationForToken : ( line , kind , container ) =>
543- shouldAddDelta ( line , kind , container ) ? indentation + getDelta ( container ) : indentation ,
542+ // if list end token is LessThanToken '>' then its delta should be explicitly suppressed
543+ // so that LessThanToken as a binary operator can still be indented.
544+ // foo.then
545+ // <
546+ // number,
547+ // string,
548+ // >();
549+ // vs
550+ // var a = xValue
551+ // > yValue;
552+ getIndentationForToken : ( line , kind , container , suppressDelta ) =>
553+ ! suppressDelta && shouldAddDelta ( line , kind , container ) ? indentation + getDelta ( container ) : indentation ,
544554 getIndentation : ( ) => indentation ,
545555 getDelta,
546556 recomputeIndentation : lineAdded => {
@@ -556,7 +566,6 @@ namespace ts.formatting {
556566 // open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent
557567 case SyntaxKind . OpenBraceToken :
558568 case SyntaxKind . CloseBraceToken :
559- case SyntaxKind . OpenParenToken :
560569 case SyntaxKind . CloseParenToken :
561570 case SyntaxKind . ElseKeyword :
562571 case SyntaxKind . WhileKeyword :
@@ -737,11 +746,23 @@ namespace ts.formatting {
737746 else if ( tokenInfo . token . kind === listStartToken ) {
738747 // consume list start token
739748 startLine = sourceFile . getLineAndCharacterOfPosition ( tokenInfo . token . pos ) . line ;
740- const indentation =
741- computeIndentation ( tokenInfo . token , startLine , Constants . Unknown , parent , parentDynamicIndentation , parentStartLine ) ;
742749
743- listDynamicIndentation = getDynamicIndentation ( parent , parentStartLine , indentation . indentation , indentation . delta ) ;
744- consumeTokenAndAdvanceScanner ( tokenInfo , parent , listDynamicIndentation , parent ) ;
750+ consumeTokenAndAdvanceScanner ( tokenInfo , parent , parentDynamicIndentation , parent ) ;
751+
752+ let indentationOnListStartToken : number ;
753+ if ( indentationOnLastIndentedLine !== Constants . Unknown ) {
754+ // scanner just processed list start token so consider last indentation as list indentation
755+ // function foo(): { // last indentation was 0, list item will be indented based on this value
756+ // foo: number;
757+ // }: {};
758+ indentationOnListStartToken = indentationOnLastIndentedLine ;
759+ }
760+ else {
761+ const startLinePosition = getLineStartPositionForPosition ( tokenInfo . token . pos , sourceFile ) ;
762+ indentationOnListStartToken = SmartIndenter . findFirstNonWhitespaceColumn ( startLinePosition , tokenInfo . token . pos , sourceFile , options ) ;
763+ }
764+
765+ listDynamicIndentation = getDynamicIndentation ( parent , parentStartLine , indentationOnListStartToken , options . indentSize ! ) ; // TODO: GH#18217
745766 }
746767 else {
747768 // consume any tokens that precede the list as child elements of 'node' using its indentation scope
@@ -770,12 +791,12 @@ namespace ts.formatting {
770791 // without this check close paren will be interpreted as list end token for function expression which is wrong
771792 if ( tokenInfo && tokenInfo . token . kind === listEndToken && rangeContainsRange ( parent , tokenInfo . token ) ) {
772793 // consume list end token
773- consumeTokenAndAdvanceScanner ( tokenInfo , parent , listDynamicIndentation , parent ) ;
794+ consumeTokenAndAdvanceScanner ( tokenInfo , parent , listDynamicIndentation , parent , /*isListEndToken*/ true ) ;
774795 }
775796 }
776797 }
777798
778- function consumeTokenAndAdvanceScanner ( currentTokenInfo : TokenInfo , parent : Node , dynamicIndentation : DynamicIndentation , container : Node ) : void {
799+ function consumeTokenAndAdvanceScanner ( currentTokenInfo : TokenInfo , parent : Node , dynamicIndentation : DynamicIndentation , container : Node , isListEndToken ?: boolean ) : void {
779800 Debug . assert ( rangeContainsRange ( parent , currentTokenInfo . token ) ) ;
780801
781802 const lastTriviaWasNewLine = formattingScanner . lastTrailingTriviaWasNewLine ( ) ;
@@ -813,7 +834,7 @@ namespace ts.formatting {
813834
814835 if ( indentToken ) {
815836 const tokenIndentation = ( isTokenInRange && ! rangeContainsError ( currentTokenInfo . token ) ) ?
816- dynamicIndentation . getIndentationForToken ( tokenStart . line , currentTokenInfo . token . kind , container ) :
837+ dynamicIndentation . getIndentationForToken ( tokenStart . line , currentTokenInfo . token . kind , container , ! ! isListEndToken ) :
817838 Constants . Unknown ;
818839
819840 let indentNextTokenOrTrivia = true ;
@@ -1227,6 +1248,9 @@ namespace ts.formatting {
12271248 if ( ( < TypeReferenceNode > node ) . typeArguments === list ) {
12281249 return SyntaxKind . LessThanToken ;
12291250 }
1251+ break ;
1252+ case SyntaxKind . TypeLiteral :
1253+ return SyntaxKind . OpenBraceToken ;
12301254 }
12311255
12321256 return SyntaxKind . Unknown ;
@@ -1238,6 +1262,8 @@ namespace ts.formatting {
12381262 return SyntaxKind . CloseParenToken ;
12391263 case SyntaxKind . LessThanToken :
12401264 return SyntaxKind . GreaterThanToken ;
1265+ case SyntaxKind . OpenBraceToken :
1266+ return SyntaxKind . CloseBraceToken ;
12411267 }
12421268
12431269 return SyntaxKind . Unknown ;
0 commit comments