• 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

98.48
/SRC/Private/SyntaxFactories/InterfaceProxySyntaxFactory.Common.cs
1
/********************************************************************************
2
* InterfaceProxySyntaxFactory.Common.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
    using Properties;
20

21
    internal partial class InterfaceProxySyntaxFactory
22
    {
23
        #if DEBUG
24
        internal
25
        #else
26
        private
27
        #endif
28
        bool AlreadyImplemented<TMember>(TMember ifaceMember, IEnumerable<TMember> targetMembers, Func<TMember, TMember, bool> signatureEquals) where TMember : IMemberInfo
29
        {
1✔
30
            //
31
            // Starting from .NET7.0 interfaces may have abstract static members
32
            //
33

34
            if (ifaceMember.IsAbstract && ifaceMember.IsStatic)
1✔
35
                throw new NotSupportedException(Resources.ABSTRACT_STATIC_NOT_SUPPORTED);
×
36

37
            return
×
38
                InterceptorType.Interfaces.Any(iface => iface.EqualsTo(ifaceMember.DeclaringType)) ||
1✔
39
                targetMembers.Any(targetMember => signatureEquals(targetMember, ifaceMember));
1✔
40
        }
1✔
41

42
        #if DEBUG
43
        internal
44
        #endif
45
        protected override ParenthesizedLambdaExpressionSyntax ResolveInvokeTarget(IMethodInfo method, Func<ParameterSyntax, ParameterSyntax, LocalDeclarationStatementSyntax?, IReadOnlyList<LocalDeclarationStatementSyntax>, StatementSyntax> invocationFactory)
46
        {
1✔
47
            ParenthesizedLambdaExpressionSyntax lambda = base.ResolveInvokeTarget(method, invocationFactory);
1✔
48
            if (LanguageVersion >= LanguageVersion.CSharp9)
1✔
49
                lambda = lambda.WithModifiers
1✔
50
                (
1✔
51
                    modifiers: TokenList
1✔
52
                    (
1✔
53
                        Token(SyntaxKind.StaticKeyword)
1✔
54
                    )
1✔
55
                );
1✔
56
            return lambda;
1✔
57
        }
1✔
58

59
        /// <summary>
60
        /// <code>
61
        /// InterfaceMap&lt;TInterface, TTarget&gt;.Value | null
62
        /// </code>
63
        /// </summary>
64
        #if DEBUG
65
        internal
66
        #else
67
        private
68
        #endif
69
        ExpressionSyntax ResolveInterfaceMap()
70
        {
1✔
71
            if (TargetType.IsInterface)
1✔
72
                return LiteralExpression(SyntaxKind.NullLiteralExpression);
1✔
73

74
            IGenericTypeInfo map = 
1✔
75
            (
1✔
76
                (IGenericTypeInfo) MetadataTypeInfo.CreateFrom(typeof(InterfaceMap<,>))
1✔
77
            ).Close(InterfaceType, TargetType);
1✔
78

79
            return MemberAccessExpression
1✔
80
            (
1✔
81
                SyntaxKind.SimpleMemberAccessExpression,
1✔
82
                ResolveType(map),
1✔
83
                IdentifierName(nameof(InterfaceMap<object, object>.Value))
1✔
84
            );
1✔
85
        }
1✔
86

87
        /// <summary>
88
        /// <code>
89
        /// private static readonly InterfaceInterceptionContext FXxX = new InterfaceInterceptionContext(static (object target, object[] args) => 
90
        /// {                                                                                               
91
        ///     System.Int32 cb_a = (System.Int32) args[0];                                                
92
        ///     System.String cb_b;                                                                     
93
        ///     TT cb_c = (TT) args[2];                                                                    
94
        ///     ...                                                                                    
95
        /// }, CALL_INDEX, InterfaceMap&lt;TInterface, TTarget&gt;.Value | null);
96
        /// </code>
97
        /// </summary>
98
        #if DEBUG
99
        internal
100
        #else
101
        private
102
        #endif
103
        FieldDeclarationSyntax ResolveMethodContext(ParenthesizedLambdaExpressionSyntax lambda, int callIndex) => ResolveStaticGlobal<InterfaceInterceptionContext>
1✔
104
        (
1✔
105
            $"F{lambda.GetMD5HashCode()}",
1✔
106
            ResolveObject<InterfaceInterceptionContext>
1✔
107
            (
1✔
108
                Argument(lambda),
1✔
109
                Argument
1✔
110
                (
1✔
111
                    callIndex.AsLiteral()
1✔
112
                ),
1✔
113
                Argument
1✔
114
                (
1✔
115
                    ResolveInterfaceMap()
1✔
116
                )
1✔
117
            )     
1✔
118
        );
1✔
119

120
        /// <summary>
121
        /// <code>
122
        /// private static class WrapperXxX&lt;T1, T2, ...&gt; [where ...]                                            
123
        /// {                                                                                                   
124
        ///     public static readonly InterfaceInterceptionContext Value = new InterfaceInterceptionContext(static (object target, object[] args) => 
125
        ///     {                                                                                               
126
        ///         System.Int32 cb_a = (System.Int32) args[0];                                                  
127
        ///         System.String cb_b;                                                                      
128
        ///         T1 cb_c = (T1) args[2];                                                                 
129
        ///         ...                                                                                     
130
        ///     }, CALL_INDEX, InterfaceMap&lt;TInterface, TTarget&gt;.Value | null);                                
131
        /// }
132
        /// </code>
133
        /// </summary>
134
        #if DEBUG
135
        internal
136
        #else
137
        private
138
        #endif
139
        ClassDeclarationSyntax ResolveMethodContext(ParenthesizedLambdaExpressionSyntax lambda, int callIndex, IEnumerable<ITypeInfo> genericArguments, IEnumerable<IGenericConstraint> constraints)
140
        {
1✔
141
            return ClassDeclaration
1✔
142
            (
1✔
143
                $"Wrapper{lambda.GetMD5HashCode()}"
1✔
144
            )
1✔
145
            .WithModifiers
1✔
146
            (
1✔
147
                TokenList
1✔
148
                (
1✔
149
                    new SyntaxToken[]
1✔
150
                    {
1✔
151
                        Token(SyntaxKind.PrivateKeyword),
1✔
152
                        Token(SyntaxKind.StaticKeyword)
1✔
153
                    }
1✔
154
                )
1✔
155
            )
1✔
156
            .WithTypeParameterList
1✔
157
            (
1✔
158
                TypeParameterList
1✔
159
                (
1✔
160
                    genericArguments.ToSyntaxList(ga =>
1✔
161
                    {
1✔
162
                        Debug.Assert(ga.IsGenericParameter, "Argument must be a generic parameter");
1✔
163
                        return TypeParameter(ga.Name);
1✔
164
                    })
1✔
165
                )
1✔
166
            )
1✔
167
            .WithConstraintClauses
1✔
168
            (
1✔
169
                List
1✔
170
                (
1✔
171
                    constraints.Select
1✔
172
                    (
1✔
173
                        constraint => TypeParameterConstraintClause
1✔
174
                        (
1✔
175
                            IdentifierName
1✔
176
                            (
1✔
177
                                constraint.Target.Name  // T, T, etc
1✔
178
                            )
1✔
179
                        )
1✔
180
                        .WithConstraints
1✔
181
                        (
1✔
182
                            GetConstraints(constraint).ToSyntaxList()
1✔
183
                        )
1✔
184
                    )
1✔
185
                )
1✔
186
            )
1✔
187
            .AddMembers
1✔
188
            (
1✔
189
                ResolveStaticGlobal<InterfaceInterceptionContext>
1✔
190
                (
1✔
191
                    $"Value",
1✔
192
                    ResolveObject<InterfaceInterceptionContext>
1✔
193
                    (
1✔
194
                        Argument(lambda),
1✔
195
                        Argument
1✔
196
                        (
1✔
197
                            callIndex.AsLiteral()
1✔
198
                        ),
1✔
199
                        Argument
1✔
200
                        (
1✔
201
                            ResolveInterfaceMap()
1✔
202
                        )
1✔
203
                    ),
1✔
204
                    @private: false
1✔
205
                )
1✔
206
            );
1✔
207

208
            IEnumerable<TypeParameterConstraintSyntax> GetConstraints(IGenericConstraint constraint)
209
            {
1✔
210
                if (constraint.Struct)
1✔
211
                    yield return ClassOrStructConstraint(SyntaxKind.StructConstraint);
1✔
212
                if (constraint.Reference)
1✔
213
                    yield return ClassOrStructConstraint(SyntaxKind.ClassConstraint);
1✔
214
                if (constraint.DefaultConstructor)
1✔
215
                    yield return ConstructorConstraint();
1✔
216

217
                foreach (ITypeInfo typeConstraint in constraint.ConstraintTypes)
1✔
218
                {
1✔
219
                    yield return TypeConstraint
1✔
220
                    (
1✔
221
                        ResolveType(typeConstraint)
1✔
222
                    );
1✔
223
                }
1✔
224
            }
1✔
225
        }
1✔
226
    }
227
}
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