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

Sholtee / proxygen / 976

08 Apr 2025 02:56PM UTC coverage: 91.686% (+1.6%) from 90.091%
976

push

appveyor

Sholtee
introduce PlatformAssemblies class, drop TargetFramework settings

4819 of 5256 relevant lines covered (91.69%)

0.92 hits per line

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

93.65
/SRC/Private/Extensions/Metadata/MethodInfoExtensions.cs
1
/********************************************************************************
2
* MethodInfoExtensions.cs                                                       *
3
*                                                                               *
4
* Author: Denes Solti                                                           *
5
********************************************************************************/
6
using System;
7
using System.Collections.Generic;
8
using System.Linq;
9
using System.Linq.Expressions;
10
using System.Reflection;
11

12
namespace Solti.Utils.Proxy.Internals
13
{
14
    using Properties;
15

16
    internal static class MethodInfoExtensions
17
    {
18
        public static AccessModifiers GetAccessModifiers(this MethodBase src) => src switch
1✔
19
        {
1✔
20
            _ when src.IsFamily => AccessModifiers.Protected,
1✔
21
            _ when src.IsAssembly => AccessModifiers.Internal,
1✔
22
            _ when src.IsFamilyOrAssembly => AccessModifiers.Protected | AccessModifiers.Internal,
1✔
23
            _ when src.IsFamilyAndAssembly => AccessModifiers.Protected | AccessModifiers.Private,
1✔
24
            _ when src.IsPublic => AccessModifiers.Public,
1✔
25
            _ when src.IsPrivate && src.GetImplementedInterfaceMethods().Any() => AccessModifiers.Explicit,
1✔
26
            _ when src.IsPrivate => AccessModifiers.Private,
1✔
27
            _ => throw new InvalidOperationException(Resources.UNDETERMINED_ACCESS_MODIFIER)
×
28
        };
1✔
29

30
        public static IEnumerable<Type> GetDeclaringInterfaces(this MethodBase src) => src.ReflectedType.IsInterface
1✔
31
            ? Array.Empty<Type>()
1✔
32
            : src
1✔
33
                .GetImplementedInterfaceMethods()
1✔
34
                .Select(static m => m.ReflectedType);
1✔
35

36
        public static IEnumerable<MethodBase> GetImplementedInterfaceMethods(this MethodBase src)
37
        {
1✔
38
            //
39
            // As of C# 11 interfaces may have static abstract methods... We don't deal with
40
            // the implementors.
41
            //
42

43
            if (src.IsStatic || src is not MethodInfo method /*ctor*/)
1✔
44
                yield break;
1✔
45

46
            Type reflectedType = src.ReflectedType;
1✔
47
            if (reflectedType.IsInterface)
1✔
48
                yield break;
1✔
49

50
            foreach (Type iface in reflectedType.GetInterfaces())
1✔
51
            {
1✔
52
                //
53
                // https://docs.microsoft.com/en-us/dotnet/api/system.type.getinterfacemap?view=netcore-3.1#exceptions
54
                //
55

56
                if (iface.IsGenericType && reflectedType.IsArray)
1✔
57
                    continue;
×
58

59
                InterfaceMapping mapping = reflectedType.GetInterfaceMap(iface);
1✔
60

61
                int? mapIndex = mapping
1✔
62
                    .TargetMethods
1✔
63
                    .IndexOf(method);
1✔
64

65
                if (mapIndex >= 0) 
1✔
66
                    yield return mapping.InterfaceMethods[mapIndex.Value];
1✔
67
            }
1✔
68
        }
1✔
69

70
        public static MethodInfo? GetOverriddenMethod(this MethodInfo method)
71
        {
1✔
72
            /*
73
            if (method.IsVirtual)
74
            {
75
                MethodInfo overriddenMethod = method.GetBaseDefinition();
76
                return overriddenMethod != method
77
                    ? overriddenMethod
78
                    : null;
79
            }
80
            */
81

82
            if (method.IsGenericMethod)
1✔
83
                method = method.GetGenericMethodDefinition();
1✔
84

85
            //
86
            // GetBaseDefinition() won't work for "new" override as well as it always return the declaring
87
            // method instead of the overridden one.
88
            //
89

90
            Type[] paramz = [..method.GetParameters().Select(static p => p.ParameterType)];
1✔
91

92
            foreach (Type baseType in method.ReflectedType.GetBaseTypes())
1✔
93
            {
1✔
94
                //
95
                // baseType.GetMethod(method.Name, types: paramz) won't for for generic methods
96
                //
97

98
                foreach(MethodInfo baseMethod in  baseType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | (method.IsStatic ? BindingFlags.Static : BindingFlags.Instance)))
1✔
99
                {
1✔
100
                    if (baseMethod.Name != method.Name)
1✔
101
                        continue;
1✔
102

103
                    if (baseMethod.IsGenericMethod)
1✔
104
                    {
1✔
105
                        if (!method.IsGenericMethod || baseMethod.GetGenericArguments().Length != method.GetGenericArguments().Length)
×
106
                            continue;
×
107

108
                        //
109
                        // We don't need to compare the generic parameters
110
                        //
111
                    }
1✔
112

113
                    ParameterInfo[] baseParamz = baseMethod.GetParameters();
1✔
114
                    if (baseParamz.Length != paramz.Length)
1✔
115
                        continue;
1✔
116

117
                    for (int i = 0; i < baseParamz.Length; i++)
1✔
118
                        if (!paramz[i].EqualsTo(baseParamz[i].ParameterType))
1✔
119
                            goto next;
1✔
120

121
                    return baseMethod;
1✔
122
                    next:;
1✔
123
                }
1✔
124
            }
1✔
125
            return null;
1✔
126
        }
1✔
127

128
        //
129
        // Similar logic is provided by Solti.Utils.Primitives, too. But we don't want to ship
130
        // that library with our source generator, so reimplement it.
131
        //
132

133
        public static MethodInfo ExtractFrom<T>(Expression<Action<T>> expression) => ((MethodCallExpression) expression.Body).Method;
1✔
134

135
        public static bool IsVirtual(this MethodBase method) =>
136
            method.IsVirtual && !method.IsFinal && !method.ReflectedType.IsInterface;
1✔
137
    }
138
}
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