Browse Source

If the decompiler crashes: Show name of the decompiled method in the exception message.

pull/10/head
Daniel Grunwald 14 years ago
parent
commit
12a0bb330d
  1. 4
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 12
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  3. 27
      ICSharpCode.Decompiler/DecompilerException.cs
  4. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  5. 14
      ILSpy/CSharpLanguage.cs
  6. 2
      ILSpy/MainWindow.xaml.cs
  7. 67
      ILSpy/TextView/DecompilerTextView.cs

4
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -337,6 +337,8 @@ namespace Decompiler @@ -337,6 +337,8 @@ namespace Decompiler
Modifiers ConvertModifiers(MethodDefinition methodDef)
{
if (methodDef == null)
return Modifiers.None;
Modifiers modifiers = Modifiers.None;
if (methodDef.IsPrivate)
modifiers |= Modifiers.Private;
@ -431,7 +433,7 @@ namespace Decompiler @@ -431,7 +433,7 @@ namespace Decompiler
PropertyDeclaration CreateProperty(PropertyDefinition propDef)
{
PropertyDeclaration astProp = new PropertyDeclaration();
astProp.Modifiers = ConvertModifiers(propDef.GetMethod);
astProp.Modifiers = ConvertModifiers(propDef.GetMethod ?? propDef.SetMethod);
astProp.Name = propDef.Name;
astProp.ReturnType = ConvertType(propDef.PropertyType, propDef);
if (propDef.GetMethod != null) {

12
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -21,7 +21,17 @@ namespace Decompiler @@ -21,7 +21,17 @@ namespace Decompiler
{
AstMethodBodyBuilder builder = new AstMethodBodyBuilder();
builder.methodDef = methodDef;
return builder.CreateMethodBody();
if (Debugger.IsAttached) {
return builder.CreateMethodBody();
} else {
try {
return builder.CreateMethodBody();
} catch (OperationCanceledException) {
throw;
} catch (Exception ex) {
throw new ICSharpCode.Decompiler.DecompilerException(methodDef, ex);
}
}
}
static readonly Dictionary<string, string> typeNameToVariableNameDict = new Dictionary<string, string> {

27
ICSharpCode.Decompiler/DecompilerException.cs

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Runtime.Serialization;
using Mono.Cecil;
namespace ICSharpCode.Decompiler
{
/// <summary>
/// Desctiption of DecompilerException.
/// </summary>
public class DecompilerException : Exception, ISerializable
{
public MethodDefinition DecompiledMethod { get; set; }
public DecompilerException(MethodDefinition decompiledMethod, Exception innerException)
: base("Error decompiling " + decompiledMethod.FullName, innerException)
{
}
// This constructor is needed for serialization.
protected DecompilerException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -64,6 +64,7 @@ @@ -64,6 +64,7 @@
<Compile Include="Ast\Transforms\RestoreLoop.cs" />
<Compile Include="Ast\Transforms\TransformationPipeline.cs" />
<Compile Include="CecilExtensions.cs" />
<Compile Include="DecompilerException.cs" />
<Compile Include="Disassembler\DisassemblerHelpers.cs" />
<Compile Include="Disassembler\ILStructure.cs" />
<Compile Include="Disassembler\MethodBodyDisassembler.cs" />

14
ILSpy/CSharpLanguage.cs

@ -101,6 +101,20 @@ namespace ICSharpCode.ILSpy @@ -101,6 +101,20 @@ namespace ICSharpCode.ILSpy
codeDomBuilder.GenerateCode(output, transformAbortCondition);
}
public override void DecompileAssembly(AssemblyDefinition assembly, string fileName, ITextOutput output, DecompilationOptions options)
{
if (options.FullDecompilation) {
foreach (TypeDefinition type in assembly.MainModule.Types) {
AstBuilder codeDomBuilder = new AstBuilder();
codeDomBuilder.AddType(type);
codeDomBuilder.GenerateCode(output, transformAbortCondition);
output.WriteLine();
}
} else {
base.DecompileAssembly(assembly, fileName, output, options);
}
}
public override string TypeToString(TypeReference type, bool includeNamespace, ICustomAttributeProvider typeAttributes)
{
AstType astType = AstBuilder.ConvertType(type, typeAttributes);

2
ILSpy/MainWindow.xaml.cs

@ -397,7 +397,7 @@ namespace ICSharpCode.ILSpy @@ -397,7 +397,7 @@ namespace ICSharpCode.ILSpy
}
decompilerTextView.SaveToDisk(sessionSettings.FilterSettings.Language,
treeView.GetTopLevelSelection().OfType<ILSpyTreeNode>(),
new DecompilationOptions());
new DecompilationOptions() { FullDecompilation = true });
}
#endregion

67
ILSpy/TextView/DecompilerTextView.cs

@ -225,7 +225,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -225,7 +225,7 @@ namespace ICSharpCode.ILSpy.TextView
RunWithCancellation(
delegate (CancellationToken ct) { // creation of the background task
context.Options.CancellationToken = ct;
return RunDecompiler(context, outputLengthLimit);
return DecompileAsync(context, outputLengthLimit);
},
delegate (Task<AvalonEditTextOutput> task) { // handling the result
try {
@ -250,7 +250,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -250,7 +250,7 @@ namespace ICSharpCode.ILSpy.TextView
});
}
static Task<AvalonEditTextOutput> RunDecompiler(DecompilationContext context, int outputLengthLimit)
static Task<AvalonEditTextOutput> DecompileAsync(DecompilationContext context, int outputLengthLimit)
{
Debug.WriteLine("Start decompilation of {0} tree nodes", context.TreeNodes.Length);
@ -274,10 +274,11 @@ namespace ICSharpCode.ILSpy.TextView @@ -274,10 +274,11 @@ namespace ICSharpCode.ILSpy.TextView
} catch (AggregateException ex) {
tcs.SetException(ex);
} catch (OperationCanceledException ex) {
tcs.SetException(ex);
#else
} catch (Exception ex) {
#endif
tcs.SetException(ex);
#endif
}
}));
thread.Start();
@ -392,29 +393,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -392,29 +393,7 @@ namespace ICSharpCode.ILSpy.TextView
RunWithCancellation(
delegate (CancellationToken ct) {
context.Options.CancellationToken = ct;
return Task.Factory.StartNew(
delegate {
using (StreamWriter w = new StreamWriter(fileName)) {
try {
DecompileNodes(context, new PlainTextOutput(w));
} catch (OperationCanceledException) {
w.WriteLine();
w.WriteLine("Decompiled was cancelled.");
throw;
}
}
AvalonEditTextOutput output = new AvalonEditTextOutput();
output.WriteLine("Decompilation complete.");
output.WriteLine();
output.AddButton(
null, "Open Explorer",
delegate {
Process.Start("explorer", "/select,\"" + fileName + "\"");
}
);
output.WriteLine();
return output;
}, TaskCreationOptions.LongRunning);
return SaveToDiskAsync(context, fileName);
},
delegate (Task<AvalonEditTextOutput> task) {
try {
@ -433,6 +412,42 @@ namespace ICSharpCode.ILSpy.TextView @@ -433,6 +412,42 @@ namespace ICSharpCode.ILSpy.TextView
}
});
}
Task<AvalonEditTextOutput> SaveToDiskAsync(DecompilationContext context, string fileName)
{
TaskCompletionSource<AvalonEditTextOutput> tcs = new TaskCompletionSource<AvalonEditTextOutput>();
Thread thread = new Thread(new ThreadStart(
delegate {
try {
using (StreamWriter w = new StreamWriter(fileName)) {
try {
DecompileNodes(context, new PlainTextOutput(w));
} catch (OperationCanceledException) {
w.WriteLine();
w.WriteLine("Decompiled was cancelled.");
throw;
}
}
AvalonEditTextOutput output = new AvalonEditTextOutput();
output.WriteLine("Decompilation complete.");
output.WriteLine();
output.AddButton(null, "Open Explorer", delegate { Process.Start("explorer", "/select,\"" + fileName + "\""); });
output.WriteLine();
tcs.SetResult(output);
#if DEBUG
} catch (OperationCanceledException ex) {
tcs.SetException(ex);
} catch (AggregateException ex) {
tcs.SetException(ex);
#else
} catch (Exception ex) {
tcs.SetException(ex);
#endif
}
}));
thread.Start();
return tcs.Task;
}
/// <summary>
/// Cleans up a node name for use as a file name.

Loading…
Cancel
Save