• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In
You are now the owner of this repo.

Sholtee / proxygen / 920

22 Mar 2025 02:56PM UTC coverage: 91.244% (-0.3%) from 91.496%
920

push

appveyor

Sholtee
add method override support for ResolveProperty()

4554 of 4991 relevant lines covered (91.24%)

0.91 hits per line

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

98.24
/SRC/Private/SyntaxFactories/ClassSyntaxFactoryBase.Method.cs
1
/********************************************************************************
2
* ClassSyntaxFactoryBase.Method.cs                                              *
3
*                                                                               *
4
* Author: Denes Solti                                                           *
5
********************************************************************************/
6
using System;
7
using System.Collections.Generic;
8
using System.Diagnostics;
9
using System.Linq;
10

11
using Microsoft.CodeAnalysis;
12
using Microsoft.CodeAnalysis.CSharp;
13
using Microsoft.CodeAnalysis.CSharp.Syntax;
14

15
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
16

17
namespace Solti.Utils.Proxy.Internals
18
{
19
    internal partial class ClassSyntaxFactoryBase
20
    {
21
        /// <summary>
22
        /// <code>
23
        /// [[(Type)] target | [(Type)] this | Namespace.Type].Method&lt;...&gt;(...)
24
        /// </code>
25
        /// </summary>
26
        #if DEBUG
27
        internal
28
        #endif
29
        protected MemberAccessExpressionSyntax MethodAccess(ExpressionSyntax? target, IMethodInfo method, ITypeInfo? castTargetTo = null)
30
        {
1✔
31
            SimpleNameSyntax identifier = IdentifierName(method.Name);
1✔
32
            if (method is IGenericMethodInfo genericMethod)
1✔
33
                identifier = GenericName(identifier.Identifier).WithTypeArgumentList
1✔
34
                (
1✔
35
                    typeArgumentList: TypeArgumentList
1✔
36
                    (
1✔
37
                        arguments: genericMethod.GenericArguments.ToSyntaxList(ResolveType)
1✔
38
                    )
1✔
39
                );
1✔
40

41
            return SimpleMemberAccess
1✔
42
            (
1✔
43
                AmendTarget(target, method, castTargetTo),
1✔
44
                identifier
1✔
45
            );
1✔
46
        }
1✔
47

48
        /// <summary>
49
        /// <code>
50
        /// int IInterface.Foo&lt;...&gt;(T a, ref TT b) [where ...]
51
        /// </code>
52
        /// or
53
        /// <code>
54
        /// public override int Foo&lt;...&gt;(T a, ref TT b) [where ...]
55
        /// </code>
56
        /// </summary>
57
        #if DEBUG
58
        internal
59
        #endif
60
        protected MethodDeclarationSyntax ResolveMethod(IMethodInfo method, bool forceInlining = false)
61
        {
1✔
62
            TypeSyntax returnTypeSyntax = ResolveType(method.ReturnValue.Type);
1✔
63

64
            if (method.ReturnValue.Kind >= ParameterKind.Ref)
1✔
65
            {
1✔
66
                RefTypeSyntax refReturnTypeSyntax = RefType(returnTypeSyntax);
1✔
67

68
                if (method.ReturnValue.Kind is ParameterKind.RefReadonly)
1✔
69
                    refReturnTypeSyntax = refReturnTypeSyntax.WithReadOnlyKeyword
1✔
70
                    (
1✔
71
                        Token(SyntaxKind.ReadOnlyKeyword)
1✔
72
                    );
1✔
73

74
                returnTypeSyntax = refReturnTypeSyntax;
1✔
75
            }
1✔
76

77
            MethodDeclarationSyntax result = MethodDeclaration
1✔
78
            (
1✔
79
                returnType: returnTypeSyntax,
1✔
80
                identifier: Identifier(method.Name)
1✔
81
            )
1✔
82
            .WithParameterList
1✔
83
            (
1✔
84
                ParameterList
1✔
85
                (
1✔
86
                    parameters: method.Parameters.ToSyntaxList(param =>
1✔
87
                    {
1✔
88
                        ParameterSyntax parameter = Parameter
1✔
89
                        (
1✔
90
                            Identifier(param.Name)
1✔
91
                        )
1✔
92
                        .WithType
1✔
93
                        (
1✔
94
                            type: ResolveType(param.Type)
1✔
95
                        );
1✔
96

1✔
97
                        SyntaxKind? modifier = param.Kind switch
1✔
98
                        {
1✔
99
                            ParameterKind.In => SyntaxKind.InKeyword,
1✔
100
                            ParameterKind.Out => SyntaxKind.OutKeyword,
1✔
101
                            ParameterKind.Ref => SyntaxKind.RefKeyword,
1✔
102
                            ParameterKind.Params => SyntaxKind.ParamsKeyword,
1✔
103
                            _ => null
1✔
104
                        };
1✔
105

1✔
106
                        if (modifier is not null)
1✔
107
                            parameter = parameter.WithModifiers
1✔
108
                            (
1✔
109
                                TokenList(Token(modifier.Value))
1✔
110
                            );
1✔
111

1✔
112
                        return parameter;
1✔
113
                    })
1✔
114
                )
1✔
115
            );
1✔
116

117
            if (method.DeclaringType.IsInterface)
1✔
118
                result = result.WithExplicitInterfaceSpecifier
1✔
119
                (
1✔
120
                    explicitInterfaceSpecifier: ExplicitInterfaceSpecifier((NameSyntax) ResolveType(method.DeclaringType))
1✔
121
                );
1✔
122
            else
123
            {
1✔
124
                List<SyntaxKind> tokens = method
1✔
125
                    .AccessModifiers
1✔
126
                    .SetFlags()
1✔
127
                    .Select
1✔
128
                    (
1✔
129
                        static am =>
1✔
130
                        {
1✔
131
                            switch (am)
1✔
132
                            {
1✔
133
                                case AccessModifiers.Public: return SyntaxKind.PublicKeyword;
×
134
                                case AccessModifiers.Protected: return SyntaxKind.ProtectedKeyword;
1✔
135
                                case AccessModifiers.Internal: return SyntaxKind.InternalKeyword;
1✔
136
                                default:
1✔
137
                                    Debug.Fail("Method not visible");
×
138
                                    return SyntaxKind.None;
×
139
                            }
1✔
140
                        }
1✔
141
                    )
1✔
142
                    .ToList();
1✔
143

144
                tokens.Add(method.IsVirtual || method.IsAbstract ? SyntaxKind.OverrideKeyword : SyntaxKind.NewKeyword);
1✔
145

146
                result = result.WithModifiers
1✔
147
                (
1✔
148
                    TokenList
1✔
149
                    (
1✔
150
                        tokens.Select(Token)
1✔
151
                    )
1✔
152
                );
1✔
153
            }
1✔
154

155
            if (method is IGenericMethodInfo genericMethod)
1✔
156
            {
1✔
157
                result = result.WithTypeParameterList
1✔
158
                (
1✔
159
                    typeParameterList: TypeParameterList
1✔
160
                    (
1✔
161
                        parameters: genericMethod
1✔
162
                            .GenericArguments
1✔
163
                            .ToSyntaxList
1✔
164
                            (
1✔
165
                                type => TypeParameter
1✔
166
                                (
1✔
167
                                    ResolveType(type).ToFullString()
1✔
168
                                )
1✔
169
                            )
1✔
170
                    )
1✔
171
                );
1✔
172

173
                if (genericMethod.IsGenericDefinition)
1✔
174
                {
1✔
175
                    result = result.WithConstraintClauses
1✔
176
                    (
1✔
177
                        List
1✔
178
                        (
1✔
179
                            genericMethod
1✔
180
                                .GenericConstraints
1✔
181
                                .Where(constraint => GetConstraints(constraint).Any())
1✔
182
                                .Select
1✔
183
                                (
1✔
184
                                    constraint => TypeParameterConstraintClause
1✔
185
                                    (
1✔
186
                                        IdentifierName
1✔
187
                                        (
1✔
188
                                            constraint.Target.Name  // T, T, etc
1✔
189
                                        )
1✔
190
                                    )
1✔
191
                                    .WithConstraints
1✔
192
                                    (
1✔
193
                                        GetConstraints(constraint).ToSyntaxList()
1✔
194
                                    )
1✔
195
                                )
1✔
196
                        )
1✔
197
                    );
1✔
198

199
                    IEnumerable<TypeParameterConstraintSyntax> GetConstraints(IGenericConstraint constraint)
200
                    {
1✔
201
                        if (constraint.Struct)
1✔
202
                            yield return ClassOrStructConstraint(SyntaxKind.StructConstraint);
1✔
203
                        if (constraint.Reference)
1✔
204
                            yield return ClassOrStructConstraint(SyntaxKind.ClassConstraint);
1✔
205

206
                        //
207
                        // Explicit interface implementations must not specify type constraints
208
                        //
209

210
                        if (method.DeclaringType.IsInterface)
1✔
211
                            yield break;
1✔
212

213
                        if (constraint.DefaultConstructor)
1✔
214
                            yield return ConstructorConstraint();
1✔
215

216
                        foreach (ITypeInfo typeConstraint in constraint.ConstraintTypes)
1✔
217
                        {
1✔
218
                            yield return TypeConstraint
1✔
219
                            (
1✔
220
                                ResolveType(typeConstraint)
1✔
221
                            );
1✔
222
                        }
1✔
223
                    }
1✔
224
                }
1✔
225
            }
1✔
226

227
            if (forceInlining) result = result.WithAttributeLists
1✔
228
            (
1✔
229
                attributeLists: ResolveMethodImplAttributeToForceInlining()
1✔
230
            );
1✔
231

232
            return result;
1✔
233
        }
1✔
234

235
        /// <summary>
236
        /// <code>
237
        /// target.Foo(..., ref ..., ...)
238
        /// </code>
239
        /// </summary>
240
        #if DEBUG
241
        internal
242
        #endif
243
        protected InvocationExpressionSyntax InvokeMethod(IMethodInfo method, ExpressionSyntax? target = null, ITypeInfo? castTargetTo = null, params ArgumentSyntax[] arguments)
244
        {
1✔
245
            IReadOnlyList<IParameterInfo> paramz = method.Parameters;
1✔
246

247
            Debug.Assert(arguments.Length == paramz.Count);
1✔
248

249
            return InvocationExpression
1✔
250
            (
1✔
251
                expression: MethodAccess
1✔
252
                (
1✔
253
                    target,
1✔
254
                    method,
1✔
255
                    castTargetTo
1✔
256
                )
1✔
257
            )
1✔
258
            .WithArgumentList
1✔
259
            (
1✔
260
                argumentList: ArgumentList
1✔
261
                (
1✔
262
                    arguments.ToSyntaxList
1✔
263
                    (
1✔
264
                        (arg, i) => paramz[i].Kind switch
1✔
265
                        {
1✔
266
                            ParameterKind.In => arg.WithRefKindKeyword
1✔
267
                            (
1✔
268
                                refKindKeyword: Token(SyntaxKind.InKeyword)
1✔
269
                            ),
1✔
270
                            ParameterKind.Out => arg.WithRefKindKeyword
1✔
271
                            (
1✔
272
                                refKindKeyword: Token(SyntaxKind.OutKeyword)
1✔
273
                            ),
1✔
274
                            ParameterKind.Ref => arg.WithRefKindKeyword
1✔
275
                            (
1✔
276
                                refKindKeyword: Token(SyntaxKind.RefKeyword)
1✔
277
                            ),
1✔
278
                            _ => arg
1✔
279
                        }
1✔
280
                    )
1✔
281
                )
1✔
282
            );
1✔
283
        }
1✔
284

285
        /// <summary>
286
        /// <code>
287
        /// target.Foo(ref a, b, c)
288
        /// </code>
289
        /// </summary>
290
        #if DEBUG
291
        internal
292
        #endif
293
        protected InvocationExpressionSyntax InvokeMethod(IMethodInfo method, ExpressionSyntax? target = null, ITypeInfo? castTargetTo = null, params string[] arguments)
294
        {
1✔
295
            IReadOnlyList<IParameterInfo> paramz = method.Parameters;
1✔
296

297
            Debug.Assert(arguments.Length == paramz.Count);
1✔
298

299
            return InvokeMethod
1✔
300
            (
1✔
301
                method,
1✔
302
                target,
1✔
303
                castTargetTo,
1✔
304
                arguments: paramz
1✔
305
                    .Select
1✔
306
                    (
1✔
307
                        (param, i) => Argument
1✔
308
                        (
1✔
309
                            expression: IdentifierName(arguments[i])
1✔
310
                        )
1✔
311
                    )
1✔
312
                    .ToArray()
1✔
313
            );
1✔
314
        }
1✔
315
    
316
        #if DEBUG
317
        internal
318
        #endif
319
        protected virtual ClassDeclarationSyntax ResolveMethods(ClassDeclarationSyntax cls, object context) => cls;
1✔
320

321
        #if DEBUG
322
        internal
323
        #endif
324
        protected virtual ClassDeclarationSyntax ResolveMethod(ClassDeclarationSyntax cls, object context, IMethodInfo method) => cls;
×
325
    }
326
}
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