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

Sholtee / proxygen / 957

03 Apr 2025 03:49AM UTC coverage: 90.283% (+3.1%) from 87.222%
957

push

appveyor

Sholtee
fix method hash generation

4841 of 5362 relevant lines covered (90.28%)

0.9 hits per line

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

97.54
/SRC/Private/Reflection/MetadataTypeInfo.cs
1
/********************************************************************************
2
* MetadataTypeInfo.cs                                                           *
3
*                                                                               *
4
* Author: Denes Solti                                                           *
5
********************************************************************************/
6
using System;
7
using System.Collections.Generic;
8
using System.Collections.Immutable;
9
using System.Linq;
10
using System.Reflection;
11

12
namespace Solti.Utils.Proxy.Internals
13
{
14
    internal class MetadataTypeInfo(Type underlyingType) : ITypeInfo
1✔
15
    {
16
        protected Type UnderlyingType { get; } = underlyingType;
1✔
17

18
        public static ITypeInfo CreateFrom(Type underlyingType)
19
        {
1✔
20
            while (underlyingType.IsByRef)
1✔
21
            {
1✔
22
                underlyingType = underlyingType.GetElementType();
1✔
23
            }
1✔
24

25
            if (underlyingType.IsFunctionPointer())
1✔
26
                underlyingType = typeof(IntPtr);
1✔
27

28
            return underlyingType switch
1✔
29
            {
1✔
30
                _ when underlyingType.IsArray => new MetadataArrayTypeInfo(underlyingType),
1✔
31
                _ when underlyingType.GetOwnGenericArguments().Any() => new MetadataGenericTypeInfo(underlyingType),
1✔
32
                _ => new MetadataTypeInfo(underlyingType)
1✔
33
            };
1✔
34
        }
1✔
35

36
        public override bool Equals(object obj) => obj is MetadataTypeInfo that && UnderlyingType.Equals(that.UnderlyingType);
×
37

38
        public override int GetHashCode() => UnderlyingType.GetHashCode();
1✔
39

40
        public override string ToString() => UnderlyingType.ToString();
1✔
41

42
        private IAssemblyInfo? FDeclaringAssembly;
43
        public IAssemblyInfo DeclaringAssembly => FDeclaringAssembly ??= MetadataAssemblyInfo.CreateFrom(UnderlyingType.Assembly);
1✔
44

45
        public bool IsVoid => UnderlyingType == typeof(void);
1✔
46

47
        private readonly Lazy<ITypeInfo?> FEnclosingType = new(() =>
1✔
48
        {
1✔
49
            Type? enclosingType = underlyingType.GetEnclosingType();
1✔
50

1✔
51
            return enclosingType is not null
1✔
52
                ? CreateFrom(enclosingType)
1✔
53
                : null;
1✔
54
        });
1✔
55
        public ITypeInfo? EnclosingType => FEnclosingType.Value;
1✔
56

57
        private IReadOnlyList<ITypeInfo>? FInterfaces;
58
        public IReadOnlyList<ITypeInfo> Interfaces => FInterfaces ??= UnderlyingType
1✔
59
            .GetAllInterfaces()
1✔
60
            .Select(CreateFrom)
1✔
61
            .ToImmutableList();
1✔
62

63
        private ITypeInfo? FBaseType;
64
        public ITypeInfo? BaseType => UnderlyingType.GetBaseType() is not null
1✔
65
            ? FBaseType ??= CreateFrom(UnderlyingType.GetBaseType()!)
1✔
66
            : null;
1✔
67

68
        public virtual string Name => UnderlyingType.GetFriendlyName();
1✔
69

70
        public RefType RefType => UnderlyingType.GetRefType();
1✔
71

72
        private readonly Lazy<ITypeInfo?> FElementType = new(() =>
1✔
73
        {
1✔
74
            Type? realType = underlyingType.GetElementType();
1✔
75

1✔
76
            return realType is not null
1✔
77
                ? CreateFrom(realType)
1✔
78
                : null;
1✔
79
        }) ;
1✔
80
        public ITypeInfo? ElementType => FElementType.Value;
1✔
81

82
        //
83
        // In case of "Cica<T>.Mica<TT>", "TT" is embedded which is inappropriate to us
84
        //
85

86
        public bool IsNested => UnderlyingType.IsNested() && !IsGenericParameter;
1✔
87

88
        public bool IsInterface => UnderlyingType.IsInterface;
1✔
89

90
        private IReadOnlyList<IPropertyInfo>? FProperties;
91
        public IReadOnlyList<IPropertyInfo> Properties => FProperties ??= UnderlyingType
1✔
92
            .ListProperties(includeStatic: true)
1✔
93
            .Select(MetadataPropertyInfo.CreateFrom)
1✔
94
            .Sort()
1✔
95
            .ToImmutableList();
1✔
96

97
        private IReadOnlyList<IEventInfo>? FEvents;
98
        public IReadOnlyList<IEventInfo> Events => FEvents ??= UnderlyingType
1✔
99
            .ListEvents(includeStatic: true)
1✔
100
            .Select(MetadataEventInfo.CreateFrom)
1✔
101
            .Sort()
1✔
102
            .ToImmutableList();
1✔
103

104
        //
105
        // These methods are generated by the compiler
106
        //
107

108
        private static bool ShouldSkip(MethodInfo m) =>
109
            (m.DeclaringType.IsClass && m.Name == "Finalize") || // destructor
1✔
110
            (m.DeclaringType.IsArray && m.Name == "Get") || // = array[i]
1✔
111
            (m.DeclaringType.IsArray && m.Name == "Set") ||  // array[i] =
1✔
112
            (m.DeclaringType.IsArray && m.Name == "Address") || // = ref array[i]
1✔
113
            (typeof(Delegate).IsAssignableFrom(m.DeclaringType) && m.Name == "Invoke"); // delegate.Invoke(...)
1✔
114

115
        private IReadOnlyList<IMethodInfo>? FMethods;
116
        public IReadOnlyList<IMethodInfo> Methods => FMethods ??= UnderlyingType
1✔
117
            .ListMethods(includeStatic: true)
1✔
118
            .Where(static meth => !ShouldSkip(meth))
1✔
119
            .Select(MetadataMethodInfo.CreateFrom)
1✔
120
            .Sort()
1✔
121
            .ToImmutableList();
1✔
122

123
        private IReadOnlyList<IConstructorInfo>? FConstructors;
124
        public IReadOnlyList<IConstructorInfo> Constructors => FConstructors ??= UnderlyingType
1✔
125
                .GetDeclaredConstructors()
1✔
126
                .Select(static ctor => (IConstructorInfo) MetadataMethodInfo.CreateFrom(ctor))
1✔
127
                .Sort()
1✔
128
                .ToImmutableList();
1✔
129

130
        public string? AssemblyQualifiedName => QualifiedName is not null //  (UnderlyingType.IsGenericType ? UnderlyingType.GetGenericTypeDefinition() : UnderlyingType).AssemblyQualifiedName;
1✔
131
            ? $"{QualifiedName}, {UnderlyingType.Assembly}"
1✔
132
            : null;
1✔
133

134
        public bool IsGenericParameter => (UnderlyingType.GetInnermostElementType() ?? UnderlyingType).IsGenericParameter;
1✔
135

136
        public string? QualifiedName => UnderlyingType.GetQualifiedName();
1✔
137

138
        public bool IsClass => UnderlyingType.IsClass();
1✔
139

140
        public bool IsFinal => UnderlyingType.IsSealed;
1✔
141

142
        public bool IsAbstract => UnderlyingType.IsAbstract();
1✔
143

144
        private readonly Lazy<IHasName?> FContainingMember = new(() =>
1✔
145
        {
1✔
146
            Type concreteType = underlyingType.GetInnermostElementType() ?? underlyingType;
1✔
147

1✔
148
            return concreteType switch
1✔
149
            {
1✔
150
                _ when concreteType.IsGenericParameter && concreteType.DeclaringMethod is not null => MetadataMethodInfo.CreateFrom(concreteType.DeclaringMethod),
1✔
151
                _ when concreteType.GetEnclosingType() is not null => MetadataTypeInfo.CreateFrom(concreteType.GetEnclosingType()!),
1✔
152
                _ => null
1✔
153
            };
1✔
154
        });
1✔
155
        public IHasName? ContainingMember => FContainingMember.Value;
1✔
156

157
        public AccessModifiers AccessModifiers => UnderlyingType.GetAccessModifiers();
1✔
158

159
        private sealed class MetadataGenericTypeInfo : MetadataTypeInfo, IGenericTypeInfo
160
        {
161
            public MetadataGenericTypeInfo(Type underlyingType) : base(underlyingType) { }
1✔
162

163
            public bool IsGenericDefinition => UnderlyingType
1✔
164
                .GetGenericArguments()
1✔
165
                .Any(static ga => ga.IsGenericParameter);
1✔
166

167
            private IReadOnlyList<ITypeInfo>? FGenericArguments;
168
            public IReadOnlyList<ITypeInfo> GenericArguments => FGenericArguments ??= UnderlyingType
1✔
169
                .GetOwnGenericArguments()
1✔
170
                .Select(CreateFrom)
1✔
171
                .ToImmutableList();
1✔
172

173
            public override string Name => !UnderlyingType.IsGenericType || UnderlyingType.IsGenericTypeDefinition // FIXME: Type.GetFriendlyName() doesn't handle closed generics
1✔
174
                ? base.Name
1✔
175
                : GenericDefinition.Name;
1✔
176

177
            public IGenericTypeInfo GenericDefinition => new MetadataGenericTypeInfo(UnderlyingType.GetGenericTypeDefinition());
1✔
178

179
            public IReadOnlyList<IGenericConstraint> GenericConstraints =>
180
                //
181
                // We never generate open generic proxies so implementing this property not required
182
                //
183

184
                throw new NotImplementedException();
×
185

186
            public IGenericTypeInfo Close(params ITypeInfo[] genericArgs)
187
            {
1✔
188
                if (UnderlyingType.IsNested)
1✔
189
                    throw new NotImplementedException(); // TODO
×
190

191
                Type[] gas = new Type[genericArgs.Length];
1✔
192

193
                for (int i = 0; i < genericArgs.Length; i++)
1✔
194
                {
1✔
195
                    gas[i] = genericArgs[i].ToMetadata();
1✔
196
                }
1✔
197

198
                return (IGenericTypeInfo) CreateFrom(UnderlyingType.MakeGenericType(gas));
1✔
199
            }
1✔
200
        }
201

202
        private sealed class MetadataArrayTypeInfo : MetadataTypeInfo, IArrayTypeInfo 
203
        {
204
            public MetadataArrayTypeInfo(Type underlyingType) : base(underlyingType) { }
1✔
205

206
            public int Rank => UnderlyingType.GetArrayRank();
1✔
207
        }
208
    }
209
}
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