Skip to content

Commit f67d5e1

Browse files
committed
C#: Add tests for the LINQ missed-where and missed-cast queries.
1 parent 1a511c2 commit f67d5e1

File tree

8 files changed

+175
-0
lines changed

8 files changed

+175
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
5+
class MissedCastOpportunity
6+
{
7+
public void M1(List<Animal> animals)
8+
{
9+
// BAD: Can be replaced with animals.Cast<Dog>().
10+
foreach (Animal a in animals)
11+
{
12+
Dog d = (Dog)a;
13+
d.Woof();
14+
}
15+
}
16+
17+
public void M2(NonEnumerableClass nec)
18+
{
19+
// GOOD: Not possible to use Linq here.
20+
foreach (Animal a in nec)
21+
{
22+
Dog d = (Dog)a;
23+
d.Woof();
24+
}
25+
}
26+
27+
public void M3(Animal[] animals)
28+
{
29+
// BAD: Can be replaced with animals.Cast<Dog>().
30+
foreach (Animal animal in animals)
31+
{
32+
Dog d = (Dog)animal;
33+
d.Woof();
34+
}
35+
}
36+
37+
public void M4(Array animals)
38+
{
39+
// BAD: Can be replaced with animals.Cast<Dog>().
40+
foreach (Animal animal in animals)
41+
{
42+
Dog d = (Dog)animal;
43+
d.Woof();
44+
}
45+
}
46+
47+
public void M5(IEnumerable animals)
48+
{
49+
// BAD: Can be replaced with animals.Cast<Dog>().
50+
foreach (object animal in animals)
51+
{
52+
Dog d = (Dog)animal;
53+
d.Woof();
54+
}
55+
}
56+
57+
public class NonEnumerableClass
58+
{
59+
public IEnumerator<Animal> GetEnumerator() => throw null;
60+
}
61+
62+
public class Animal { }
63+
64+
class Dog : Animal
65+
{
66+
private string name;
67+
68+
public Dog(string name)
69+
{
70+
this.name = name;
71+
}
72+
73+
public void Woof()
74+
{
75+
Console.WriteLine("Woof! My name is " + name + ".");
76+
}
77+
}
78+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| MissedCastOpportunity.cs:10:9:14:9 | foreach (... ... in ...) ... | This foreach loop immediately $@ - consider casting the sequence explicitly using '.Cast(...)'. | MissedCastOpportunity.cs:12:13:12:27 | ... ...; | casts its iteration variable to another type |
2+
| MissedCastOpportunity.cs:30:9:34:9 | foreach (... ... in ...) ... | This foreach loop immediately $@ - consider casting the sequence explicitly using '.Cast(...)'. | MissedCastOpportunity.cs:32:13:32:32 | ... ...; | casts its iteration variable to another type |
3+
| MissedCastOpportunity.cs:40:9:44:9 | foreach (... ... in ...) ... | This foreach loop immediately $@ - consider casting the sequence explicitly using '.Cast(...)'. | MissedCastOpportunity.cs:42:13:42:32 | ... ...; | casts its iteration variable to another type |
4+
| MissedCastOpportunity.cs:50:9:54:9 | foreach (... ... in ...) ... | This foreach loop immediately $@ - consider casting the sequence explicitly using '.Cast(...)'. | MissedCastOpportunity.cs:52:13:52:32 | ... ...; | casts its iteration variable to another type |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Linq/MissedCastOpportunity.ql
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
semmle-extractor-options: /nostdlib /noconfig
2+
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using System;
2+
using System.Linq;
3+
using System.Collections.Generic;
4+
5+
class MissedWhereOpportunity
6+
{
7+
public void M1(List<int> lst)
8+
{
9+
// BAD: Can be replaced with lst.Where(e => e % 2 == 0)
10+
foreach (int i in lst)
11+
{
12+
if (i % 2 != 0)
13+
continue;
14+
Console.WriteLine(i);
15+
Console.WriteLine((i / 2));
16+
}
17+
18+
// BAD: Can be replaced with lst.Where(e => e % 2 == 0)
19+
foreach (int i in lst)
20+
{
21+
if (i % 2 == 0)
22+
{
23+
Console.WriteLine(i);
24+
Console.WriteLine((i / 2));
25+
}
26+
}
27+
}
28+
29+
public void M2(NonEnumerableClass nec)
30+
{
31+
// GOOD: Linq can't be used here.
32+
foreach (int i in nec)
33+
{
34+
if (i % 2 == 0)
35+
{
36+
Console.WriteLine(i);
37+
Console.WriteLine((i / 2));
38+
}
39+
}
40+
}
41+
42+
public void M3(int[] arr)
43+
{
44+
// BAD: Can be replaced with arr.Where(e => e % 2 == 0)
45+
foreach (var n in arr)
46+
{
47+
if (n % 2 == 0)
48+
{
49+
Console.WriteLine(n);
50+
Console.WriteLine((n / 2));
51+
}
52+
}
53+
}
54+
55+
public void M4(Array arr)
56+
{
57+
// GOOD: Linq can't be used here.
58+
foreach (var element in arr)
59+
{
60+
if (element.GetHashCode() % 2 == 0)
61+
{
62+
Console.WriteLine(element);
63+
}
64+
}
65+
}
66+
67+
public void M5(IEnumerable<int> elements)
68+
{
69+
// BAD: Can be replaced with elements.Where(e => e.GetHashCode() % 2 == 0)
70+
foreach (var element in elements)
71+
{
72+
if (element.GetHashCode() % 2 == 0)
73+
{
74+
Console.WriteLine(element);
75+
}
76+
}
77+
}
78+
79+
public class NonEnumerableClass
80+
{
81+
public IEnumerator<int> GetEnumerator() => throw null;
82+
}
83+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| MissedWhereOpportunity.cs:10:9:16:9 | foreach (... ... in ...) ... | This foreach loop $@ - consider filtering the sequence explicitly using '.Where(...)'. | MissedWhereOpportunity.cs:12:17:12:26 | ... != ... | implicitly filters its target sequence |
2+
| MissedWhereOpportunity.cs:19:9:26:9 | foreach (... ... in ...) ... | This foreach loop $@ - consider filtering the sequence explicitly using '.Where(...)'. | MissedWhereOpportunity.cs:21:17:21:26 | ... == ... | implicitly filters its target sequence |
3+
| MissedWhereOpportunity.cs:45:9:52:9 | foreach (... ... in ...) ... | This foreach loop $@ - consider filtering the sequence explicitly using '.Where(...)'. | MissedWhereOpportunity.cs:47:17:47:26 | ... == ... | implicitly filters its target sequence |
4+
| MissedWhereOpportunity.cs:70:9:76:9 | foreach (... ... in ...) ... | This foreach loop $@ - consider filtering the sequence explicitly using '.Where(...)'. | MissedWhereOpportunity.cs:72:17:72:46 | ... == ... | implicitly filters its target sequence |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Linq/MissedWhereOpportunity.ql
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
semmle-extractor-options: /nostdlib /noconfig
2+
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj

0 commit comments

Comments
 (0)