diff --git a/ICSharpCode.Decompiler/FlowAnalysis/OpCodeInfo.cs b/ICSharpCode.Decompiler/FlowAnalysis/OpCodeInfo.cs index 9da741a58..763fef4dc 100644 --- a/ICSharpCode.Decompiler/FlowAnalysis/OpCodeInfo.cs +++ b/ICSharpCode.Decompiler/FlowAnalysis/OpCodeInfo.cs @@ -205,7 +205,7 @@ namespace ICSharpCode.Decompiler // CanThrow is true by default - most OO instructions can throw, so we don't specify CanThrow all of the time new OpCodeInfo(OpCodes.Box), new OpCodeInfo(OpCodes.Callvirt), - new OpCodeInfo(OpCodes.Castclass), // (output type not Input0 as type arguments may change) + new OpCodeInfo(OpCodes.Castclass), new OpCodeInfo(OpCodes.Cpobj), new OpCodeInfo(OpCodes.Initobj) { CanThrow = false }, new OpCodeInfo(OpCodes.Isinst) { CanThrow = false }, @@ -232,11 +232,11 @@ namespace ICSharpCode.Decompiler new OpCodeInfo(OpCodes.Ldstr) { CanThrow = false }, new OpCodeInfo(OpCodes.Ldtoken) { CanThrow = false }, new OpCodeInfo(OpCodes.Ldvirtftn), - //new OpCodeInfo(OpCodes.Mkrefany), don't enable this without checking what it is + new OpCodeInfo(OpCodes.Mkrefany), new OpCodeInfo(OpCodes.Newarr), new OpCodeInfo(OpCodes.Newobj), - //new OpCodeInfo(OpCodes.Mkrefany), don't enable this without checking what it is - //new OpCodeInfo(OpCodes.Refanyval), don't enable this without checking what it is + new OpCodeInfo(OpCodes.Refanytype) { CanThrow = false }, + new OpCodeInfo(OpCodes.Refanyval), new OpCodeInfo(OpCodes.Rethrow), new OpCodeInfo(OpCodes.Sizeof) { CanThrow = false }, new OpCodeInfo(OpCodes.Stelem_Any), diff --git a/ILSpy/Disassembler/ReflectionDisassembler.cs b/ILSpy/Disassembler/ReflectionDisassembler.cs index 005a7e0c7..97bef7134 100644 --- a/ILSpy/Disassembler/ReflectionDisassembler.cs +++ b/ILSpy/Disassembler/ReflectionDisassembler.cs @@ -142,13 +142,17 @@ namespace ICSharpCode.ILSpy.Disassembler WriteFlags(method.ImplAttributes & ~(MethodImplAttributes.CodeTypeMask | MethodImplAttributes.ManagedMask), methodImpl); output.Unindent(); - OpenBlock(isInType); - WriteAttributes(method.CustomAttributes); - - if (method.HasBody) - methodBodyDisassembler.Disassemble(method.Body); - - CloseBlock("End of method " + method.DeclaringType.Name + "." + method.Name); + if (method.HasBody || method.HasCustomAttributes) { + OpenBlock(defaultCollapsed: isInType); + WriteAttributes(method.CustomAttributes); + + if (method.HasBody) + methodBodyDisassembler.Disassemble(method.Body); + + CloseBlock("End of method " + method.DeclaringType.Name + "." + method.Name); + } else { + output.WriteLine(); + } } void WriteParameters(Collection parameters) @@ -181,6 +185,7 @@ namespace ICSharpCode.ILSpy.Disassembler { FieldAttributes.InitOnly, "initonly" }, { FieldAttributes.SpecialName, "specialname" }, { FieldAttributes.RTSpecialName, "rtspecialname" }, + { FieldAttributes.NotSerialized, "notserialized" }, }; public void DisassembleField(FieldDefinition field) @@ -195,7 +200,13 @@ namespace ICSharpCode.ILSpy.Disassembler output.Write(" = "); DisassemblerHelpers.WriteOperand(output, field.Constant); } - output.WriteLine(); + if (field.HasCustomAttributes) { + OpenBlock(false); + WriteAttributes(field.CustomAttributes); + CloseBlock(); + } else { + output.WriteLine(); + } } #endregion @@ -296,6 +307,7 @@ namespace ICSharpCode.ILSpy.Disassembler { TypeAttributes.Import, "import" }, { TypeAttributes.Serializable, "serializable" }, { TypeAttributes.BeforeFieldInit, "beforefieldinit" }, + { TypeAttributes.HasSecurity, null }, }; public void DisassembleType(TypeDefinition type) @@ -311,16 +323,19 @@ namespace ICSharpCode.ILSpy.Disassembler WriteFlags(type.Attributes & ~masks, typeAttributes); output.Write(DisassemblerHelpers.Escape(type.Name)); + output.MarkFoldStart(defaultCollapsed: isInType); + output.WriteLine(); if (type.BaseType != null) { - output.WriteLine(); output.Indent(); output.Write("extends "); type.BaseType.WriteTo(output, true); + output.WriteLine(); output.Unindent(); } - OpenBlock(isInType); + output.WriteLine("{"); + output.Indent(); bool oldIsInType = isInType; isInType = true; WriteAttributes(type.CustomAttributes); @@ -351,7 +366,6 @@ namespace ICSharpCode.ILSpy.Disassembler foreach (var prop in type.Properties) { cancellationToken.ThrowIfCancellationRequested(); DisassembleProperty(prop); - output.WriteLine(); } output.WriteLine(); } @@ -374,9 +388,8 @@ namespace ICSharpCode.ILSpy.Disassembler output.WriteLine(); } } - output.WriteLine(); } - CloseBlock("// End of class " + type.FullName); + CloseBlock("End of class " + type.FullName); isInType = oldIsInType; } #endregion @@ -428,7 +441,7 @@ namespace ICSharpCode.ILSpy.Disassembler output.Unindent(); output.Write("}"); if (comment != null) - output.Write("// " + comment); + output.Write(" // " + comment); output.MarkFoldEnd(); output.WriteLine(); } @@ -439,7 +452,7 @@ namespace ICSharpCode.ILSpy.Disassembler long tested = 0; foreach (var pair in flagNames) { tested |= pair.Key; - if ((val & pair.Key) != 0) { + if ((val & pair.Key) != 0 && pair.Value != null) { output.Write(pair.Value); output.Write(' '); } @@ -453,8 +466,10 @@ namespace ICSharpCode.ILSpy.Disassembler long val = Convert.ToInt64(enumValue); foreach (var pair in enumNames) { if (pair.Key == val) { - output.Write(pair.Value); - output.Write(' '); + if (pair.Value != null) { + output.Write(pair.Value); + output.Write(' '); + } return; } } diff --git a/ILSpy/TextView/DecompilerTextView.cs b/ILSpy/TextView/DecompilerTextView.cs index aee8d6945..1fb76156c 100644 --- a/ILSpy/TextView/DecompilerTextView.cs +++ b/ILSpy/TextView/DecompilerTextView.cs @@ -88,6 +88,7 @@ namespace ICSharpCode.ILSpy.TextView if (currentCancellationTokenSource == myCancellationTokenSource) { currentCancellationTokenSource = null; waitAdorner.Visibility = Visibility.Collapsed; + textEditor.ScrollToHome(); foldingManager.Clear(); try { SmartTextOutput textOutput = task.Result;