Skip to content

Commit 02ca5be

Browse files
Merge pull request #28340 from saschanaz/listindent-revive
List position based formatting
2 parents 50a0174 + 7995f91 commit 02ca5be

10 files changed

+370
-190
lines changed

src/services/formatting/formatting.ts

+38-12
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
@@ -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

Comments
 (0)