Browse Source

Add method used by + virtual used by

pull/1030/head
Siegfried Pammer 7 years ago
parent
commit
1e3cfd19f5
  1. 41
      ILSpy/Analyzers/Builtin/MethodUsedByAnalyzer.cs
  2. 55
      ILSpy/Analyzers/Builtin/MethodVirtualUsedByAnalyzer.cs
  3. 3
      ILSpy/ILSpy.csproj

41
ILSpy/Analyzers/Builtin/MethodUsedByAnalyzer.cs

@ -17,39 +17,46 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -17,39 +17,46 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
{
public string Text => "Used By";
public bool Show(IMethod entity) => true;
public bool Show(IMethod entity) => !entity.IsVirtual;
public IEnumerable<IEntity> Analyze(IMethod analyzedMethod, IMethod method, MethodBodyBlock methodBody, AnalyzerContext context)
{
var blob = methodBody.GetILReader();
var baseMethod = InheritanceHelper.GetBaseMember(analyzedMethod);
while (blob.RemainingBytes > 0) {
var opCode = blob.DecodeOpCode();
switch (opCode.GetOperandType()) {
case OperandType.Field:
case OperandType.Method:
case OperandType.Sig:
case OperandType.Tok:
if (opCode != ILOpCode.Call && opCode != ILOpCode.Callvirt) {
ILParser.SkipOperand(ref blob, opCode);
continue;
}
var member = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32());
if (member.IsNil) continue;
if (member.IsNil || !member.Kind.IsMemberKind()) continue;
switch (member.Kind) {
case HandleKind.MethodDefinition:
case HandleKind.MethodSpecification:
case HandleKind.MemberReference:
var m = context.TypeSystem.ResolveAsMember(member)?.MemberDefinition;
if (m.MetadataToken == analyzedMethod.MetadataToken && m.ParentAssembly.PEFile == analyzedMethod.ParentAssembly.PEFile) {
if (m == null) continue;
if (opCode == ILOpCode.Call) {
if (IsSameMember(analyzedMethod, m)) {
yield return method;
yield break;
}
break;
}
break;
default:
ILParser.SkipOperand(ref blob, opCode);
break;
if (opCode == ILOpCode.Callvirt && baseMethod != null) {
if (IsSameMember(baseMethod, m)) {
yield return method;
yield break;
}
}
}
}
static bool IsSameMember(IMember analyzedMethod, IMember m)
{
return m.MetadataToken == analyzedMethod.MetadataToken
&& m.ParentAssembly.PEFile == analyzedMethod.ParentAssembly.PEFile;
}
}
}

55
ILSpy/Analyzers/Builtin/MethodVirtualUsedByAnalyzer.cs

@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.ILSpy.Analyzers.Builtin
{
/// <summary>
/// Shows entities that are used by a method.
/// </summary>
[Export(typeof(IAnalyzer<IMethod>))]
class MethodVirtualUsedByAnalyzer : IMethodBodyAnalyzer<IMethod>
{
public string Text => "Used By";
public bool Show(IMethod entity) => entity.IsVirtual;
public IEnumerable<IEntity> Analyze(IMethod analyzedMethod, IMethod method, MethodBodyBlock methodBody, AnalyzerContext context)
{
var blob = methodBody.GetILReader();
while (blob.RemainingBytes > 0) {
var opCode = blob.DecodeOpCode();
switch (opCode.GetOperandType()) {
case OperandType.Field:
case OperandType.Method:
case OperandType.Sig:
case OperandType.Tok:
var member = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32());
if (member.IsNil) continue;
switch (member.Kind) {
case HandleKind.MethodDefinition:
case HandleKind.MethodSpecification:
case HandleKind.MemberReference:
var m = context.TypeSystem.ResolveAsMember(member)?.MemberDefinition;
if (m.MetadataToken == analyzedMethod.MetadataToken && m.ParentAssembly.PEFile == analyzedMethod.ParentAssembly.PEFile) {
yield return method;
yield break;
}
break;
}
break;
default:
ILParser.SkipOperand(ref blob, opCode);
break;
}
}
}
}
}

3
ILSpy/ILSpy.csproj

@ -66,11 +66,14 @@ @@ -66,11 +66,14 @@
<ItemGroup>
<Compile Include="AboutPage.cs" />
<Compile Include="Analyzers\Builtin\EventImplementsInterfaceAnalyzer.cs" />
<Compile Include="Analyzers\Builtin\EventOverriddenByAnalyzer.cs" />
<Compile Include="Analyzers\Builtin\MethodImplementsInterfaceAnalyzer.cs" />
<Compile Include="Analyzers\Builtin\MethodOverriddenByAnalyzer.cs" />
<Compile Include="Analyzers\Builtin\MethodVirtualUsedByAnalyzer.cs" />
<Compile Include="Analyzers\Builtin\MethodUsedByAnalyzer.cs" />
<Compile Include="Analyzers\Builtin\MethodUsesAnalyzer.cs" />
<Compile Include="Analyzers\Builtin\PropertyImplementsInterfaceAnalyzer.cs" />
<Compile Include="Analyzers\Builtin\PropertyOverriddenByAnalyzer.cs" />
<Compile Include="Analyzers\Builtin\TypeExposedByAnalyzer.cs" />
<Compile Include="Analyzers\Builtin\TypeInstantiatedByAnalyzer.cs" />

Loading…
Cancel
Save