• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

NetFabric / NetFabric.CodeAnalysis / 6130084901

09 Sep 2023 09:14AM UTC coverage: 83.158% (+0.2%) from 82.932%
6130084901

push

github

web-flow
Fixes (#27)

227 of 266 branches covered (0.0%)

Branch coverage included in aggregate %.

661 of 661 new or added lines in 31 files covered. (100.0%)

642 of 779 relevant lines covered (82.41%)

18.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.31
/NetFabric.Reflection/Reflection/TypeExtensions.IsAsyncEnumerable.cs
1
using System;
2
using System.Collections;
3
using System.Collections.Generic;
4
using System.Diagnostics.CodeAnalysis;
5
using System.Threading;
6

7
namespace NetFabric.Reflection;
8

9
public static partial class TypeExtensions
10
{        
11

12
    /// <summary>
13
    /// Gets a value indicating whether 'await foreach' considers <see cref="System.Type"/> to be enumerable.
14
    /// </summary>
15
    /// <param name="type">The <see cref="System.Type"/> to test.</param>
16
    /// <param name="enumerableInfo">If methods returns <c>true</c>, contains information on the methods 'await foreach' will use to enumerate.</param>
17
    /// <returns><c>true</c> if 'await foreach' considers <see cref="System.Type"/> to be enumerable; otherwise, <c>false</c>.</returns>
18
    public static bool IsAsyncEnumerable(this Type type, [NotNullWhen(true)] out AsyncEnumerableInfo? enumerableInfo)
19
        => IsAsyncEnumerable(type, out enumerableInfo, out _);
×
20

21
    /// <summary>
22
    /// Gets a value indicating whether 'await foreach' considers <see cref="System.Type"/> to be enumerable.
23
    /// </summary>
24
    /// <param name="type">The <see cref="System.Type"/> to test.</param>
25
    /// <param name="enumerableInfo">If methods returns <c>true</c>, contains information on the methods 'await foreach' will use to enumerate.</param>
26
    /// <param name="errors">Gets information on what error caused the method to return <c>false</c>.</param>
27
    /// <returns><c>true</c> if 'await foreach' considers <see cref="System.Type"/> to be enumerable; otherwise, <c>false</c>.</returns>
28
    public static bool IsAsyncEnumerable(this Type type,
29
        [NotNullWhen(true)] out AsyncEnumerableInfo? enumerableInfo,
30
        out Errors errors)
31
    {
32
        if (!type.IsInterface)
12✔
33
        {
34
            var getAsyncEnumerator = type.GetPublicInstanceMethod(nameof(IAsyncEnumerable<int>.GetAsyncEnumerator), typeof(CancellationToken));
11✔
35
            if (getAsyncEnumerator is null)
11✔
36
                getAsyncEnumerator = type.GetPublicInstanceMethod(nameof(IAsyncEnumerable<int>.GetAsyncEnumerator));
8✔
37
            
38
            if (getAsyncEnumerator is not null)
11✔
39
            {
40
                var enumeratorType = getAsyncEnumerator.ReturnType;
9✔
41
                
42
                var current = enumeratorType.GetPublicInstanceReadProperty(nameof(IEnumerator.Current));
9✔
43
                if (current is null)
9✔
44
                {
45
                    enumerableInfo = default;
1✔
46
                    errors = Errors.MissingCurrent;
1✔
47
                    return false;
1✔
48
                }
49
                
50
                var moveNextAsync = enumeratorType.GetPublicInstanceMethod(nameof(IAsyncEnumerator<int>.MoveNextAsync), Type.EmptyTypes);
8✔
51
                if (moveNextAsync is null)
8✔
52
                {
53
                    enumerableInfo = default;
1✔
54
                    errors = Errors.MissingMoveNext;
1✔
55
                    return false;
1✔
56
                }
57
                
58
                _ = enumeratorType.IsAsyncDisposable(out var dispose);
7✔
59

60
                enumerableInfo = new AsyncEnumerableInfo(
7✔
61
                    getAsyncEnumerator: getAsyncEnumerator,
7✔
62
                    new AsyncEnumeratorInfo(current, moveNextAsync)
7✔
63
                    {
7✔
64
                        DisposeAsync = dispose,
7✔
65
                        IsValueType = getAsyncEnumerator.ReturnType.IsValueType,
7✔
66
                        IsAsyncEnumeratorInterface = enumeratorType.IsInterface,
7✔
67
                    }
7✔
68
                );
7✔
69
                errors = Errors.None; 
7✔
70
                return true;
7✔
71
            }
72
        }
73

74
        if (type.ImplementsInterface(typeof(IAsyncEnumerable<>), out var genericArguments))
3✔
75
        {
76
            var enumerableType = typeof(IAsyncEnumerable<>).MakeGenericType(genericArguments[0]);
2✔
77
            var enumeratorType = typeof(IAsyncEnumerator<>).MakeGenericType(genericArguments[0]);
2✔
78
            enumerableInfo = new AsyncEnumerableInfo(
2✔
79
                getAsyncEnumerator: enumerableType.GetPublicInstanceDeclaredOnlyMethod(nameof(IAsyncEnumerable<int>.GetAsyncEnumerator), typeof(CancellationToken))!,
2✔
80
                new AsyncEnumeratorInfo(
2✔
81
                    current: enumeratorType.GetPublicInstanceDeclaredOnlyReadProperty(nameof(IAsyncEnumerator<int>.Current))!,
2✔
82
                    moveNextAsync: enumeratorType.GetPublicInstanceDeclaredOnlyMethod(nameof(IAsyncEnumerator<int>.MoveNextAsync), Type.EmptyTypes)!)
2✔
83
                {
2✔
84
                    DisposeAsync = typeof(IAsyncDisposable).GetPublicInstanceDeclaredOnlyMethod(nameof(IAsyncDisposable.DisposeAsync), Type.EmptyTypes),
2✔
85
                    IsAsyncEnumeratorInterface = true,
2✔
86
                }
2✔
87
            );
2✔
88
            errors = Errors.None; 
2✔
89
            return true;
2✔
90
        }
91

92
        enumerableInfo = default;
1✔
93
        errors = Errors.MissingGetEnumerator;
1✔
94
        return false;
1✔
95
    }
96
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc