Skip to content

Commit bf054d5

Browse files
Merge pull request #59259 from CyrusNajmabadi/populateSwitchPatternDefault
Fix 'populate switch' to understand more possible user cases
2 parents 49fe412 + a8da77b commit bf054d5

File tree

2 files changed

+125
-9
lines changed

2 files changed

+125
-9
lines changed

src/Analyzers/CSharp/Tests/PopulateSwitch/PopulateSwitchExpressionTests.cs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,5 +1261,111 @@ public enum E
12611261
"
12621262
);
12631263
}
1264+
1265+
[Fact, WorkItem(58468, "https://github.com/dotnet/roslyn/issues/58468")]
1266+
public async Task NotOnOrPatternWhichAlwaysSucceeds1()
1267+
{
1268+
await TestMissingInRegularAndScriptAsync(
1269+
@"
1270+
enum Greeting
1271+
{
1272+
Hello,
1273+
Goodbye
1274+
};
1275+
1276+
class C
1277+
{
1278+
void M()
1279+
{
1280+
Greeting greeting = Greeting.Hello;
1281+
string message = greeting [||]switch
1282+
{
1283+
Greeting.Hello => ""Hey!"",
1284+
Greeting.Goodbye or _ => ""Not sure what to say 🤔""
1285+
};
1286+
}
1287+
}
1288+
");
1289+
}
1290+
1291+
[Fact, WorkItem(58468, "https://github.com/dotnet/roslyn/issues/58468")]
1292+
public async Task NotOnOrPatternWhichAlwaysSucceeds2()
1293+
{
1294+
await TestMissingInRegularAndScriptAsync(
1295+
@"
1296+
enum Greeting
1297+
{
1298+
Hello,
1299+
Goodbye
1300+
};
1301+
1302+
class C
1303+
{
1304+
void M()
1305+
{
1306+
Greeting greeting = Greeting.Hello;
1307+
string message = greeting [||]switch
1308+
{
1309+
Greeting.Hello => ""Hey!"",
1310+
_ or Greeting.Goodbye => ""Not sure what to say 🤔""
1311+
};
1312+
}
1313+
}
1314+
");
1315+
}
1316+
1317+
[Fact, WorkItem(58468, "https://github.com/dotnet/roslyn/issues/58468")]
1318+
public async Task NotOnOrPatternWhichAlwaysSucceeds3()
1319+
{
1320+
await TestMissingInRegularAndScriptAsync(
1321+
@"
1322+
enum Greeting
1323+
{
1324+
Hello,
1325+
Goodbye
1326+
};
1327+
1328+
class C
1329+
{
1330+
void M()
1331+
{
1332+
Greeting greeting = Greeting.Hello;
1333+
string message = greeting [||]switch
1334+
{
1335+
Greeting.Hello => ""Hey!"",
1336+
Greeting.Goodbye => ""Bye!"",
1337+
_ and var v => ""Not sure what to say 🤔""
1338+
};
1339+
}
1340+
}
1341+
");
1342+
}
1343+
1344+
[Fact, WorkItem(58468, "https://github.com/dotnet/roslyn/issues/58468")]
1345+
public async Task NotOnOrPatternWhichAlwaysSucceeds4()
1346+
{
1347+
await TestMissingInRegularAndScriptAsync(
1348+
@"
1349+
enum Greeting
1350+
{
1351+
Hello,
1352+
Goodbye
1353+
};
1354+
1355+
class C
1356+
{
1357+
void M()
1358+
{
1359+
Greeting greeting = Greeting.Hello;
1360+
string message = greeting [||]switch
1361+
{
1362+
Greeting.Hello => ""Hey!"",
1363+
Greeting.Goodbye => ""Bye!"",
1364+
var x and var y => ""Not sure what to say 🤔""
1365+
};
1366+
}
1367+
}
1368+
");
1369+
}
12641370
}
12651371
}

src/Analyzers/Core/Analyzers/PopulateSwitch/PopulateSwitchExpressionHelpers.cs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,17 +70,27 @@ private static void RemoveIfConstantPatternHasValue(IOperation operation, Dictio
7070
}
7171

7272
public static bool HasDefaultCase(ISwitchExpressionOperation operation)
73-
=> operation.Arms.Any(a => IsDefault(a));
73+
=> operation.Arms.Any(IsDefault);
7474

7575
public static bool IsDefault(ISwitchExpressionArmOperation arm)
76-
{
77-
if (arm.Pattern.Kind == OperationKind.DiscardPattern)
78-
return true;
79-
80-
if (arm.Pattern is IDeclarationPatternOperation declarationPattern)
81-
return declarationPattern.MatchesNull;
76+
=> IsDefault(arm.Pattern);
8277

83-
return false;
84-
}
78+
private static bool IsDefault(IPatternOperation pattern)
79+
=> pattern switch
80+
{
81+
// _ => ...
82+
IDiscardPatternOperation => true,
83+
// var v => ...
84+
IDeclarationPatternOperation declarationPattern => declarationPattern.MatchesNull,
85+
IBinaryPatternOperation binaryPattern => binaryPattern.OperatorKind switch
86+
{
87+
// x or _ => ...
88+
BinaryOperatorKind.Or => IsDefault(binaryPattern.LeftPattern) || IsDefault(binaryPattern.RightPattern),
89+
// _ and var x => ...
90+
BinaryOperatorKind.And => IsDefault(binaryPattern.LeftPattern) && IsDefault(binaryPattern.RightPattern),
91+
_ => false,
92+
},
93+
_ => false
94+
};
8595
}
8696
}

0 commit comments

Comments
 (0)