Browse Source

Merge branch 'master' of https://github.com/icsharpcode/ILSpy into metadata-explorer

pull/1716/head
Siegfried Pammer 7 years ago
parent
commit
721932b45f
  1. 22
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.cs
  2. 12
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.cs
  3. 38
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  4. 52
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  5. 2
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  6. 5
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
  7. 10
      ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs
  8. 10
      ICSharpCode.Decompiler/Metadata/DotNetCorePathFinder.cs
  9. 2
      ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs
  10. 14
      ILSpy/Commands/DecompileInNewViewCommand.cs
  11. 21
      ILSpy/Docking/DockWorkspace.cs
  12. 2
      ILSpy/Docking/PaneCollection.cs
  13. 2
      ILSpy/ILSpy.csproj
  14. 2
      ILSpy/MainWindow.xaml
  15. 6
      ILSpy/MainWindow.xaml.cs
  16. 2
      ILSpy/Properties/AssemblyInfo.template.cs
  17. 5
      ILSpy/TextView/DecompilerTextView.cs
  18. 2
      ILSpy/TreeNodes/AssemblyListTreeNode.cs
  19. 8
      ILSpy/ViewModels/PaneModel.cs

22
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.cs

@ -60,6 +60,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
get; get;
set; set;
} }
public bool BoolProperty {
get;
set;
}
public uint this[string name] { public uint this[string name] {
get { get {
@ -802,6 +807,23 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
return M().ByteProperty *= 2; return M().ByteProperty *= 2;
} }
public void BitManipBoolProperty(bool b)
{
M().BoolProperty |= b;
M().BoolProperty &= b;
M().BoolProperty ^= b;
}
public bool BitOrBoolPropertyAndReturn(bool b)
{
return M().BoolProperty |= b;
}
public bool BitAndBoolPropertyAndReturn(bool b)
{
return M().BoolProperty &= b;
}
public int PreIncrementStaticField() public int PreIncrementStaticField()
{ {
return ++StaticField; return ++StaticField;

12
ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.cs

@ -196,6 +196,18 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
readOnlyStruct.Method(); readOnlyStruct.Method();
} }
public void M(in DateTime a = default(DateTime))
{
}
public void M2<T>(in T a = default(T))
{
}
public void M3<T>(in T? a = null) where T : struct
{
}
public static TReturn Invoker<T1, TReturn>(RefFunc<T1, TReturn> action, T1 value) public static TReturn Invoker<T1, TReturn>(RefFunc<T1, TReturn> action, T1 value)
{ {
return action(value); return action(value);

38
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -1280,6 +1280,18 @@ namespace ICSharpCode.Decompiler.CSharp
right.ResolveResult)); right.ResolveResult));
} }
} }
if (op.IsBitwise()
&& left.Type.IsKnownType(KnownTypeCode.Boolean)
&& right.Type.IsKnownType(KnownTypeCode.Boolean)
&& SemanticHelper.IsPure(inst.Right.Flags))
{
// Undo the C# compiler's optimization of "a && b" to "a & b".
if (op == BinaryOperatorType.BitwiseAnd) {
op = BinaryOperatorType.ConditionalAnd;
} else if (op == BinaryOperatorType.BitwiseOr) {
op = BinaryOperatorType.ConditionalOr;
}
}
if (op.IsBitwise() && (left.Type.Kind == TypeKind.Enum || right.Type.Kind == TypeKind.Enum)) { if (op.IsBitwise() && (left.Type.Kind == TypeKind.Enum || right.Type.Kind == TypeKind.Enum)) {
left = AdjustConstantExpressionToType(left, right.Type); left = AdjustConstantExpressionToType(left, right.Type);
@ -2103,20 +2115,28 @@ namespace ICSharpCode.Decompiler.CSharp
protected internal override TranslatedExpression VisitLdLen(LdLen inst, TranslationContext context) protected internal override TranslatedExpression VisitLdLen(LdLen inst, TranslationContext context)
{ {
TranslatedExpression arrayExpr = Translate(inst.Array, typeHint: compilation.FindType(KnownTypeCode.Array)); IType arrayType = compilation.FindType(KnownTypeCode.Array);
TranslatedExpression arrayExpr = Translate(inst.Array, typeHint: arrayType);
if (arrayExpr.Type.Kind != TypeKind.Array) { if (arrayExpr.Type.Kind != TypeKind.Array) {
arrayExpr = arrayExpr.ConvertTo(compilation.FindType(KnownTypeCode.Array), this); arrayExpr = arrayExpr.ConvertTo(arrayType, this);
} }
arrayExpr = EnsureTargetNotNullable(arrayExpr); arrayExpr = EnsureTargetNotNullable(arrayExpr);
string memberName;
KnownTypeCode code;
if (inst.ResultType == StackType.I4) { if (inst.ResultType == StackType.I4) {
return new MemberReferenceExpression(arrayExpr.Expression, "Length") memberName = "Length";
.WithILInstruction(inst) code = KnownTypeCode.Int32;
.WithRR(new ResolveResult(compilation.FindType(KnownTypeCode.Int32)));
} else { } else {
return new MemberReferenceExpression(arrayExpr.Expression, "LongLength") memberName = "LongLength";
.WithILInstruction(inst) code = KnownTypeCode.Int64;
.WithRR(new ResolveResult(compilation.FindType(KnownTypeCode.Int64))); }
} IProperty member = arrayType.GetProperties(p => p.Name == memberName).FirstOrDefault();
ResolveResult rr = member == null
? new ResolveResult(compilation.FindType(code))
: new MemberResolveResult(arrayExpr.ResolveResult, member);
return new MemberReferenceExpression(arrayExpr.Expression, memberName)
.WithILInstruction(inst)
.WithRR(rr);
} }
protected internal override TranslatedExpression VisitLdFlda(LdFlda inst, TranslationContext context) protected internal override TranslatedExpression VisitLdFlda(LdFlda inst, TranslationContext context)

52
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -272,26 +272,32 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
return astType; return astType;
} else { } else {
AstType astType; AstType astType;
if (type is ITypeDefinition typeDef) { switch (type) {
if (ShowTypeParametersForUnboundTypes) { case ITypeDefinition _:
astType = ConvertTypeHelper(typeDef, typeDef.TypeArguments); case UnknownType _:
} else if (typeDef.TypeParameterCount > 0) { if (type.IsUnbound()) {
// Unbound type if (ShowTypeParametersForUnboundTypes) {
IType[] typeArguments = new IType[typeDef.TypeParameterCount]; astType = ConvertTypeHelper(type, type.TypeArguments);
for (int i = 0; i < typeArguments.Length; i++) { } else {
typeArguments[i] = SpecialType.UnboundTypeArgument; IType[] typeArguments = new IType[type.TypeParameterCount];
for (int i = 0; i < typeArguments.Length; i++) {
typeArguments[i] = SpecialType.UnboundTypeArgument;
}
astType = ConvertTypeHelper(type, typeArguments);
}
} else {
astType = ConvertTypeHelper(type, EmptyList<IType>.Instance);
} }
astType = ConvertTypeHelper(typeDef, typeArguments); break;
} else { case ParameterizedType pt:
astType = ConvertTypeHelper(typeDef, EmptyList<IType>.Instance); if (AlwaysUseBuiltinTypeNames && pt.IsKnownType(KnownTypeCode.NullableOfT)) {
} return ConvertType(pt.TypeArguments[0]).MakeNullableType();
} else if (type is ParameterizedType pt) { }
if (AlwaysUseBuiltinTypeNames && pt.IsKnownType(KnownTypeCode.NullableOfT)) { astType = ConvertTypeHelper(pt.GenericType, pt.TypeArguments);
return ConvertType(pt.TypeArguments[0]).MakeNullableType(); break;
} default:
astType = ConvertTypeHelper(pt.GenericType, pt.TypeArguments); astType = MakeSimpleType(type.Name);
} else { break;
astType = MakeSimpleType(type.Name);
} }
if (type.Nullability == Nullability.Nullable) { if (type.Nullability == Nullability.Nullable) {
AddTypeAnnotation(astType, type.ChangeNullability(Nullability.Oblivious)); AddTypeAnnotation(astType, type.ChangeNullability(Nullability.Oblivious));
@ -1262,18 +1268,20 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
if (ShowAttributes) { if (ShowAttributes) {
decl.Attributes.AddRange(ConvertAttributes(parameter.GetAttributes())); decl.Attributes.AddRange(ConvertAttributes(parameter.GetAttributes()));
} }
IType parameterType;
if (parameter.Type.Kind == TypeKind.ByReference) { if (parameter.Type.Kind == TypeKind.ByReference) {
// avoid 'out ref' // avoid 'out ref'
decl.Type = ConvertType(((ByReferenceType)parameter.Type).ElementType); parameterType = ((ByReferenceType)parameter.Type).ElementType;
} else { } else {
decl.Type = ConvertType(parameter.Type); parameterType = parameter.Type;
} }
decl.Type = ConvertType(parameterType);
if (this.ShowParameterNames) { if (this.ShowParameterNames) {
decl.Name = parameter.Name; decl.Name = parameter.Name;
} }
if (parameter.IsOptional && parameter.HasConstantValueInSignature && this.ShowConstantValues) { if (parameter.IsOptional && parameter.HasConstantValueInSignature && this.ShowConstantValues) {
try { try {
decl.DefaultExpression = ConvertConstantValue(parameter.Type, parameter.GetConstantValue(throwOnInvalidMetadata: true)); decl.DefaultExpression = ConvertConstantValue(parameterType, parameter.GetConstantValue(throwOnInvalidMetadata: true));
} catch (BadImageFormatException ex) { } catch (BadImageFormatException ex) {
decl.DefaultExpression = new ErrorExpression(ex.Message); decl.DefaultExpression = new ErrorExpression(ex.Message);
} }

2
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -51,7 +51,7 @@
<PackageReference Include="System.Collections.Immutable" Version="1.5.0" /> <PackageReference Include="System.Collections.Immutable" Version="1.5.0" />
<PackageReference Include="System.Reflection.Metadata" Version="1.6.0" /> <PackageReference Include="System.Reflection.Metadata" Version="1.6.0" />
<PackageReference Include="System.ValueTuple" Version="4.3.0" /> <PackageReference Include="System.ValueTuple" Version="4.3.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01"> <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>

5
ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

@ -679,11 +679,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{ {
if (new NullableLiftingTransform(context).Run(inst)) { if (new NullableLiftingTransform(context).Run(inst)) {
// e.g. "(a.GetValueOrDefault() == b.GetValueOrDefault()) & (a.HasValue & b.HasValue)" // e.g. "(a.GetValueOrDefault() == b.GetValueOrDefault()) & (a.HasValue & b.HasValue)"
} else if (SemanticHelper.IsPure(inst.Right.Flags)) {
context.Step("Replace bit.and with logic.and", inst);
var expr = IfInstruction.LogicAnd(inst.Left, inst.Right);
inst.ReplaceWith(expr);
expr.AcceptVisitor(this);
} }
} }
break; break;

10
ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs

@ -459,6 +459,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return conv.TargetType != type.ToPrimitiveType(); return conv.TargetType != type.ToPrimitiveType();
} else if (value is Comp) { } else if (value is Comp) {
return false; // comp returns 0 or 1, which always fits return false; // comp returns 0 or 1, which always fits
} else if (value is BinaryNumericInstruction bni) {
switch (bni.Operator) {
case BinaryNumericOperator.BitAnd:
case BinaryNumericOperator.BitOr:
case BinaryNumericOperator.BitXor:
// If both input values fit into the type without truncation,
// the result of a binary operator will also fit.
return IsImplicitTruncation(bni.Left, type, compilation, allowNullableValue)
|| IsImplicitTruncation(bni.Right, type, compilation, allowNullableValue);
}
} else if (value is IfInstruction ifInst) { } else if (value is IfInstruction ifInst) {
return IsImplicitTruncation(ifInst.TrueInst, type, compilation, allowNullableValue) return IsImplicitTruncation(ifInst.TrueInst, type, compilation, allowNullableValue)
|| IsImplicitTruncation(ifInst.FalseInst, type, compilation, allowNullableValue); || IsImplicitTruncation(ifInst.FalseInst, type, compilation, allowNullableValue);

10
ICSharpCode.Decompiler/Metadata/DotNetCorePathFinder.cs

@ -60,7 +60,7 @@ namespace ICSharpCode.Decompiler.Metadata
"Microsoft.AspNetCore.All" "Microsoft.AspNetCore.All"
}; };
readonly Dictionary<string, DotNetCorePackageInfo> packages; readonly DotNetCorePackageInfo[] packages;
ISet<string> packageBasePaths = new HashSet<string>(StringComparer.Ordinal); ISet<string> packageBasePaths = new HashSet<string>(StringComparer.Ordinal);
readonly Version version; readonly Version version;
readonly string dotnetBasePath = FindDotNetExeDirectory(); readonly string dotnetBasePath = FindDotNetExeDirectory();
@ -82,13 +82,13 @@ namespace ICSharpCode.Decompiler.Metadata
return; return;
} }
packages = LoadPackageInfos(depsJsonFileName, targetFrameworkId).ToDictionary(i => i.Name); packages = LoadPackageInfos(depsJsonFileName, targetFrameworkId).ToArray();
foreach (var path in LookupPaths) { foreach (var path in LookupPaths) {
foreach (var pk in packages) { foreach (var p in packages) {
foreach (var item in pk.Value.RuntimeComponents) { foreach (var item in p.RuntimeComponents) {
var itemPath = Path.GetDirectoryName(item); var itemPath = Path.GetDirectoryName(item);
var fullPath = Path.Combine(path, pk.Value.Name, pk.Value.Version, itemPath).ToLowerInvariant(); var fullPath = Path.Combine(path, p.Name, p.Version, itemPath).ToLowerInvariant();
if (Directory.Exists(fullPath)) if (Directory.Exists(fullPath))
packageBasePaths.Add(fullPath); packageBasePaths.Add(fullPath);
} }

2
ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs

@ -211,7 +211,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
{ {
if (type == null) if (type == null)
throw new ArgumentNullException(nameof(type)); throw new ArgumentNullException(nameof(type));
return type is ITypeDefinition && type.TypeParameterCount > 0; return (type is ITypeDefinition || type is UnknownType) && type.TypeParameterCount > 0;
} }
/// <summary> /// <summary>

14
ILSpy/Commands/DecompileInNewViewCommand.cs

@ -18,6 +18,7 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Windows.Threading;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Docking; using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.Properties; using ICSharpCode.ILSpy.Properties;
@ -42,7 +43,12 @@ namespace ICSharpCode.ILSpy.Commands
public void Execute(TextViewContext context) public void Execute(TextViewContext context)
{ {
if (context.SelectedTreeNodes != null) { if (context.SelectedTreeNodes != null) {
var nodes = context.SelectedTreeNodes.OfType<IMemberTreeNode>().Select(FindTreeNode).ToArray(); ILSpyTreeNode[] nodes;
if (context.TreeView != MainWindow.Instance.treeView) {
nodes = context.SelectedTreeNodes.OfType<IMemberTreeNode>().Select(FindTreeNode).ToArray();
} else {
nodes = context.SelectedTreeNodes.OfType<ILSpyTreeNode>().ToArray();
}
DecompileNodes(nodes); DecompileNodes(nodes);
} else if (context.Reference?.Reference is IEntity entity) { } else if (context.Reference?.Reference is IEntity entity) {
if (MainWindow.Instance.FindTreeNode(entity) is ILSpyTreeNode node) { if (MainWindow.Instance.FindTreeNode(entity) is ILSpyTreeNode node) {
@ -62,12 +68,12 @@ namespace ICSharpCode.ILSpy.Commands
{ {
if (nodes.Length == 0) if (nodes.Length == 0)
return; return;
var title = string.Join(", ", nodes.Select(x => x.ToString())); var title = string.Join(", ", nodes.Select(x => x.ToString()));
DockWorkspace.Instance.Documents.Add(new ViewModels.DecompiledDocumentModel(title, title) { Language = MainWindow.Instance.CurrentLanguage, LanguageVersion = MainWindow.Instance.CurrentLanguageVersion }); DockWorkspace.Instance.Documents.Add(new ViewModels.DecompiledDocumentModel(title, title) { Language = MainWindow.Instance.CurrentLanguage, LanguageVersion = MainWindow.Instance.CurrentLanguageVersion });
DockWorkspace.Instance.ActiveDocument = DockWorkspace.Instance.Documents.Last(); DockWorkspace.Instance.ActiveDocument = DockWorkspace.Instance.Documents.Last();
MainWindow.Instance.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Background, (Action)delegate { MainWindow.Instance.SelectNodes(nodes);
DockWorkspace.Instance.GetTextView().DecompileAsync(MainWindow.Instance.CurrentLanguage, nodes, new DecompilationOptions()); MainWindow.Instance.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)MainWindow.Instance.RefreshDecompiledView);
});
} }
} }
} }

21
ILSpy/Docking/DockWorkspace.cs

@ -25,6 +25,7 @@ using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Threading;
using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.ViewModels; using ICSharpCode.ILSpy.ViewModels;
@ -43,6 +44,16 @@ namespace ICSharpCode.ILSpy.Docking
private DockWorkspace() private DockWorkspace()
{ {
this.Documents.CollectionChanged += Documents_CollectionChanged;
}
private void Documents_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
var collection = (PaneCollection<DocumentModel>)sender;
bool canClose = collection.Count > 1;
foreach (var item in collection) {
item.IsCloseable = canClose;
}
} }
public PaneCollection<DocumentModel> Documents { get; } = new PaneCollection<DocumentModel>(); public PaneCollection<DocumentModel> Documents { get; } = new PaneCollection<DocumentModel>();
@ -83,6 +94,11 @@ namespace ICSharpCode.ILSpy.Docking
if (value is DecompiledDocumentModel ddm) { if (value is DecompiledDocumentModel ddm) {
this.sessionSettings.FilterSettings.Language = ddm.Language; this.sessionSettings.FilterSettings.Language = ddm.Language;
this.sessionSettings.FilterSettings.LanguageVersion = ddm.LanguageVersion; this.sessionSettings.FilterSettings.LanguageVersion = ddm.LanguageVersion;
if (ddm.TextView is DecompilerTextView view) {
var state = view.GetState();
if (state != null)
MainWindow.Instance.SelectNodes(state.DecompiledNodes);
}
} }
RaisePropertyChanged(nameof(ActiveDocument)); RaisePropertyChanged(nameof(ActiveDocument));
} }
@ -123,6 +139,7 @@ namespace ICSharpCode.ILSpy.Docking
e.Cancel = true; e.Cancel = true;
break; break;
} }
la.CanDockAsTabbedDocument = false;
if (!e.Cancel) { if (!e.Cancel) {
e.Cancel = ((ToolPaneModel)e.Content).IsVisible; e.Cancel = ((ToolPaneModel)e.Content).IsVisible;
((ToolPaneModel)e.Content).IsVisible = true; ((ToolPaneModel)e.Content).IsVisible = true;
@ -151,7 +168,7 @@ namespace ICSharpCode.ILSpy.Docking
public DecompilerTextViewState GetState() public DecompilerTextViewState GetState()
{ {
return GetTextView().GetState(); return GetTextView()?.GetState();
} }
public Task<T> RunWithCancellation<T>(Func<CancellationToken, Task<T>> taskCreation) public Task<T> RunWithCancellation<T>(Func<CancellationToken, Task<T>> taskCreation)
@ -193,8 +210,10 @@ namespace ICSharpCode.ILSpy.Docking
foreach (var pane in ToolPanes) { foreach (var pane in ToolPanes) {
pane.IsVisible = false; pane.IsVisible = false;
} }
CloseAllDocuments();
sessionSettings.DockLayout.Reset(); sessionSettings.DockLayout.Reset();
InitializeLayout(MainWindow.Instance.DockManager); InitializeLayout(MainWindow.Instance.DockManager);
MainWindow.Instance.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)MainWindow.Instance.RefreshDecompiledView);
} }
} }
} }

2
ILSpy/Docking/PaneCollection.cs

@ -49,7 +49,7 @@ namespace ICSharpCode.ILSpy.Docking
item.IsActive = true; item.IsActive = true;
} }
public int Count => observableCollection.Count(); public int Count => observableCollection.Count;
public bool IsReadOnly => false; public bool IsReadOnly => false;
public void Clear() => observableCollection.Clear(); public void Clear() => observableCollection.Clear();
public bool Contains(T item) => observableCollection.Contains(item); public bool Contains(T item) => observableCollection.Contains(item);

2
ILSpy/ILSpy.csproj

@ -393,7 +393,7 @@
<Generator>PublicResXFileCodeGenerator</Generator> <Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput> <LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.zh-Hans.resx" /> <EmbeddedResource Condition=" '$(COMPUTERNAME)' != 'DANIEL-E590' " Include="Properties\Resources.zh-Hans.resx" />
<Resource Include="Images\ILSpy.ico" /> <Resource Include="Images\ILSpy.ico" />
<EmbeddedResource Include="TextView\CSharp-Mode.xshd" /> <EmbeddedResource Include="TextView\CSharp-Mode.xshd" />
<None Include="app.config" /> <None Include="app.config" />

2
ILSpy/MainWindow.xaml

@ -211,7 +211,7 @@
<Setter Property="IsSelected" Value="{Binding Model.IsSelected, Mode=TwoWay}"/> <Setter Property="IsSelected" Value="{Binding Model.IsSelected, Mode=TwoWay}"/>
<Setter Property="IsActive" Value="{Binding Model.IsActive, Mode=TwoWay}"/> <Setter Property="IsActive" Value="{Binding Model.IsActive, Mode=TwoWay}"/>
<Setter Property="CloseCommand" Value="{Binding Model.CloseCommand}" /> <Setter Property="CloseCommand" Value="{Binding Model.CloseCommand}" />
<Setter Property="CanClose" Value="{Binding Model.IsCloseable}" /> <Setter Property="CanClose" Value="{Binding Model.IsCloseable, Mode=TwoWay}" />
</Style> </Style>
</docking:PaneStyleSelector.DocumentStyle> </docking:PaneStyleSelector.DocumentStyle>
</docking:PaneStyleSelector> </docking:PaneStyleSelector>

6
ILSpy/MainWindow.xaml.cs

@ -117,11 +117,8 @@ namespace ICSharpCode.ILSpy
}; };
DockWorkspace.Instance.LoadSettings(sessionSettings); DockWorkspace.Instance.LoadSettings(sessionSettings);
InitializeComponent(); InitializeComponent();
DockWorkspace.Instance.InitializeLayout(DockManager); DockWorkspace.Instance.InitializeLayout(DockManager);
sessionSettings.FilterSettings.PropertyChanged += filterSettings_PropertyChanged; sessionSettings.FilterSettings.PropertyChanged += filterSettings_PropertyChanged;
InitMainMenu(); InitMainMenu();
@ -457,7 +454,6 @@ namespace ICSharpCode.ILSpy
void MainWindow_Loaded(object sender, RoutedEventArgs e) void MainWindow_Loaded(object sender, RoutedEventArgs e)
{ {
DockWorkspace.Instance.Documents.Add(new DecompiledDocumentModel() { DockWorkspace.Instance.Documents.Add(new DecompiledDocumentModel() {
IsCloseable = false,
Language = CurrentLanguage, Language = CurrentLanguage,
LanguageVersion = CurrentLanguageVersion LanguageVersion = CurrentLanguageVersion
}); });
@ -746,6 +742,8 @@ namespace ICSharpCode.ILSpy
public ILSpyTreeNode FindTreeNode(object reference) public ILSpyTreeNode FindTreeNode(object reference)
{ {
switch (reference) { switch (reference) {
case LoadedAssembly lasm:
return assemblyListTreeNode.FindAssemblyNode(lasm);
case PEFile asm: case PEFile asm:
return assemblyListTreeNode.FindAssemblyNode(asm); return assemblyListTreeNode.FindAssemblyNode(asm);
case Resource res: case Resource res:

2
ILSpy/Properties/AssemblyInfo.template.cs

@ -39,7 +39,7 @@ internal static class RevisionClass
public const string Minor = "0"; public const string Minor = "0";
public const string Build = "0"; public const string Build = "0";
public const string Revision = "$INSERTREVISION$"; public const string Revision = "$INSERTREVISION$";
public const string VersionName = "alpha1"; public const string VersionName = "preview1";
public const string FullVersion = Major + "." + Minor + "." + Build + ".$INSERTREVISION$$INSERTBRANCHPOSTFIX$$INSERTVERSIONNAMEPOSTFIX$"; public const string FullVersion = Major + "." + Minor + "." + Build + ".$INSERTREVISION$$INSERTBRANCHPOSTFIX$$INSERTVERSIONNAMEPOSTFIX$";
} }

5
ILSpy/TextView/DecompilerTextView.cs

@ -417,7 +417,9 @@ namespace ICSharpCode.ILSpy.TextView
}; };
this.Child = border; this.Child = border;
viewer.Foreground = SystemColors.InfoTextBrush; viewer.Foreground = SystemColors.InfoTextBrush;
document.TextAlignment = TextAlignment.Left;
document.FontSize = fontSize; document.FontSize = fontSize;
document.FontFamily = SystemFonts.SmallCaptionFontFamily;
} }
public bool CloseWhenMouseMovesAway { public bool CloseWhenMouseMovesAway {
@ -570,7 +572,8 @@ namespace ICSharpCode.ILSpy.TextView
this.nextDecompilationRun.TaskCompletionSource.TrySetCanceled(); this.nextDecompilationRun.TaskCompletionSource.TrySetCanceled();
this.nextDecompilationRun = null; this.nextDecompilationRun = null;
} }
textOutput.Title = string.Join(", ", nodes.Select(n => n.ToString())); if (nodes != null && string.IsNullOrEmpty(textOutput.Title))
textOutput.Title = string.Join(", ", nodes.Select(n => n.ToString()));
ShowOutput(textOutput, highlighting); ShowOutput(textOutput, highlighting);
decompiledNodes = nodes; decompiledNodes = nodes;
} }

2
ILSpy/TreeNodes/AssemblyListTreeNode.cs

@ -116,6 +116,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
foreach (LoadedAssembly asm in assemblies) { foreach (LoadedAssembly asm in assemblies) {
assemblyList.assemblies.Insert(index, asm); assemblyList.assemblies.Insert(index, asm);
} }
var nodes = assemblies.SelectArray(MainWindow.Instance.FindTreeNode);
MainWindow.Instance.SelectNodes(nodes);
} }
} }
} }

8
ILSpy/ViewModels/PaneModel.cs

@ -31,6 +31,14 @@ namespace ICSharpCode.ILSpy.ViewModels
public CloseCommandImpl(PaneModel model) public CloseCommandImpl(PaneModel model)
{ {
this.model = model; this.model = model;
this.model.PropertyChanged += Model_PropertyChanged;
}
private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(model.IsCloseable)) {
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
} }
public event EventHandler CanExecuteChanged; public event EventHandler CanExecuteChanged;

Loading…
Cancel
Save