203 lines
10 KiB
C#
Raw Permalink Normal View History

2021-09-20 18:20:01 +02:00
/*
Copyright (C) 2014-2019 de4dot@gmail.com
This file is part of dnSpy
dnSpy is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
dnSpy is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with dnSpy. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Diagnostics;
using System.Linq;
using dnSpy.Contracts.MVVM;
using dnSpy.Contracts.Settings.Dialog;
using dnSpy.Decompiler.ILSpy.Properties;
using ICSharpCode.Decompiler;
namespace dnSpy.Decompiler.ILSpy.Settings {
sealed class CSharpDecompilerSettingsPage : AppSettingsPage, IAppSettingsPage2 {
readonly DecompilerSettings _global_decompilerSettings;
readonly DecompilerSettings decompilerSettings;
public override double Order => AppSettingsConstants.ORDER_DECOMPILER_SETTINGS_ILSPY_CSHARP;
public DecompilerSettings Settings => decompilerSettings;
public override Guid ParentGuid => new Guid(AppSettingsConstants.GUID_DECOMPILER);
public override Guid Guid => new Guid("8929CE8E-7E2C-4701-A8BA-42F70363872C");
public override string Title => "C# / Visual Basic (ILSpy)";
public override object? UIObject => this;
public DecompilationObjectVM[] DecompilationObjectsArray => decompilationObjectVMs2;
readonly DecompilationObjectVM[] decompilationObjectVMs;
readonly DecompilationObjectVM[] decompilationObjectVMs2;
public DecompilationObjectVM DecompilationObject0 {
get => decompilationObjectVMs[0];
set => SetDecompilationObject(0, value);
}
public DecompilationObjectVM DecompilationObject1 {
get => decompilationObjectVMs[1];
set => SetDecompilationObject(1, value);
}
public DecompilationObjectVM DecompilationObject2 {
get => decompilationObjectVMs[2];
set => SetDecompilationObject(2, value);
}
public DecompilationObjectVM DecompilationObject3 {
get => decompilationObjectVMs[3];
set => SetDecompilationObject(3, value);
}
public DecompilationObjectVM DecompilationObject4 {
get => decompilationObjectVMs[4];
set => SetDecompilationObject(4, value);
}
void SetDecompilationObject(int index, DecompilationObjectVM newValue) {
Debug2.Assert(newValue is not null);
if (newValue is null)
throw new ArgumentNullException(nameof(newValue));
if (decompilationObjectVMs[index] == newValue)
return;
int otherIndex = Array.IndexOf(decompilationObjectVMs, newValue);
Debug.Assert(otherIndex >= 0);
if (otherIndex >= 0) {
decompilationObjectVMs[otherIndex] = decompilationObjectVMs[index];
decompilationObjectVMs[index] = newValue;
OnPropertyChanged($"DecompilationObject{otherIndex}");
}
OnPropertyChanged($"DecompilationObject{index}");
}
public CSharpDecompilerSettingsPage(DecompilerSettings decompilerSettings) {
_global_decompilerSettings = decompilerSettings;
this.decompilerSettings = decompilerSettings.Clone();
var defObjs = typeof(DecompilationObject).GetEnumValues().Cast<DecompilationObject>().ToArray();
decompilationObjectVMs = new DecompilationObjectVM[defObjs.Length];
for (int i = 0; i < defObjs.Length; i++)
decompilationObjectVMs[i] = new DecompilationObjectVM(defObjs[i], ToString(defObjs[i]));
decompilationObjectVMs2 = decompilationObjectVMs.ToArray();
DecompilationObject0 = decompilationObjectVMs.First(a => a.Object == decompilerSettings.DecompilationObject0);
DecompilationObject1 = decompilationObjectVMs.First(a => a.Object == decompilerSettings.DecompilationObject1);
DecompilationObject2 = decompilationObjectVMs.First(a => a.Object == decompilerSettings.DecompilationObject2);
DecompilationObject3 = decompilationObjectVMs.First(a => a.Object == decompilerSettings.DecompilationObject3);
DecompilationObject4 = decompilationObjectVMs.First(a => a.Object == decompilerSettings.DecompilationObject4);
}
static string ToString(DecompilationObject o) {
switch (o) {
case DecompilationObject.NestedTypes: return dnSpy_Decompiler_ILSpy_Resources.DecompilationOrder_NestedTypes;
case DecompilationObject.Fields: return dnSpy_Decompiler_ILSpy_Resources.DecompilationOrder_Fields;
case DecompilationObject.Events: return dnSpy_Decompiler_ILSpy_Resources.DecompilationOrder_Events;
case DecompilationObject.Properties: return dnSpy_Decompiler_ILSpy_Resources.DecompilationOrder_Properties;
case DecompilationObject.Methods: return dnSpy_Decompiler_ILSpy_Resources.DecompilationOrder_Methods;
default:
Debug.Fail("Shouldn't be here");
return "???";
}
}
[Flags]
enum RefreshFlags {
ShowMember = 0x00000001,
ILAst = 0x00000002,
CSharp = 0x00000004,
VB = 0x00000008,
DecompileAll = ILAst | CSharp | VB,
}
public override void OnApply() => throw new InvalidOperationException();
public void OnApply(IAppRefreshSettings appRefreshSettings) {
RefreshFlags flags = 0;
var g = _global_decompilerSettings;
var d = decompilerSettings;
d.DecompilationObject0 = DecompilationObject0.Object;
d.DecompilationObject1 = DecompilationObject1.Object;
d.DecompilationObject2 = DecompilationObject2.Object;
d.DecompilationObject3 = DecompilationObject3.Object;
d.DecompilationObject4 = DecompilationObject4.Object;
if (g.AnonymousMethods != d.AnonymousMethods) flags |= RefreshFlags.ILAst | RefreshFlags.ShowMember;
if (g.ExpressionTrees != d.ExpressionTrees) flags |= RefreshFlags.ILAst;
if (g.YieldReturn != d.YieldReturn) flags |= RefreshFlags.ILAst | RefreshFlags.ShowMember;
if (g.AsyncAwait != d.AsyncAwait) flags |= RefreshFlags.ILAst | RefreshFlags.ShowMember;
if (g.AutomaticProperties != d.AutomaticProperties) flags |= RefreshFlags.CSharp | RefreshFlags.ShowMember;
if (g.AutomaticEvents != d.AutomaticEvents) flags |= RefreshFlags.CSharp | RefreshFlags.ShowMember;
if (g.UsingStatement != d.UsingStatement) flags |= RefreshFlags.CSharp;
if (g.ForEachStatement != d.ForEachStatement) flags |= RefreshFlags.CSharp;
if (g.LockStatement != d.LockStatement) flags |= RefreshFlags.CSharp;
if (g.SwitchStatementOnString != d.SwitchStatementOnString) flags |= RefreshFlags.CSharp | RefreshFlags.ShowMember;
if (g.UsingDeclarations != d.UsingDeclarations) flags |= RefreshFlags.CSharp;
if (g.QueryExpressions != d.QueryExpressions) flags |= RefreshFlags.CSharp;
if (g.FullyQualifyAmbiguousTypeNames != d.FullyQualifyAmbiguousTypeNames) flags |= RefreshFlags.CSharp;
if (g.FullyQualifyAllTypes != d.FullyQualifyAllTypes) flags |= RefreshFlags.CSharp;
if (g.UseDebugSymbols != d.UseDebugSymbols) flags |= RefreshFlags.DecompileAll;
if (g.ObjectOrCollectionInitializers != d.ObjectOrCollectionInitializers) flags |= RefreshFlags.ILAst;
if (g.ShowXmlDocumentation != d.ShowXmlDocumentation) flags |= RefreshFlags.DecompileAll;
if (g.RemoveEmptyDefaultConstructors != d.RemoveEmptyDefaultConstructors) flags |= RefreshFlags.CSharp;
if (g.IntroduceIncrementAndDecrement != d.IntroduceIncrementAndDecrement) flags |= RefreshFlags.ILAst;
if (g.MakeAssignmentExpressions != d.MakeAssignmentExpressions) flags |= RefreshFlags.ILAst;
if (g.AlwaysGenerateExceptionVariableForCatchBlocksUnlessTypeIsObject != d.AlwaysGenerateExceptionVariableForCatchBlocksUnlessTypeIsObject) flags |= RefreshFlags.ILAst;
if (g.ShowTokenAndRvaComments != d.ShowTokenAndRvaComments) flags |= RefreshFlags.DecompileAll;
if (g.DecompilationObject0 != d.DecompilationObject0) flags |= RefreshFlags.CSharp;
if (g.DecompilationObject1 != d.DecompilationObject1) flags |= RefreshFlags.CSharp;
if (g.DecompilationObject2 != d.DecompilationObject2) flags |= RefreshFlags.CSharp;
if (g.DecompilationObject3 != d.DecompilationObject3) flags |= RefreshFlags.CSharp;
if (g.DecompilationObject4 != d.DecompilationObject4) flags |= RefreshFlags.CSharp;
if (g.SortMembers != d.SortMembers) flags |= RefreshFlags.CSharp;
if (g.ForceShowAllMembers != d.ForceShowAllMembers) flags |= RefreshFlags.CSharp | RefreshFlags.ShowMember;
if (g.SortSystemUsingStatementsFirst != d.SortSystemUsingStatementsFirst) flags |= RefreshFlags.CSharp;
if (g.MaxArrayElements != d.MaxArrayElements) flags |= RefreshFlags.CSharp;
if (g.MaxStringLength != d.MaxStringLength) flags |= RefreshFlags.CSharp;
if (g.SortCustomAttributes != d.SortCustomAttributes) flags |= RefreshFlags.CSharp;
if (g.UseSourceCodeOrder != d.UseSourceCodeOrder) flags |= RefreshFlags.CSharp;
if (g.AllowFieldInitializers != d.AllowFieldInitializers) flags |= RefreshFlags.CSharp;
if (g.OneCustomAttributePerLine != d.OneCustomAttributePerLine) flags |= RefreshFlags.CSharp;
if (g.TypeAddInternalModifier != d.TypeAddInternalModifier) flags |= RefreshFlags.CSharp;
if (g.MemberAddPrivateModifier != d.MemberAddPrivateModifier) flags |= RefreshFlags.CSharp;
if (g.HexadecimalNumbers != d.HexadecimalNumbers) flags |= RefreshFlags.CSharp;
if ((flags & RefreshFlags.ShowMember) != 0)
appRefreshSettings.Add(AppSettingsConstants.REFRESH_LANGUAGE_SHOWMEMBER);
if ((flags & RefreshFlags.ILAst) != 0)
appRefreshSettings.Add(SettingsConstants.REDECOMPILE_ILAST_ILSPY_CODE);
if ((flags & RefreshFlags.CSharp) != 0)
appRefreshSettings.Add(SettingsConstants.REDECOMPILE_CSHARP_ILSPY_CODE);
if ((flags & RefreshFlags.VB) != 0)
appRefreshSettings.Add(SettingsConstants.REDECOMPILE_VB_ILSPY_CODE);
decompilerSettings.CopyTo(_global_decompilerSettings);
}
public override string[]? GetSearchStrings() => DecompilationObjectsArray.Select(a => a.Text).ToArray();
}
sealed class DecompilationObjectVM : ViewModelBase {
public DecompilationObject Object { get; }
public string Text { get; }
public DecompilationObjectVM(DecompilationObject decompilationObject, string text) {
Object = decompilationObject;
Text = text;
}
}
}