From 4f6f7effd99d2941d419f4900e370ceef1e83621 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 29 Jan 2022 15:12:43 +0100 Subject: [PATCH] #2594: Add AnalyzerHelpers.IsPossibleReferenceTo for methods to speed MethodUsedByAnalyzer --- ILSpy/Analyzers/AnalyzerHelpers.cs | 52 +++++++++++++++++++ .../Analyzers/Builtin/MethodUsedByAnalyzer.cs | 18 ++++--- 2 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 ILSpy/Analyzers/AnalyzerHelpers.cs diff --git a/ILSpy/Analyzers/AnalyzerHelpers.cs b/ILSpy/Analyzers/AnalyzerHelpers.cs new file mode 100644 index 000000000..a4b8c6432 --- /dev/null +++ b/ILSpy/Analyzers/AnalyzerHelpers.cs @@ -0,0 +1,52 @@ +// Copyright (c) 2018 Siegfried Pammer +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System.Reflection.Metadata; + +using ICSharpCode.Decompiler.Metadata; + +namespace ICSharpCode.ILSpy.Analyzers +{ + using ICSharpCode.Decompiler.TypeSystem; + + internal static class AnalyzerHelpers + { + public static bool IsPossibleReferenceTo(EntityHandle member, PEFile module, IMethod analyzedMethod) + { + if (member.IsNil) + return false; + MetadataReader metadata = module.Metadata; + switch (member.Kind) + { + case HandleKind.MethodDefinition: + return member == analyzedMethod.MetadataToken + && module == analyzedMethod.ParentModule.PEFile; + case HandleKind.MemberReference: + var mr = metadata.GetMemberReference((MemberReferenceHandle)member); + if (mr.GetKind() != MemberReferenceKind.Method) + return false; + return metadata.StringComparer.Equals(mr.Name, analyzedMethod.Name); + case HandleKind.MethodSpecification: + var ms = metadata.GetMethodSpecification((MethodSpecificationHandle)member); + return IsPossibleReferenceTo(ms.Method, module, analyzedMethod); + default: + return false; + } + } + } +} diff --git a/ILSpy/Analyzers/Builtin/MethodUsedByAnalyzer.cs b/ILSpy/Analyzers/Builtin/MethodUsedByAnalyzer.cs index a94121993..80fa96326 100644 --- a/ILSpy/Analyzers/Builtin/MethodUsedByAnalyzer.cs +++ b/ILSpy/Analyzers/Builtin/MethodUsedByAnalyzer.cs @@ -117,7 +117,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin var mainModule = (MetadataModule)method.ParentModule; var blob = methodBody.GetILReader(); - var baseMethod = InheritanceHelper.GetBaseMember(analyzedMethod); + var baseMethod = (IMethod)InheritanceHelper.GetBaseMember(analyzedMethod); var genericContext = new Decompiler.TypeSystem.GenericContext(); // type parameters don't matter for this analyzer while (blob.RemainingBytes > 0) @@ -137,8 +137,13 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin return false; // unexpected end of blob } var member = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32()); - if (member.IsNil || !member.Kind.IsMemberKind()) - continue; + if (!AnalyzerHelpers.IsPossibleReferenceTo(member, mainModule.PEFile, analyzedMethod)) + { + if (baseMethod == null || !AnalyzerHelpers.IsPossibleReferenceTo(member, mainModule.PEFile, baseMethod)) + { + continue; + } + } IMember m; try @@ -159,12 +164,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin return true; } } - else + if (IsSameMember(analyzedMethod, m)) { - if (IsSameMember(analyzedMethod, m)) - { - return true; - } + return true; } }