Skip to content

Commit 040b347

Browse files
committed
feat: Adds consider replacing switch statement with switch expression
1 parent 9f14c63 commit 040b347

File tree

4 files changed

+60
-15
lines changed

4 files changed

+60
-15
lines changed

src/Sharpen.Engine/Sharpen.Engine.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,9 @@
288288
<Compile Include="SharpenSuggestions\CSharp80\NullableReferenceTypes\Suggestions\EnableNullableContextAndDeclareReferencePropertyAsNullable.cs" />
289289
<Compile Include="SharpenSuggestions\CSharp80\NullableReferenceTypes\Suggestions\EnableNullableContextAndDeclareReferenceFieldAsNullable.cs" />
290290
<Compile Include="SharpenSuggestions\CSharp80\SwitchExpressions\Analyzers\ReplaceSwitchStatementWithSwitchExpressionAnalyzer.cs" />
291+
<Compile Include="SharpenSuggestions\CSharp80\SwitchExpressions\Suggestions\ConsiderReplacingSwitchStatementContainingOnlyAssignmentsWithSwitchExpression.cs" />
291292
<Compile Include="SharpenSuggestions\CSharp80\SwitchExpressions\Suggestions\ReplaceSwitchStatementContainingOnlyAssignmentsWithSwitchExpression.cs" />
293+
<Compile Include="SharpenSuggestions\CSharp80\SwitchExpressions\Suggestions\ConsiderReplacingSwitchStatementContainingOnlyReturnsWithSwitchExpression.cs" />
292294
<Compile Include="SharpenSuggestions\CSharp80\SwitchExpressions\Suggestions\ReplaceSwitchStatementContainingOnlyReturnsWithSwitchExpression.cs" />
293295
<Compile Include="SharpenSuggestions\CSharp80\UsingDeclarations\Analyzers\ReplaceUsingStatementWithUsingDeclarationAnalyzer.cs" />
294296
<Compile Include="SharpenSuggestions\CSharp80\UsingDeclarations\Suggestions\ConsiderReplacingUsingStatementWithUsingDeclaration.cs" />

src/Sharpen.Engine/SharpenSuggestions/CSharp80/SwitchExpressions/Analyzers/ReplaceSwitchStatementWithSwitchExpressionAnalyzer.cs

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,35 +37,48 @@ public IEnumerable<AnalysisResult> Analyze(SyntaxTree syntaxTree, SemanticModel
3737
.Where(replaceabilityInfo => replaceabilityInfo.switchStatement != null)
3838
.Select(replaceabilityInfo => new AnalysisResult
3939
(
40-
replaceabilityInfo.category == SwitchStatementSectionsCategory.AllSwitchSectionsAreReturnStatements
41-
? (ISharpenSuggestion)ReplaceSwitchStatementContainingOnlyReturnsWithSwitchExpression.Instance
42-
: ReplaceSwitchStatementContainingOnlyAssignmentsWithSwitchExpression.Instance,
40+
GetSuggestion(replaceabilityInfo.category, replaceabilityInfo.isSurelyExhaustive),
4341
analysisContext,
4442
syntaxTree.FilePath,
4543
replaceabilityInfo.switchStatement.SwitchKeyword,
4644
replaceabilityInfo.switchStatement
4745
));
4846

49-
(SwitchStatementSyntax switchStatement, SwitchStatementSectionsCategory category) GetSwitchStatementPotentialReplaceabilityInfo(SwitchStatementSyntax switchStatement)
47+
ISharpenSuggestion GetSuggestion(SwitchStatementSectionsCategory category, bool isSurelyExhaustive)
48+
{
49+
// TODO-IG: It will be so nice to switch to switch statement one day we move Sharpen to C# 8.0 :-)
50+
if (category == SwitchStatementSectionsCategory.AllSwitchSectionsAreAssignmentsToTheSameIdentifier)
51+
{
52+
return isSurelyExhaustive
53+
? (ISharpenSuggestion)ReplaceSwitchStatementContainingOnlyAssignmentsWithSwitchExpression.Instance
54+
: ConsiderReplacingSwitchStatementContainingOnlyAssignmentsWithSwitchExpression.Instance;
55+
}
56+
else
57+
{
58+
return isSurelyExhaustive
59+
? (ISharpenSuggestion)ReplaceSwitchStatementContainingOnlyReturnsWithSwitchExpression.Instance
60+
: ConsiderReplacingSwitchStatementContainingOnlyReturnsWithSwitchExpression.Instance;
61+
}
62+
}
63+
64+
(SwitchStatementSyntax switchStatement, SwitchStatementSectionsCategory category, bool isSurelyExhaustive) GetSwitchStatementPotentialReplaceabilityInfo(SwitchStatementSyntax switchStatement)
5065
{
5166
// We have to have at least one switch section (case or default).
52-
if (switchStatement.Sections.Count <= 0) return (null, SwitchStatementSectionsCategory.None);
67+
if (switchStatement.Sections.Count <= 0) return (null, SwitchStatementSectionsCategory.None, false);
5368

54-
// We have to have the default section, otherwise we cannot replace the switch
55-
// statement with a switch expressions.
56-
// TODO-IG: Provide additional "consider" suggestion in case of missing the return.
57-
// Something like "Consider adding the default case and replacing switch statement with switch expression".
58-
if (!switchStatement.Sections.Any(switchSection =>
59-
switchSection.Labels.Any(label => label.IsKind(SyntaxKind.DefaultSwitchLabel))))
60-
return (null, SwitchStatementSectionsCategory.None);
69+
// If we have the default section it is surely exhaustive.
70+
// Otherwise we cannot be sure. We will of course not do any
71+
// proper check that the compiler does.
72+
bool isSurelyExhaustive = switchStatement.Sections.Any(switchSection =>
73+
switchSection.Labels.Any(label => label.IsKind(SyntaxKind.DefaultSwitchLabel)));
6174

6275
if (AllSwitchSectionsAreAssignmentsToTheSameIdentifier(switchStatement.Sections))
63-
return (switchStatement, SwitchStatementSectionsCategory.AllSwitchSectionsAreAssignmentsToTheSameIdentifier);
76+
return (switchStatement, SwitchStatementSectionsCategory.AllSwitchSectionsAreAssignmentsToTheSameIdentifier, isSurelyExhaustive);
6477

6578
if (AllSwitchSectionsAreReturnStatements(switchStatement.Sections))
66-
return (switchStatement, SwitchStatementSectionsCategory.AllSwitchSectionsAreReturnStatements);
79+
return (switchStatement, SwitchStatementSectionsCategory.AllSwitchSectionsAreReturnStatements, isSurelyExhaustive);
6780

68-
return (null, SwitchStatementSectionsCategory.None);
81+
return (null, SwitchStatementSectionsCategory.None, false);
6982

7083
bool AllSwitchSectionsAreAssignmentsToTheSameIdentifier(SyntaxList<SwitchSectionSyntax> switchSections)
7184
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace Sharpen.Engine.SharpenSuggestions.CSharp80.SwitchExpressions.Suggestions
2+
{
3+
internal sealed class ConsiderReplacingSwitchStatementContainingOnlyAssignmentsWithSwitchExpression : ISharpenSuggestion
4+
{
5+
private ConsiderReplacingSwitchStatementContainingOnlyAssignmentsWithSwitchExpression() { }
6+
7+
public string MinimumLanguageVersion { get; } = CSharpLanguageVersions.CSharp80;
8+
9+
public ICSharpFeature LanguageFeature { get; } = CSharpFeatures.SwitchExpressions.Instance;
10+
11+
public string FriendlyName { get; } = "Consider replacing switch statement containing only assignments with switch expression";
12+
13+
public static readonly ConsiderReplacingSwitchStatementContainingOnlyAssignmentsWithSwitchExpression Instance = new ConsiderReplacingSwitchStatementContainingOnlyAssignmentsWithSwitchExpression();
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace Sharpen.Engine.SharpenSuggestions.CSharp80.SwitchExpressions.Suggestions
2+
{
3+
internal sealed class ConsiderReplacingSwitchStatementContainingOnlyReturnsWithSwitchExpression : ISharpenSuggestion
4+
{
5+
private ConsiderReplacingSwitchStatementContainingOnlyReturnsWithSwitchExpression() { }
6+
7+
public string MinimumLanguageVersion { get; } = CSharpLanguageVersions.CSharp80;
8+
9+
public ICSharpFeature LanguageFeature { get; } = CSharpFeatures.SwitchExpressions.Instance;
10+
11+
public string FriendlyName { get; } = "Consider replacing switch statement containing only returns with switch expression";
12+
13+
public static readonly ConsiderReplacingSwitchStatementContainingOnlyReturnsWithSwitchExpression Instance = new ConsiderReplacingSwitchStatementContainingOnlyReturnsWithSwitchExpression();
14+
}
15+
}

0 commit comments

Comments
 (0)