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

Sholtee / proxygen / 1060

02 May 2025 09:09AM UTC coverage: 92.623% (-0.08%) from 92.705%
1060

push

appveyor

Sholtee
fix RoslynV3 ParameterList issue

4859 of 5246 relevant lines covered (92.62%)

0.93 hits per line

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

99.52
/SRC/Private/SyntaxFactories/ProxyUnitSyntaxFactoryBase.Activator.cs
1
/********************************************************************************
2
* ProxyUnitSyntaxFactoryBase.Activator.cs                                       *
3
*                                                                               *
4
* Author: Denes Solti                                                           *
5
********************************************************************************/
6
using System;
7
using System.Collections.Generic;
8
using System.Linq;
9

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

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

16
namespace Solti.Utils.Proxy.Internals
17
{
18
    using Properties;
19

20
    internal abstract partial class ProxyUnitSyntaxFactoryBase
21
    {
22
        protected const string ACTIVATOR_NAME = "__Activator";
23

24
        /// <summary>
25
        /// <code>
26
        /// public static readonly Func&lt;object, object&gt; __Activator = static tuple =>
27
        /// {
28
        ///    switch (tuple)
29
        ///    {
30
        ///        case null: return new Class();
31
        ///        case Tuple&lt;int, string&gt; t1: return new Class(t1.Item1, t1.Item2);
32
        ///        default: throw new MissingMethodException("...");
33
        ///    }
34
        /// }
35
        /// </code>
36
        /// </summary>
37
        #if DEBUG
38
        internal
39
        #endif
40
        protected ClassDeclarationSyntax ResolveActivator(ClassDeclarationSyntax cls, object context)
41
        {
1✔
42
            const string tuple = nameof(tuple);
43

44
            return cls.AddMembers
1✔
45
            (
1✔
46
                ResolveField
1✔
47
                (
1✔
48
                    MetadataTypeInfo.CreateFrom(typeof(Func<object, object>)),
1✔
49
                    ACTIVATOR_NAME,
1✔
50
                    initializer:
1✔
51
                        SimpleLambdaExpression
1✔
52
                        (
1✔
53
                            Parameter
1✔
54
                            (
1✔
55
                                Identifier(tuple)
1✔
56
                            )
1✔
57
                        )
1✔
58
                        .WithModifiers
1✔
59
                        (
1✔
60
                            TokenList
1✔
61
                            (
1✔
62
                                Token(SyntaxKind.StaticKeyword)
1✔
63
                            )
1✔
64
                        )
1✔
65
                        .WithBlock
1✔
66
                        (
1✔
67
                            Block
1✔
68
                            (
1✔
69
                                List
1✔
70
                                (
1✔
71
                                    ResolveActivatorBody
1✔
72
                                    (
1✔
73
                                        cls,
1✔
74
                                        IdentifierName(tuple),
1✔
75
                                        context
1✔
76
                                    )
1✔
77
                                )
1✔
78
                            )
1✔
79
                        ),
1✔
80
                    @private: false
1✔
81
                )
1✔
82
            );
1✔
83
        }
1✔
84

85
        /// <summary>
86
        /// <code>
87
        /// new Proxy(...);
88
        /// </code>
89
        /// </summary>
90
        protected virtual IEnumerable<StatementSyntax> ResolveProxyObject(ClassDeclarationSyntax cls, object context, params IEnumerable<ExpressionSyntax> arguments)
91
        {
1✔
92
            yield return ReturnStatement
1✔
93
            (
1✔
94
                ObjectCreationExpression
1✔
95
                (
1✔
96
                    AliasQualifiedName
1✔
97
                    (
1✔
98
                        IdentifierName
1✔
99
                        (
1✔
100
                            Token(SyntaxKind.GlobalKeyword)
1✔
101
                        ),
1✔
102
                        IdentifierName(cls.Identifier)
1✔
103
                    )
1✔
104
                )
1✔
105
                .WithArgumentList
1✔
106
                (
1✔
107
                    ArgumentList
1✔
108
                    (
1✔
109
                        arguments
1✔
110
                            .Select(Argument)
1✔
111
                            .ToSyntaxList()
1✔
112
                    )
1✔
113
                )
1✔
114
            );
1✔
115
        }
1✔
116

117
        protected virtual IEnumerable<ParameterSyntax> FilterProxyObjectCtorParameters(ConstructorDeclarationSyntax ctor) => ctor
1✔
118
            .ParameterList
1✔
119
            .Parameters;
1✔
120

121
        /// <summary>
122
        /// <code>
123
        /// switch (tuple)
124
        /// {
125
        ///     case null: return new Class();
126
        ///     case Tuple&lt;int, string&gt; t1: return new Class(t1.Item1, t1.Item2);
127
        ///     default: throw new MissingMethodException("...");
128
        /// }
129
        /// </code>
130
        /// </summary>
131
        protected virtual IEnumerable<StatementSyntax> ResolveActivatorBody(ClassDeclarationSyntax cls, ExpressionSyntax tuple, object context)
132
        {
1✔
133
            yield return SwitchStatement(tuple).WithSections
1✔
134
            (
1✔
135
                List
1✔
136
                (
1✔
137
                    GetCases()
1✔
138
                )
1✔
139
            );
1✔
140

141
            IEnumerable<SwitchSectionSyntax> GetCases()
142
            {
1✔
143
                int i = 0;
1✔
144
                foreach (ConstructorDeclarationSyntax ctor in cls.Members.OfType<ConstructorDeclarationSyntax>())
1✔
145
                {
1✔
146
                    IReadOnlyList<ParameterSyntax> parameters = [..FilterProxyObjectCtorParameters(ctor)];
1✔
147

148
                    switch (parameters.Count)
149
                    {
150
                        case > 7:
151
                            //
152
                            // Tuple may hold at most 7 items
153
                            //
154

155
                            throw new InvalidOperationException(Resources.TOO_MANY_CTOR_PARAMS);
×
156
                        case 0:
157
                            yield return SwitchSection()
1✔
158
                                .WithLabels
1✔
159
                                (
1✔
160
                                    SingletonList<SwitchLabelSyntax>
1✔
161
                                    (
1✔
162
                                        CaseSwitchLabel
1✔
163
                                        (
1✔
164
                                            LiteralExpression(SyntaxKind.NullLiteralExpression)
1✔
165
                                        )
1✔
166
                                    )
1✔
167
                                )
1✔
168
                                .WithStatements
1✔
169
                                (
1✔
170
                                    List
1✔
171
                                    (
1✔
172
                                        ResolveProxyObject(cls, context)
1✔
173
                                    )
1✔
174
                                );
1✔
175
                            break;
1✔
176
                        default:
177
                            string tupleId = $"t{i++}";
1✔
178

179
                            yield return SwitchSection()
1✔
180
                                .WithLabels
1✔
181
                                (
1✔
182
                                    SingletonList<SwitchLabelSyntax>
1✔
183
                                    (
1✔
184
                                        CasePatternSwitchLabel
1✔
185
                                        (
1✔
186
                                            DeclarationPattern
1✔
187
                                            (
1✔
188
                                                GetTupleForCtor(parameters),
1✔
189
                                                SingleVariableDesignation
1✔
190
                                                (
1✔
191
                                                    Identifier(tupleId)
1✔
192
                                                )
1✔
193
                                            ),
1✔
194
                                            Token(SyntaxKind.ColonToken)
1✔
195
                                        )
1✔
196
                                    )
1✔
197
                                )
1✔
198
                                .WithStatements
1✔
199
                                (
1✔
200
                                    List
1✔
201
                                    (
1✔
202
                                        ResolveProxyObject
1✔
203
                                        (
1✔
204
                                            cls,
1✔
205
                                            context,
1✔
206
                                            parameters.Select
1✔
207
                                            (
1✔
208
                                                (parameter, i) =>
1✔
209
                                                {
1✔
210
                                                    if (parameter.Modifiers.Any(static token => token.IsKind(SyntaxKind.OutKeyword) || token.IsKind(SyntaxKind.RefKeyword)))
1✔
211
                                                        throw new InvalidOperationException(Resources.BYREF_CTOR_PARAMETER);
1✔
212

1✔
213
                                                    return SimpleMemberAccess
1✔
214
                                                    (
1✔
215
                                                        IdentifierName(tupleId),
1✔
216
                                                        IdentifierName($"Item{i + 1}")
1✔
217
                                                    );
1✔
218
                                                }
1✔
219
                                            )
1✔
220
                                        )
1✔
221
                                    )
1✔
222
                                );
1✔
223
                            break;
1✔
224
                    }
225
                }
1✔
226

227
                yield return SwitchSection()
1✔
228
                    .WithLabels
1✔
229
                    (
1✔
230
                        SingletonList<SwitchLabelSyntax>
1✔
231
                        (
1✔
232
                            DefaultSwitchLabel()
1✔
233
                        )
1✔
234
                    )
1✔
235
                    .WithStatements
1✔
236
                    (
1✔
237
                        SingletonList<StatementSyntax>
1✔
238
                        (
1✔
239
                            ThrowStatement
1✔
240
                            (
1✔
241
                                ObjectCreationExpression
1✔
242
                                (
1✔
243
                                    ResolveType<MissingMethodException>()
1✔
244
                                )
1✔
245
                                .WithArgumentList
1✔
246
                                (
1✔
247
                                    ArgumentList
1✔
248
                                    (
1✔
249
                                        SingletonSeparatedList
1✔
250
                                        (
1✔
251
                                            Argument
1✔
252
                                            (
1✔
253
                                                Resources.CTOR_NOT_FOUND.AsLiteral()
1✔
254
                                            )
1✔
255
                                        )
1✔
256
                                    )
1✔
257
                                )
1✔
258
                            )
1✔
259
                        )
1✔
260
                    );
1✔
261
            }
1✔
262

263
            TypeSyntax GetTupleForCtor(IReadOnlyList<ParameterSyntax> parameters)
264
            {
1✔
265
                TypeSyntax generic = ResolveType
1✔
266
                (
1✔
267
                    MetadataTypeInfo.CreateFrom
1✔
268
                    (
1✔
269
                        typeof(Tuple).Assembly.GetType
1✔
270
                        (
1✔
271
                            $"System.Tuple`{parameters.Count}",
1✔
272
                            throwOnError: true
1✔
273
                        )
1✔
274
                    )
1✔
275
                );
1✔
276

277
                //
278
                // Hacky specialization
279
                //
280

281
                int arity = 0;
1✔
282

283
                SyntaxNode gn = generic
1✔
284
                    .ChildNodes()
1✔
285
                    .Single(static node => node is GenericNameSyntax)!;
1✔
286

287
                return generic.ReplaceNodes
1✔
288
                (
1✔
289
                    gn.DescendantNodes().OfType<TypeSyntax>(),
1✔
290
                    (_, _) => parameters[arity++].Type!
1✔
291
                );
1✔
292
            }
1✔
293
        }
1✔
294
    }
295
}
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