• 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

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

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

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

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

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

31
            return cls;
1✔
32

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

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

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

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

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

91
            const int CALL_INDEX = 0;
92

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

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

99
            if (property.GetMethod is not null)
1✔
100
            {
1✔
101
                //
102
                // Starting from .NET 5.0 interfaces may have visibility.
103
                //
104

105
                Visibility.Check(property.GetMethod, ContainingAssembly);
1✔
106

107
                FieldDeclarationSyntax getCtx = ResolveMethodContext
1✔
108
                (
1✔
109
                    property.GetMethod.GetMD5HashCode(),
1✔
110
                    ResolveInvokeTarget
1✔
111
                    (
1✔
112
                        property.GetMethod,
1✔
113
                        hasTarget: true,
1✔
114
                        (paramz, locals) => PropertyAccess
×
115
                        (
×
116
                            property,
×
117
                            IdentifierName(paramz[0].Identifier),
×
118
                            castTargetTo: property.DeclaringType,
×
119
                            indices: locals.Select(ResolveArgument)
×
120
                        )
×
121
                    ),
1✔
122
                    CALL_INDEX
1✔
123
                );
1✔
124
                members.Add(getCtx);
1✔
125

126
                LocalDeclarationStatementSyntax argsArray = ResolveArgumentsArray(property.GetMethod);
1✔
127

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

153
            if (property.SetMethod is not null)
1✔
154
            {
1✔
155
                Visibility.Check(property.SetMethod, ContainingAssembly);
1✔
156

157
                FieldDeclarationSyntax setCtx = ResolveMethodContext
1✔
158
                (
1✔
159
                    property.SetMethod.GetMD5HashCode(),
1✔
160
                    ResolveInvokeTarget
1✔
161
                    (
1✔
162
                        property.SetMethod,
1✔
163
                        hasTarget: true,
1✔
164
                        (paramz, locals) => AssignmentExpression // target.Prop = _value
×
165
                        (
×
166
                            kind: SyntaxKind.SimpleAssignmentExpression,
×
167
                            left: PropertyAccess
×
168
                            (
×
169
                                property,
×
170
                                IdentifierName(paramz[0].Identifier),
×
171
                                castTargetTo: property.DeclaringType,
×
172
                                indices: locals
×
173
                                    .Take(locals.Count - 1)
×
174
                                    .Select(ResolveArgument)
×
175
                            ),
×
176
                            right: ResolveIdentifierName(locals[locals.Count - 1])
×
177
                        )
×
178
                    ),
1✔
179
                    CALL_INDEX
1✔
180
                );
1✔
181
                members.Add(setCtx);
1✔
182

183
                LocalDeclarationStatementSyntax argsArray = ResolveArgumentsArray(property.SetMethod);
1✔
184

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

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

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