-
Notifications
You must be signed in to change notification settings - Fork 275
Expand file tree
/
Copy pathTrimmingAttributes.cs
More file actions
423 lines (381 loc) · 17.4 KB
/
TrimmingAttributes.cs
File metadata and controls
423 lines (381 loc) · 17.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
// This collection of attribute definitions are helpers for accessing trim-related attributes in
// projects targeting .NET 6 or lower. Since the trimmer queries for these attributes by name, having
// these attributes source included is sufficient for the trimmer to recognize them. For more information
// on this approach, see https://devblogs.microsoft.com/dotnet/creating-aot-compatible-libraries/#approach-2-define-the-attributes-internally.
namespace System.Diagnostics.CodeAnalysis
{
#if !NET7_0_OR_GREATER
/// <summary>
/// Indicates that the specified method requires the ability to generate new code at runtime,
/// for example through <see cref="System.Reflection"/>.
/// </summary>
/// <remarks>
/// This allows tools to understand which methods are unsafe to call when compiling ahead of time.
/// </remarks>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class, Inherited = false)]
internal sealed class RequiresDynamicCodeAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="RequiresDynamicCodeAttribute"/> class
/// with the specified message.
/// </summary>
/// <param name="message">
/// A message that contains information about the usage of dynamic code.
/// </param>
public RequiresDynamicCodeAttribute(string message)
{
Message = message;
}
/// <summary>
/// Gets a message that contains information about the usage of dynamic code.
/// </summary>
public string Message { get; }
/// <summary>
/// Gets or sets an optional URL that contains more information about the method,
/// why it requires dynamic code, and what options a consumer has to deal with it.
/// </summary>
public string? Url { get; set; }
}
#endif
#if !NET5_0_OR_GREATER
/// <summary>
/// Indicates that the specified method requires dynamic access to code that is not referenced
/// statically, for example through <see cref="System.Reflection"/>.
/// </summary>
/// <remarks>
/// This allows tools to understand which methods are unsafe to call when removing unreferenced
/// code from an application.
/// </remarks>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class, Inherited = false)]
internal sealed class RequiresUnreferencedCodeAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="RequiresUnreferencedCodeAttribute"/> class
/// with the specified message.
/// </summary>
/// <param name="message">
/// A message that contains information about the usage of unreferenced code.
/// </param>
public RequiresUnreferencedCodeAttribute(string message)
{
Message = message;
}
/// <summary>
/// Gets a message that contains information about the usage of unreferenced code.
/// </summary>
public string Message { get; }
/// <summary>
/// Gets or sets an optional URL that contains more information about the method,
/// why it requires unreferenced code, and what options a consumer has to deal with it.
/// </summary>
public string? Url { get; set; }
}
/// <summary>
/// Suppresses reporting of a specific rule violation, allowing multiple suppressions on a
/// single code artifact.
/// </summary>
/// <remarks>
/// <see cref="UnconditionalSuppressMessageAttribute"/> is different than
/// <see cref="SuppressMessageAttribute"/> in that it doesn't have a
/// <see cref="ConditionalAttribute"/>. So it is always preserved in the compiled assembly.
/// </remarks>
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
internal sealed class UnconditionalSuppressMessageAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="UnconditionalSuppressMessageAttribute"/>
/// class, specifying the category of the tool and the identifier for an analysis rule.
/// </summary>
/// <param name="category">The category for the attribute.</param>
/// <param name="checkId">The identifier of the analysis rule the attribute applies to.</param>
public UnconditionalSuppressMessageAttribute(string category, string checkId)
{
Category = category;
CheckId = checkId;
}
/// <summary>
/// Gets the category identifying the classification of the attribute.
/// </summary>
/// <remarks>
/// The <see cref="Category"/> property describes the tool or tool analysis category
/// for which a message suppression attribute applies.
/// </remarks>
public string Category { get; }
/// <summary>
/// Gets the identifier of the analysis tool rule to be suppressed.
/// </summary>
/// <remarks>
/// Concatenated together, the <see cref="Category"/> and <see cref="CheckId"/>
/// properties form a unique check identifier.
/// </remarks>
public string CheckId { get; }
/// <summary>
/// Gets or sets the scope of the code that is relevant for the attribute.
/// </summary>
/// <remarks>
/// The Scope property is an optional argument that specifies the metadata scope for which
/// the attribute is relevant.
/// </remarks>
public string? Scope { get; set; }
/// <summary>
/// Gets or sets a fully qualified path that represents the target of the attribute.
/// </summary>
/// <remarks>
/// The <see cref="Target"/> property is an optional argument identifying the analysis target
/// of the attribute. An example value is "System.IO.Stream.ctor():System.Void".
/// Because it is fully qualified, it can be long, particularly for targets such as parameters.
/// The analysis tool user interface should be capable of automatically formatting the parameter.
/// </remarks>
public string? Target { get; set; }
/// <summary>
/// Gets or sets an optional argument expanding on exclusion criteria.
/// </summary>
/// <remarks>
/// The <see cref="MessageId "/> property is an optional argument that specifies additional
/// exclusion where the literal metadata target is not sufficiently precise. For example,
/// the <see cref="UnconditionalSuppressMessageAttribute"/> cannot be applied within a method,
/// and it may be desirable to suppress a violation against a statement in the method that will
/// give a rule violation, but not against all statements in the method.
/// </remarks>
public string? MessageId { get; set; }
/// <summary>
/// Gets or sets the justification for suppressing the code analysis message.
/// </summary>
public string? Justification { get; set; }
}
/// <summary>
/// States a dependency that one member has on another.
/// </summary>
/// <remarks>
/// This can be used to inform tooling of a dependency that is otherwise not evident purely from
/// metadata and IL, for example a member relied on via reflection.
/// </remarks>
[AttributeUsage(
AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method,
AllowMultiple = true, Inherited = false)]
internal sealed class DynamicDependencyAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="DynamicDependencyAttribute"/> class
/// with the specified signature of a member on the same type as the consumer.
/// </summary>
/// <param name="memberSignature">The signature of the member depended on.</param>
public DynamicDependencyAttribute(string memberSignature)
{
MemberSignature = memberSignature;
}
/// <summary>
/// Initializes a new instance of the <see cref="DynamicDependencyAttribute"/> class
/// with the specified signature of a member on a <see cref="System.Type"/>.
/// </summary>
/// <param name="memberSignature">The signature of the member depended on.</param>
/// <param name="type">The <see cref="System.Type"/> containing <paramref name="memberSignature"/>.</param>
public DynamicDependencyAttribute(string memberSignature, Type type)
{
MemberSignature = memberSignature;
Type = type;
}
/// <summary>
/// Initializes a new instance of the <see cref="DynamicDependencyAttribute"/> class
/// with the specified signature of a member on a type in an assembly.
/// </summary>
/// <param name="memberSignature">The signature of the member depended on.</param>
/// <param name="typeName">The full name of the type containing the specified member.</param>
/// <param name="assemblyName">The assembly name of the type containing the specified member.</param>
public DynamicDependencyAttribute(string memberSignature, string typeName, string assemblyName)
{
MemberSignature = memberSignature;
TypeName = typeName;
AssemblyName = assemblyName;
}
/// <summary>
/// Initializes a new instance of the <see cref="DynamicDependencyAttribute"/> class
/// with the specified types of members on a <see cref="System.Type"/>.
/// </summary>
/// <param name="memberTypes">The types of members depended on.</param>
/// <param name="type">The <see cref="System.Type"/> containing the specified members.</param>
public DynamicDependencyAttribute(DynamicallyAccessedMemberTypes memberTypes, Type type)
{
MemberTypes = memberTypes;
Type = type;
}
/// <summary>
/// Initializes a new instance of the <see cref="DynamicDependencyAttribute"/> class
/// with the specified types of members on a type in an assembly.
/// </summary>
/// <param name="memberTypes">The types of members depended on.</param>
/// <param name="typeName">The full name of the type containing the specified members.</param>
/// <param name="assemblyName">The assembly name of the type containing the specified members.</param>
public DynamicDependencyAttribute(DynamicallyAccessedMemberTypes memberTypes, string typeName, string assemblyName)
{
MemberTypes = memberTypes;
TypeName = typeName;
AssemblyName = assemblyName;
}
/// <summary>
/// Gets the signature of the member depended on.
/// </summary>
/// <remarks>
/// Either <see cref="MemberSignature"/> must be a valid string or <see cref="MemberTypes"/>
/// must not equal <see cref="DynamicallyAccessedMemberTypes.None"/>, but not both.
/// </remarks>
public string? MemberSignature { get; }
/// <summary>
/// Gets the <see cref="DynamicallyAccessedMemberTypes"/> which specifies the type
/// of members depended on.
/// </summary>
/// <remarks>
/// Either <see cref="MemberSignature"/> must be a valid string or <see cref="MemberTypes"/>
/// must not equal <see cref="DynamicallyAccessedMemberTypes.None"/>, but not both.
/// </remarks>
public DynamicallyAccessedMemberTypes MemberTypes { get; }
/// <summary>
/// Gets the <see cref="System.Type"/> containing the specified member.
/// </summary>
/// <remarks>
/// If neither <see cref="Type"/> nor <see cref="TypeName"/> are specified,
/// the type of the consumer is assumed.
/// </remarks>
public Type? Type { get; }
/// <summary>
/// Gets the full name of the type containing the specified member.
/// </summary>
/// <remarks>
/// If neither <see cref="Type"/> nor <see cref="TypeName"/> are specified,
/// the type of the consumer is assumed.
/// </remarks>
public string? TypeName { get; }
/// <summary>
/// Gets the assembly name of the specified type.
/// </summary>
/// <remarks>
/// <see cref="AssemblyName"/> is only valid when <see cref="TypeName"/> is specified.
/// </remarks>
public string? AssemblyName { get; }
/// <summary>
/// Gets or sets the condition in which the dependency is applicable, e.g. "DEBUG".
/// </summary>
public string? Condition { get; set; }
}
/// <summary>
/// Indicates that certain members on a specified <see cref="Type"/> are accessed dynamically,
/// for example through <see cref="System.Reflection"/>.
/// </summary>
/// <remarks>
/// This allows tools to understand which members are being accessed during the execution
/// of a program.
///
/// This attribute is valid on members whose type is <see cref="Type"/> or <see cref="string"/>.
///
/// When this attribute is applied to a location of type <see cref="string"/>, the assumption is
/// that the string represents a fully qualified type name.
///
/// When this attribute is applied to a class, interface, or struct, the members specified
/// can be accessed dynamically on <see cref="Type"/> instances returned from calling
/// <see cref="object.GetType"/> on instances of that class, interface, or struct.
///
/// If the attribute is applied to a method it's treated as a special case and it implies
/// the attribute should be applied to the "this" parameter of the method. As such the attribute
/// should only be used on instance methods of types assignable to System.Type (or string, but no methods
/// will use it there).
/// </remarks>
[AttributeUsage(
AttributeTargets.Field | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter |
AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method |
AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct,
Inherited = false)]
internal sealed class DynamicallyAccessedMembersAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="DynamicallyAccessedMembersAttribute"/> class
/// with the specified member types.
/// </summary>
/// <param name="memberTypes">The types of members dynamically accessed.</param>
public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes)
{
MemberTypes = memberTypes;
}
/// <summary>
/// Gets the <see cref="DynamicallyAccessedMemberTypes"/> which specifies the type
/// of members dynamically accessed.
/// </summary>
public DynamicallyAccessedMemberTypes MemberTypes { get; }
}
/// <summary>
/// Specifies the types of members that are dynamically accessed.
///
/// This enumeration has a <see cref="FlagsAttribute"/> attribute that allows a
/// bitwise combination of its member values.
/// </summary>
[Flags]
internal enum DynamicallyAccessedMemberTypes
{
/// <summary>
/// Specifies no members.
/// </summary>
None = 0,
/// <summary>
/// Specifies the default, parameterless public constructor.
/// </summary>
PublicParameterlessConstructor = 0x0001,
/// <summary>
/// Specifies all public constructors.
/// </summary>
PublicConstructors = 0x0002 | PublicParameterlessConstructor,
/// <summary>
/// Specifies all non-public constructors.
/// </summary>
NonPublicConstructors = 0x0004,
/// <summary>
/// Specifies all public methods.
/// </summary>
PublicMethods = 0x0008,
/// <summary>
/// Specifies all non-public methods.
/// </summary>
NonPublicMethods = 0x0010,
/// <summary>
/// Specifies all public fields.
/// </summary>
PublicFields = 0x0020,
/// <summary>
/// Specifies all non-public fields.
/// </summary>
NonPublicFields = 0x0040,
/// <summary>
/// Specifies all public nested types.
/// </summary>
PublicNestedTypes = 0x0080,
/// <summary>
/// Specifies all non-public nested types.
/// </summary>
NonPublicNestedTypes = 0x0100,
/// <summary>
/// Specifies all public properties.
/// </summary>
PublicProperties = 0x0200,
/// <summary>
/// Specifies all non-public properties.
/// </summary>
NonPublicProperties = 0x0400,
/// <summary>
/// Specifies all public events.
/// </summary>
PublicEvents = 0x0800,
/// <summary>
/// Specifies all non-public events.
/// </summary>
NonPublicEvents = 0x1000,
/// <summary>
/// Specifies all interfaces implemented by the type.
/// </summary>
Interfaces = 0x2000,
/// <summary>
/// Specifies all members.
/// </summary>
All = ~None
}
#endif
}