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

Sholtee / proxygen / 961

04 Apr 2025 04:54PM UTC coverage: 90.185% (-0.1%) from 90.282%
961

push

appveyor

Sholtee
introduce IInterceptorAccess interface, simplify proxy activation

4815 of 5339 relevant lines covered (90.19%)

0.9 hits per line

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

67.65
/SRC/Private/SyntaxFactories/ClassProxySyntaxFactory.MethodInterceptorFactory.cs
1
/********************************************************************************
2
* ClassProxySyntaxFactory.MethodInterceptorFactory.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.Syntax;
11

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

14
namespace Solti.Utils.Proxy.Internals
15
{
16
    internal partial class ClassProxySyntaxFactory
17
    {
18
        #if DEBUG
19
        internal
20
        #endif
21
        protected override ClassDeclarationSyntax ResolveMethods(ClassDeclarationSyntax cls, object context)
22
        {
1✔
23
            foreach (IMethodInfo method in TargetType.Methods)
1✔
24
            {
1✔
25
                if (method.IsSpecial || (!method.IsAbstract && !method.IsVirtual))
×
26
                    continue;
1✔
27

28
                cls = ResolveMethod(cls, context, method);
1✔
29
            }
1✔
30

31
            return cls;
1✔
32
        }
1✔
33

34
        /// <summary>
35
        /// <code>
36
        /// private static ExtendedMemberInfo FXxX;
37
        /// public override TResult TGeneric1&gt;.Bar&lt;TGeneric2&gt;(TGeneric1 para1, ref T1 para2, out T2 para3, TGeneric2 para4)
38
        /// {
39
        ///     CurrentMethod.GetBase(ref FXxX);
40
        ///     
41
        ///     object[] args = new object[] {para1, para2, default(T3), para4};
42
        ///     
43
        ///     System.Object result = FInterceptor.Invoke
44
        ///     (
45
        ///         new ClassInvocationContext
46
        ///         (
47
        ///             FXxX,
48
        ///             args =>
49
        ///             {
50
        ///                 TGeneric1 cb_a = (TGeneric1) args[0];
51
        ///                 T1 cb_b;                                                                               
52
        ///                 T2 cb_c = (T2) args[2];   
53
        ///                 
54
        ///                 System.Object result;                                                                                
55
        ///                 result = base.Bar&lt;TGeneric2&gt;(cb_a, out cb_b, ref cb_c);                                  
56
        ///                                                                                                        
57
        ///                 args[1] = (System.Object) cb_b;                                                                  
58
        ///                 args[2] = (System.Object) cb_c;   
59
        ///                 
60
        ///                 return result;    
61
        ///             },
62
        ///             args,
63
        ///             new Type[] {typeof(TGeneric)}
64
        ///         )
65
        ///     );
66
        ///     
67
        ///     para2 = (T1) args[1];                                                                            
68
        ///     para3 = (T2) args[2];                                                                               
69
        ///     return (TResult) result;   
70
        /// }
71
        /// </code>
72
        /// </summary>
73
        #if DEBUG
74
        internal
75
        #endif
76
        protected override ClassDeclarationSyntax ResolveMethod(ClassDeclarationSyntax cls, object context, IMethodInfo targetMethod)
77
        {
1✔
78
            //
79
            // Check if the method is visible.
80
            //
81

82
            Visibility.Check(targetMethod, ContainingAssembly, allowProtected: true);
1✔
83

84
            FieldDeclarationSyntax memberInfo = ResolveField<ExtendedMemberInfo>
1✔
85
            (
1✔
86
                $"F{targetMethod.GetMD5HashCode()}",
1✔
87
                @readonly: false
1✔
88
            );
1✔
89

90
            List<StatementSyntax> body = [];
1✔
91

92
            body.Add
1✔
93
            (
1✔
94
                ExpressionStatement
1✔
95
                (
1✔
96
                    InvokeMethod
1✔
97
                    (
1✔
98
                        FGetBase,
1✔
99
                        arguments: Argument
1✔
100
                        (
1✔
101
                            StaticMemberAccess(cls, memberInfo)
1✔
102
                        )
1✔
103
                    )
1✔
104
                )
1✔
105
            );
1✔
106

107
            LocalDeclarationStatementSyntax argsArray = ResolveArgumentsArray(targetMethod);
1✔
108
            body.Add(argsArray);
1✔
109

110
            InvocationExpressionSyntax invokeInterceptor = InvokeInterceptor
×
111
            (
×
112
                Argument
×
113
                (
×
114
                    StaticMemberAccess(cls, memberInfo)
×
115
                ),
×
116
                Argument
×
117
                (
×
118
                    targetMethod.IsAbstract ? ResolveNotImplemented() : ResolveInvokeTarget
×
119
                    (
×
120
                        targetMethod,
×
121
                        hasTarget: false,
×
122
                        (_, locals) => InvokeMethod
1✔
123
                        (
1✔
124
                            targetMethod,
1✔
125
                            target: BaseExpression(),
1✔
126
                            castTargetTo: null,
1✔
127
                            arguments: locals.Select(ResolveArgument).ToArray()
1✔
128
                        )
1✔
129
                    )
×
130
                ),
×
131
                Argument
×
132
                (
×
133
                    ResolveIdentifierName(argsArray)
×
134
                ),
×
135
                Argument
×
136
                (
×
137
                    ResolveArray<Type>
×
138
                    (
×
139
                        (targetMethod as IGenericMethodInfo)?.GenericArguments.Select
×
140
                        (
×
141
                            static ga => TypeOfExpression
1✔
142
                            (
1✔
143
                                IdentifierName(ga.Name)
1✔
144
                            )
1✔
145
                        ) ?? []
×
146
                    )
×
147
                )
×
148
            );
×
149

150
            LocalDeclarationStatementSyntax? result;
151
            if (targetMethod.ReturnValue.Type.IsVoid)
1✔
152
            {
×
153
                result = null;
×
154
                body.Add(ExpressionStatement(invokeInterceptor));
×
155
            }
×
156
            else
157
            {
1✔
158
                result = ResolveLocal<object>
1✔
159
                (
1✔
160
                    EnsureUnused(nameof(result), targetMethod),
1✔
161
                    invokeInterceptor
1✔
162
                );
1✔
163
                body.Add(result);
1✔
164
            }
1✔
165

166
            body.AddRange
1✔
167
            (
1✔
168
                AssignByRefParameters(targetMethod, argsArray)
1✔
169
            );
1✔
170

171
            if (result is not null) body.Add
1✔
172
            (
1✔
173
                ReturnResult(targetMethod.ReturnValue.Type, result)
1✔
174
            );
1✔
175

176
            return cls.AddMembers
1✔
177
            (
1✔
178
                memberInfo,
1✔
179
                ResolveMethod(targetMethod).WithBody
1✔
180
                (
1✔
181
                    Block(body)
1✔
182
                )
1✔
183
            );
1✔
184
        }
1✔
185
    }
186
}
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