Skip to content

Commit 55dafb5

Browse files
committed
Merge pull request #2110 from Microsoft/formattingQMark
Add space after '?' only for conditional operators
2 parents d1df797 + e549f2f commit 55dafb5

File tree

4 files changed

+34
-6
lines changed

4 files changed

+34
-6
lines changed

src/services/formatting/rules.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,13 @@ module ts.formatting {
3535
// Space after keyword but not before ; or : or ?
3636
public NoSpaceBeforeSemicolon: Rule;
3737
public NoSpaceBeforeColon: Rule;
38-
public NoSpaceBeforeQMark: Rule;
38+
public NoSpaceBeforeQuestionMark: Rule;
3939
public SpaceAfterColon: Rule;
40-
public SpaceAfterQMark: Rule;
40+
// insert space after '?' only when it is used in conditional operator
41+
public SpaceAfterQuestionMarkInConditionalOperator: Rule;
42+
// in other cases there should be no space between '?' and next token
43+
public NoSpaceAfterQuestionMark: Rule;
44+
4145
public SpaceAfterSemicolon: Rule;
4246

4347
// Space/new line after }.
@@ -215,9 +219,10 @@ module ts.formatting {
215219
// Space after keyword but not before ; or : or ?
216220
this.NoSpaceBeforeSemicolon = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.SemicolonToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
217221
this.NoSpaceBeforeColon = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.ColonToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Delete));
218-
this.NoSpaceBeforeQMark = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.QuestionToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Delete));
222+
this.NoSpaceBeforeQuestionMark = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.QuestionToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Delete));
219223
this.SpaceAfterColon = new Rule(RuleDescriptor.create3(SyntaxKind.ColonToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Space));
220-
this.SpaceAfterQMark = new Rule(RuleDescriptor.create3(SyntaxKind.QuestionToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Space));
224+
this.SpaceAfterQuestionMarkInConditionalOperator = new Rule(RuleDescriptor.create3(SyntaxKind.QuestionToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsConditionalOperatorContext), RuleAction.Space));
225+
this.NoSpaceAfterQuestionMark = new Rule(RuleDescriptor.create3(SyntaxKind.QuestionToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
221226
this.SpaceAfterSemicolon = new Rule(RuleDescriptor.create3(SyntaxKind.SemicolonToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space));
222227

223228
// Space after }.
@@ -341,7 +346,8 @@ module ts.formatting {
341346
this.HighPriorityCommonRules =
342347
[
343348
this.IgnoreBeforeComment, this.IgnoreAfterLineComment,
344-
this.NoSpaceBeforeColon, this.SpaceAfterColon, this.NoSpaceBeforeQMark, this.SpaceAfterQMark,
349+
this.NoSpaceBeforeColon, this.SpaceAfterColon, this.NoSpaceBeforeQuestionMark, this.SpaceAfterQuestionMarkInConditionalOperator,
350+
this.NoSpaceAfterQuestionMark,
345351
this.NoSpaceBeforeDot, this.NoSpaceAfterDot,
346352
this.NoSpaceAfterUnaryPrefixOperator,
347353
this.NoSpaceAfterUnaryPreincrementOperator, this.NoSpaceAfterUnaryPredecrementOperator,
@@ -475,6 +481,10 @@ module ts.formatting {
475481
return !Rules.IsBinaryOpContext(context);
476482
}
477483

484+
static IsConditionalOperatorContext(context: FormattingContext): boolean {
485+
return context.contextNode.kind === SyntaxKind.ConditionalExpression;
486+
}
487+
478488
static IsSameLineTokenOrBeforeMultilineBlockContext(context: FormattingContext): boolean {
479489
//// This check is mainly used inside SpaceBeforeOpenBraceInControl and SpaceBeforeOpenBraceInFunction.
480490
////
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
////var x=true?1:2
4+
format.document();
5+
goTo.bof();
6+
verify.currentLineContentIs("var x = true ? 1 : 2");;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
////interface A {
4+
/////*1*/ foo? ();
5+
/////*2*/ foo? <T>();
6+
////}
7+
8+
format.document();
9+
goTo.marker("1");
10+
verify.currentLineContentIs(" foo?();");
11+
goTo.marker("2");
12+
verify.currentLineContentIs(" foo?<T>();");

tests/cases/fourslash/genericsFormatting.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,4 @@ goTo.marker("inNewSignature");
3030
verify.currentLineContentIs(" new <T>(a: T);");
3131

3232
goTo.marker("inOptionalMethodSignature");
33-
verify.currentLineContentIs(" op? <T, M>(a: T, b: M);");
33+
verify.currentLineContentIs(" op?<T, M>(a: T, b: M);");

0 commit comments

Comments
 (0)