[C#] Find missing [EnumeratorCancellation] parameter

CancellationToken parameters with the [EnumeratorCancellation] attribute are needed on methods, returning IAsyncEnumerable and use yield return in their method body. Otherwise it is not possible to cancel that enumerable even if the IAsyncEnumerator was disposed. Therefore a missing [EnumeratorCancellation] parameter on such a method is very likely a bug, because the enumerable continues although the enumerator was already disposed.

Hi @PSanetra,

Welcome to our community and thanks for the rule suggestion!

In order to better understand the problem, could you please create a rule description similar to C# static code analysis: HTTP responses should not be vulnerable to session fixation or any other rule?

Having a rule description together with compliant and non-compliant examples, and maybe documentation links will help us a lot.

So if understand correctly, this are the cases to take into account:

using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;

class Concompliant
{
    public static async IAsyncEnumerable<int> Yields([EnumeratorCancellation] CancellationToken token) // Compliant
    {
        yield return 13;
    }

    public static IAsyncEnumerable<int> WithoutYielding(CancellationToken token) // Compliant
    {
        return null;
    }
    public static IAsyncEnumerable<int> WithoutYielding() // Compliant
    {
        return null;
    }

    public static IAsyncEnumerable<int> WithoutBody() => null; // Compliant
}

class Noncompliant
{
    public static async IAsyncEnumerable<int> Yields(CancellationToken token) // Noncompliant
    {
        yield return 42;
    }
    public static async IAsyncEnumerable<int> YieldsWithoutCancelation() // Noncompliant
    {
        yield return 42;
    }
}

So if an IAsyncEnumerable<T> is the return type, and there is a yield return statement (what about yield break?) the method should have a CancellationToken as argument, and it should be decorated with an [EnumeratorCancellation] attribute?

And an implementation: New rule: Async methods with yield statements should have a decorated cancelation token by Corniel · Pull Request #5876 · SonarSource/sonar-dotnet · GitHub

As @costin.zaharia proposed, @PSanetra can you help writing a rule description?