Browse Source

Add --ilspy-settingsfile and -ds|--decompiler-setting name=value options

pull/3505/head
Siegfried Pammer 2 weeks ago
parent
commit
bf5249be2b
  1. 88
      ICSharpCode.ILSpyCmd/IlspyCmdProgram.cs
  2. 15
      ICSharpCode.ILSpyX/Settings/DecompilerSettings.cs

88
ICSharpCode.ILSpyCmd/IlspyCmdProgram.cs

@ -91,7 +91,7 @@ Examples:
public (bool IsSet, string Value) InputPDBFile { get; } public (bool IsSet, string Value) InputPDBFile { get; }
[Option("-l|--list <entity-type(s)>", "Lists all entities of the specified type(s). Valid types: c(lass), i(nterface), s(truct), d(elegate), e(num)", CommandOptionType.MultipleValue)] [Option("-l|--list <entity-type(s)>", "Lists all entities of the specified type(s). Valid types: c(lass), i(nterface), s(truct), d(elegate), e(num)", CommandOptionType.MultipleValue)]
public string[] EntityTypes { get; } = new string[0]; public string[] EntityTypes { get; } = Array.Empty<string>();
public string DecompilerVersion => "ilspycmd: " + typeof(ILSpyCmdProgram).Assembly.GetName().Version.ToString() + public string DecompilerVersion => "ilspycmd: " + typeof(ILSpyCmdProgram).Assembly.GetName().Version.ToString() +
Environment.NewLine Environment.NewLine
@ -100,9 +100,16 @@ Examples:
[Option("-lv|--languageversion <version>", "C# Language version: CSharp1, CSharp2, CSharp3, " + [Option("-lv|--languageversion <version>", "C# Language version: CSharp1, CSharp2, CSharp3, " +
"CSharp4, CSharp5, CSharp6, CSharp7, CSharp7_1, CSharp7_2, CSharp7_3, CSharp8_0, CSharp9_0, " + "CSharp4, CSharp5, CSharp6, CSharp7, CSharp7_1, CSharp7_2, CSharp7_3, CSharp8_0, CSharp9_0, " +
"CSharp10_0, Preview or Latest", CommandOptionType.SingleValue)] "CSharp10_0, CSharp11_0, CSharp12_0, CSharp13_0, Preview or Latest", CommandOptionType.SingleValue)]
public LanguageVersion LanguageVersion { get; } = LanguageVersion.Latest; public LanguageVersion LanguageVersion { get; } = LanguageVersion.Latest;
[FileExists]
[Option("--ilspy-settingsfile <path>", "Path to an ILSpy settings file.", CommandOptionType.SingleValue)]
public string ILSpySettingsFile { get; }
[Option("-ds|--decompiler-setting <name>=<value>", "Set a decompiler setting. Use multiple times to set multiple settings.", CommandOptionType.MultipleValue)]
public string[] DecompilerSettingOverrides { get; set; } = Array.Empty<string>();
[DirectoryExists] [DirectoryExists]
[Option("-r|--referencepath <path>", "Path to a directory containing dependencies of the assembly that is being decompiled.", CommandOptionType.MultipleValue)] [Option("-r|--referencepath <path>", "Path to a directory containing dependencies of the assembly that is being decompiled.", CommandOptionType.MultipleValue)]
public string[] ReferencePaths { get; } public string[] ReferencePaths { get; }
@ -325,13 +332,76 @@ Examples:
DecompilerSettings GetSettings(PEFile module) DecompilerSettings GetSettings(PEFile module)
{ {
return new DecompilerSettings(LanguageVersion) { DecompilerSettings decompilerSettings = null;
ThrowOnAssemblyResolveErrors = false,
RemoveDeadCode = RemoveDeadCode, if (ILSpySettingsFile != null)
RemoveDeadStores = RemoveDeadStores, {
UseSdkStyleProjectFormat = WholeProjectDecompiler.CanUseSdkStyleProjectFormat(module), try
UseNestedDirectoriesForNamespaces = NestedDirectories, {
}; ILSpyX.Settings.ILSpySettings.SettingsFilePathProvider = new ILSpyX.Settings.DefaultSettingsFilePathProvider(ILSpySettingsFile);
var settingsService = new ILSpyX.Settings.SettingsServiceBase(ILSpyX.Settings.ILSpySettings.Load());
decompilerSettings = settingsService.GetSettings<ILSpyX.Settings.DecompilerSettings>();
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error loading ILSpy settings file '{ILSpySettingsFile}': {ex.Message}");
}
}
if (decompilerSettings == null)
{
decompilerSettings = new DecompilerSettings(LanguageVersion) {
ThrowOnAssemblyResolveErrors = false,
RemoveDeadCode = RemoveDeadCode,
RemoveDeadStores = RemoveDeadStores,
UseSdkStyleProjectFormat = WholeProjectDecompiler.CanUseSdkStyleProjectFormat(module),
UseNestedDirectoriesForNamespaces = NestedDirectories,
};
}
if (DecompilerSettingOverrides is { Length: > 0 })
{
foreach (var entry in DecompilerSettingOverrides)
{
int equals = entry.IndexOf('=');
if (equals <= 0)
{
Console.Error.WriteLine($"Decompiler setting '{entry}' is invalid; use '<Name>=<Value>'");
continue;
}
string name = entry[..equals].Trim();
string value = entry[(equals + 1)..].Trim();
if (!ILSpyX.Settings.DecompilerSettings.IsKnownOption(name, out var property))
{
Console.Error.WriteLine($"Decompiler setting '{name}' is unknown.");
continue;
}
object typedValue;
try
{
typedValue = Convert.ChangeType(value, property.PropertyType);
}
catch (Exception)
{
Console.Error.WriteLine($"Decompiler setting '{name}': Value '{value}' could not be converted to '{property.PropertyType.FullName}'.");
continue;
}
if (typedValue == null && property.PropertyType.IsValueType)
{
Console.Error.WriteLine($"Decompiler setting '{name}': Value '{value}' could not be converted to '{property.PropertyType.FullName}'.");
continue;
}
property.SetValue(decompilerSettings, typedValue);
}
}
return decompilerSettings;
} }
CSharpDecompiler GetDecompiler(string assemblyFileName) CSharpDecompiler GetDecompiler(string assemblyFileName)

15
ICSharpCode.ILSpyX/Settings/DecompilerSettings.cs

@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Xml.Linq; using System.Xml.Linq;
@ -57,5 +58,19 @@ namespace ICSharpCode.ILSpyX.Settings
{ {
return (DecompilerSettings)base.Clone(); return (DecompilerSettings)base.Clone();
} }
public static bool IsKnownOption(string name, [NotNullWhen(true)] out PropertyInfo? property)
{
property = null;
foreach (var item in properties)
{
if (item.Name != name)
continue;
property = item;
return true;
}
return false;
}
} }
} }

Loading…
Cancel
Save