Skip to content

Commit 7e98fc7

Browse files
authored
Merge pull request #13111 from SaschaNaz/formatDestruct
Format destructuring by brace format option
2 parents fbe7a4f + a1f88d2 commit 7e98fc7

File tree

5 files changed

+43
-40
lines changed

5 files changed

+43
-40
lines changed

src/harness/fourslash.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ namespace FourSlash {
479479
endPos = endMarker.position;
480480
}
481481

482-
errors.forEach(function(error: ts.Diagnostic) {
482+
errors.forEach(function (error: ts.Diagnostic) {
483483
if (predicate(error.start, error.start + error.length, startPos, endPos)) {
484484
exists = true;
485485
}
@@ -496,7 +496,7 @@ namespace FourSlash {
496496
Harness.IO.log("Unexpected error(s) found. Error list is:");
497497
}
498498

499-
errors.forEach(function(error: ts.Diagnostic) {
499+
errors.forEach(function (error: ts.Diagnostic) {
500500
Harness.IO.log(" minChar: " + error.start +
501501
", limChar: " + (error.start + error.length) +
502502
", message: " + ts.flattenDiagnosticMessageText(error.messageText, Harness.IO.newLine()) + "\n");
@@ -3524,11 +3524,8 @@ namespace FourSlashInterface {
35243524
this.state.formatOnType(this.state.getMarkerByName(posMarker).position, key);
35253525
}
35263526

3527-
public setOption(name: string, value: number): void;
3528-
public setOption(name: string, value: string): void;
3529-
public setOption(name: string, value: boolean): void;
3530-
public setOption(name: string, value: any): void {
3531-
(<any>this.state.formatCodeSettings)[name] = value;
3527+
public setOption(name: keyof ts.FormatCodeSettings, value: number | string | boolean): void {
3528+
this.state.formatCodeSettings[name] = value;
35323529
}
35333530
}
35343531

src/server/utilities.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ namespace ts.server {
8686
insertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
8787
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
8888
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
89+
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true,
8990
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
9091
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false,
9192
insertSpaceBeforeFunctionParenthesis: false,

src/services/formatting/rules.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -292,10 +292,10 @@ namespace ts.formatting {
292292
this.SpaceBeforeOpenBraceInControl = new Rule(RuleDescriptor.create2(this.ControlOpenBraceLeftTokenRange, SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsControlDeclContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeMultilineBlockContext), RuleAction.Space), RuleFlags.CanDeleteNewLines);
293293

294294
// Insert a space after { and before } in single-line contexts, but remove space from empty object literals {}.
295-
this.SpaceAfterOpenBrace = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSingleLineBlockContext), RuleAction.Space));
296-
this.SpaceBeforeCloseBrace = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSingleLineBlockContext), RuleAction.Space));
297-
this.NoSpaceAfterOpenBrace = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSingleLineBlockContext), RuleAction.Delete));
298-
this.NoSpaceBeforeCloseBrace = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSingleLineBlockContext), RuleAction.Delete));
295+
this.SpaceAfterOpenBrace = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsBraceWrappedContext), RuleAction.Space));
296+
this.SpaceBeforeCloseBrace = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsBraceWrappedContext), RuleAction.Space));
297+
this.NoSpaceAfterOpenBrace = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsBraceWrappedContext), RuleAction.Delete));
298+
this.NoSpaceBeforeCloseBrace = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsBraceWrappedContext), RuleAction.Delete));
299299
this.NoSpaceBetweenEmptyBraceBrackets = new Rule(RuleDescriptor.create1(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsObjectContext), RuleAction.Delete));
300300

301301
// Insert new line after { and before } in multi-line contexts.
@@ -617,6 +617,10 @@ namespace ts.formatting {
617617
return context.TokensAreOnSameLine() || Rules.IsBeforeMultilineBlockContext(context);
618618
}
619619

620+
static IsBraceWrappedContext(context: FormattingContext): boolean {
621+
return context.contextNode.kind === SyntaxKind.ObjectBindingPattern || Rules.IsSingleLineBlockContext(context);
622+
}
623+
620624
// This check is done before an open brace in a control construct, a function, or a typescript block declaration
621625
static IsBeforeMultilineBlockContext(context: FormattingContext): boolean {
622626
return Rules.IsBeforeBlockContext(context) && !(context.NextNodeAllOnSameLine() || context.NextNodeBlockIsOnOneLine());
Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,34 @@
11
///<reference path="fourslash.ts"/>
22

3-
/////*InsertSpaceAfterCommaDelimiter*/[1,2, 3];[ 72 , ];
4-
/////*InsertSpaceAfterSemicolonInForStatements*/for (i = 0;i; i++);
5-
/////*InsertSpaceBeforeAndAfterBinaryOperators*/1+2- 3
6-
/////*InsertSpaceAfterKeywordsInControlFlowStatements*/if (true) { }
7-
/////*InsertSpaceAfterFunctionKeywordForAnonymousFunctions*/(function () { })
8-
/////*InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis*/(1 )
9-
/////*InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets*/[1 ]; [ ]; []; [,];
10-
/////*InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces*/`${1}`;`${ 1 }`
11-
/////*InsertSpaceAfterTypeAssertion*/const bar = <Bar> Thing.getFoo();
12-
/////*PlaceOpenBraceOnNewLineForFunctions*/class foo {
3+
/////*insertSpaceAfterCommaDelimiter*/[1,2, 3];[ 72 , ];
4+
/////*insertSpaceAfterSemicolonInForStatements*/for (i = 0;i; i++);
5+
/////*insertSpaceBeforeAndAfterBinaryOperators*/1+2- 3
6+
/////*insertSpaceAfterKeywordsInControlFlowStatements*/if (true) { }
7+
/////*insertSpaceAfterFunctionKeywordForAnonymousFunctions*/(function () { })
8+
/////*insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis*/(1 )
9+
/////*insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets*/[1 ]; [ ]; []; [,];
10+
/////*insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces*/`${1}`;`${ 1 }`
11+
/////*insertSpaceAfterTypeAssertion*/const bar = <Bar> Thing.getFoo();
12+
/////*placeOpenBraceOnNewLineForFunctions*/class foo {
1313
////}
14-
/////*PlaceOpenBraceOnNewLineForControlBlocks*/if (true) {
14+
/////*placeOpenBraceOnNewLineForControlBlocks*/if (true) {
1515
////}
16-
/////*InsertSpaceAfterOpeningAndBeforeClosingNonemptyBraces*/{ var t = 1};
17-
18-
runTest("InsertSpaceAfterCommaDelimiter", "[1, 2, 3];[72,];", "[1,2,3];[72,];");
19-
runTest("InsertSpaceAfterSemicolonInForStatements", "for (i = 0; i; i++);", "for (i = 0;i;i++);");
20-
runTest("InsertSpaceBeforeAndAfterBinaryOperators", "1 + 2 - 3", "1+2-3");
21-
runTest("InsertSpaceAfterKeywordsInControlFlowStatements", "if (true) { }", "if(true) { }");
22-
runTest("InsertSpaceAfterFunctionKeywordForAnonymousFunctions", "(function () { })", "(function() { })");
23-
runTest("InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis", " ( 1 )", " (1)");
24-
runTest("InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets", "[ 1 ];[];[];[ , ];", "[1];[];[];[,];");
25-
runTest("InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces", "`${ 1 }`; `${ 1 }`", "`${1}`; `${1}`");
26-
runTest("InsertSpaceAfterTypeAssertion", "const bar = <Bar> Thing.getFoo();", "const bar = <Bar>Thing.getFoo();");
27-
runTest("PlaceOpenBraceOnNewLineForFunctions", "class foo", "class foo {");
28-
runTest("PlaceOpenBraceOnNewLineForControlBlocks", "if ( true )", "if ( true ) {");
29-
runTest("InsertSpaceAfterOpeningAndBeforeClosingNonemptyBraces", "{ var t = 1 };", "{var t = 1};");
30-
16+
/////*insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces*/{ var t = 1}; var {a,b } = { a: 'sw', b:'r' };function f( { a, b}) { }
17+
18+
const defaultFormatOption = format.copyFormatOptions();
19+
20+
runTest("insertSpaceAfterCommaDelimiter", "[1, 2, 3];[72,];", "[1,2,3];[72,];");
21+
runTest("insertSpaceAfterSemicolonInForStatements", "for (i = 0; i; i++);", "for (i = 0;i;i++);");
22+
runTest("insertSpaceBeforeAndAfterBinaryOperators", "1 + 2 - 3", "1+2-3");
23+
runTest("insertSpaceAfterKeywordsInControlFlowStatements", "if (true) { }", "if(true) { }");
24+
runTest("insertSpaceAfterFunctionKeywordForAnonymousFunctions", "(function () { })", "(function() { })");
25+
runTest("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis", " ( 1 )", " (1)");
26+
runTest("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets", "[ 1 ];[];[];[ , ];", "[1];[];[];[,];");
27+
runTest("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces", "`${ 1 }`; `${ 1 }`", "`${1}`; `${1}`");
28+
runTest("insertSpaceAfterTypeAssertion", "const bar = <Bar> Thing.getFoo();", "const bar = <Bar>Thing.getFoo();");
29+
runTest("placeOpenBraceOnNewLineForFunctions", "class foo", "class foo {");
30+
runTest("placeOpenBraceOnNewLineForControlBlocks", "if (true)", "if (true) {");
31+
runTest("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces", "{ var t = 1 }; var { a, b } = { a: 'sw', b: 'r' }; function f({ a, b }) { }", "{var t = 1}; var {a, b} = {a: 'sw', b: 'r'}; function f({a, b}) {}");
3132

3233
function runTest(propertyName: string, expectedStringWhenTrue: string, expectedStringWhenFalse: string) {
3334
// Go to the correct file
@@ -52,4 +53,6 @@ function runTest(propertyName: string, expectedStringWhenTrue: string, expectedS
5253
// Verify
5354
goTo.marker(propertyName);
5455
verify.currentLineContentIs(expectedStringWhenTrue);
56+
57+
format.setOption(propertyName, defaultFormatOption[propertyName])
5558
}

tests/cases/fourslash/fourslash.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,7 @@ declare namespace FourSlashInterface {
294294
setFormatOptions(options: FormatCodeOptions): any;
295295
selection(startMarker: string, endMarker: string): void;
296296
onType(posMarker: string, key: string): void;
297-
setOption(name: string, value: number): any;
298-
setOption(name: string, value: string): any;
299-
setOption(name: string, value: boolean): any;
297+
setOption(name: string, value: number | string | boolean): void;
300298
}
301299
class cancellation {
302300
resetCancelled(): void;

0 commit comments

Comments
 (0)