提交 59e6ec05 编写于 作者: C CyrusNajmabadi 提交者: GitHub

Merge pull request #21121 from CyrusNajmabadi/convertIfToSwitchTrivia

Preserve trivia better when converting if to switch.
......@@ -38,7 +38,7 @@ void M(int i)
return;
}
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -66,7 +66,7 @@ void M(int i)
break;
}
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -103,7 +103,7 @@ void M(int i)
break;
}
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -135,7 +135,7 @@ void M(object o)
return;
}
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -162,7 +162,7 @@ void M(int i)
return;
}
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -191,7 +191,7 @@ void M(int i)
return;
}
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -259,7 +259,7 @@ void M(object o)
return;
}
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -288,7 +288,7 @@ void M(object o)
return;
}
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -317,7 +317,7 @@ void M(object o)
return;
}
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -346,7 +346,7 @@ void M(object o)
return;
}
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -375,7 +375,7 @@ void M(object o)
return;
}
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -406,10 +406,10 @@ void M(object o)
{
case string s when s.Length > 5 &&
s.Length < 10:
M(o: 0);
M(o: 0);
break;
case int i:
M(o: 0);
M(o: 0);
break;
}
}
......@@ -457,11 +457,12 @@ void M(int i)
var x = i;
break;
}
case 4:
break;
}
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -528,12 +529,13 @@ void M(int i)
{
break;
}
break;
case 2:
break;
}
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -562,7 +564,7 @@ int M(int? i)
}
return 7;
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -586,14 +588,14 @@ int M(int? i)
switch (i)
{
case null:
return 5;
return 5;
case 0:
break;
}
if (i == 1) return 6;
return 7;
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -631,7 +633,7 @@ int M(int? i)
return 7;
}
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -662,7 +664,7 @@ string M(object i)
return i.ToString();
}
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -693,7 +695,7 @@ int M(int i)
if (i == i) return 0;
reuturn 7;
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -736,7 +738,7 @@ int M(int i)
}
reuturn 7;
}
}");
}", ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
......@@ -782,6 +784,7 @@ int M(int i)
case 1:
return 1;
}
if (i == 10)
{
return 5;
......@@ -796,7 +799,81 @@ int M(int i)
}
reuturn 7;
}
}");
}", ignoreTrivia: false);
}
[WorkItem(21109, "https://github.com/dotnet/roslyn/issues/21109")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
public async Task TestTrivia1()
{
await TestInRegularAndScriptAsync(
@"class C
{
int M(int i)
{
#if TRUE
Console.WriteLine();
#endif
[||]if (x == 1)
{
Console.WriteLine(x + z);
}
else if (x == 2)
{
Console.WriteLine(x + z);
}
}
}",
@"class C
{
int M(int i)
{
#if TRUE
Console.WriteLine();
#endif
switch (x)
{
case 1:
Console.WriteLine(x + z);
break;
case 2:
Console.WriteLine(x + z);
break;
}
}
}", ignoreTrivia: false);
}
[WorkItem(21101, "https://github.com/dotnet/roslyn/issues/21101")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)]
public async Task TestTrivia2()
{
await TestInRegularAndScriptAsync(
@"class C
{
int M(int i)
{
[||]if (/* t0 */args.Length /* t1*/ == /* t2 */ 2)
return /* t3 */ 0 /* t4 */; /* t5 */
else /* t6 */
return /* t7 */ 3 /* t8 */;
}
}",
@"class C
{
int M(int i)
{
switch (/* t0 */args.Length /* t1*/ )
{
case 2:
return /* t3 */ 0 /* t4 */; /* t5 */
default:
return /* t7 */ 3 /* t8 */;
}
}
}", ignoreTrivia: false);
}
}
}
......@@ -37,7 +37,7 @@ End Class",
M(2)
End Select
End Sub
End Class")
End Class", ignoreTrivia:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)>
......@@ -59,7 +59,7 @@ End Class",
M(0)
End Select
End Sub
End Class")
End Class", ignoreTrivia:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)>
......@@ -115,7 +115,7 @@ End Class",
Case 6 To 7
End Select
End Sub
End Class")
End Class", ignoreTrivia:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)>
......@@ -133,7 +133,7 @@ End Class",
Case Is <= 5, Is >= 1
End Select
End Sub
End Class")
End Class", ignoreTrivia:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)>
......@@ -151,7 +151,7 @@ End Class",
Case Is < 10, Is > 20, 30 To 40, 50
End Select
End Sub
End Class")
End Class", ignoreTrivia:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)>
......@@ -171,7 +171,7 @@ End Class",
M(6)
End Select
End Sub
End Class")
End Class", ignoreTrivia:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)>
......@@ -194,7 +194,7 @@ End Class",
End Select
Return 7
End Function
End Class")
End Class", ignoreTrivia:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)>
......@@ -217,7 +217,7 @@ End Class",
Return 7
End Select
End Function
End Class")
End Class", ignoreTrivia:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)>
......@@ -242,7 +242,7 @@ End Class",
If i = 30 Then Return 6
Return 7
End Function
End Class")
End Class", ignoreTrivia:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)>
......@@ -267,7 +267,7 @@ End Class",
If i = i Then Return 0
Return 7
End Function
End Class")
End Class", ignoreTrivia:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)>
......@@ -298,7 +298,7 @@ End Class",
If i = i Then Return 0
Return 8
End Function
End Class")
End Class", ignoreTrivia:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)>
......@@ -332,7 +332,7 @@ End Class",
If i = 5 Then Return 0
Return 8
End Function
End Class")
End Class", ignoreTrivia:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)>
......@@ -358,7 +358,44 @@ End Class",
End Select
End While
End Sub
End Class")
End Class", ignoreTrivia:=False)
End Function
<WorkItem(21103, "https://github.com/dotnet/roslyn/issues/21103")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertIfToSwitch)>
Public Async Function TestTrivia1() As Task
Await TestInRegularAndScriptAsync(
"Class C
Sub M(i As Integer)
#if true
Console.WriteLine()
#end if
[||]If i = 1 OrElse 2 = i OrElse i = 3 Then
M(0)
ElseIf i = 4 OrElse 5 = i OrElse i = 6 Then
M(1)
Else
M(2)
End If
End Sub
End Class",
"Class C
Sub M(i As Integer)
#if true
Console.WriteLine()
#end if
Select i
Case 1, 2, 3
M(0)
Case 4, 5, 6
M(1)
Case Else
M(2)
End Select
End Sub
End Class", ignoreTrivia:=False)
End Function
End Class
End Namespace
......@@ -8,6 +8,7 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.ConvertIfToSwitch;
using Microsoft.CodeAnalysis.Shared.Extensions;
namespace Microsoft.CodeAnalysis.CSharp.ConvertIfToSwitch
{
......@@ -249,6 +250,21 @@ protected override ExpressionSyntax UnwrapCast(ExpressionSyntax expression)
return expression;
}
}
protected override SyntaxNode CreateSwitchStatement(
IfStatementSyntax ifStatement, ExpressionSyntax expression, List<SyntaxNode> sectionList)
{
var block = ifStatement.Statement as BlockSyntax;
return SyntaxFactory.SwitchStatement(
SyntaxFactory.Token(SyntaxKind.SwitchKeyword).WithTriviaFrom(ifStatement.IfKeyword),
ifStatement.OpenParenToken,
expression,
ifStatement.CloseParenToken.WithPrependedLeadingTrivia(SyntaxFactory.ElasticMarker),
block?.OpenBraceToken ?? SyntaxFactory.Token(SyntaxKind.OpenBraceToken),
new SyntaxList<SwitchSectionSyntax>(sectionList.OfType<SwitchSectionSyntax>()),
block?.CloseBraceToken ?? SyntaxFactory.Token(SyntaxKind.CloseBraceToken));
}
}
}
}
......@@ -10,6 +10,7 @@
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.Formatting;
namespace Microsoft.CodeAnalysis.ConvertIfToSwitch
{
......@@ -227,14 +228,22 @@ private IEnumerable<SyntaxNode> GetSubsequentStatements(SyntaxNode currentStatem
}
var ifSpan = ifStatement.Span;
var @switch = generator.SwitchStatement(_switchExpression, sectionList);
var @switch = CreateSwitchStatement(ifStatement, _switchExpression, sectionList);
var nodesToRemove = GetSubsequentStatements(ifStatement)
.Skip(1).Take(_numberOfSubsequentIfStatementsToRemove);
.Skip(1).Take(_numberOfSubsequentIfStatementsToRemove).ToList();
root = root.RemoveNodes(nodesToRemove, SyntaxRemoveOptions.KeepNoTrivia);
var lastNode = nodesToRemove.LastOrDefault() ?? ifStatement;
@switch = @switch.WithLeadingTrivia(ifStatement.GetLeadingTrivia())
.WithTrailingTrivia(lastNode.GetTrailingTrivia())
.WithAdditionalAnnotations(Formatter.Annotation);
root = root.ReplaceNode(root.FindNode(ifSpan), @switch);
return Task.FromResult(document.WithSyntaxRoot(root));
}
protected abstract SyntaxNode CreateSwitchStatement(TIfStatementSyntax ifStatement, TExpressionSyntax expression, List<SyntaxNode> sectionList);
protected abstract TExpressionSyntax UnwrapCast(TExpressionSyntax expression);
protected abstract bool EndPointIsReachable(TIfStatementSyntax ifStatement);
......
......@@ -29,7 +29,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertIfToSwitch
_operatorTokenKind = operatorTokenKind
End Sub
Public Overrides Function CreateSwitchLabel() As CaseClauseSyntax
Protected Overrides Function CreateSwitchLabelWorker() As CaseClauseSyntax
Dim comparisonToken = If(_inverted, s_comparisonTokenMap(_operatorTokenKind).inverse, _operatorTokenKind)
Return SyntaxFactory.RelationalCaseClause(
s_comparisonTokenMap(comparisonToken).caseClause,
......@@ -47,7 +47,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertIfToSwitch
_constant = constant
End Sub
Public Overrides Function CreateSwitchLabel() As CaseClauseSyntax
Protected Overrides Function CreateSwitchLabelWorker() As CaseClauseSyntax
Return SyntaxFactory.SimpleCaseClause(_constant)
End Function
End Class
......@@ -61,12 +61,17 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertIfToSwitch
_rangeBounds = rangeBounds
End Sub
Public Overrides Function CreateSwitchLabel() As CaseClauseSyntax
Protected Overrides Function CreateSwitchLabelWorker() As CaseClauseSyntax
Return SyntaxFactory.RangeCaseClause(_rangeBounds.lower, _rangeBounds.upper)
End Function
End Class
Public MustOverride Function CreateSwitchLabel() As CaseClauseSyntax Implements IPattern(Of CaseClauseSyntax).CreateSwitchLabel
Public Function CreateSwitchLabel() As CaseClauseSyntax Implements IPattern(Of CaseClauseSyntax).CreateSwitchLabel
Return CreateSwitchLabelWorker().WithAppendedTrailingTrivia(SyntaxFactory.ElasticMarker)
End Function
Protected MustOverride Function CreateSwitchLabelWorker() As CaseClauseSyntax
End Class
End Class
End Namespace
......@@ -6,6 +6,7 @@ Imports Microsoft.CodeAnalysis.CodeRefactorings
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Microsoft.CodeAnalysis.LanguageServices
Imports Microsoft.CodeAnalysis.ConvertIfToSwitch
Imports Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertIfToSwitch
<ExportCodeRefactoringProvider(LanguageNames.VisualBasic, Name:=NameOf(VisualBasicConvertIfToSwitchCodeRefactoringProvider)), [Shared]>
......@@ -183,6 +184,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertIfToSwitch
Protected Overrides Function UnwrapCast(expression As ExpressionSyntax) As ExpressionSyntax
Return expression
End Function
Protected Overrides Function CreateSwitchStatement(ifStatement As ExecutableStatementSyntax, expression As ExpressionSyntax, sectionList As List(Of SyntaxNode)) As SyntaxNode
Return VisualBasicSyntaxGenerator.Instance.SwitchStatement(expression, sectionList)
End Function
End Class
End Class
End Namespace
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册