Sandbox error reference locator now works with generic method calls

This means resolving the MethodSpec table entry for it.
This commit is contained in:
Pieter-Jan Briers
2024-11-22 18:06:33 +01:00
parent 5f3a54376d
commit 3086fc446c
2 changed files with 19 additions and 2 deletions

View File

@@ -47,7 +47,7 @@ END TEMPLATE-->
### Other
*None yet*
* Sandbox error reference locator now works with generic method calls.
### Internal

View File

@@ -39,7 +39,7 @@ internal sealed partial class AssemblyTypeChecker
{
if (instruction.TryGetEntityHandle(out var handle))
{
if (refs.Contains(handle))
if (refs.Overlaps(ExpandHandle(reader, handle)))
{
var type = GetTypeFromDefinition(reader, methodDef.GetDeclaringType());
_sawmill.Error(
@@ -56,6 +56,12 @@ internal sealed partial class AssemblyTypeChecker
{
switch (handle.Kind)
{
case HandleKind.MethodSpecification:
var methodSpec = reader.GetMethodSpecification((MethodSpecificationHandle)handle);
var methodProvider = new TypeProvider();
var spec = methodSpec.DecodeSignature(methodProvider, 0);
return $"{DisplayHandle(reader, methodSpec.Method)}<{string.Join(", ", spec.Select(t => t.ToString()))}>";
case HandleKind.MemberReference:
var memberRef = reader.GetMemberReference((MemberReferenceHandle)handle);
var name = reader.GetString(memberRef.Name);
@@ -92,6 +98,17 @@ internal sealed partial class AssemblyTypeChecker
handles.UnionWith(toAdd);
}
private static IEnumerable<EntityHandle> ExpandHandle(MetadataReader reader, EntityHandle handle)
{
// Annoying, S.R.M gives no way to iterate over the MethodSpec table.
// This means the only way to correlate MethodSpec references is to do it for each handle.
yield return handle;
if (handle.Kind == HandleKind.MethodSpecification)
yield return reader.GetMethodSpecification((MethodSpecificationHandle)handle).Method;
}
private readonly struct ILInstruction
{
public readonly ILOpCode OpCode;