Hiya :)
Thanks for the reply, yes I did some reading and ended up finding that some 
methods are called with callvirt, or ldftn/ldvirtftn in some cases. I also 
ran in to a case where a usage was in a nested type, and my original code 
wasn't searching through the nesting.
Problem solved.

I'm trying to apply the same logic to find fields which are only written to 
and never read. I'm whitelisting fields by finding all reads, assuming that 
Ldfld, Ldflda, Ldsfld and Ldsflda are the only Opcodes I should expect for 
reading.

private static IEnumerable<FieldReference> 
GetFieldReadsInProperties(IEnumerable<PropertyDefinition> properties)
{
    var getMethods = properties.Select(p => p.GetMethod).Where(m => m != 
null);
    var setMethods = properties.Select(p => p.SetMethod).Where(m => m != 
null);

    var allMethods = getMethods.Concat(setMethods).Where(m => m.HasBody);
            
    return allMethods
        .SelectMany(m => m.Body.Instructions)
        .Where(i => ReadOpCodes.Any(o => i.OpCode == o))
        .Select(f => f.Operand as FieldReference)
        .DistinctBy(f => f.FullName);
}

private static IEnumerable<FieldReference> 
GetFieldReadsInMethods(IEnumerable<MethodDefinition> methods)
{
    return methods.Where(m => m.HasBody)
        .SelectMany(m => m.Body.Instructions)
        .Where(i => ReadOpCodes.Any(o => i.OpCode == o))
        .Select(f => f.Operand as FieldReference)
        .DistinctBy(f => f.FullName);
}

private static OpCode[] ReadOpCodes = new[] { OpCodes.Ldfld, 
OpCodes.Ldflda, OpCodes.Ldsfld, OpCodes.Ldsflda };

This seems to be ok, but it trips up with enum fields, again with a vague 
error :D

System.ArgumentException
  HResult=0x80070057
  Message=Value does not fall within the expected range.
  Source=Mono.Cecil
  StackTrace:
   at Mono.Cecil.Mixin.GetEnumUnderlyingType(TypeDefinition self) in 
<redacted>\cecil-master\Mono.Cecil\TypeDefinition.cs:line 600
   at Mono.Cecil.MetadataBuilder.GetConstantType(TypeReference 
constant_type, Object constant) in 
<redacted>\cecil-master\Mono.Cecil\AssemblyWriter.cs:line 1882
   at Mono.Cecil.MetadataBuilder.AddConstant(IConstantProvider owner, 
TypeReference type) in 
<redacted>\cecil-master\Mono.Cecil\AssemblyWriter.cs:line 1864
   at Mono.Cecil.MetadataBuilder.AddField(FieldDefinition field) in 
<redacted>\cecil-master\Mono.Cecil\AssemblyWriter.cs:line 1624
   at Mono.Cecil.MetadataBuilder.AddFields(TypeDefinition type) in 
<redacted>\cecil-master\Mono.Cecil\AssemblyWriter.cs:line 1602
   at Mono.Cecil.MetadataBuilder.AddType(TypeDefinition type) in 
<redacted>\cecil-master\Mono.Cecil\AssemblyWriter.cs:line 1437
   at Mono.Cecil.MetadataBuilder.AddNestedTypes(TypeDefinition type) in 
<redacted>\cecil-master\Mono.Cecil\AssemblyWriter.cs:line 1592
   at Mono.Cecil.MetadataBuilder.AddType(TypeDefinition type) in 
<redacted>\cecil-master\Mono.Cecil\AssemblyWriter.cs:line 1455
   at Mono.Cecil.MetadataBuilder.AddTypes() in 
<redacted>\cecil-master\Mono.Cecil\AssemblyWriter.cs:line 1413
   at Mono.Cecil.MetadataBuilder.BuildTypes() in 
<redacted>\cecil-master\Mono.Cecil\AssemblyWriter.cs:line 1266
   at Mono.Cecil.MetadataBuilder.BuildModule() in 
<redacted>\cecil-master\Mono.Cecil\AssemblyWriter.cs:line 1036
   at Mono.Cecil.MetadataBuilder.BuildMetadata() in 
<redacted>\cecil-master\Mono.Cecil\AssemblyWriter.cs:line 1006
   at Mono.Cecil.ModuleWriter.<>c.<BuildMetadata>b__2_0(MetadataBuilder 
builder, MetadataReader _) in 
<redacted>\cecil-master\Mono.Cecil\AssemblyWriter.cs:line 144
   at Mono.Cecil.ModuleDefinition.Read[TItem,TRet](TItem item, Func`3 read) 
in <redacted>\cecil-master\Mono.Cecil\ModuleDefinition.cs:line 950
   at Mono.Cecil.ModuleWriter.BuildMetadata(ModuleDefinition module, 
MetadataBuilder metadata) in 
<redacted>\cecil-master\Mono.Cecil\AssemblyWriter.cs:line 143
   at Mono.Cecil.ModuleWriter.Write(ModuleDefinition module, Disposable`1 
stream, WriterParameters parameters) in 
<redacted>\cecil-master\Mono.Cecil\AssemblyWriter.cs:line 119
   at Mono.Cecil.ModuleWriter.WriteModule(ModuleDefinition module, 
Disposable`1 stream, WriterParameters parameters) in 
<redacted>\cecil-master\Mono.Cecil\AssemblyWriter.cs:line 78
   at Mono.Cecil.ModuleDefinition.Write(String fileName, WriterParameters 
parameters) in <redacted>\cecil-master\Mono.Cecil\ModuleDefinition.cs:line 
1139
   at Mono.Cecil.AssemblyDefinition.Write(String fileName, WriterParameters 
parameters) in 
<redacted>\cecil-master\Mono.Cecil\AssemblyDefinition.cs:line 161
   at Mono.Cecil.AssemblyDefinition.Write(String fileName) in 
<redacted>\cecil-master\Mono.Cecil\AssemblyDefinition.cs:line 156
   at <redacted>(String[] args) in <redacted>

Guess I need to do some more reading :D


On Tuesday, 14 April 2020 17:44:42 UTC+1, Jb Evain wrote:
>
> Hey Rick,
>
> Yes, it seems you missed some usages :)
>
> In the IL, the method call be called using callvirt for instance, or 
> referenced by a ldtoken.
>
> Unfortunately the error is not very explicit, but you're completely right, 
> you don't need to import a reference here. It just means that Cecil is 
> seeing a reference to a stray method that is without a module.
>
> Jb
>

-- 
-- 
--
mono-cecil
--- 
You received this message because you are subscribed to the Google Groups 
"mono-cecil" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/mono-cecil/5a43d2b0-918d-4249-beff-e667bc80026d%40googlegroups.com.

Reply via email to