• 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

60.0
/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 = InvokeMethod
×
111
            (
×
112
                method: FInvoke,
×
113
                target: SimpleMemberAccess
×
114
                (
×
115
                    ThisExpression(),
×
116
                    ResolveIdentifierName(FInterceptor)
×
117
                ),
×
118
                castTargetTo: null,
×
119
                arguments: Argument
×
120
                (
×
121
                    ResolveObject<ClassInvocationContext>
×
122
                    (
×
123
                        Argument
×
124
                        (
×
125
                            StaticMemberAccess(cls, memberInfo)
×
126
                        ),
×
127
                        Argument
×
128
                        (
×
129
                            targetMethod.IsAbstract ? ResolveNotImplemented() : ResolveInvokeTarget
×
130
                            (
×
131
                                targetMethod,
×
132
                                hasTarget: false,
×
133
                                (_, locals) => InvokeMethod
1✔
134
                                (
1✔
135
                                    targetMethod,
1✔
136
                                    target: BaseExpression(),
1✔
137
                                    castTargetTo: null,
1✔
138
                                    arguments: locals.Select(ResolveArgument).ToArray()
1✔
139
                                )
1✔
140
                            )
×
141
                        ),
×
142
                        Argument
×
143
                        (
×
144
                            ResolveIdentifierName(argsArray)
×
145
                        ),
×
146
                        Argument
×
147
                        (
×
148
                            ResolveArray<Type>
×
149
                            (
×
150
                                (targetMethod as IGenericMethodInfo)?.GenericArguments.Select
×
151
                                (
×
152
                                    static ga => TypeOfExpression
1✔
153
                                    (
1✔
154
                                        IdentifierName(ga.Name)
1✔
155
                                    )
1✔
156
                                ) ?? []
×
157
                            )
×
158
                        )
×
159
                    )
×
160
                )
×
161
            );
×
162

163
            LocalDeclarationStatementSyntax? result;
164
            if (targetMethod.ReturnValue.Type.IsVoid)
1✔
165
            {
×
166
                result = null;
×
167
                body.Add(ExpressionStatement(invokeInterceptor));
×
168
            }
×
169
            else
170
            {
1✔
171
                result = ResolveLocal<object>
1✔
172
                (
1✔
173
                    EnsureUnused(nameof(result), targetMethod),
1✔
174
                    invokeInterceptor
1✔
175
                );
1✔
176
                body.Add(result);
1✔
177
            }
1✔
178

179
            body.AddRange
1✔
180
            (
1✔
181
                AssignByRefParameters(targetMethod, argsArray)
1✔
182
            );
1✔
183

184
            if (result is not null) body.Add
1✔
185
            (
1✔
186
                ReturnResult(targetMethod.ReturnValue.Type, result)
1✔
187
            );
1✔
188

189
            return cls.AddMembers
1✔
190
            (
1✔
191
                memberInfo,
1✔
192
                ResolveMethod(targetMethod).WithBody
1✔
193
                (
1✔
194
                    Block(body)
1✔
195
                )
1✔
196
            );
1✔
197
        }
1✔
198
    }
199
}
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