New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No way to extract CustomAttribute from interfaces in SR.Metadata #30570
Comments
/cc @tmat |
There are two
using var peReader = new PEReader(File.OpenRead(Assembly.GetExecutingAssembly().Location));
var mdReader = peReader.GetMetadataReader();
foreach (var attributeHandle in mdReader.CustomAttributes)
{
var attribute = mdReader.GetCustomAttribute(attributeHandle);
var ctorHandle = attribute.Constructor;
EntityHandle attributeTypeHandle = ctorHandle.Kind switch
{
HandleKind.MethodDefinition => mdReader.GetMethodDefinition((MethodDefinitionHandle)ctorHandle).GetDeclaringType(),
HandleKind.MemberReference => mdReader.GetMemberReference((MemberReferenceHandle)ctorHandle).Parent,
_ => throw new InvalidOperationException(),
};
StringHandle attributeTypeNameHandle = attributeTypeHandle.Kind switch
{
HandleKind.TypeDefinition => mdReader.GetTypeDefinition((TypeDefinitionHandle)attributeTypeHandle).Name,
HandleKind.TypeReference => mdReader.GetTypeReference((TypeReferenceHandle)attributeTypeHandle).Name,
_ => throw new InvalidOperationException(),
};
if (mdReader.StringComparer.Equals(attributeTypeNameHandle, "NullableAttribute"))
{
Console.WriteLine(attribute.Parent.Kind);
}
}
|
That's solely because it's the one matching the .custom implementation above rather than a fixed test.. The point is I'm not getting inside the InterfaceImplementation any attributes coming through with the above sample. |
so I am unable to get the |
See my sample. I don't think it is correct that the first attribute is the one you are looking for. The one applied to a Parameter is applied to the return value of GetEnumerator. From ILSpy decompilation: [return: System.Runtime.CompilerServices.Nullable(new byte[]
{
1,
1,
2
})]
public IEnumerator<IEnumerable<string>> GetEnumerator() From IL:
I can find the one on the InterfaceImplementation, it's just a different attribute application. |
Yes, My original code was Get interface implementations for type DerivedInterface2, Get custom attributes for InterfaceImplementation, InterfaceImplementation CustomAttribute is empty. The I solely did it for @jnm2 suggestion on gitter. |
to be honest @nguerrera I have found this interaction extremely rude. Given that @terrajobst has been attempting to help me with the issue and @jnm2 without much success. |
I apologize that this sounded rude. I am trying to help here too. I didn't have the prior context, and I took time out of my weekend to investigate here with the sample above. |
I'm digging further based on your updated information. |
yeah sorry about that. Just iteration upon iteration so the code has gotten away from my initial problem. So that's my attempt so far, there is a bit of a wrapper around the InterfaceImplementation here So that interface implementation is correctly the IEnumerable<....> but the custom attributes doesn't seem to be producing anything in the interface implementation |
This was my attempt to repro that path: using var peReader = new PEReader(File.OpenRead(Assembly.GetExecutingAssembly().Location));
var mdReader = peReader.GetMetadataReader();
foreach (var typeDefinitionHandle in mdReader.TypeDefinitions)
{
var typeDefinition = mdReader.GetTypeDefinition(typeDefinitionHandle);
foreach (var interfaceImplementationHandle in typeDefinition.GetInterfaceImplementations())
{
var interfaceImplementation = mdReader.GetInterfaceImplementation(interfaceImplementationHandle);
foreach (var attribute in interfaceImplementation.GetCustomAttributes())
{
var typeName = mdReader.GetString(typeDefinition.Name);
Console.WriteLine($"Found attribute on InterfaceImplementation by {typeName}");
}
}
} But it worked for me. Above prints:
I will look at the code links above next. |
I can't spot an obvious issue in the linked code. Are you able to reduce what you are seeing into steps that I can run? I can debug it from there. |
There are two InterfaceImplementations, one of |
Sorry, I missed this before. Are you saying that when you run my code snippets above, you don't get the same results? What is |
sorry, preview6, after upgrading I am now getting more consistent results with what you have above. |
Thanks for your help regardless, I appreciate you helping on your day off |
No problem, glad it worked out. :) |
Hi,
I am making a public api approval tool for my application. I am adding support for C# 8 nullable contexts. I have one issue remaining which seems to be having bugs with SR.Metadata
I have the following class in my test suite:
It generates the following IL for the
NullableAttribute
:I would assume the .custom after the `interfaceimpl would be available in the InterfaceImplementation custom attributes.
However, although I can see the NullableAttribute generated in the MetadataReader main list of CustomAttributes I don't see it associated with the interface.
I made my own test code against the SR.Metadata to find the parent of the attribute (which in my example has row number 1).
The handle returned is a
Parameter
(despite being the valid .custom in the above generated IL), with a row number also of 1.The text was updated successfully, but these errors were encountered: