From 3b3d71542c045f5f8228f8c795ff2a18db36df66 Mon Sep 17 00:00:00 2001 From: Andrew Ochsner Date: Tue, 20 Dec 2016 10:05:10 -0600 Subject: [PATCH] Add InsertSpaceAfterConstructor option & additonal test cases Fixes #12234 --- src/harness/fourslash.ts | 1 + src/server/protocol.ts | 1 + src/server/utilities.ts | 1 + src/services/formatting/rules.ts | 4 +++- src/services/formatting/rulesProvider.ts | 7 +++++++ src/services/types.ts | 2 ++ .../fourslash/formattingSpaceBeforeFunctionParen.ts | 8 +++++++- .../cases/fourslash/formattingSpacesAfterConstructor.ts | 9 ++++++++- 8 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 7c7a06db0b6..653b87236fd 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -341,6 +341,7 @@ namespace FourSlash { insertSpaceAfterCommaDelimiter: true, insertSpaceAfterSemicolonInForStatements: true, insertSpaceBeforeAndAfterBinaryOperators: true, + insertSpaceAfterConstructor: false, insertSpaceAfterKeywordsInControlFlowStatements: true, insertSpaceAfterFunctionKeywordForAnonymousFunctions: false, insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, diff --git a/src/server/protocol.ts b/src/server/protocol.ts index f38862befce..680b81dff99 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2194,6 +2194,7 @@ namespace ts.server.protocol { insertSpaceAfterCommaDelimiter?: boolean; insertSpaceAfterSemicolonInForStatements?: boolean; insertSpaceBeforeAndAfterBinaryOperators?: boolean; + insertSpaceAfterConstructor?: boolean; insertSpaceAfterKeywordsInControlFlowStatements?: boolean; insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean; insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean; diff --git a/src/server/utilities.ts b/src/server/utilities.ts index f15a494b5c4..641ca128e63 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -78,6 +78,7 @@ namespace ts.server { newLineCharacter: host.newLine || "\n", convertTabsToSpaces: true, indentStyle: ts.IndentStyle.Smart, + insertSpaceAfterConstructor: false, insertSpaceAfterCommaDelimiter: true, insertSpaceAfterSemicolonInForStatements: true, insertSpaceBeforeAndAfterBinaryOperators: true, diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 869f84d2653..be592174d2e 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -113,6 +113,7 @@ namespace ts.formatting { // TypeScript-specific rules // Treat constructor as an identifier in a function declaration, and remove spaces between constructor and following left parentheses + public SpaceAfterConstructor: Rule; public NoSpaceAfterConstructor: Rule; // Use of module as a function call. e.g.: import m2 = module("m2"); @@ -354,6 +355,7 @@ namespace ts.formatting { // TypeScript-specific higher priority rules // Treat constructor as an identifier in a function declaration, and remove spaces between constructor and following left parentheses + this.SpaceAfterConstructor = new Rule(RuleDescriptor.create1(SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); this.NoSpaceAfterConstructor = new Rule(RuleDescriptor.create1(SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); // Use of module as a function call. e.g.: import m2 = module("m2"); @@ -439,7 +441,7 @@ namespace ts.formatting { this.NoSpaceBeforeEqualInJsxAttribute, this.NoSpaceAfterEqualInJsxAttribute, // TypeScript-specific rules - this.NoSpaceAfterConstructor, this.NoSpaceAfterModuleImport, + this.NoSpaceAfterModuleImport, this.SpaceAfterCertainTypeScriptKeywords, this.SpaceBeforeCertainTypeScriptKeywords, this.SpaceAfterModuleName, this.SpaceBeforeArrow, this.SpaceAfterArrow, diff --git a/src/services/formatting/rulesProvider.ts b/src/services/formatting/rulesProvider.ts index f999b780e87..14e08e4857a 100644 --- a/src/services/formatting/rulesProvider.ts +++ b/src/services/formatting/rulesProvider.ts @@ -38,6 +38,13 @@ namespace ts.formatting { private createActiveRules(options: ts.FormatCodeSettings): Rule[] { let rules = this.globalRules.HighPriorityCommonRules.slice(0); + if (options.insertSpaceAfterConstructor) { + rules.push(this.globalRules.SpaceAfterConstructor); + } + else { + rules.push(this.globalRules.NoSpaceAfterConstructor); + } + if (options.insertSpaceAfterCommaDelimiter) { rules.push(this.globalRules.SpaceAfterComma); } diff --git a/src/services/types.ts b/src/services/types.ts index ac7d422a299..88ffe2950ce 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -418,6 +418,7 @@ namespace ts { InsertSpaceAfterCommaDelimiter: boolean; InsertSpaceAfterSemicolonInForStatements: boolean; InsertSpaceBeforeAndAfterBinaryOperators: boolean; + InsertSpaceAfterConstructor?: boolean; InsertSpaceAfterKeywordsInControlFlowStatements: boolean; InsertSpaceAfterFunctionKeywordForAnonymousFunctions: boolean; InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean; @@ -435,6 +436,7 @@ namespace ts { insertSpaceAfterCommaDelimiter?: boolean; insertSpaceAfterSemicolonInForStatements?: boolean; insertSpaceBeforeAndAfterBinaryOperators?: boolean; + insertSpaceAfterConstructor?: boolean; insertSpaceAfterKeywordsInControlFlowStatements?: boolean; insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean; insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean; diff --git a/tests/cases/fourslash/formattingSpaceBeforeFunctionParen.ts b/tests/cases/fourslash/formattingSpaceBeforeFunctionParen.ts index 4b21a3f0389..ce85521879e 100644 --- a/tests/cases/fourslash/formattingSpaceBeforeFunctionParen.ts +++ b/tests/cases/fourslash/formattingSpaceBeforeFunctionParen.ts @@ -2,6 +2,8 @@ /////*1*/function foo() { } /////*2*/function boo () { } +/////*3*/var bar = function foo() { }; +/////*4*/var foo = { bar() { } }; format.setOption("InsertSpaceBeforeFunctionParenthesis", true); @@ -10,4 +12,8 @@ format.document(); goTo.marker('1'); verify.currentLineContentIs('function foo () { }'); goTo.marker('2'); -verify.currentLineContentIs('function boo () { }'); \ No newline at end of file +verify.currentLineContentIs('function boo () { }'); +goTo.marker('3'); +verify.currentLineContentIs('var bar = function foo () { };'); +goTo.marker('4'); +verify.currentLineContentIs('var foo = { bar () { } };'); \ No newline at end of file diff --git a/tests/cases/fourslash/formattingSpacesAfterConstructor.ts b/tests/cases/fourslash/formattingSpacesAfterConstructor.ts index 8df762def20..2195d74adbc 100644 --- a/tests/cases/fourslash/formattingSpacesAfterConstructor.ts +++ b/tests/cases/fourslash/formattingSpacesAfterConstructor.ts @@ -3,4 +3,11 @@ /////*1*/class test { constructor () { } } format.document(); goTo.marker("1"); -verify.currentLineContentIs("class test { constructor() { } }"); \ No newline at end of file +verify.currentLineContentIs("class test { constructor() { } }"); + +/////*2*/class test { constructor () { } } +format.setOption("InsertSpaceAfterConstructor", true); + +format.document(); +goTo.marker("2"); +verify.currentLineContentIs("class test { constructor () { } }"); \ No newline at end of file