From 1efcfe4ae415b3ab964cfd4a96faf194b4c3c628 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 29 Jan 2022 17:33:07 +0100 Subject: [PATCH] #2594: Improve AssemblyListSnapshot: normalize all .NET Framework versions "v4.x" to "v4" --- .../Metadata/UniversalAssemblyResolver.cs | 2 +- ILSpy/Analyzers/AnalyzerScope.cs | 2 +- .../Analyzers/Builtin/MethodUsedByAnalyzer.cs | 26 +++++++++---------- ILSpy/AssemblyListSnapshot.cs | 8 ++++++ ILSpy/LoadedAssemblyExtensions.cs | 5 ++++ 5 files changed, 28 insertions(+), 15 deletions(-) diff --git a/ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs b/ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs index 17c690f46..f1148efb1 100644 --- a/ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs +++ b/ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs @@ -676,7 +676,7 @@ namespace ICSharpCode.Decompiler.Metadata { var gac = Path.Combine(gac_paths[i], gacs[j]); var file = GetAssemblyFile(reference, prefixes[i], gac); - if (Directory.Exists(gac) && File.Exists(file)) + if (File.Exists(file)) return file; } } diff --git a/ILSpy/Analyzers/AnalyzerScope.cs b/ILSpy/Analyzers/AnalyzerScope.cs index f9df75a0e..a040cee33 100644 --- a/ILSpy/Analyzers/AnalyzerScope.cs +++ b/ILSpy/Analyzers/AnalyzerScope.cs @@ -97,7 +97,7 @@ namespace ICSharpCode.ILSpy.Analyzers { foreach (var module in GetModulesInScope(ct)) { - var typeSystem = new DecompilerTypeSystem(module, module.GetAssemblyResolver()); + var typeSystem = new DecompilerTypeSystem(module, module.GetAssemblyResolver(assemblyListSnapshot, loadOnDemand: false)); foreach (var type in typeSystem.MainModule.TypeDefinitions) { yield return type; diff --git a/ILSpy/Analyzers/Builtin/MethodUsedByAnalyzer.cs b/ILSpy/Analyzers/Builtin/MethodUsedByAnalyzer.cs index 80fa96326..5ca4e01bc 100644 --- a/ILSpy/Analyzers/Builtin/MethodUsedByAnalyzer.cs +++ b/ILSpy/Analyzers/Builtin/MethodUsedByAnalyzer.cs @@ -45,6 +45,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin Debug.Assert(analyzedSymbol is IMethod); var analyzedMethod = (IMethod)analyzedSymbol; + var analyzedBaseMethod = (IMethod)InheritanceHelper.GetBaseMember(analyzedMethod); var mapping = context.Language .GetCodeMappingInfo(analyzedMethod.ParentModule.PEFile, analyzedMethod.DeclaringTypeDefinition.MetadataToken); @@ -61,7 +62,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin var methods = type.GetMembers(m => m is IMethod, Options).OfType(); foreach (var method in methods) { - if (IsUsedInMethod((IMethod)analyzedSymbol, method, context)) + if (IsUsedInMethod(analyzedMethod, analyzedBaseMethod, method, context)) { mapping ??= context.Language.GetCodeMappingInfo(parentModule.PEFile, type.MetadataToken); var parent = mapping.GetParentMethod((MethodDefinitionHandle)method.MetadataToken); @@ -71,12 +72,12 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin foreach (var property in type.Properties) { - if (property.CanGet && IsUsedInMethod((IMethod)analyzedSymbol, property.Getter, context)) + if (property.CanGet && IsUsedInMethod(analyzedMethod, analyzedBaseMethod, property.Getter, context)) { yield return property; continue; } - if (property.CanSet && IsUsedInMethod((IMethod)analyzedSymbol, property.Setter, context)) + if (property.CanSet && IsUsedInMethod(analyzedMethod, analyzedBaseMethod, property.Setter, context)) { yield return property; continue; @@ -85,17 +86,17 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin foreach (var @event in type.Events) { - if (@event.CanAdd && IsUsedInMethod((IMethod)analyzedSymbol, @event.AddAccessor, context)) + if (@event.CanAdd && IsUsedInMethod(analyzedMethod, analyzedBaseMethod, @event.AddAccessor, context)) { yield return @event; continue; } - if (@event.CanRemove && IsUsedInMethod((IMethod)analyzedSymbol, @event.RemoveAccessor, context)) + if (@event.CanRemove && IsUsedInMethod(analyzedMethod, analyzedBaseMethod, @event.RemoveAccessor, context)) { yield return @event; continue; } - if (@event.CanInvoke && IsUsedInMethod((IMethod)analyzedSymbol, @event.InvokeAccessor, context)) + if (@event.CanInvoke && IsUsedInMethod(analyzedMethod, analyzedBaseMethod, @event.InvokeAccessor, context)) { yield return @event; continue; @@ -104,12 +105,12 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin } } - bool IsUsedInMethod(IMethod analyzedEntity, IMethod method, AnalyzerContext context) + bool IsUsedInMethod(IMethod analyzedEntity, IMethod analyzedBaseMethod, IMethod method, AnalyzerContext context) { - return ScanMethodBody(analyzedEntity, method, context.GetMethodBody(method)); + return ScanMethodBody(analyzedEntity, method, analyzedBaseMethod, context.GetMethodBody(method)); } - static bool ScanMethodBody(IMethod analyzedMethod, IMethod method, MethodBodyBlock methodBody) + static bool ScanMethodBody(IMethod analyzedMethod, IMethod method, IMethod analyzedBaseMethod, MethodBodyBlock methodBody) { if (methodBody == null) return false; @@ -117,7 +118,6 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin var mainModule = (MetadataModule)method.ParentModule; var blob = methodBody.GetILReader(); - var baseMethod = (IMethod)InheritanceHelper.GetBaseMember(analyzedMethod); var genericContext = new Decompiler.TypeSystem.GenericContext(); // type parameters don't matter for this analyzer while (blob.RemainingBytes > 0) @@ -139,7 +139,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin var member = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32()); if (!AnalyzerHelpers.IsPossibleReferenceTo(member, mainModule.PEFile, analyzedMethod)) { - if (baseMethod == null || !AnalyzerHelpers.IsPossibleReferenceTo(member, mainModule.PEFile, baseMethod)) + if (analyzedBaseMethod == null || !AnalyzerHelpers.IsPossibleReferenceTo(member, mainModule.PEFile, analyzedBaseMethod)) { continue; } @@ -157,9 +157,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin if (m == null) continue; - if (opCode == ILOpCode.Callvirt && baseMethod != null) + if (opCode == ILOpCode.Callvirt && analyzedBaseMethod != null) { - if (IsSameMember(baseMethod, m)) + if (IsSameMember(analyzedBaseMethod, m)) { return true; } diff --git a/ILSpy/AssemblyListSnapshot.cs b/ILSpy/AssemblyListSnapshot.cs index 0f0bb9a84..a69547575 100644 --- a/ILSpy/AssemblyListSnapshot.cs +++ b/ILSpy/AssemblyListSnapshot.cs @@ -44,6 +44,10 @@ namespace ICSharpCode.ILSpy public async Task TryGetModuleAsync(IAssemblyReference reference, string tfm) { bool isWinRT = reference.IsWindowsRuntime; + if (tfm.StartsWith(".NETFramework,Version=v4.", StringComparison.Ordinal)) + { + tfm = ".NETFramework,Version=v4"; + } string key = tfm + ";" + (isWinRT ? reference.Name : reference.FullName); var lookup = LazyInit.VolatileRead(ref isWinRT ? ref asmLookupByShortName : ref asmLookupByFullName); if (lookup == null) @@ -70,6 +74,10 @@ namespace ICSharpCode.ILSpy if (reader == null || !reader.IsAssembly) continue; string tfm = await loaded.GetTargetFrameworkIdAsync().ConfigureAwait(false); + if (tfm.StartsWith(".NETFramework,Version=v4.", StringComparison.Ordinal)) + { + tfm = ".NETFramework,Version=v4"; + } string key = tfm + ";" + (shortNames ? module.Name : module.FullName); if (!result.ContainsKey(key)) diff --git a/ILSpy/LoadedAssemblyExtensions.cs b/ILSpy/LoadedAssemblyExtensions.cs index 0b8e3060f..05d210145 100644 --- a/ILSpy/LoadedAssemblyExtensions.cs +++ b/ILSpy/LoadedAssemblyExtensions.cs @@ -31,6 +31,11 @@ namespace ICSharpCode.ILSpy return GetLoadedAssembly(file).GetAssemblyResolver(loadOnDemand); } + internal static IAssemblyResolver GetAssemblyResolver(this PEFile file, AssemblyListSnapshot snapshot, bool loadOnDemand = true) + { + return GetLoadedAssembly(file).GetAssemblyResolver(snapshot, loadOnDemand); + } + public static IDebugInfoProvider GetDebugInfoOrNull(this PEFile file) { return GetLoadedAssembly(file).GetDebugInfoOrNull();