Skip to content

Commit cc1226c

Browse files
authored
Merge pull request #4609 from SaschaNaz/fixExportImportFormatting
Fix named export/import formatting
2 parents b2bc91b + a8ac0ef commit cc1226c

File tree

4 files changed

+104
-3
lines changed

4 files changed

+104
-3
lines changed

src/services/formatting/rules.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ namespace ts.formatting {
264264
this.SpaceBeforeOpenBraceInFunction = new Rule(RuleDescriptor.create2(this.FunctionOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext, Rules.IsBeforeBlockContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeMultilineBlockContext), RuleAction.Space), RuleFlags.CanDeleteNewLines);
265265

266266
// Place a space before open brace in a TypeScript declaration that has braces as children (class, module, enum, etc)
267-
this.TypeScriptOpenBraceLeftTokenRange = Shared.TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.MultiLineCommentTrivia, SyntaxKind.ClassKeyword]);
267+
this.TypeScriptOpenBraceLeftTokenRange = Shared.TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.MultiLineCommentTrivia, SyntaxKind.ClassKeyword, SyntaxKind.ExportKeyword, SyntaxKind.ImportKeyword]);
268268
this.SpaceBeforeOpenBraceInTypeScriptDeclWithBlock = new Rule(RuleDescriptor.create2(this.TypeScriptOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsTypeScriptDeclWithBlockContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeMultilineBlockContext), RuleAction.Space), RuleFlags.CanDeleteNewLines);
269269

270270
// Place a space before open brace in a control flow construct
@@ -338,8 +338,8 @@ namespace ts.formatting {
338338
this.NoSpaceAfterModuleImport = new Rule(RuleDescriptor.create2(Shared.TokenRange.FromTokens([SyntaxKind.ModuleKeyword, SyntaxKind.RequireKeyword]), SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
339339

340340
// Add a space around certain TypeScript keywords
341-
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.SetKeyword, SyntaxKind.StaticKeyword, SyntaxKind.TypeKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
342-
this.SpaceBeforeCertainTypeScriptKeywords = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.ExtendsKeyword, SyntaxKind.ImplementsKeyword])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
341+
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.SetKeyword, SyntaxKind.StaticKeyword, SyntaxKind.TypeKeyword, SyntaxKind.FromKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
342+
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));
343343

344344
// Treat string literals in module names as identifiers, and add a space between the literal and the opening Brace braces, e.g.: module "m2" {
345345
this.SpaceAfterModuleName = new Rule(RuleDescriptor.create1(SyntaxKind.StringLiteral, SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsModuleDeclContext), RuleAction.Space));
@@ -514,6 +514,8 @@ namespace ts.formatting {
514514
case SyntaxKind.BinaryExpression:
515515
case SyntaxKind.ConditionalExpression:
516516
case SyntaxKind.AsExpression:
517+
case SyntaxKind.ExportSpecifier:
518+
case SyntaxKind.ImportSpecifier:
517519
case SyntaxKind.TypePredicate:
518520
case SyntaxKind.UnionType:
519521
case SyntaxKind.IntersectionType:
@@ -650,6 +652,10 @@ namespace ts.formatting {
650652
case SyntaxKind.EnumDeclaration:
651653
case SyntaxKind.TypeLiteral:
652654
case SyntaxKind.ModuleDeclaration:
655+
case SyntaxKind.ExportDeclaration:
656+
case SyntaxKind.NamedExports:
657+
case SyntaxKind.ImportDeclaration:
658+
case SyntaxKind.NamedImports:
653659
return true;
654660
}
655661

src/services/formatting/smartIndenter.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,10 @@ namespace ts.formatting {
466466
case SyntaxKind.ParenthesizedType:
467467
case SyntaxKind.TaggedTemplateExpression:
468468
case SyntaxKind.AwaitExpression:
469+
case SyntaxKind.NamedExports:
469470
case SyntaxKind.NamedImports:
471+
case SyntaxKind.ExportSpecifier:
472+
case SyntaxKind.ImportSpecifier:
470473
return true;
471474
}
472475
return false;
@@ -490,6 +493,11 @@ namespace ts.formatting {
490493
case SyntaxKind.GetAccessor:
491494
case SyntaxKind.SetAccessor:
492495
return childKind !== SyntaxKind.Block;
496+
case SyntaxKind.ExportDeclaration:
497+
return childKind !== SyntaxKind.NamedExports;
498+
case SyntaxKind.ImportDeclaration:
499+
return childKind !== SyntaxKind.ImportClause ||
500+
(<ImportClause>child).namedBindings.kind !== SyntaxKind.NamedImports;
493501
case SyntaxKind.JsxElement:
494502
return childKind !== SyntaxKind.JsxClosingElement;
495503
}

src/services/utilities.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ namespace ts {
5353
case SyntaxKind.Block:
5454
case SyntaxKind.ModuleBlock:
5555
case SyntaxKind.CaseBlock:
56+
case SyntaxKind.NamedImports:
57+
case SyntaxKind.NamedExports:
5658
return nodeEndsWith(n, SyntaxKind.CloseBraceToken, sourceFile);
5759
case SyntaxKind.CatchClause:
5860
return isCompletedNode((<CatchClause>n).block, sourceFile);
@@ -156,6 +158,10 @@ namespace ts {
156158
case SyntaxKind.TemplateSpan:
157159
return nodeIsPresent((<TemplateSpan>n).literal);
158160

161+
case SyntaxKind.ExportDeclaration:
162+
case SyntaxKind.ImportDeclaration:
163+
return nodeIsPresent((<ExportDeclaration | ImportDeclaration>n).moduleSpecifier);
164+
159165
case SyntaxKind.PrefixUnaryExpression:
160166
return isCompletedNode((<PrefixUnaryExpression>n).operand, sourceFile);
161167
case SyntaxKind.BinaryExpression:
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
/////*selectionStart*/
4+
////export { x, y as yy, z } from "foo"/*export1*/
5+
////export{x, y as yy, z}from"bar"/*export2*/
6+
////
7+
////export
8+
/////*exportOpenBrace*/{x,/*exportSpecifier1*/
9+
////y as yy, z/*exportSpecifier2*/ }/*exportCloseBrace*/
10+
//// from/*fromKeywordAutoformat*/
11+
/////*fromKeywordIndent*/
12+
////"foo"/*exportDir*/
13+
////
14+
////import {x, y as yy, z}from "baz"/*import1*/
15+
////
16+
////import/*importOpenBrace*/{x,/*importSpecifier1*/
17+
////y
18+
////as yy,/*importSpecifier2*/
19+
////z}/*importCloseBrace*/
20+
////from "wow"/*importDir*/
21+
/////*selectionEnd*/
22+
////
23+
////export/*formatOnEnter*/{/*formatOnEnterOpenBrace*/
24+
/////*differentLineIndent*/x/*differentLineAutoformat*/
25+
////} from "abc"
26+
////
27+
////export {
28+
/////*incompleteExportDeclIndent*/
29+
/////*incompleteExportDeclIndent2*/
30+
31+
format.selection("selectionStart", "selectionEnd");
32+
33+
goTo.marker("export1");
34+
verify.currentLineContentIs('export { x, y as yy, z } from "foo"');
35+
goTo.marker("export2");
36+
verify.currentLineContentIs('export { x, y as yy, z } from "bar"');
37+
38+
goTo.marker("exportOpenBrace");
39+
verify.currentLineContentIs("export {");
40+
goTo.marker("exportSpecifier1");
41+
verify.currentLineContentIs(" x,");
42+
goTo.marker("exportSpecifier2");
43+
verify.currentLineContentIs(" y as yy, z");
44+
goTo.marker("exportCloseBrace");
45+
verify.currentLineContentIs("}");
46+
goTo.marker("fromKeywordAutoformat");
47+
verify.currentLineContentIs(" from");
48+
goTo.marker("fromKeywordIndent");
49+
verify.indentationIs(4);
50+
goTo.marker("exportDir");
51+
verify.currentLineContentIs(' "foo"');
52+
53+
goTo.marker("import1");
54+
verify.currentLineContentIs('import { x, y as yy, z } from "baz"');
55+
56+
goTo.marker("importOpenBrace");
57+
verify.currentLineContentIs("import {");
58+
goTo.marker("importSpecifier1");
59+
verify.currentLineContentIs(" x,");
60+
goTo.marker("importSpecifier2");
61+
verify.currentLineContentIs(" as yy,");
62+
goTo.marker("importCloseBrace");
63+
verify.currentLineContentIs("}");
64+
goTo.marker("importDir");
65+
verify.currentLineContentIs(' from "wow"');
66+
67+
goTo.marker("formatOnEnter");
68+
edit.insertLine('');
69+
goTo.marker("formatOnEnterOpenBrace");
70+
verify.currentLineContentIs("{");
71+
goTo.marker("differentLineIndent");
72+
verify.indentationIs(4);
73+
edit.insertLine('');
74+
goTo.marker("differentLineAutoformat");
75+
verify.currentLineContentIs(" x");
76+
77+
goTo.marker("incompleteExportDeclIndent")
78+
verify.indentationIs(4);
79+
edit.insert("} from");
80+
goTo.marker("incompleteExportDeclIndent2");
81+
verify.indentationIs(4);

0 commit comments

Comments
 (0)