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

Sholtee / proxygen / 936

28 Mar 2025 05:09AM UTC coverage: 91.359% (-0.1%) from 91.489%
936

push

appveyor

Sholtee
introduce IMethodInfoExtensions.GetMD5HashCode() method

4504 of 4930 relevant lines covered (91.36%)

0.91 hits per line

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

72.03
/SRC/Private/SyntaxFactories/InterfaceProxySyntaxFactory.PropertyInterceptorFactory.cs
1
/********************************************************************************
2
* InterfaceProxySyntaxFactory.PropertyInterceptorFactory.cs                     *
3
*                                                                               *
4
* Author: Denes Solti                                                           *
5
********************************************************************************/
6
using System;
7
using System.Collections.Generic;
8
using System.Linq;
9

10
using Microsoft.CodeAnalysis.CSharp;
11
using Microsoft.CodeAnalysis.CSharp.Syntax;
12

13
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
14

15
namespace Solti.Utils.Proxy.Internals
16
{
17
    internal partial class InterfaceProxySyntaxFactory
18
    {
19
        #if DEBUG
20
        internal
21
        #endif
22
        protected override ClassDeclarationSyntax ResolveProperties(ClassDeclarationSyntax cls, object context)
23
        {
1✔
24
            foreach (IPropertyInfo prop in InterfaceType.Properties)
1✔
25
            {
1✔
26
                if (AlreadyImplemented(prop, InterceptorType.Properties, SignatureEquals))
1✔
27
                    continue;
×
28

29
                cls = ResolveProperty(cls, context, prop);
1✔
30
            }
1✔
31

32
            return cls;
1✔
33

34
            static bool SignatureEquals(IPropertyInfo targetProp, IPropertyInfo ifaceProp)
35
            {
1✔
36
                //
37
                // We allow the implementation to declare a getter or setter that is not required by the interface.
38
                //
39

40
                if (ifaceProp.GetMethod is not null)
1✔
41
                {
1✔
42
                    if (targetProp.GetMethod?.SignatureEquals(ifaceProp.GetMethod) is not true)
1✔
43
                        return false;
1✔
44
                }
×
45

46
                if (ifaceProp.SetMethod is not null)
×
47
                {
×
48
                    if (targetProp.SetMethod?.SignatureEquals(ifaceProp.SetMethod) is not true)
×
49
                        return false;
×
50
                }
×
51

52
                return true;
×
53
            }
1✔
54
        }
1✔
55

56
        /// <summary>
57
        /// <code>
58
        /// private static readonly InterfaceInterceptionContext FxXx = new InterfaceInterceptionContext(static (ITarget target, object[] args) =>  
59
        /// {                                                                                                 
60
        ///     return target.Prop;                                                                           
61
        /// }, CALL_INDEX, InterfaceMap&lt;TInterface, TTarget&gt;.Value | null);                                                                                          
62
        /// private static readonly InterfaceInterceptionContext FyYy = new InterfaceInterceptionContext(static (ITarget target, object[] args) =>  
63
        /// {                                                                                                
64
        ///     TValue _value = (TValue) args[0];                                                             
65
        ///     target.Prop = _value;                                                                         
66
        ///     return null;                                                                                   
67
        /// }, CALL_INDEX, InterfaceMap&lt;TInterface, TTarget&gt;.Value | null);                                                                                            
68
        /// TResult IInterface.Prop                                                                          
69
        /// {                                                                                                 
70
        ///     get                                                                                            
71
        ///     {                                                                                            
72
        ///         object[] args = new object[] { };                                                          
73
        ///         return (TResult) Invoke(new InvocationContext(args, FxXx));                               
74
        ///     }                                                                                            
75
        ///     set                                                                                         
76
        ///     {                                                                                            
77
        ///         object[] args = new object[] { value };                                                  
78
        ///         Invoke(new InvocationContext(args, FyYy));                                               
79
        ///     }                                                                                              
80
        /// }
81
        /// </code>
82
        /// </summary>
83
        #if DEBUG
84
        internal
85
        #endif
86
        protected override ClassDeclarationSyntax ResolveProperty(ClassDeclarationSyntax cls, object context, IPropertyInfo property)
87
        {
1✔
88
            //
89
            // For now, we only have call-index of 0
90
            //
91

92
            const int CALL_INDEX = 0;
93

94
            List<MemberDeclarationSyntax> members = new();
1✔
95

96
            BlockSyntax?
1✔
97
                get = null,
1✔
98
                set = null;
1✔
99

100
            if (property.GetMethod is not null)
1✔
101
            {
1✔
102
                FieldDeclarationSyntax getCtx = ResolveMethodContext
1✔
103
                (
1✔
104
                    property.GetMethod.GetMD5HashCode(),
1✔
105
                    ResolveInvokeTarget
1✔
106
                    (
1✔
107
                        property.GetMethod,
1✔
108
                        (target, args, result, locals) => ExpressionStatement
×
109
                        (
×
110
                            AssignmentExpression
×
111
                            (
×
112
                                kind: SyntaxKind.SimpleAssignmentExpression,
×
113
                                left: ResolveIdentifierName(result!),
×
114
                                right: PropertyAccess
×
115
                                (
×
116
                                    property,
×
117
                                    IdentifierName(target.Identifier),
×
118
                                    castTargetTo: property.DeclaringType,
×
119
                                    indices: locals.Select(ResolveArgument)
×
120
                                )
×
121
                            )
×
122
                        )
×
123
                    ),
1✔
124
                    CALL_INDEX
1✔
125
                );
1✔
126
                members.Add(getCtx);
1✔
127

128
                LocalDeclarationStatementSyntax argsArray = ResolveArgumentsArray(property.GetMethod);
1✔
129

130
                get = Block
1✔
131
                (
1✔
132
                    argsArray,
1✔
133
                    ReturnResult
1✔
134
                    (
1✔
135
                        property.Type,
1✔
136
                        InvokeMethod
1✔
137
                        (
1✔
138
                            Invoke,
1✔
139
                            arguments: Argument
1✔
140
                            (
1✔
141
                                ResolveObject<InterfaceInvocationContext>
1✔
142
                                (
1✔
143
                                    ResolveArgument(argsArray),
1✔
144
                                    Argument
1✔
145
                                    (
1✔
146
                                        StaticMemberAccess(cls, getCtx)
1✔
147
                                    )
1✔
148
                                )
1✔
149
                            )
1✔
150
                        )
1✔
151
                    )
1✔
152
                );
1✔
153
            }
1✔
154

155
            if (property.SetMethod is not null)
1✔
156
            {
1✔
157
                FieldDeclarationSyntax setCtx = ResolveMethodContext
1✔
158
                (
1✔
159
                    property.SetMethod.GetMD5HashCode(),
1✔
160
                    ResolveInvokeTarget
1✔
161
                    (
1✔
162
                        property.SetMethod,
1✔
163
                        (target, args, result, locals) => ExpressionStatement
×
164
                        (
×
165
                            expression: AssignmentExpression
×
166
                            (
×
167
                                kind: SyntaxKind.SimpleAssignmentExpression,
×
168
                                left: PropertyAccess
×
169
                                (
×
170
                                    property,
×
171
                                    IdentifierName(target.Identifier),
×
172
                                    castTargetTo: property.DeclaringType,
×
173
                                    indices: locals
×
174
                                        .Take(locals.Count - 1)
×
175
                                        .Select(ResolveArgument)
×
176
                                ),
×
177
                                right: ResolveIdentifierName(locals.Last())
×
178
                            )
×
179
                        )
×
180
                    ),
1✔
181
                    CALL_INDEX
1✔
182
                );
1✔
183
                members.Add(setCtx);
1✔
184

185
                LocalDeclarationStatementSyntax argsArray = ResolveArgumentsArray(property.SetMethod);
1✔
186

187
                set = Block
1✔
188
                (
1✔
189
                    argsArray,
1✔
190
                    ExpressionStatement
1✔
191
                    (
1✔
192
                        InvokeMethod
1✔
193
                        (
1✔
194
                            Invoke,
1✔
195
                            arguments: Argument
1✔
196
                            (
1✔
197
                                ResolveObject<InterfaceInvocationContext>
1✔
198
                                (
1✔
199
                                    ResolveArgument(argsArray),
1✔
200
                                    Argument
1✔
201
                                    (
1✔
202
                                        StaticMemberAccess(cls, setCtx)
1✔
203
                                    )
1✔
204
                                )
1✔
205
                            )
1✔
206
                        )
1✔
207
                    )
1✔
208
                );
1✔
209
            }
1✔
210

211
            members.Add
1✔
212
            (
1✔
213
                property.Indices.Any() 
1✔
214
                    ? ResolveIndexer(property, get, set, false)
1✔
215
                    : ResolveProperty(property, get, set, false)
1✔
216
            );
1✔
217

218
            return cls.WithMembers
1✔
219
            (
1✔
220
                cls.Members.AddRange(members)
1✔
221
            );
1✔
222
        }
1✔
223
    }
224
}
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