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.