/
IMethodSymbol.cs
297 lines (252 loc) · 13 KB
/
IMethodSymbol.cs
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
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Immutable;
using System.Reflection;
using System.Reflection.Metadata;
namespace Microsoft.CodeAnalysis
{
/// <summary>
/// Represents a method or method-like symbol (including constructor,
/// destructor, operator, or property/event accessor).
/// </summary>
/// <remarks>
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
/// </remarks>
public interface IMethodSymbol : ISymbol
{
/// <summary>
/// Gets what kind of method this is. There are several different kinds of things in the
/// C# language that are represented as methods. This property allow distinguishing those things
/// without having to decode the name of the method.
/// </summary>
MethodKind MethodKind { get; }
/// <summary>
/// Returns the arity of this method, or the number of type parameters it takes.
/// A non-generic method has zero arity.
/// </summary>
int Arity { get; }
/// <summary>
/// Returns whether this method is generic; i.e., does it have any type parameters?
/// </summary>
bool IsGenericMethod { get; }
/// <summary>
/// Returns true if this method is an extension method.
/// </summary>
bool IsExtensionMethod { get; }
/// <summary>
/// Returns true if this method is an async method
/// </summary>
bool IsAsync { get; }
/// <summary>
/// Returns whether this method is using CLI VARARG calling convention. This is used for
/// C-style variable argument lists. This is used extremely rarely in C# code and is
/// represented using the undocumented "__arglist" keyword.
///
/// Note that methods with "params" on the last parameter are indicated with the "IsParams"
/// property on ParameterSymbol, and are not represented with this property.
/// </summary>
bool IsVararg { get; }
/// <summary>
/// Returns whether this built-in operator checks for integer overflow.
/// </summary>
bool IsCheckedBuiltin { get; }
/// <summary>
/// Returns true if this method hides base methods by name. This cannot be specified directly
/// in the C# language, but can be true for methods defined in other languages imported from
/// metadata. The equivalent of the "hidebyname" flag in metadata.
/// </summary>
bool HidesBaseMethodsByName { get; }
/// <summary>
/// Returns true if this method has no return type; i.e., returns "void".
/// </summary>
bool ReturnsVoid { get; }
/// <summary>
/// Returns true if this method returns by reference.
/// </summary>
bool ReturnsByRef { get; }
/// <summary>
/// Returns true if this method returns by ref readonly.
/// </summary>
bool ReturnsByRefReadonly { get; }
/// <summary>
/// Returns the RefKind of the method.
/// </summary>
RefKind RefKind { get; }
/// <summary>
/// Gets the return type of the method.
/// </summary>
ITypeSymbol ReturnType { get; }
/// <summary>
/// Gets the top-level nullability of the return type of the method.
/// </summary>
NullableAnnotation ReturnNullableAnnotation { get; }
/// <summary>
/// Returns the type arguments that have been substituted for the type parameters.
/// If nothing has been substituted for a given type parameter,
/// then the type parameter itself is consider the type argument.
/// </summary>
ImmutableArray<ITypeSymbol> TypeArguments { get; }
/// <summary>
/// Returns the top-level nullability of the type arguments that have been substituted
/// for the type parameters. If nothing has been substituted for a given type parameter,
/// then <see cref="NullableAnnotation.None"/> is returned.
/// </summary>
ImmutableArray<NullableAnnotation> TypeArgumentNullableAnnotations { get; }
/// <summary>
/// Get the type parameters on this method. If the method has not generic,
/// returns an empty list.
/// </summary>
ImmutableArray<ITypeParameterSymbol> TypeParameters { get; }
/// <summary>
/// Gets the parameters of this method. If this method has no parameters, returns
/// an empty list.
/// </summary>
ImmutableArray<IParameterSymbol> Parameters { get; }
/// <summary>
/// Returns the method symbol that this method was constructed from. The resulting
/// method symbol
/// has the same containing type (if any), but has type arguments that are the same
/// as the type parameters (although its containing type might not).
/// </summary>
IMethodSymbol ConstructedFrom { get; }
/// <summary>
/// Indicates whether the method is readonly,
/// i.e. whether the 'this' receiver parameter is 'ref readonly'.
/// Returns true for readonly instance methods and accessors
/// and for reduced extension methods with a 'this in' parameter.
/// </summary>
bool IsReadOnly { get; }
/// <summary>
/// Returns true for 'init' set accessors, and false otherwise.
/// </summary>
bool IsInitOnly { get; }
/// <summary>
/// Get the original definition of this symbol. If this symbol is derived from another
/// symbol by (say) type substitution, this gets the original symbol, as it was defined in
/// source or metadata.
/// </summary>
new IMethodSymbol OriginalDefinition { get; }
/// <summary>
/// If this method overrides another method (because it both had the override modifier
/// and there correctly was a method to override), returns the overridden method.
/// </summary>
IMethodSymbol? OverriddenMethod { get; }
/// <summary>
/// If this method can be applied to an object, returns the type of object it is applied to.
/// </summary>
ITypeSymbol? ReceiverType { get; }
/// <summary>
/// If this method can be applied to an object, returns the top-level nullability of the object it is applied to.
/// </summary>
NullableAnnotation ReceiverNullableAnnotation { get; }
/// <summary>
/// If this method is a reduced extension method, returns the definition of extension
/// method from which this was reduced. Otherwise, returns null.
/// </summary>
IMethodSymbol? ReducedFrom { get; }
/// <summary>
/// If this method is a reduced extension method, returns a type inferred during reduction process for the type parameter.
/// </summary>
/// <param name="reducedFromTypeParameter">Type parameter of the corresponding <see cref="ReducedFrom"/> method.</param>
/// <returns>Inferred type or Nothing if nothing was inferred.</returns>
/// <exception cref="System.InvalidOperationException">If this is not a reduced extension method.</exception>
/// <exception cref="System.ArgumentNullException">If <paramref name="reducedFromTypeParameter"/> is null.</exception>
/// <exception cref="System.ArgumentException">If <paramref name="reducedFromTypeParameter"/> doesn't belong to the corresponding <see cref="ReducedFrom"/> method.</exception>
ITypeSymbol? GetTypeInferredDuringReduction(ITypeParameterSymbol reducedFromTypeParameter);
/// <summary>
/// If this is an extension method that can be applied to a receiver of the given type,
/// returns a reduced extension method symbol thus formed. Otherwise, returns null.
/// </summary>
IMethodSymbol? ReduceExtensionMethod(ITypeSymbol receiverType);
/// <summary>
/// Returns interface methods explicitly implemented by this method.
/// </summary>
/// <remarks>
/// Methods imported from metadata can explicitly implement more than one method,
/// that is why return type is ImmutableArray.
/// </remarks>
ImmutableArray<IMethodSymbol> ExplicitInterfaceImplementations { get; }
/// <summary>
/// Returns the list of custom modifiers, if any, associated with the return type.
/// </summary>
ImmutableArray<CustomModifier> ReturnTypeCustomModifiers { get; }
/// <summary>
/// Custom modifiers associated with the ref modifier, or an empty array if there are none.
/// </summary>
ImmutableArray<CustomModifier> RefCustomModifiers { get; }
/// <summary>
/// Returns the list of custom attributes, if any, associated with the returned value.
/// </summary>
ImmutableArray<AttributeData> GetReturnTypeAttributes();
/// <summary>
/// The calling convention enum of the method symbol.
/// </summary>
SignatureCallingConvention CallingConvention { get; }
/// <summary>
/// Modifier types that are considered part of the calling convention of this method, if the <see cref="MethodKind"/> is <see cref="MethodKind.FunctionPointerSignature"/>
/// and the <see cref="CallingConvention"/> is <see cref="SignatureCallingConvention.Unmanaged"/>. If this is not a function pointer signature or the calling convention is
/// not unmanaged, this is an empty array. Order and duplication of these modifiers reflect source/metadata order and duplication, whichever this symbol came from.
/// </summary>
ImmutableArray<INamedTypeSymbol> UnmanagedCallingConventionTypes { get; }
/// <summary>
/// Returns a symbol (e.g. property, event, etc.) associated with the method.
/// </summary>
/// <remarks>
/// If this method has <see cref="MethodKind"/> of <see cref="MethodKind.PropertyGet"/> or <see cref="MethodKind.PropertySet"/>,
/// returns the property that this method is the getter or setter for.
/// If this method has <see cref="MethodKind"/> of <see cref="MethodKind.EventAdd"/> or <see cref="MethodKind.EventRemove"/>,
/// returns the event that this method is the adder or remover for.
/// Note, the set of possible associated symbols might be expanded in the future to
/// reflect changes in the languages.
/// </remarks>
ISymbol? AssociatedSymbol { get; }
/// <summary>
/// Returns a constructed method given its type arguments.
/// </summary>
/// <param name="typeArguments">The immediate type arguments to be replaced for type
/// parameters in the method.</param>
IMethodSymbol Construct(params ITypeSymbol[] typeArguments);
/// <summary>
/// Returns a constructed method given its type arguments and type argument nullable annotations.
/// </summary>
IMethodSymbol Construct(ImmutableArray<ITypeSymbol> typeArguments, ImmutableArray<NullableAnnotation> typeArgumentNullableAnnotations);
/// <summary>
/// If this is a partial method implementation part, returns the corresponding
/// definition part. Otherwise null.
/// </summary>
IMethodSymbol? PartialDefinitionPart { get; }
/// <summary>
/// If this is a partial method declaration without a body, and the method is
/// implemented with a body, returns that implementing definition. Otherwise
/// null.
/// </summary>
IMethodSymbol? PartialImplementationPart { get; }
/// <summary>
/// Returns the implementation flags for the given method symbol.
/// </summary>
MethodImplAttributes MethodImplementationFlags { get; }
/// <summary>
/// Return true if this is a partial method definition without a body. If there
/// is an implementing body, it can be retrieved with <see cref="PartialImplementationPart"/>.
/// </summary>
bool IsPartialDefinition { get; }
/// <summary>
/// Platform invoke information, or null if the method isn't a P/Invoke.
/// </summary>
DllImportData? GetDllImportData();
/// <summary>
/// If this method is a Lambda method (MethodKind = MethodKind.LambdaMethod) and
/// there is an anonymous delegate associated with it, returns this delegate.
///
/// Returns null if the symbol is not a lambda or if it does not have an
/// anonymous delegate associated with it.
/// </summary>
INamedTypeSymbol? AssociatedAnonymousDelegate { get; }
/// <summary>
/// Returns a flag indicating whether this symbol has at least one applied/inherited conditional attribute.
/// </summary>
bool IsConditional { get; }
}
}