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

Sholtee / proxygen / 964

05 Apr 2025 04:30AM UTC coverage: 90.091% (-0.02%) from 90.108%
964

push

appveyor

Sholtee
validate ctor parameter count

4773 of 5298 relevant lines covered (90.09%)

0.9 hits per line

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

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

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

159
                string tupleId = $"t{i++}";
1✔
160

161
                return SwitchSection().WithLabels
1✔
162
                (
1✔
163
                    SingletonList<SwitchLabelSyntax>
1✔
164
                    (
1✔
165
                        CasePatternSwitchLabel
1✔
166
                        (
1✔
167
                            DeclarationPattern
1✔
168
                            (
1✔
169
                                GetTupleForCtor(ctor),
1✔
170
                                SingleVariableDesignation
1✔
171
                                (
1✔
172
                                    Identifier(tupleId)
1✔
173
                                )
1✔
174
                            ),
1✔
175
                            Token(SyntaxKind.ColonToken)
1✔
176
                        )
1✔
177
                    )
1✔
178
                )
1✔
179
                .WithStatements
1✔
180
                (
1✔
181
                    InvokeCtor
1✔
182
                    (
1✔
183
                        ctor.ParameterList.Parameters.Count.Times
1✔
184
                        (
1✔
185
                            i => Argument
1✔
186
                            (
1✔
187
                                SimpleMemberAccess
1✔
188
                                (
1✔
189
                                    IdentifierName(tupleId),
1✔
190
                                    IdentifierName($"Item{i + 1}")
1✔
191
                                )
1✔
192
                            )
1✔
193
                        )
1✔
194
                    )
1✔
195
                );
1✔
196
            }
1✔
197

198
            SyntaxList<StatementSyntax> InvokeCtor(params IEnumerable<ArgumentSyntax> arguments) => SingletonList<StatementSyntax>
1✔
199
            (
1✔
200
                ReturnStatement
1✔
201
                (
1✔
202
                    ObjectCreationExpression
1✔
203
                    (
1✔
204
                        AliasQualifiedName
1✔
205
                        (
1✔
206
                            IdentifierName
1✔
207
                            (
1✔
208
                                Token(SyntaxKind.GlobalKeyword)
1✔
209
                            ),
1✔
210
                            IdentifierName(cls.Identifier)
1✔
211
                        )
1✔
212
                    )
1✔
213
                    .WithArgumentList
1✔
214
                    (
1✔
215
                        ArgumentList(arguments.ToSyntaxList())
1✔
216
                    )
1✔
217
                )
1✔
218
            );
1✔
219

220
            TypeSyntax GetTupleForCtor(ConstructorDeclarationSyntax ctor)
221
            {
1✔
222
                TypeSyntax generic = ResolveType
1✔
223
                (
1✔
224
                    MetadataTypeInfo.CreateFrom
1✔
225
                    (
1✔
226
                        typeof(Tuple)
1✔
227
                            .Assembly
1✔
228
                            .GetType($"System.Tuple`{ctor.ParameterList.Parameters.Count}", throwOnError: true)
1✔
229
                    )
1✔
230
                );
1✔
231

232
                //
233
                // Hacky specialization
234
                //
235

236
                int arity = 0;
1✔
237

238
                SyntaxNode gn = generic
1✔
239
                    .ChildNodes()
1✔
240
                    .Single(static node => node is GenericNameSyntax)!;
1✔
241

242
                return generic.ReplaceNodes
1✔
243
                (
1✔
244
                    gn.DescendantNodes().OfType<TypeSyntax>(),
1✔
245
                    (_, _) => ctor.ParameterList.Parameters[arity++].Type!
1✔
246
                );
1✔
247
            }
1✔
248
        }
1✔
249
    }
250
}
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