C#: Add tests for the LINQ missed-where and missed-cast queries.

This commit is contained in:
Michael Nebel
2023-08-04 14:48:24 +02:00
parent 1a511c2d52
commit f67d5e1dc6
8 changed files with 175 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
using System;
using System.Collections;
using System.Collections.Generic;
class MissedCastOpportunity
{
public void M1(List<Animal> animals)
{
// BAD: Can be replaced with animals.Cast<Dog>().
foreach (Animal a in animals)
{
Dog d = (Dog)a;
d.Woof();
}
}
public void M2(NonEnumerableClass nec)
{
// GOOD: Not possible to use Linq here.
foreach (Animal a in nec)
{
Dog d = (Dog)a;
d.Woof();
}
}
public void M3(Animal[] animals)
{
// BAD: Can be replaced with animals.Cast<Dog>().
foreach (Animal animal in animals)
{
Dog d = (Dog)animal;
d.Woof();
}
}
public void M4(Array animals)
{
// BAD: Can be replaced with animals.Cast<Dog>().
foreach (Animal animal in animals)
{
Dog d = (Dog)animal;
d.Woof();
}
}
public void M5(IEnumerable animals)
{
// BAD: Can be replaced with animals.Cast<Dog>().
foreach (object animal in animals)
{
Dog d = (Dog)animal;
d.Woof();
}
}
public class NonEnumerableClass
{
public IEnumerator<Animal> GetEnumerator() => throw null;
}
public class Animal { }
class Dog : Animal
{
private string name;
public Dog(string name)
{
this.name = name;
}
public void Woof()
{
Console.WriteLine("Woof! My name is " + name + ".");
}
}
}

View File

@@ -0,0 +1,4 @@
| 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 |
| 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 |
| 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 |
| 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 |

View File

@@ -0,0 +1 @@
Linq/MissedCastOpportunity.ql

View File

@@ -0,0 +1,2 @@
semmle-extractor-options: /nostdlib /noconfig
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj

View File

@@ -0,0 +1,83 @@
using System;
using System.Linq;
using System.Collections.Generic;
class MissedWhereOpportunity
{
public void M1(List<int> lst)
{
// BAD: Can be replaced with lst.Where(e => e % 2 == 0)
foreach (int i in lst)
{
if (i % 2 != 0)
continue;
Console.WriteLine(i);
Console.WriteLine((i / 2));
}
// BAD: Can be replaced with lst.Where(e => e % 2 == 0)
foreach (int i in lst)
{
if (i % 2 == 0)
{
Console.WriteLine(i);
Console.WriteLine((i / 2));
}
}
}
public void M2(NonEnumerableClass nec)
{
// GOOD: Linq can't be used here.
foreach (int i in nec)
{
if (i % 2 == 0)
{
Console.WriteLine(i);
Console.WriteLine((i / 2));
}
}
}
public void M3(int[] arr)
{
// BAD: Can be replaced with arr.Where(e => e % 2 == 0)
foreach (var n in arr)
{
if (n % 2 == 0)
{
Console.WriteLine(n);
Console.WriteLine((n / 2));
}
}
}
public void M4(Array arr)
{
// GOOD: Linq can't be used here.
foreach (var element in arr)
{
if (element.GetHashCode() % 2 == 0)
{
Console.WriteLine(element);
}
}
}
public void M5(IEnumerable<int> elements)
{
// BAD: Can be replaced with elements.Where(e => e.GetHashCode() % 2 == 0)
foreach (var element in elements)
{
if (element.GetHashCode() % 2 == 0)
{
Console.WriteLine(element);
}
}
}
public class NonEnumerableClass
{
public IEnumerator<int> GetEnumerator() => throw null;
}
}

View File

@@ -0,0 +1,4 @@
| 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 |
| 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 |
| 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 |
| 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 |

View File

@@ -0,0 +1 @@
Linq/MissedWhereOpportunity.ql

View File

@@ -0,0 +1,2 @@
semmle-extractor-options: /nostdlib /noconfig
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj