forked from github/codeql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMemberReferenceMethod.cs
More file actions
95 lines (71 loc) · 3.37 KB
/
Copy pathMemberReferenceMethod.cs
File metadata and controls
95 lines (71 loc) · 3.37 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
using System.Reflection.Metadata;
using System.Collections.Generic;
using System.Linq;
namespace Semmle.Extraction.CIL.Entities
{
/// <summary>
/// This is a late-bound reference to a method.
/// </summary>
internal sealed class MemberReferenceMethod : Method
{
private readonly MemberReferenceHandle handle;
private readonly MemberReference mr;
private readonly Type declaringType;
private readonly IGenericContext parent;
private readonly Method? sourceDeclaration;
public MemberReferenceMethod(IGenericContext gc, MemberReferenceHandle handle) : base(gc)
{
this.handle = handle;
this.gc = gc;
mr = Context.MdReader.GetMemberReference(handle);
signature = mr.DecodeMethodSignature(new SignatureDecoder(), gc);
parent = (IGenericContext)Context.CreateGeneric(gc, mr.Parent);
var declType = parent is Method parentMethod
? parentMethod.DeclaringType
: parent as Type;
if (declType is null)
throw new InternalError("Parent context of method is not a type");
declaringType = declType;
nameLabel = Context.GetString(mr.Name);
var typeSourceDeclaration = declaringType.SourceDeclaration;
sourceDeclaration = typeSourceDeclaration == declaringType ? (Method)this : typeSourceDeclaration.LookupMethod(mr.Name, mr.Signature);
}
private readonly string nameLabel;
public override string NameLabel => nameLabel;
public override bool Equals(object? obj)
{
return obj is MemberReferenceMethod method && handle.Equals(method.handle);
}
public override int GetHashCode()
{
return handle.GetHashCode();
}
public override Method? SourceDeclaration => sourceDeclaration;
public override bool IsStatic => !signature.Header.IsInstance;
public override Type DeclaringType => declaringType;
public override string Name => Context.ShortName(mr.Name);
public override IEnumerable<Type> TypeParameters => parent.TypeParameters.Concat(gc.TypeParameters);
public override IEnumerable<IExtractionProduct> Contents
{
get
{
genericParams = new MethodTypeParameter[signature.GenericParameterCount];
for (var p = 0; p < genericParams.Length; ++p)
genericParams[p] = Context.Populate(new MethodTypeParameter(this, this, p));
foreach (var p in genericParams)
yield return p;
var typeSignature = mr.DecodeMethodSignature(Context.TypeSignatureDecoder, this);
var parameters = GetParameterExtractionProducts(typeSignature.ParameterTypes).ToArray();
Parameters = parameters.OfType<Parameter>().ToArray();
foreach (var p in parameters) yield return p;
foreach (var f in PopulateFlags) yield return f;
foreach (var m in GetMethodExtractionProducts(Name, DeclaringType, typeSignature.ReturnType))
{
yield return m;
}
if (SourceDeclaration is not null)
yield return Tuples.cil_method_source_declaration(this, SourceDeclaration);
}
}
}
}