• 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

90.16
/NetFabric.CodeAnalysis/ITypeSymbolExtensions.cs
1
using Microsoft.CodeAnalysis;
2
using System;
3
using System.Collections.Immutable;
4
// ReSharper disable InvertIf
5

6
namespace NetFabric.CodeAnalysis;
7

8
public static partial class ITypeSymbolExtensions
9
{
10
    
11
    /// <summary>
12
    /// Gets a value indicating whether <see cref="Microsoft.CodeAnalysis.ITypeSymbol"/> implements the given interface type.
13
    /// </summary>
14
    /// <param name="typeSymbol">The <see cref="System.Type"/> to test.</param>
15
    /// <param name="interfaceType">The interface <see cref="System.Type"/> to test.</param>
16
    /// <param name="genericArguments">If methods returns <c>true</c> and interface type is generic, contains the generic arguments of the implemented interface.</param>
17
    /// <returns><c>true</c> if <see cref="Microsoft.CodeAnalysis.ITypeSymbol"/> implements interface type; otherwise, <c>false</c>.</returns>
18
    public static bool ImplementsInterface(this ITypeSymbol typeSymbol, SpecialType interfaceType, out ImmutableArray<ITypeSymbol> genericArguments)
19
    {
20
        if (typeSymbol is INamedTypeSymbol namedTypeSymbol 
33✔
21
            && namedTypeSymbol.OriginalDefinition.SpecialType == interfaceType)
33✔
22
        {
23
            genericArguments = namedTypeSymbol.TypeArguments;
3✔
24
            return true;
3✔
25
        }
26
        
27
        // ReSharper disable once ForeachCanBePartlyConvertedToQueryUsingAnotherGetEnumerator
28
        foreach (var @interface in typeSymbol.AllInterfaces)
88✔
29
        {
30
            if (@interface.OriginalDefinition.SpecialType == interfaceType)
20✔
31
            {
32
                genericArguments = @interface.TypeArguments;
12✔
33
                return true;
12✔
34
            }
35
        }
36

37
        genericArguments = default;
18✔
38
        return false;
18✔
39
    }
40

41
    /// <summary>
42
    /// Gets a value indicating whether <see cref="Microsoft.CodeAnalysis.ITypeSymbol"/> implements the given interface type.
43
    /// </summary>
44
    /// <param name="typeSymbol">The <see cref="System.Type"/> to test.</param>
45
    /// <param name="interfaceType">The interface <see cref="System.Type"/> to test.</param>
46
    /// <param name="genericArguments">If methods returns <c>true</c> and interface type is generic, contains the generic arguments of the implemented interface.</param>
47
    /// <returns><c>true</c> if <see cref="Microsoft.CodeAnalysis.ITypeSymbol"/> implements interface type; otherwise, <c>false</c>.</returns>
48
    public static bool ImplementsInterface(this ITypeSymbol typeSymbol, INamedTypeSymbol interfaceType, out ImmutableArray<ITypeSymbol> genericArguments)
49
    {
50
        if (typeSymbol is INamedTypeSymbol namedTypeSymbol 
16✔
51
            && SymbolEqualityComparer.Default.Equals(namedTypeSymbol.OriginalDefinition, interfaceType))
16✔
52
        {
53
            genericArguments = namedTypeSymbol.TypeArguments;
2✔
54
            return true;
2✔
55
        }
56
        
57
        // ReSharper disable once ForeachCanBePartlyConvertedToQueryUsingAnotherGetEnumerator
58
        foreach (var @interface in typeSymbol.AllInterfaces)
33✔
59
        {
60
            if (SymbolEqualityComparer.Default.Equals(@interface.OriginalDefinition, interfaceType))
5✔
61
            {
62
                genericArguments = @interface.TypeArguments;
5✔
63
                return true;
5✔
64
            }
65
        }
66

67
        genericArguments = default;
9✔
68
        return false;
9✔
69
    }
70

71
    internal static IPropertySymbol? GetPublicReadProperty(this ITypeSymbol typeSymbol, string name)
72
    {
73
        foreach (var member in typeSymbol.GetMembers(name).OfType<IPropertySymbol>())
195✔
74
        {
75
            if (!member.IsStatic && member.DeclaredAccessibility == Accessibility.Public && member.GetMethod is not null)
47✔
76
                return member;
47✔
77
        }
78

79
        if (typeSymbol.TypeKind == TypeKind.Interface)
27!
80
        {
81
            // ReSharper disable once ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator
82
            foreach (var @interface in typeSymbol.AllInterfaces)
×
83
            {
84
                var property = @interface.GetPublicReadProperty(name);
×
85
                if (property is not null)
×
86
                    return property;
×
87
            }
88
        }
89
        else
90
        {
91
            var baseType = typeSymbol.BaseType;
27✔
92
            if (baseType is not null)
27✔
93
                return baseType.GetPublicReadProperty(name);
17✔
94
        }
95

96
        return null;
10✔
97
    }
47✔
98

99
    internal static IMethodSymbol? GetPublicMethod(this ITypeSymbol typeSymbol, string name, params Type[] parameters)
100
    {
101
        foreach (var member in typeSymbol.GetMembers(name).OfType<IMethodSymbol>())
571✔
102
        {
103
            if (!member.IsStatic &&
109✔
104
                member.DeclaredAccessibility == Accessibility.Public &&
109✔
105
                SequenceEqual(member.Parameters, parameters))
109✔
106
            {
107
                return member;
97✔
108
            }
109
        }
110

111
        if (typeSymbol.TypeKind == TypeKind.Interface)
128✔
112
        {
113
            // ReSharper disable once ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator
114
            foreach (var @interface in typeSymbol.AllInterfaces)
14✔
115
            {
116
                var method = @interface.GetPublicMethod(name, parameters);
4✔
117
                if (method is not null)
4✔
118
                    return method;
2✔
119
            }
120
        }
121
        else
122
        {
123
            var baseType = typeSymbol.BaseType;
124✔
124
            if (baseType is not null)
124✔
125
                return baseType.GetPublicMethod(name, parameters);
82✔
126
        }
127

128
        return null;
44✔
129
    }
97✔
130

131
    static bool SequenceEqual(ImmutableArray<IParameterSymbol> parameters, Type[] types)
132
    {
133
        if (parameters.Length != types.Length)
105✔
134
            return false;
8✔
135

136
        // ReSharper disable once LoopCanBeConvertedToQuery
137
        for (var index = 0; index < parameters.Length; index++)
212✔
138
        {
139
            if (parameters[index].Type.MetadataName != types[index].Name)
9!
140
                return false;
×
141
        }
142

143
        return true;
97✔
144
    }
145

146
    public static bool IsSpanOrReadOnlySpanType(this ITypeSymbol typeSymbol)
147
    {
148
        if (typeSymbol.Name == "Span" || typeSymbol.Name == "ReadOnlySpan")
23✔
149
        {
150
            var containingNamespace = typeSymbol.ContainingNamespace.ToDisplayString();
2✔
151
            return containingNamespace == "System" && 
2!
152
                typeSymbol is INamedTypeSymbol namedType && 
2✔
153
                namedType.TypeArguments.Length == 1;
2✔
154
        }
155

156
        return false;
21✔
157
    }
158
}
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

© 2026 Coveralls, Inc