diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts
index bae2977c44a..a42abbbc609 100644
--- a/src/harness/fourslash.ts
+++ b/src/harness/fourslash.ts
@@ -324,6 +324,7 @@ namespace FourSlash {
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
+ InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false,
PlaceOpenBraceOnNewLineForFunctions: false,
PlaceOpenBraceOnNewLineForControlBlocks: false,
};
diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts
index e48d6192017..092450e526c 100644
--- a/src/server/editorServices.ts
+++ b/src/server/editorServices.ts
@@ -1580,6 +1580,7 @@ namespace ts.server {
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
+ InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false,
PlaceOpenBraceOnNewLineForFunctions: false,
PlaceOpenBraceOnNewLineForControlBlocks: false,
});
diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts
index 50d6d596198..6e132f03465 100644
--- a/src/services/formatting/rules.ts
+++ b/src/services/formatting/rules.ts
@@ -52,10 +52,6 @@ namespace ts.formatting {
public SpaceBeforeCloseBrace: Rule;
public NoSpaceBetweenEmptyBraceBrackets: Rule;
- // No space after { and before } in JSX expression
- public NoSpaceAfterOpenBraceInJsxExpression: Rule;
- public NoSpaceBeforeCloseBraceInJsxExpression: Rule;
-
// Insert new line after { and before } in multi-line contexts.
public NewLineAfterOpenBraceInBlockContext: Rule;
@@ -229,6 +225,12 @@ namespace ts.formatting {
public NoSpaceBeforeTemplateMiddleAndTail: Rule;
public SpaceBeforeTemplateMiddleAndTail: Rule;
+ // No space after { and before } in JSX expression
+ public NoSpaceAfterOpenBraceInJsxExpression: Rule;
+ public SpaceAfterOpenBraceInJsxExpression: Rule;
+ public NoSpaceBeforeCloseBraceInJsxExpression: Rule;
+ public SpaceBeforeCloseBraceInJsxExpression: Rule;
+
constructor() {
///
/// Common Rules
@@ -280,10 +282,6 @@ namespace ts.formatting {
this.SpaceBeforeCloseBrace = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSingleLineBlockContext), RuleAction.Space));
this.NoSpaceBetweenEmptyBraceBrackets = new Rule(RuleDescriptor.create1(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsObjectContext), RuleAction.Delete));
- // No space after { and before } in JSX expression
- this.NoSpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Delete));
- this.NoSpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Delete));
-
// Insert new line after { and before } in multi-line contexts.
this.NewLineAfterOpenBraceInBlockContext = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsMultilineBlockContext), RuleAction.NewLine));
@@ -403,7 +401,6 @@ namespace ts.formatting {
this.SpaceAfterSubtractWhenFollowedByUnaryMinus, this.SpaceAfterSubtractWhenFollowedByPredecrement,
this.NoSpaceAfterCloseBrace,
this.SpaceAfterOpenBrace, this.SpaceBeforeCloseBrace, this.NewLineBeforeCloseBraceInBlockContext,
- this.NoSpaceAfterOpenBraceInJsxExpression, this.NoSpaceBeforeCloseBraceInJsxExpression,
this.SpaceAfterCloseBrace, this.SpaceBetweenCloseBraceAndElse, this.SpaceBetweenCloseBraceAndWhile, this.NoSpaceBetweenEmptyBraceBrackets,
this.NoSpaceBetweenFunctionKeywordAndStar, this.SpaceAfterStarInGeneratorDeclaration,
this.SpaceAfterFunctionInFuncDecl, this.NewLineAfterOpenBraceInBlockContext, this.SpaceAfterGetSetInMember,
@@ -500,6 +497,12 @@ namespace ts.formatting {
this.NoSpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
this.SpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
+ // No space after { and before } in JSX expression
+ this.NoSpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Delete));
+ this.SpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Space));
+ this.NoSpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Delete));
+ this.SpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Space));
+
// Insert space after function keyword for anonymous functions
this.SpaceAfterAnonymousFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Space));
this.NoSpaceAfterAnonymousFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Delete));
diff --git a/src/services/formatting/rulesProvider.ts b/src/services/formatting/rulesProvider.ts
index d672a401d89..1be0f9e912d 100644
--- a/src/services/formatting/rulesProvider.ts
+++ b/src/services/formatting/rulesProvider.ts
@@ -90,6 +90,15 @@ namespace ts.formatting {
rules.push(this.globalRules.NoSpaceBeforeTemplateMiddleAndTail);
}
+ if (options.InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces) {
+ rules.push(this.globalRules.SpaceAfterOpenBraceInJsxExpression);
+ rules.push(this.globalRules.SpaceBeforeCloseBraceInJsxExpression);
+ }
+ else {
+ rules.push(this.globalRules.NoSpaceAfterOpenBraceInJsxExpression);
+ rules.push(this.globalRules.NoSpaceBeforeCloseBraceInJsxExpression);
+ }
+
if (options.InsertSpaceAfterSemicolonInForStatements) {
rules.push(this.globalRules.SpaceAfterSemicolonInFor);
}
diff --git a/src/services/services.ts b/src/services/services.ts
index a17d9feed24..5142b19b6c0 100644
--- a/src/services/services.ts
+++ b/src/services/services.ts
@@ -1267,6 +1267,7 @@ namespace ts {
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean;
InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean;
InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean;
+ InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: boolean;
PlaceOpenBraceOnNewLineForFunctions: boolean;
PlaceOpenBraceOnNewLineForControlBlocks: boolean;
[s: string]: boolean | number | string | undefined;
diff --git a/tests/cases/fourslash/formattingOptionsChangeJsx.ts b/tests/cases/fourslash/formattingOptionsChangeJsx.ts
new file mode 100644
index 00000000000..a3c7e28a1ef
--- /dev/null
+++ b/tests/cases/fourslash/formattingOptionsChangeJsx.ts
@@ -0,0 +1,32 @@
+///
+
+//@Filename: file.tsx
+/////*InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces*/;
+
+runTest("InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces", ";", ";");
+
+
+function runTest(propertyName: string, expectedStringWhenTrue: string, expectedStringWhenFalse: string) {
+ // Go to the correct file
+ goTo.marker(propertyName);
+
+ // Set the option to false first
+ format.setOption(propertyName, false);
+
+ // Format
+ format.document();
+
+ // Verify
+ goTo.marker(propertyName);
+ verify.currentLineContentIs(expectedStringWhenFalse);
+
+ // Set the option to true
+ format.setOption(propertyName, true);
+
+ // Format
+ format.document();
+
+ // Verify
+ goTo.marker(propertyName);
+ verify.currentLineContentIs(expectedStringWhenTrue);
+}
\ No newline at end of file