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

Sholtee / proxygen / 935

27 Mar 2025 05:34PM UTC coverage: 91.489% (+0.08%) from 91.411%
935

push

appveyor

Sholtee
move some common stuffs from InterfaceProxySyntaxFactory.Common to ProxyUnitSyntaxFactory.Common

4504 of 4923 relevant lines covered (91.49%)

0.91 hits per line

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

71.63
/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
                    ResolveInvokeTarget
1✔
105
                    (
1✔
106
                        property.GetMethod,
1✔
107
                        (target, args, result, locals) => ExpressionStatement
×
108
                        (
×
109
                            AssignmentExpression
×
110
                            (
×
111
                                kind: SyntaxKind.SimpleAssignmentExpression,
×
112
                                left: ResolveIdentifierName(result!),
×
113
                                right: PropertyAccess
×
114
                                (
×
115
                                    property,
×
116
                                    IdentifierName(target.Identifier),
×
117
                                    castTargetTo: property.DeclaringType,
×
118
                                    indices: locals.Select(ResolveArgument)
×
119
                                )
×
120
                            )
×
121
                        )
×
122
                    ),
1✔
123
                    CALL_INDEX
1✔
124
                );
1✔
125
                members.Add(getCtx);
1✔
126

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

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

154
            if (property.SetMethod is not null)
1✔
155
            {
1✔
156
                FieldDeclarationSyntax setCtx = ResolveMethodContext
1✔
157
                (
1✔
158
                    ResolveInvokeTarget
1✔
159
                    (
1✔
160
                        property.SetMethod,
1✔
161
                        (target, args, result, locals) => ExpressionStatement
×
162
                        (
×
163
                            expression: AssignmentExpression
×
164
                            (
×
165
                                kind: SyntaxKind.SimpleAssignmentExpression,
×
166
                                left: PropertyAccess
×
167
                                (
×
168
                                    property,
×
169
                                    IdentifierName(target.Identifier),
×
170
                                    castTargetTo: property.DeclaringType,
×
171
                                    indices: locals
×
172
                                        .Take(locals.Count - 1)
×
173
                                        .Select(ResolveArgument)
×
174
                                ),
×
175
                                right: ResolveIdentifierName(locals.Last())
×
176
                            )
×
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

© 2026 Coveralls, Inc