Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cd2e100

Browse files
josefpihrtcbersch
authored andcommitted
Fix line break when converting block to expression body
1 parent c3d6fce commit cd2e100

File tree

2 files changed

+75
-47
lines changed

2 files changed

+75
-47
lines changed

src/Tests/Analyzers.Tests/RCS1016UseExpressionBodyTests.cs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,34 @@ public C()
6262
void M() { }
6363
}
6464
",
65-
options: Options.AddConfigOption(ConfigOptionKeys.ArrowTokenNewLine, ConfigOptionValues.ArrowTokenNewLine_Before),
66-
additionalDiagnostics: new DiagnosticDescriptor[] { DiagnosticRules.PutExpressionBodyOnItsOwnLine });
65+
options: Options.EnableDiagnostic(DiagnosticRules.PutExpressionBodyOnItsOwnLine)
66+
.AddConfigOption(ConfigOptionKeys.ArrowTokenNewLine, ConfigOptionValues.ArrowTokenNewLine_Before));
67+
}
68+
69+
[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.UseBlockBodyOrExpressionBody)]
70+
public async Task Test_Constructor_BreakAfterArrow()
71+
{
72+
await VerifyDiagnosticAndFixAsync(@"
73+
class C
74+
{
75+
public C()
76+
[|{
77+
M();
78+
}|]
79+
80+
void M() { }
81+
}
82+
", @"
83+
class C
84+
{
85+
public C() =>
86+
M();
87+
88+
void M() { }
89+
}
90+
",
91+
options: Options.EnableDiagnostic(DiagnosticRules.PutExpressionBodyOnItsOwnLine)
92+
.AddConfigOption(ConfigOptionKeys.ArrowTokenNewLine, ConfigOptionValues.ArrowTokenNewLine_After));
6793
}
6894

6995
[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.UseBlockBodyOrExpressionBody)]

src/Workspaces.Common/CSharp/Refactorings/ConvertBlockBodyToExpressionBodyRefactoring.cs

Lines changed: 47 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,9 @@ public static Task<Document> RefactorAsync(
166166
if (CanRefactor(member))
167167
{
168168
AnalyzerConfigOptions configOptions = document.GetConfigOptions(selectedMembers.Parent.SyntaxTree);
169-
bool wrapLineBeforeArrowToken = DiagnosticRules.PutExpressionBodyOnItsOwnLine.IsEffective(member.SyntaxTree, document.Project.CompilationOptions);
169+
NewLinePosition newLinePosition = GetNewLinePosition(document, member, configOptions, cancellationToken);
170170

171-
var newMember = (MemberDeclarationSyntax)Refactor(member, configOptions, wrapLineBeforeArrowToken);
171+
var newMember = (MemberDeclarationSyntax)Refactor(member, configOptions, newLinePosition);
172172

173173
return newMember
174174
.WithTrailingTrivia(member.GetTrailingTrivia())
@@ -181,20 +181,43 @@ public static Task<Document> RefactorAsync(
181181
return document.ReplaceMembersAsync(SyntaxInfo.MemberDeclarationListInfo(selectedMembers.Parent), newMembers, cancellationToken);
182182
}
183183

184-
public static Task<Document> RefactorAsync(
184+
public static async Task<Document> RefactorAsync(
185185
Document document,
186186
SyntaxNode node,
187187
CancellationToken cancellationToken = default)
188188
{
189189
AnalyzerConfigOptions configOptions = document.GetConfigOptions(node.SyntaxTree);
190-
bool wrapLineBeforeArrowToken = DiagnosticRules.PutExpressionBodyOnItsOwnLine.IsEffective(node.SyntaxTree, document.Project.CompilationOptions, cancellationToken);
190+
NewLinePosition newLinePosition = GetNewLinePosition(document, node, configOptions, cancellationToken);
191+
192+
SyntaxNode newNode = Refactor(node, configOptions, newLinePosition).WithFormatterAnnotation();
191193

192-
SyntaxNode newNode = Refactor(node, configOptions, wrapLineBeforeArrowToken).WithFormatterAnnotation();
194+
if (newLinePosition == NewLinePosition.After)
195+
{
196+
var arrowToken = CSharpUtility.GetExpressionBody(newNode).ArrowToken;
197+
var annotation = new SyntaxAnnotation();
198+
newNode = newNode.ReplaceToken(arrowToken, arrowToken.WithAdditionalAnnotations(annotation));
199+
document = await document.ReplaceNodeAsync(node, newNode, cancellationToken).ConfigureAwait(false);
200+
SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
201+
arrowToken = root.GetAnnotatedTokens(annotation).Single();
202+
var textChange = new TextChange(TextSpan.FromBounds(arrowToken.GetPreviousToken().Span.End, arrowToken.SpanStart), " ");
203+
return await document.WithTextChangeAsync(textChange, cancellationToken).ConfigureAwait(false);
204+
}
193205

194-
return document.ReplaceNodeAsync(node, newNode, cancellationToken);
206+
return await document.ReplaceNodeAsync(node, newNode, cancellationToken).ConfigureAwait(false);
195207
}
196208

197-
private static SyntaxNode Refactor(SyntaxNode node, AnalyzerConfigOptions configOptions, bool wrapLineBeforeArrowToken)
209+
private static NewLinePosition GetNewLinePosition(Document document, SyntaxNode node, AnalyzerConfigOptions configOptions, CancellationToken cancellationToken)
210+
{
211+
if (DiagnosticRules.PutExpressionBodyOnItsOwnLine.IsEffective(node.SyntaxTree, document.Project.CompilationOptions, cancellationToken)
212+
&& ConvertExpressionBodyAnalysis.AllowPutExpressionBodyOnItsOwnLine(node.Kind()))
213+
{
214+
return configOptions.GetArrowTokenNewLinePosition();
215+
}
216+
217+
return NewLinePosition.None;
218+
}
219+
220+
private static SyntaxNode Refactor(SyntaxNode node, AnalyzerConfigOptions configOptions, NewLinePosition newLinePosition)
198221
{
199222
switch (node.Kind())
200223
{
@@ -204,7 +227,7 @@ private static SyntaxNode Refactor(SyntaxNode node, AnalyzerConfigOptions config
204227
BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(methodDeclaration.Body);
205228

206229
return methodDeclaration
207-
.WithExpressionBody(CreateExpressionBody(analysis, methodDeclaration, configOptions, wrapLineBeforeArrowToken))
230+
.WithExpressionBody(CreateExpressionBody(analysis, methodDeclaration, configOptions, newLinePosition))
208231
.WithSemicolonToken(CreateSemicolonToken(methodDeclaration.Body, analysis))
209232
.WithBody(null);
210233
}
@@ -214,7 +237,7 @@ private static SyntaxNode Refactor(SyntaxNode node, AnalyzerConfigOptions config
214237
BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(constructorDeclaration.Body);
215238

216239
return constructorDeclaration
217-
.WithExpressionBody(CreateExpressionBody(analysis, constructorDeclaration, configOptions, wrapLineBeforeArrowToken))
240+
.WithExpressionBody(CreateExpressionBody(analysis, constructorDeclaration, configOptions, newLinePosition))
218241
.WithSemicolonToken(CreateSemicolonToken(constructorDeclaration.Body, analysis))
219242
.WithBody(null);
220243
}
@@ -224,7 +247,7 @@ private static SyntaxNode Refactor(SyntaxNode node, AnalyzerConfigOptions config
224247
BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(destructorDeclaration.Body);
225248

226249
return destructorDeclaration
227-
.WithExpressionBody(CreateExpressionBody(analysis, destructorDeclaration, configOptions, wrapLineBeforeArrowToken))
250+
.WithExpressionBody(CreateExpressionBody(analysis, destructorDeclaration, configOptions, newLinePosition))
228251
.WithSemicolonToken(CreateSemicolonToken(destructorDeclaration.Body, analysis))
229252
.WithBody(null);
230253
}
@@ -234,7 +257,7 @@ private static SyntaxNode Refactor(SyntaxNode node, AnalyzerConfigOptions config
234257
BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(localFunction.Body);
235258

236259
return localFunction
237-
.WithExpressionBody(CreateExpressionBody(analysis, localFunction, configOptions, wrapLineBeforeArrowToken))
260+
.WithExpressionBody(CreateExpressionBody(analysis, localFunction, configOptions, newLinePosition))
238261
.WithSemicolonToken(CreateSemicolonToken(localFunction.Body, analysis))
239262
.WithBody(null);
240263
}
@@ -244,7 +267,7 @@ private static SyntaxNode Refactor(SyntaxNode node, AnalyzerConfigOptions config
244267
BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(operatorDeclaration.Body);
245268

246269
return operatorDeclaration
247-
.WithExpressionBody(CreateExpressionBody(analysis, operatorDeclaration, configOptions, wrapLineBeforeArrowToken))
270+
.WithExpressionBody(CreateExpressionBody(analysis, operatorDeclaration, configOptions, newLinePosition))
248271
.WithSemicolonToken(CreateSemicolonToken(operatorDeclaration.Body, analysis))
249272
.WithBody(null);
250273
}
@@ -254,7 +277,7 @@ private static SyntaxNode Refactor(SyntaxNode node, AnalyzerConfigOptions config
254277
BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(operatorDeclaration.Body);
255278

256279
return operatorDeclaration
257-
.WithExpressionBody(CreateExpressionBody(analysis, operatorDeclaration, configOptions, wrapLineBeforeArrowToken))
280+
.WithExpressionBody(CreateExpressionBody(analysis, operatorDeclaration, configOptions, newLinePosition))
258281
.WithSemicolonToken(CreateSemicolonToken(operatorDeclaration.Body, analysis))
259282
.WithBody(null);
260283
}
@@ -264,7 +287,7 @@ private static SyntaxNode Refactor(SyntaxNode node, AnalyzerConfigOptions config
264287
BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(propertyDeclaration.AccessorList);
265288

266289
return propertyDeclaration
267-
.WithExpressionBody(CreateExpressionBody(analysis, propertyDeclaration, configOptions, wrapLineBeforeArrowToken))
290+
.WithExpressionBody(CreateExpressionBody(analysis, propertyDeclaration, configOptions, newLinePosition))
268291
.WithSemicolonToken(CreateSemicolonToken(analysis.Block, analysis))
269292
.WithAccessorList(null);
270293
}
@@ -274,7 +297,7 @@ private static SyntaxNode Refactor(SyntaxNode node, AnalyzerConfigOptions config
274297
BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(indexerDeclaration.AccessorList);
275298

276299
return indexerDeclaration
277-
.WithExpressionBody(CreateExpressionBody(analysis, indexerDeclaration, configOptions, wrapLineBeforeArrowToken))
300+
.WithExpressionBody(CreateExpressionBody(analysis, indexerDeclaration, configOptions, newLinePosition))
278301
.WithSemicolonToken(CreateSemicolonToken(analysis.Block, analysis))
279302
.WithAccessorList(null);
280303
}
@@ -288,7 +311,7 @@ private static SyntaxNode Refactor(SyntaxNode node, AnalyzerConfigOptions config
288311
BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(accessor);
289312

290313
return accessor
291-
.WithExpressionBody(CreateExpressionBody(analysis, accessor, configOptions, wrapLineBeforeArrowToken))
314+
.WithExpressionBody(CreateExpressionBody(analysis, accessor, configOptions, newLinePosition))
292315
.WithSemicolonToken(CreateSemicolonToken(analysis.Block, analysis))
293316
.WithBody(null);
294317
}
@@ -304,7 +327,7 @@ private static ArrowExpressionClauseSyntax CreateExpressionBody(
304327
BlockExpressionAnalysis analysis,
305328
SyntaxNode declaration,
306329
AnalyzerConfigOptions configOptions,
307-
bool wrapLineBeforeArrowToken)
330+
NewLinePosition newLinePosition)
308331
{
309332
SyntaxToken arrowToken = Token(SyntaxKind.EqualsGreaterThanToken);
310333

@@ -335,42 +358,21 @@ private static ArrowExpressionClauseSyntax CreateExpressionBody(
335358
}
336359
}
337360

338-
expression = SyntaxTriviaAnalysis.SetIndentation(expression, declaration, configOptions);
339-
340-
if (wrapLineBeforeArrowToken)
341-
{
342-
NewLinePosition newLinePosition = GetArrowNewLinePosition(declaration.Kind(), configOptions);
343-
return CreateArrayExpression(arrowToken, expression, newLinePosition);
344-
}
345-
else
346-
{
347-
return ArrowExpressionClause(arrowToken, expression);
348-
}
349-
}
350-
351-
private static NewLinePosition GetArrowNewLinePosition(SyntaxKind syntaxKind, AnalyzerConfigOptions configOptions)
352-
{
353-
if (ConvertExpressionBodyAnalysis.AllowPutExpressionBodyOnItsOwnLine(syntaxKind))
354-
{
355-
return configOptions.GetArrowTokenNewLinePosition();
356-
}
357-
else
358-
{
359-
return NewLinePosition.None;
360-
}
361-
}
362-
363-
private static ArrowExpressionClauseSyntax CreateArrayExpression(SyntaxToken arrowToken, ExpressionSyntax expression, NewLinePosition newLinePosition)
364-
{
365361
switch (newLinePosition)
366362
{
367363
case NewLinePosition.After:
368364
arrowToken = arrowToken.AppendToTrailingTrivia(CSharpFactory.NewLine());
365+
expression = SyntaxTriviaAnalysis.SetIndentation(expression, declaration, configOptions);
369366
break;
370367
case NewLinePosition.Before:
371-
arrowToken = arrowToken.PrependToLeadingTrivia(CSharpFactory.NewLine());
368+
SyntaxTrivia trivia = SyntaxTriviaAnalysis.GetIncreasedIndentationTrivia(declaration, configOptions, CancellationToken.None);
369+
arrowToken = arrowToken.WithLeadingTrivia(trivia);
370+
break;
371+
default:
372+
expression = SyntaxTriviaAnalysis.SetIndentation(expression, declaration, configOptions);
372373
break;
373374
}
375+
374376
return ArrowExpressionClause(arrowToken, expression);
375377
}
376378

0 commit comments

Comments
 (0)