Skip to content

Commit c90af3a

Browse files
authored
Merge pull request #13045 from aochsner/fix-12234
space-before-function-paren
2 parents 6c60bfc + 3b3d715 commit c90af3a

File tree

8 files changed

+55
-3
lines changed

8 files changed

+55
-3
lines changed

src/harness/fourslash.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ namespace FourSlash {
341341
insertSpaceAfterCommaDelimiter: true,
342342
insertSpaceAfterSemicolonInForStatements: true,
343343
insertSpaceBeforeAndAfterBinaryOperators: true,
344+
insertSpaceAfterConstructor: false,
344345
insertSpaceAfterKeywordsInControlFlowStatements: true,
345346
insertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
346347
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,

src/server/protocol.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2194,12 +2194,14 @@ namespace ts.server.protocol {
21942194
insertSpaceAfterCommaDelimiter?: boolean;
21952195
insertSpaceAfterSemicolonInForStatements?: boolean;
21962196
insertSpaceBeforeAndAfterBinaryOperators?: boolean;
2197+
insertSpaceAfterConstructor?: boolean;
21972198
insertSpaceAfterKeywordsInControlFlowStatements?: boolean;
21982199
insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean;
21992200
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean;
22002201
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean;
22012202
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
22022203
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
2204+
insertSpaceBeforeFunctionParenthesis?: boolean;
22032205
placeOpenBraceOnNewLineForFunctions?: boolean;
22042206
placeOpenBraceOnNewLineForControlBlocks?: boolean;
22052207
}

src/server/utilities.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ namespace ts.server {
7878
newLineCharacter: host.newLine || "\n",
7979
convertTabsToSpaces: true,
8080
indentStyle: ts.IndentStyle.Smart,
81+
insertSpaceAfterConstructor: false,
8182
insertSpaceAfterCommaDelimiter: true,
8283
insertSpaceAfterSemicolonInForStatements: true,
8384
insertSpaceBeforeAndAfterBinaryOperators: true,
@@ -87,6 +88,7 @@ namespace ts.server {
8788
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
8889
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
8990
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false,
91+
insertSpaceBeforeFunctionParenthesis: false,
9092
placeOpenBraceOnNewLineForFunctions: false,
9193
placeOpenBraceOnNewLineForControlBlocks: false,
9294
};

src/services/formatting/rules.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ namespace ts.formatting {
8787
public SpaceAfterLetConstInVariableDeclaration: Rule;
8888
public NoSpaceBeforeOpenParenInFuncCall: Rule;
8989
public SpaceAfterFunctionInFuncDecl: Rule;
90+
public SpaceBeforeOpenParenInFuncDecl: Rule;
9091
public NoSpaceBeforeOpenParenInFuncDecl: Rule;
9192
public SpaceAfterVoidOperator: Rule;
9293

@@ -112,6 +113,7 @@ namespace ts.formatting {
112113
// TypeScript-specific rules
113114

114115
// Treat constructor as an identifier in a function declaration, and remove spaces between constructor and following left parentheses
116+
public SpaceAfterConstructor: Rule;
115117
public NoSpaceAfterConstructor: Rule;
116118

117119
// Use of module as a function call. e.g.: import m2 = module("m2");
@@ -329,6 +331,7 @@ namespace ts.formatting {
329331
this.SpaceAfterLetConstInVariableDeclaration = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.LetKeyword, SyntaxKind.ConstKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsStartOfVariableDeclarationList), RuleAction.Space));
330332
this.NoSpaceBeforeOpenParenInFuncCall = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionCallOrNewContext, Rules.IsPreviousTokenNotComma), RuleAction.Delete));
331333
this.SpaceAfterFunctionInFuncDecl = new Rule(RuleDescriptor.create3(SyntaxKind.FunctionKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Space));
334+
this.SpaceBeforeOpenParenInFuncDecl = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionDeclContext), RuleAction.Space));
332335
this.NoSpaceBeforeOpenParenInFuncDecl = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionDeclContext), RuleAction.Delete));
333336
this.SpaceAfterVoidOperator = new Rule(RuleDescriptor.create3(SyntaxKind.VoidKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsVoidOpContext), RuleAction.Space));
334337

@@ -352,6 +355,7 @@ namespace ts.formatting {
352355
// TypeScript-specific higher priority rules
353356

354357
// Treat constructor as an identifier in a function declaration, and remove spaces between constructor and following left parentheses
358+
this.SpaceAfterConstructor = new Rule(RuleDescriptor.create1(SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
355359
this.NoSpaceAfterConstructor = new Rule(RuleDescriptor.create1(SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
356360

357361
// Use of module as a function call. e.g.: import m2 = module("m2");
@@ -437,7 +441,7 @@ namespace ts.formatting {
437441
this.NoSpaceBeforeEqualInJsxAttribute, this.NoSpaceAfterEqualInJsxAttribute,
438442

439443
// TypeScript-specific rules
440-
this.NoSpaceAfterConstructor, this.NoSpaceAfterModuleImport,
444+
this.NoSpaceAfterModuleImport,
441445
this.SpaceAfterCertainTypeScriptKeywords, this.SpaceBeforeCertainTypeScriptKeywords,
442446
this.SpaceAfterModuleName,
443447
this.SpaceBeforeArrow, this.SpaceAfterArrow,
@@ -462,7 +466,6 @@ namespace ts.formatting {
462466
this.NoSpaceBeforeOpenBracket,
463467
this.NoSpaceAfterCloseBracket,
464468
this.SpaceAfterSemicolon,
465-
this.NoSpaceBeforeOpenParenInFuncDecl,
466469
this.SpaceBetweenStatements, this.SpaceAfterTryFinally
467470
];
468471

src/services/formatting/rulesProvider.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ namespace ts.formatting {
3838
private createActiveRules(options: ts.FormatCodeSettings): Rule[] {
3939
let rules = this.globalRules.HighPriorityCommonRules.slice(0);
4040

41+
if (options.insertSpaceAfterConstructor) {
42+
rules.push(this.globalRules.SpaceAfterConstructor);
43+
}
44+
else {
45+
rules.push(this.globalRules.NoSpaceAfterConstructor);
46+
}
47+
4148
if (options.insertSpaceAfterCommaDelimiter) {
4249
rules.push(this.globalRules.SpaceAfterComma);
4350
}
@@ -128,6 +135,13 @@ namespace ts.formatting {
128135
rules.push(this.globalRules.NoSpaceAfterBinaryOperator);
129136
}
130137

138+
if (options.insertSpaceBeforeFunctionParenthesis) {
139+
rules.push(this.globalRules.SpaceBeforeOpenParenInFuncDecl);
140+
}
141+
else {
142+
rules.push(this.globalRules.NoSpaceBeforeOpenParenInFuncDecl);
143+
}
144+
131145
if (options.placeOpenBraceOnNewLineForControlBlocks) {
132146
rules.push(this.globalRules.NewLineBeforeOpenBraceInControl);
133147
}

src/services/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ namespace ts {
418418
InsertSpaceAfterCommaDelimiter: boolean;
419419
InsertSpaceAfterSemicolonInForStatements: boolean;
420420
InsertSpaceBeforeAndAfterBinaryOperators: boolean;
421+
InsertSpaceAfterConstructor?: boolean;
421422
InsertSpaceAfterKeywordsInControlFlowStatements: boolean;
422423
InsertSpaceAfterFunctionKeywordForAnonymousFunctions: boolean;
423424
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean;
@@ -426,6 +427,7 @@ namespace ts {
426427
InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean;
427428
InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
428429
InsertSpaceAfterTypeAssertion?: boolean;
430+
InsertSpaceBeforeFunctionParenthesis?: boolean;
429431
PlaceOpenBraceOnNewLineForFunctions: boolean;
430432
PlaceOpenBraceOnNewLineForControlBlocks: boolean;
431433
}
@@ -434,6 +436,7 @@ namespace ts {
434436
insertSpaceAfterCommaDelimiter?: boolean;
435437
insertSpaceAfterSemicolonInForStatements?: boolean;
436438
insertSpaceBeforeAndAfterBinaryOperators?: boolean;
439+
insertSpaceAfterConstructor?: boolean;
437440
insertSpaceAfterKeywordsInControlFlowStatements?: boolean;
438441
insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean;
439442
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean;
@@ -442,6 +445,7 @@ namespace ts {
442445
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
443446
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
444447
insertSpaceAfterTypeAssertion?: boolean;
448+
insertSpaceBeforeFunctionParenthesis?: boolean;
445449
placeOpenBraceOnNewLineForFunctions?: boolean;
446450
placeOpenBraceOnNewLineForControlBlocks?: boolean;
447451
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
/////*1*/function foo() { }
4+
/////*2*/function boo () { }
5+
/////*3*/var bar = function foo() { };
6+
/////*4*/var foo = { bar() { } };
7+
8+
format.setOption("InsertSpaceBeforeFunctionParenthesis", true);
9+
10+
format.document();
11+
12+
goTo.marker('1');
13+
verify.currentLineContentIs('function foo () { }');
14+
goTo.marker('2');
15+
verify.currentLineContentIs('function boo () { }');
16+
goTo.marker('3');
17+
verify.currentLineContentIs('var bar = function foo () { };');
18+
goTo.marker('4');
19+
verify.currentLineContentIs('var foo = { bar () { } };');

tests/cases/fourslash/formattingSpacesAfterConstructor.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,11 @@
33
/////*1*/class test { constructor () { } }
44
format.document();
55
goTo.marker("1");
6-
verify.currentLineContentIs("class test { constructor() { } }");
6+
verify.currentLineContentIs("class test { constructor() { } }");
7+
8+
/////*2*/class test { constructor () { } }
9+
format.setOption("InsertSpaceAfterConstructor", true);
10+
11+
format.document();
12+
goTo.marker("2");
13+
verify.currentLineContentIs("class test { constructor () { } }");

0 commit comments

Comments
 (0)