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

Sholtee / proxygen / 980

10 Apr 2025 02:40PM UTC coverage: 91.933% (+0.2%) from 91.686%
980

push

appveyor

Sholtee
test ClassProxyGenerator against system types, related fixes III

4866 of 5293 relevant lines covered (91.93%)

0.92 hits per line

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

98.96
/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
        public 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);  // C# 7.0 compatible
32
        ///        default: throw new MissingMethodException("...");
33
        ///    }
34
        /// }
35
        /// </code>
36
        /// </summary>
37
        #if DEBUG
38
        internal
39
        #endif
40
        protected virtual 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
                                SingletonList<StatementSyntax>
1✔
70
                                (
1✔
71
                                    SwitchStatement
1✔
72
                                    (
1✔
73
                                        IdentifierName(tuple)
1✔
74
                                    )
1✔
75
                                    .WithSections
1✔
76
                                    (
1✔
77
                                        List
1✔
78
                                        (
1✔
79
                                            GetCases()
1✔
80
                                        )
1✔
81
                                    )
1✔
82
                                )
1✔
83
                            )
1✔
84
                        ),
1✔
85
                    @private: false
1✔
86
                )
1✔
87
            );
1✔
88

89
            IEnumerable<SwitchSectionSyntax> GetCases()
90
            {
1✔
91
                int i = 0;
1✔
92
                foreach (ConstructorDeclarationSyntax ctor in cls.Members.OfType<ConstructorDeclarationSyntax>())
1✔
93
                {
1✔
94
                    //
95
                    // Tuple may hold at most 7 items
96
                    //
97

98
                    if (ctor.ParameterList.Parameters.Count > 7)
1✔
99
                        throw new InvalidOperationException(Resources.TOO_MANY_CTOR_PARAMS);
×
100

101
                    yield return GetCase(ctor, ref i);
1✔
102
                }
1✔
103

104
                yield return SwitchSection()
1✔
105
                    .WithLabels
1✔
106
                    (
1✔
107
                        SingletonList<SwitchLabelSyntax>
1✔
108
                        (
1✔
109
                            DefaultSwitchLabel()
1✔
110
                        )
1✔
111
                    )
1✔
112
                    .WithStatements
1✔
113
                    (
1✔
114
                        SingletonList<StatementSyntax>
1✔
115
                        (
1✔
116
                            ThrowStatement
1✔
117
                            (
1✔
118
                                ObjectCreationExpression
1✔
119
                                (
1✔
120
                                    ResolveType<MissingMethodException>()
1✔
121
                                )
1✔
122
                                .WithArgumentList
1✔
123
                                (
1✔
124
                                    ArgumentList
1✔
125
                                    (
1✔
126
                                        SingletonSeparatedList
1✔
127
                                        (
1✔
128
                                            Argument
1✔
129
                                            (
1✔
130
                                                Resources.CTOR_NOT_FOUND.AsLiteral()
1✔
131
                                            )
1✔
132
                                        )
1✔
133
                                    )
1✔
134
                                )
1✔
135
                            )
1✔
136
                        )
1✔
137
                    );
1✔
138
            }
1✔
139

140
            SwitchSectionSyntax GetCase(ConstructorDeclarationSyntax ctor, ref int i)
141
            {
1✔
142
                if (ctor.ParameterList.Parameters.Count is 0)
1✔
143
                {
1✔
144
                    return SwitchSection()
1✔
145
                        .WithLabels
1✔
146
                        (
1✔
147
                            SingletonList<SwitchLabelSyntax>
1✔
148
                            (
1✔
149
                                CaseSwitchLabel
1✔
150
                                (
1✔
151
                                    LiteralExpression(SyntaxKind.NullLiteralExpression)
1✔
152
                                )
1✔
153
                            )
1✔
154
                        )
1✔
155
                        .WithStatements
1✔
156
                        (
1✔
157
                            InvokeCtor()
1✔
158
                        );
1✔
159
                }
160

161
                string tupleId = $"t{i++}";
1✔
162

163
                return SwitchSection()
1✔
164
                    .WithLabels
1✔
165
                    (
1✔
166
                        SingletonList<SwitchLabelSyntax>
1✔
167
                        (
1✔
168
                            CasePatternSwitchLabel
1✔
169
                            (
1✔
170
                                DeclarationPattern
1✔
171
                                (
1✔
172
                                    GetTupleForCtor(ctor),
1✔
173
                                    SingleVariableDesignation
1✔
174
                                    (
1✔
175
                                        Identifier(tupleId)
1✔
176
                                    )
1✔
177
                                ),
1✔
178
                                Token(SyntaxKind.ColonToken)
1✔
179
                            )
1✔
180
                        )
1✔
181
                    )
1✔
182
                    .WithStatements
1✔
183
                    (
1✔
184
                        InvokeCtor
1✔
185
                        (
1✔
186
                            ctor.ParameterList.Parameters.Select
1✔
187
                            (
1✔
188
                                (parameter, i) =>
1✔
189
                                {
1✔
190
                                    if (parameter.Modifiers.Any(static token => token.IsKind(SyntaxKind.OutKeyword) || token.IsKind(SyntaxKind.RefKeyword)))
1✔
191
                                        throw new InvalidOperationException(Resources.BYREF_CTOR_PARAMETER);
×
192

1✔
193
                                    return Argument
1✔
194
                                    (
1✔
195
                                        SimpleMemberAccess
1✔
196
                                        (
1✔
197
                                            IdentifierName(tupleId),
1✔
198
                                            IdentifierName($"Item{i + 1}")
1✔
199
                                        )
1✔
200
                                    );
1✔
201
                                }
1✔
202
                            )
1✔
203
                        )
1✔
204
                    );
1✔
205
            }
1✔
206

207
            
208
            SyntaxList<StatementSyntax> InvokeCtor(params IEnumerable<ArgumentSyntax> arguments) => SingletonList<StatementSyntax>
1✔
209
            (
1✔
210
                ReturnStatement
1✔
211
                (
1✔
212
                    ObjectCreationExpression
1✔
213
                    (
1✔
214
                        AliasQualifiedName
1✔
215
                        (
1✔
216
                            IdentifierName
1✔
217
                            (
1✔
218
                                Token(SyntaxKind.GlobalKeyword)
1✔
219
                            ),
1✔
220
                            IdentifierName(cls.Identifier)
1✔
221
                        )
1✔
222
                    )
1✔
223
                    .WithArgumentList
1✔
224
                    (
1✔
225
                        ArgumentList(arguments.ToSyntaxList())
1✔
226
                    )
1✔
227
                )
1✔
228
            );
1✔
229

230
            TypeSyntax GetTupleForCtor(ConstructorDeclarationSyntax ctor)
231
            {
1✔
232
                TypeSyntax generic = ResolveType
1✔
233
                (
1✔
234
                    MetadataTypeInfo.CreateFrom
1✔
235
                    (
1✔
236
                        typeof(Tuple)
1✔
237
                            .Assembly
1✔
238
                            .GetType($"System.Tuple`{ctor.ParameterList.Parameters.Count}", throwOnError: true)
1✔
239
                    )
1✔
240
                );
1✔
241

242
                //
243
                // Hacky specialization
244
                //
245

246
                int arity = 0;
1✔
247

248
                SyntaxNode gn = generic
1✔
249
                    .ChildNodes()
1✔
250
                    .Single(static node => node is GenericNameSyntax)!;
1✔
251

252
                return generic.ReplaceNodes
1✔
253
                (
1✔
254
                    gn.DescendantNodes().OfType<TypeSyntax>(),
1✔
255
                    (_, _) => ctor.ParameterList.Parameters[arity++].Type!
1✔
256
                );
1✔
257
            }
1✔
258
        }
1✔
259
    }
260
}
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