Skip to content

Commit 7561ec0

Browse files
committed
use last line indentation on formatter
... and add explicit delta suppressor for list end tokens
1 parent eba83f4 commit 7561ec0

File tree

1 file changed

+38
-12
lines changed

1 file changed

+38
-12
lines changed

src/services/formatting/formatting.ts

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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
@@ -399,7 +399,7 @@ namespace ts.formatting {
399399
let previousRangeStartLine: number;
400400

401401
let lastIndentedLine: number;
402-
let indentationOnLastIndentedLine: number;
402+
let indentationOnLastIndentedLine = Constants.Unknown;
403403

404404
const edits: TextChange[] = [];
405405

@@ -540,8 +540,18 @@ namespace ts.formatting {
540540
}
541541
return tokenIndentation !== Constants.Unknown ? tokenIndentation : indentation;
542542
},
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,
545555
getIndentation: () => indentation,
546556
getDelta,
547557
recomputeIndentation: lineAdded => {
@@ -557,7 +567,6 @@ namespace ts.formatting {
557567
// open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent
558568
case SyntaxKind.OpenBraceToken:
559569
case SyntaxKind.CloseBraceToken:
560-
case SyntaxKind.OpenParenToken:
561570
case SyntaxKind.CloseParenToken:
562571
case SyntaxKind.ElseKeyword:
563572
case SyntaxKind.WhileKeyword:
@@ -726,6 +735,7 @@ namespace ts.formatting {
726735

727736
let listDynamicIndentation = parentDynamicIndentation;
728737
let startLine = parentStartLine;
738+
let indentationOnListStartToken = parentDynamicIndentation.getIndentation();
729739

730740
if (listStartToken !== SyntaxKind.Unknown) {
731741
// introduce a new indentation scope for lists (including list start and end tokens)
@@ -738,11 +748,22 @@ namespace ts.formatting {
738748
else if (tokenInfo.token.kind === listStartToken) {
739749
// consume list start token
740750
startLine = sourceFile.getLineAndCharacterOfPosition(tokenInfo.token.pos).line;
741-
const indentation =
742-
computeIndentation(tokenInfo.token, startLine, Constants.Unknown, parent, parentDynamicIndentation, parentStartLine);
743751

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
746767
}
747768
else {
748769
// consume any tokens that precede the list as child elements of 'node' using its indentation scope
@@ -771,12 +792,12 @@ namespace ts.formatting {
771792
// without this check close paren will be interpreted as list end token for function expression which is wrong
772793
if (tokenInfo && tokenInfo.token.kind === listEndToken && rangeContainsRange(parent, tokenInfo.token)) {
773794
// consume list end token
774-
consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation, parent);
795+
consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation, parent, /*isListEndToken*/ true);
775796
}
776797
}
777798
}
778799

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 {
780801
Debug.assert(rangeContainsRange(parent, currentTokenInfo.token));
781802

782803
const lastTriviaWasNewLine = formattingScanner.lastTrailingTriviaWasNewLine();
@@ -814,7 +835,7 @@ namespace ts.formatting {
814835

815836
if (indentToken) {
816837
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) :
818839
Constants.Unknown;
819840

820841
let indentNextTokenOrTrivia = true;
@@ -1228,6 +1249,9 @@ namespace ts.formatting {
12281249
if ((<TypeReferenceNode>node).typeArguments === list) {
12291250
return SyntaxKind.LessThanToken;
12301251
}
1252+
break;
1253+
case SyntaxKind.TypeLiteral:
1254+
return SyntaxKind.OpenBraceToken;
12311255
}
12321256

12331257
return SyntaxKind.Unknown;
@@ -1239,6 +1263,8 @@ namespace ts.formatting {
12391263
return SyntaxKind.CloseParenToken;
12401264
case SyntaxKind.LessThanToken:
12411265
return SyntaxKind.GreaterThanToken;
1266+
case SyntaxKind.OpenBraceToken:
1267+
return SyntaxKind.CloseBraceToken;
12421268
}
12431269

12441270
return SyntaxKind.Unknown;

0 commit comments

Comments
 (0)