Let's say we have some class someone ends up consuming:
public class SampleClass
{
[Obsolete("This property was slain in Moria", false)]
public double SampleProperty { get; set; }
[Obsolete("This method was slain in Moria", false)]
public static void SampleMethod()
{
}
}
And then let's say someone consumes it:
public static double SampleConsumer()
{
SampleClass.SampleMethod();
var classy = new SampleClass();
return classy.SampleProperty;
}
I am trying to determine all references to obsolete methods and properties within SampleConsumer
.
I have figured out how to get the methods, thanks to Kris's response to this question. In summary, that looks like:
public static void GetMethodReferences(MethodDefinition method)
{
foreach (var instruction in method.Body.Instructions)
{
if (instruction.OpCode == OpCodes.Call)
{
MethodReference methodCall = instruction.Operand as MethodReference;
// ...
wherein methodCall.CustomAttributes
would contain the obsolete attribute we wish to detect.
I am trying to accomplish something similar for property references.
What I have tried so far:
Note that in CIL, the classy.SampleProperty
is represented by a callvirt
instruction:
System.Double FoobarNamespace.SampleClass::get_SampleProperty()
I tried including the OpCodes.Callvirt
in GetMethodReferences
, but the only attribute that the virtual get
method seems to have is a CompilerGeneratedAttribute
(no obsolete attribute).
Next I decided to peek inside of the virtual get
method. Iterating on the virtual method's instructions, notice there is a ldfld
(load field) instruction:
System.Double FoobarNamespace.SampleClass::<SampleProperty>k__BackingField
I try to check it for the obsolete attributes:
// for each instruction in the virtual get_SampeProperty()
if (instruction.OpCode == OpCodes.Ldfld)
{
var fieldDefinition = instruction.Operand as MethodDefinition;
// check fieldDefinition.Attributes
// check fieldDefinition.CustomAttributes
// but neither of them have the Obsolete attribute
// ...
I think what I actually need to do is get either a PropertyDefinition
or PropertyReference
for SampleProperty
, but I can't seem to figure out how to do that in the context of the consumer method.
Ideas?