Browse Source

Fix #1311: Methods in .winmd files compiled from C# don't show up in individual method view in ILSpy 4.

Add an option to disable application of WinRT projections.
pull/1347/head
Siegfried Pammer 7 years ago
parent
commit
fac1a4d115
  1. 6
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 12
      ICSharpCode.Decompiler/DecompilerSettings.cs
  3. 12
      ICSharpCode.Decompiler/Metadata/PEFile.cs
  4. 13
      ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs
  5. 1
      ILSpy/DecompilationOptions.cs
  6. 7
      ILSpy/LoadedAssembly.cs
  7. 1
      ILSpy/Options/DecompilerSettingsPanel.xaml
  8. 17
      ILSpy/Options/DecompilerSettingsPanel.xaml.cs

6
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -347,7 +347,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -347,7 +347,8 @@ namespace ICSharpCode.Decompiler.CSharp
return new PEFile(
fileName,
new FileStream(fileName, FileMode.Open, FileAccess.Read),
options: settings.LoadInMemory ? PEStreamOptions.PrefetchEntireImage : PEStreamOptions.Default
streamOptions: settings.LoadInMemory ? PEStreamOptions.PrefetchEntireImage : PEStreamOptions.Default,
metadataOptions: settings.ApplyWindowsRuntimeProjections ? MetadataReaderOptions.ApplyWindowsRuntimeProjections : MetadataReaderOptions.None
);
}
@ -356,7 +357,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -356,7 +357,8 @@ namespace ICSharpCode.Decompiler.CSharp
var file = LoadPEFile(fileName, settings);
var resolver = new UniversalAssemblyResolver(fileName, settings.ThrowOnAssemblyResolveErrors,
file.Reader.DetectTargetFrameworkId(),
settings.LoadInMemory ? PEStreamOptions.PrefetchMetadata : PEStreamOptions.Default);
settings.LoadInMemory ? PEStreamOptions.PrefetchMetadata : PEStreamOptions.Default,
settings.ApplyWindowsRuntimeProjections ? MetadataReaderOptions.ApplyWindowsRuntimeProjections : MetadataReaderOptions.None);
return new DecompilerTypeSystem(file, resolver);
}

12
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -923,6 +923,18 @@ namespace ICSharpCode.Decompiler @@ -923,6 +923,18 @@ namespace ICSharpCode.Decompiler
}
}
bool applyWindowsRuntimeProjections = true;
public bool ApplyWindowsRuntimeProjections {
get { return applyWindowsRuntimeProjections; }
set {
if (applyWindowsRuntimeProjections != value) {
applyWindowsRuntimeProjections = value;
OnPropertyChanged();
}
}
}
#endregion
CSharpFormattingOptions csharpFormattingOptions;

12
ICSharpCode.Decompiler/Metadata/PEFile.cs

@ -47,23 +47,23 @@ namespace ICSharpCode.Decompiler.Metadata @@ -47,23 +47,23 @@ namespace ICSharpCode.Decompiler.Metadata
public PEReader Reader { get; }
public MetadataReader Metadata { get; }
public PEFile(string fileName, PEStreamOptions options = PEStreamOptions.Default)
: this(fileName, new PEReader(new FileStream(fileName, FileMode.Open, FileAccess.Read), options))
public PEFile(string fileName, PEStreamOptions streamOptions = PEStreamOptions.Default, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default)
: this(fileName, new PEReader(new FileStream(fileName, FileMode.Open, FileAccess.Read), streamOptions), metadataOptions)
{
}
public PEFile(string fileName, Stream stream, PEStreamOptions options = PEStreamOptions.Default)
: this(fileName, new PEReader(stream, options))
public PEFile(string fileName, Stream stream, PEStreamOptions streamOptions = PEStreamOptions.Default, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default)
: this(fileName, new PEReader(stream, streamOptions), metadataOptions)
{
}
public PEFile(string fileName, PEReader reader)
public PEFile(string fileName, PEReader reader, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default)
{
this.FileName = fileName ?? throw new ArgumentNullException(nameof(fileName));
this.Reader = reader ?? throw new ArgumentNullException(nameof(reader));
if (!reader.HasMetadata)
throw new PEFileNotSupportedException("PE file does not contain any managed metadata.");
this.Metadata = reader.GetMetadataReader();
this.Metadata = reader.GetMetadataReader(metadataOptions);
}
public bool IsAssembly => Metadata.IsAssembly;

13
ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs

@ -20,6 +20,7 @@ using System; @@ -20,6 +20,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Text;
@ -30,7 +31,8 @@ namespace ICSharpCode.Decompiler.Metadata @@ -30,7 +31,8 @@ namespace ICSharpCode.Decompiler.Metadata
{
DotNetCorePathFinder dotNetCorePathFinder;
readonly bool throwOnError;
readonly PEStreamOptions options;
readonly PEStreamOptions streamOptions;
readonly MetadataReaderOptions metadataOptions;
readonly string mainAssemblyFileName;
readonly string baseDirectory;
readonly List<string> directories = new List<string>();
@ -80,9 +82,10 @@ namespace ICSharpCode.Decompiler.Metadata @@ -80,9 +82,10 @@ namespace ICSharpCode.Decompiler.Metadata
Version targetFrameworkVersion;
public UniversalAssemblyResolver(string mainAssemblyFileName, bool throwOnError, string targetFramework,
PEStreamOptions options = PEStreamOptions.Default)
PEStreamOptions streamOptions = PEStreamOptions.Default, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default)
{
this.options = options;
this.streamOptions = streamOptions;
this.metadataOptions = metadataOptions;
this.targetFramework = targetFramework ?? string.Empty;
(targetFrameworkIdentifier, targetFrameworkVersion) = ParseTargetFramework(this.targetFramework);
this.mainAssemblyFileName = mainAssemblyFileName;
@ -147,7 +150,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -147,7 +150,7 @@ namespace ICSharpCode.Decompiler.Metadata
throw new AssemblyResolutionException(name);
return null;
}
return new PEFile(file, new FileStream(file, FileMode.Open, FileAccess.Read), options);
return new PEFile(file, new FileStream(file, FileMode.Open, FileAccess.Read), streamOptions, metadataOptions);
}
public PEFile ResolveModule(PEFile mainModule, string moduleName)
@ -159,7 +162,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -159,7 +162,7 @@ namespace ICSharpCode.Decompiler.Metadata
throw new Exception($"Module {moduleName} could not be found!");
return null;
}
return new PEFile(moduleFileName, new FileStream(moduleFileName, FileMode.Open, FileAccess.Read), options);
return new PEFile(moduleFileName, new FileStream(moduleFileName, FileMode.Open, FileAccess.Read), streamOptions, metadataOptions);
}
public string FindAssemblyFile(IAssemblyReference name)

1
ILSpy/DecompilationOptions.cs

@ -90,6 +90,7 @@ namespace ICSharpCode.ILSpy @@ -90,6 +90,7 @@ namespace ICSharpCode.ILSpy
ShowXmlDocumentation = settings.ShowXmlDocumentation,
UseDebugSymbols = settings.UseDebugSymbols,
UsingDeclarations = settings.UsingDeclarations,
ApplyWindowsRuntimeProjections = settings.ApplyWindowsRuntimeProjections,
};
}
}

7
ILSpy/LoadedAssembly.cs

@ -153,12 +153,13 @@ namespace ICSharpCode.ILSpy @@ -153,12 +153,13 @@ namespace ICSharpCode.ILSpy
if (stream != null)
{
// Read the module from a precrafted stream
module = new PEFile(fileName, stream);
module = new PEFile(fileName, stream, metadataOptions: DecompilerSettingsPanel.CurrentDecompilerSettings.ApplyWindowsRuntimeProjections ? MetadataReaderOptions.ApplyWindowsRuntimeProjections : MetadataReaderOptions.None);
}
else
{
// Read the module from disk (by default)
module = new PEFile(fileName, new FileStream(fileName, FileMode.Open, FileAccess.Read), PEStreamOptions.PrefetchEntireImage);
module = new PEFile(fileName, new FileStream(fileName, FileMode.Open, FileAccess.Read), PEStreamOptions.PrefetchEntireImage,
metadataOptions: DecompilerSettingsPanel.CurrentDecompilerSettings.ApplyWindowsRuntimeProjections ? MetadataReaderOptions.ApplyWindowsRuntimeProjections : MetadataReaderOptions.None);
}
if (DecompilerSettingsPanel.CurrentDecompilerSettings.UseDebugSymbols) {
@ -322,7 +323,7 @@ namespace ICSharpCode.ILSpy @@ -322,7 +323,7 @@ namespace ICSharpCode.ILSpy
class MyUniversalResolver : UniversalAssemblyResolver
{
public MyUniversalResolver(LoadedAssembly assembly)
: base(assembly.FileName, false, assembly.GetTargetFrameworkIdAsync().Result, PEStreamOptions.PrefetchEntireImage)
: base(assembly.FileName, false, assembly.GetTargetFrameworkIdAsync().Result, PEStreamOptions.PrefetchEntireImage, DecompilerSettingsPanel.CurrentDecompilerSettings.ApplyWindowsRuntimeProjections ? MetadataReaderOptions.ApplyWindowsRuntimeProjections : MetadataReaderOptions.None)
{
}
}

1
ILSpy/Options/DecompilerSettingsPanel.xaml

@ -16,5 +16,6 @@ @@ -16,5 +16,6 @@
<CheckBox IsChecked="{Binding UsingDeclarations}">Insert using declarations</CheckBox>
<CheckBox IsChecked="{Binding AlwaysUseBraces}">Always use braces</CheckBox>
<CheckBox IsChecked="{Binding ExpandMemberDefinitions}">Expand member definitions after decompilation</CheckBox>
<CheckBox IsChecked="{Binding ApplyWindowsRuntimeProjections}">Apply Windows Runtime projections on loaded assemblies</CheckBox>
</StackPanel>
</UserControl>

17
ILSpy/Options/DecompilerSettingsPanel.xaml.cs

@ -58,6 +58,7 @@ namespace ICSharpCode.ILSpy.Options @@ -58,6 +58,7 @@ namespace ICSharpCode.ILSpy.Options
s.RemoveDeadCode = (bool?)e.Attribute("removeDeadCode") ?? s.RemoveDeadCode;
s.UsingDeclarations = (bool?)e.Attribute("usingDeclarations") ?? s.UsingDeclarations;
s.AlwaysUseBraces = (bool?)e.Attribute("alwaysUseBraces") ?? s.AlwaysUseBraces;
s.ApplyWindowsRuntimeProjections = (bool?)e.Attribute("applyWindowsRuntimeProjections") ?? s.ApplyWindowsRuntimeProjections;
return s;
}
@ -73,6 +74,7 @@ namespace ICSharpCode.ILSpy.Options @@ -73,6 +74,7 @@ namespace ICSharpCode.ILSpy.Options
section.SetAttributeValue("removeDeadCode", s.RemoveDeadCode);
section.SetAttributeValue("usingDeclarations", s.UsingDeclarations);
section.SetAttributeValue("alwaysUseBraces", s.AlwaysUseBraces);
section.SetAttributeValue("applyWindowsRuntimeProjections", s.ApplyWindowsRuntimeProjections);
XElement existingElement = root.Element("DecompilerSettings");
if (existingElement != null)
@ -206,6 +208,21 @@ namespace ICSharpCode.ILSpy.Options @@ -206,6 +208,21 @@ namespace ICSharpCode.ILSpy.Options
}
}
bool applyWindowsRuntimeProjections = true;
/// <summary>
/// Gets/Sets whether to Windows Runtime projections to all loaded assemblies.
/// </summary>
public bool ApplyWindowsRuntimeProjections {
get { return applyWindowsRuntimeProjections; }
set {
if (applyWindowsRuntimeProjections != value) {
applyWindowsRuntimeProjections = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)

Loading…
Cancel
Save