Browse Source

#1330: add more exception handling to CSharpDecompiler, so an entity that caused decompilation to fail can easier be identified.

pull/1347/head
Siegfried Pammer 7 years ago
parent
commit
fd0d898703
  1. 24
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 20
      ICSharpCode.Decompiler/DecompilerException.cs

24
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -425,6 +425,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -425,6 +425,7 @@ namespace ICSharpCode.Decompiler.CSharp
void DoDecompileModuleAndAssemblyAttributes(DecompileRun decompileRun, ITypeResolveContext decompilationContext, SyntaxTree syntaxTree)
{
try {
foreach (var a in typeSystem.MainModule.GetAssemblyAttributes()) {
var astBuilder = CreateAstBuilder(decompilationContext);
var attrSection = new AttributeSection(astBuilder.ConvertAttribute(a));
@ -437,6 +438,9 @@ namespace ICSharpCode.Decompiler.CSharp @@ -437,6 +438,9 @@ namespace ICSharpCode.Decompiler.CSharp
attrSection.AttributeTarget = "module";
syntaxTree.AddChild(attrSection, SyntaxTree.MemberRole);
}
} catch (Exception innerException) when (!(innerException is OperationCanceledException || innerException is DecompilerException)) {
throw new DecompilerException(module, null, innerException, "Error decompiling module and assembly attributes of " + module.AssemblyName);
}
}
void DoDecompileTypes(IEnumerable<TypeDefinitionHandle> types, DecompileRun decompileRun, ITypeResolveContext decompilationContext, SyntaxTree syntaxTree)
@ -923,6 +927,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -923,6 +927,7 @@ namespace ICSharpCode.Decompiler.CSharp
EntityDeclaration DoDecompile(ITypeDefinition typeDef, DecompileRun decompileRun, ITypeResolveContext decompilationContext)
{
Debug.Assert(decompilationContext.CurrentTypeDefinition == typeDef);
try {
var typeSystemAstBuilder = CreateAstBuilder(decompilationContext);
var entityDecl = typeSystemAstBuilder.ConvertEntity(typeDef);
var typeDecl = entityDecl as TypeDeclaration;
@ -999,6 +1004,9 @@ namespace ICSharpCode.Decompiler.CSharp @@ -999,6 +1004,9 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
return typeDecl;
} catch (Exception innerException) when (!(innerException is OperationCanceledException || innerException is DecompilerException)) {
throw new DecompilerException(module, typeDef, innerException);
}
}
enum EnumValueDisplayMode
@ -1189,8 +1197,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1189,8 +1197,8 @@ namespace ICSharpCode.Decompiler.CSharp
RemoveAttribute(entityDecl, KnownAttribute.AsyncStateMachine);
RemoveAttribute(entityDecl, KnownAttribute.DebuggerStepThrough);
}
} catch (Exception innerException) when (!(innerException is OperationCanceledException)) {
throw new DecompilerException(module.PEFile, (MethodDefinitionHandle)method.MetadataToken, innerException);
} catch (Exception innerException) when (!(innerException is OperationCanceledException || innerException is DecompilerException)) {
throw new DecompilerException(module, method, innerException);
}
}
@ -1241,6 +1249,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1241,6 +1249,7 @@ namespace ICSharpCode.Decompiler.CSharp
EntityDeclaration DoDecompile(IField field, DecompileRun decompileRun, ITypeResolveContext decompilationContext)
{
Debug.Assert(decompilationContext.CurrentMember == field);
try {
var typeSystemAstBuilder = CreateAstBuilder(decompilationContext);
if (decompilationContext.CurrentTypeDefinition.Kind == TypeKind.Enum) {
var enumDec = new EnumMemberDeclaration { Name = field.Name };
@ -1286,6 +1295,9 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1286,6 +1295,9 @@ namespace ICSharpCode.Decompiler.CSharp
((FieldDeclaration)fieldDecl).Variables.Single().AddChild(new Comment(message, CommentType.MultiLine), Roles.Comment);
}
return fieldDecl;
} catch (Exception innerException) when (!(innerException is OperationCanceledException || innerException is DecompilerException)) {
throw new DecompilerException(module, field, innerException);
}
}
internal static bool IsFixedField(IField field, out IType type, out int elementCount)
@ -1306,6 +1318,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1306,6 +1318,7 @@ namespace ICSharpCode.Decompiler.CSharp
EntityDeclaration DoDecompile(IProperty property, DecompileRun decompileRun, ITypeResolveContext decompilationContext)
{
Debug.Assert(decompilationContext.CurrentMember == property);
try {
var typeSystemAstBuilder = CreateAstBuilder(decompilationContext);
EntityDeclaration propertyDecl = typeSystemAstBuilder.ConvertEntity(property);
if (property.IsExplicitInterfaceImplementation && !property.IsIndexer) {
@ -1332,11 +1345,15 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1332,11 +1345,15 @@ namespace ICSharpCode.Decompiler.CSharp
if (!accessorHandle.GetMethodImplementations(metadata).Any() && accessor.HasFlag(System.Reflection.MethodAttributes.Virtual) == accessor.HasFlag(System.Reflection.MethodAttributes.NewSlot))
SetNewModifier(propertyDecl);
return propertyDecl;
} catch (Exception innerException) when (!(innerException is OperationCanceledException || innerException is DecompilerException)) {
throw new DecompilerException(module, property, innerException);
}
}
EntityDeclaration DoDecompile(IEvent ev, DecompileRun decompileRun, ITypeResolveContext decompilationContext)
{
Debug.Assert(decompilationContext.CurrentMember == ev);
try {
var typeSystemAstBuilder = CreateAstBuilder(decompilationContext);
typeSystemAstBuilder.UseCustomEvents = ev.DeclaringTypeDefinition.Kind != TypeKind.Interface;
var eventDecl = typeSystemAstBuilder.ConvertEntity(ev);
@ -1355,6 +1372,9 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1355,6 +1372,9 @@ namespace ICSharpCode.Decompiler.CSharp
SetNewModifier(eventDecl);
}
return eventDecl;
} catch (Exception innerException) when (!(innerException is OperationCanceledException || innerException is DecompilerException)) {
throw new DecompilerException(module, ev, innerException);
}
}
#region Sequence Points

20
ICSharpCode.Decompiler/DecompilerException.cs

@ -34,24 +34,18 @@ namespace ICSharpCode.Decompiler @@ -34,24 +34,18 @@ namespace ICSharpCode.Decompiler
/// </summary>
public class DecompilerException : Exception, ISerializable
{
public string AssemblyName => Module.FullName;
public string AssemblyName => Module.AssemblyName;
public string FileName => Module.FileName;
public string FileName => Module.PEFile.FileName;
public MethodDefinitionHandle DecompiledMethod { get; }
public Metadata.PEFile Module { get; }
public IEntity DecompiledEntity { get; }
public IModule Module { get; }
public DecompilerException(Metadata.PEFile module, MethodDefinitionHandle decompiledMethod, Exception innerException)
: base("Error decompiling " + GetFullName(decompiledMethod, module.Metadata) + Environment.NewLine, innerException)
public DecompilerException(MetadataModule module, IEntity decompiledEntity, Exception innerException, string message = null)
: base(message ?? "Error decompiling " + decompiledEntity.FullName + Environment.NewLine, innerException)
{
this.Module = module;
this.DecompiledMethod = decompiledMethod;
}
private static string GetFullName(MethodDefinitionHandle decompiledMethod, MetadataReader metadata)
{
var method = metadata.GetMethodDefinition(decompiledMethod);
return $"{method.GetDeclaringType().GetFullTypeName(metadata).ToString()}.{metadata.GetString(method.Name)}";
this.DecompiledEntity = decompiledEntity;
}
// This constructor is needed for serialization.

Loading…
Cancel
Save