Skip to content

Commit e9da643

Browse files
authored
Merge pull request #13090 from SaschaNaz/maptype
Format mapped type
2 parents 6281d1d + c28625f commit e9da643

File tree

4 files changed

+27
-9
lines changed

4 files changed

+27
-9
lines changed

src/services/formatting/formatting.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -488,14 +488,16 @@ namespace ts.formatting {
488488
// open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent
489489
case SyntaxKind.OpenBraceToken:
490490
case SyntaxKind.CloseBraceToken:
491-
case SyntaxKind.OpenBracketToken:
492-
case SyntaxKind.CloseBracketToken:
493491
case SyntaxKind.OpenParenToken:
494492
case SyntaxKind.CloseParenToken:
495493
case SyntaxKind.ElseKeyword:
496494
case SyntaxKind.WhileKeyword:
497495
case SyntaxKind.AtToken:
498496
return indentation;
497+
case SyntaxKind.OpenBracketToken:
498+
case SyntaxKind.CloseBracketToken:
499+
return (container.kind === SyntaxKind.MappedType) ?
500+
indentation + getEffectiveDelta(delta, container) : indentation;
499501
default:
500502
// if token line equals to the line of containing node (this is a first token in the node) - use node indentation
501503
return nodeStartLine !== line ? indentation + getEffectiveDelta(delta, container) : indentation;
@@ -566,7 +568,7 @@ namespace ts.formatting {
566568
if (tokenInfo.token.end > node.end) {
567569
break;
568570
}
569-
consumeTokenAndAdvanceScanner(tokenInfo, node, nodeDynamicIndentation);
571+
consumeTokenAndAdvanceScanner(tokenInfo, node, nodeDynamicIndentation, node);
570572
}
571573

572574
function processChildNode(
@@ -617,7 +619,7 @@ namespace ts.formatting {
617619
break;
618620
}
619621

620-
consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation);
622+
consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation, node);
621623
}
622624

623625
if (!formattingScanner.isOnToken()) {
@@ -673,11 +675,11 @@ namespace ts.formatting {
673675
computeIndentation(tokenInfo.token, startLine, Constants.Unknown, parent, parentDynamicIndentation, parentStartLine);
674676

675677
listDynamicIndentation = getDynamicIndentation(parent, parentStartLine, indentation.indentation, indentation.delta);
676-
consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation);
678+
consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation, parent);
677679
}
678680
else {
679681
// consume any tokens that precede the list as child elements of 'node' using its indentation scope
680-
consumeTokenAndAdvanceScanner(tokenInfo, parent, parentDynamicIndentation);
682+
consumeTokenAndAdvanceScanner(tokenInfo, parent, parentDynamicIndentation, parent);
681683
}
682684
}
683685
}
@@ -697,13 +699,13 @@ namespace ts.formatting {
697699
// without this check close paren will be interpreted as list end token for function expression which is wrong
698700
if (tokenInfo.token.kind === listEndToken && rangeContainsRange(parent, tokenInfo.token)) {
699701
// consume list end token
700-
consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation);
702+
consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation, parent);
701703
}
702704
}
703705
}
704706
}
705707

706-
function consumeTokenAndAdvanceScanner(currentTokenInfo: TokenInfo, parent: Node, dynamicIndentation: DynamicIndentation, container?: Node): void {
708+
function consumeTokenAndAdvanceScanner(currentTokenInfo: TokenInfo, parent: Node, dynamicIndentation: DynamicIndentation, container: Node): void {
707709
Debug.assert(rangeContainsRange(parent, currentTokenInfo.token));
708710

709711
const lastTriviaWasNewLine = formattingScanner.lastTrailingTriviaWasNewLine();

src/services/formatting/rules.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ namespace ts.formatting {
362362
this.NoSpaceAfterModuleImport = new Rule(RuleDescriptor.create2(Shared.TokenRange.FromTokens([SyntaxKind.ModuleKeyword, SyntaxKind.RequireKeyword]), SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
363363

364364
// Add a space around certain TypeScript keywords
365-
this.SpaceAfterCertainTypeScriptKeywords = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.AbstractKeyword, SyntaxKind.ClassKeyword, SyntaxKind.DeclareKeyword, SyntaxKind.DefaultKeyword, SyntaxKind.EnumKeyword, SyntaxKind.ExportKeyword, SyntaxKind.ExtendsKeyword, SyntaxKind.GetKeyword, SyntaxKind.ImplementsKeyword, SyntaxKind.ImportKeyword, SyntaxKind.InterfaceKeyword, SyntaxKind.ModuleKeyword, SyntaxKind.NamespaceKeyword, SyntaxKind.PrivateKeyword, SyntaxKind.PublicKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.ReadonlyKeyword, SyntaxKind.SetKeyword, SyntaxKind.StaticKeyword, SyntaxKind.TypeKeyword, SyntaxKind.FromKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
365+
this.SpaceAfterCertainTypeScriptKeywords = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.AbstractKeyword, SyntaxKind.ClassKeyword, SyntaxKind.DeclareKeyword, SyntaxKind.DefaultKeyword, SyntaxKind.EnumKeyword, SyntaxKind.ExportKeyword, SyntaxKind.ExtendsKeyword, SyntaxKind.GetKeyword, SyntaxKind.ImplementsKeyword, SyntaxKind.ImportKeyword, SyntaxKind.InterfaceKeyword, SyntaxKind.ModuleKeyword, SyntaxKind.NamespaceKeyword, SyntaxKind.PrivateKeyword, SyntaxKind.PublicKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.ReadonlyKeyword, SyntaxKind.SetKeyword, SyntaxKind.StaticKeyword, SyntaxKind.TypeKeyword, SyntaxKind.FromKeyword, SyntaxKind.KeyOfKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
366366
this.SpaceBeforeCertainTypeScriptKeywords = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.ExtendsKeyword, SyntaxKind.ImplementsKeyword, SyntaxKind.FromKeyword])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
367367

368368
// Treat string literals in module names as identifiers, and add a space between the literal and the opening Brace braces, e.g.: module "m2" {
@@ -578,6 +578,8 @@ namespace ts.formatting {
578578
return context.currentTokenSpan.kind === SyntaxKind.EqualsToken || context.nextTokenSpan.kind === SyntaxKind.EqualsToken;
579579
// "in" keyword in for (let x in []) { }
580580
case SyntaxKind.ForInStatement:
581+
// "in" keyword in [P in keyof T]: T[P]
582+
case SyntaxKind.TypeParameter:
581583
return context.currentTokenSpan.kind === SyntaxKind.InKeyword || context.nextTokenSpan.kind === SyntaxKind.InKeyword;
582584
// Technically, "of" is not a binary operator, but format it the same way as "in"
583585
case SyntaxKind.ForOfStatement:
@@ -832,6 +834,7 @@ namespace ts.formatting {
832834
switch (parent.kind) {
833835
case SyntaxKind.TypeReference:
834836
case SyntaxKind.TypeAssertionExpression:
837+
case SyntaxKind.TypeAliasDeclaration:
835838
case SyntaxKind.ClassDeclaration:
836839
case SyntaxKind.ClassExpression:
837840
case SyntaxKind.InterfaceDeclaration:

src/services/formatting/smartIndenter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ namespace ts.formatting {
438438
case SyntaxKind.ModuleBlock:
439439
case SyntaxKind.ObjectLiteralExpression:
440440
case SyntaxKind.TypeLiteral:
441+
case SyntaxKind.MappedType:
441442
case SyntaxKind.TupleType:
442443
case SyntaxKind.CaseBlock:
443444
case SyntaxKind.DefaultClause:
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
/////*generic*/type t < T > = {
4+
/////*map*/ [ P in keyof T ] : T [ P ]
5+
////};
6+
7+
8+
format.document();
9+
goTo.marker("generic");
10+
verify.currentLineContentIs("type t<T> = {");
11+
goTo.marker("map");
12+
verify.currentLineContentIs(" [P in keyof T]: T[P]");

0 commit comments

Comments
 (0)