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. 342
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 20
      ICSharpCode.Decompiler/DecompilerException.cs

342
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -425,17 +425,21 @@ namespace ICSharpCode.Decompiler.CSharp
void DoDecompileModuleAndAssemblyAttributes(DecompileRun decompileRun, ITypeResolveContext decompilationContext, SyntaxTree syntaxTree) void DoDecompileModuleAndAssemblyAttributes(DecompileRun decompileRun, ITypeResolveContext decompilationContext, SyntaxTree syntaxTree)
{ {
foreach (var a in typeSystem.MainModule.GetAssemblyAttributes()) { try {
var astBuilder = CreateAstBuilder(decompilationContext); foreach (var a in typeSystem.MainModule.GetAssemblyAttributes()) {
var attrSection = new AttributeSection(astBuilder.ConvertAttribute(a)); var astBuilder = CreateAstBuilder(decompilationContext);
attrSection.AttributeTarget = "assembly"; var attrSection = new AttributeSection(astBuilder.ConvertAttribute(a));
syntaxTree.AddChild(attrSection, SyntaxTree.MemberRole); attrSection.AttributeTarget = "assembly";
} syntaxTree.AddChild(attrSection, SyntaxTree.MemberRole);
foreach (var a in typeSystem.MainModule.GetModuleAttributes()) { }
var astBuilder = CreateAstBuilder(decompilationContext); foreach (var a in typeSystem.MainModule.GetModuleAttributes()) {
var attrSection = new AttributeSection(astBuilder.ConvertAttribute(a)); var astBuilder = CreateAstBuilder(decompilationContext);
attrSection.AttributeTarget = "module"; var attrSection = new AttributeSection(astBuilder.ConvertAttribute(a));
syntaxTree.AddChild(attrSection, SyntaxTree.MemberRole); 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);
} }
} }
@ -923,82 +927,86 @@ namespace ICSharpCode.Decompiler.CSharp
EntityDeclaration DoDecompile(ITypeDefinition typeDef, DecompileRun decompileRun, ITypeResolveContext decompilationContext) EntityDeclaration DoDecompile(ITypeDefinition typeDef, DecompileRun decompileRun, ITypeResolveContext decompilationContext)
{ {
Debug.Assert(decompilationContext.CurrentTypeDefinition == typeDef); Debug.Assert(decompilationContext.CurrentTypeDefinition == typeDef);
var typeSystemAstBuilder = CreateAstBuilder(decompilationContext); try {
var entityDecl = typeSystemAstBuilder.ConvertEntity(typeDef); var typeSystemAstBuilder = CreateAstBuilder(decompilationContext);
var typeDecl = entityDecl as TypeDeclaration; var entityDecl = typeSystemAstBuilder.ConvertEntity(typeDef);
if (typeDecl == null) { var typeDecl = entityDecl as TypeDeclaration;
// e.g. DelegateDeclaration if (typeDecl == null) {
return entityDecl; // e.g. DelegateDeclaration
} return entityDecl;
foreach (var type in typeDef.NestedTypes) {
if (!type.MetadataToken.IsNil && !MemberIsHidden(module.PEFile, type.MetadataToken, settings)) {
var nestedType = DoDecompile(type, decompileRun, decompilationContext.WithCurrentTypeDefinition(type));
SetNewModifier(nestedType);
typeDecl.Members.Add(nestedType);
} }
} foreach (var type in typeDef.NestedTypes) {
foreach (var field in typeDef.Fields) { if (!type.MetadataToken.IsNil && !MemberIsHidden(module.PEFile, type.MetadataToken, settings)) {
if (!field.MetadataToken.IsNil && !MemberIsHidden(module.PEFile, field.MetadataToken, settings)) { var nestedType = DoDecompile(type, decompileRun, decompilationContext.WithCurrentTypeDefinition(type));
var memberDecl = DoDecompile(field, decompileRun, decompilationContext.WithCurrentMember(field)); SetNewModifier(nestedType);
typeDecl.Members.Add(memberDecl); typeDecl.Members.Add(nestedType);
}
} }
} foreach (var field in typeDef.Fields) {
foreach (var property in typeDef.Properties) { if (!field.MetadataToken.IsNil && !MemberIsHidden(module.PEFile, field.MetadataToken, settings)) {
if (!property.MetadataToken.IsNil && !MemberIsHidden(module.PEFile, property.MetadataToken, settings)) { var memberDecl = DoDecompile(field, decompileRun, decompilationContext.WithCurrentMember(field));
var propDecl = DoDecompile(property, decompileRun, decompilationContext.WithCurrentMember(property)); typeDecl.Members.Add(memberDecl);
typeDecl.Members.Add(propDecl); }
} }
} foreach (var property in typeDef.Properties) {
foreach (var @event in typeDef.Events) { if (!property.MetadataToken.IsNil && !MemberIsHidden(module.PEFile, property.MetadataToken, settings)) {
if (!@event.MetadataToken.IsNil && !MemberIsHidden(module.PEFile, @event.MetadataToken, settings)) { var propDecl = DoDecompile(property, decompileRun, decompilationContext.WithCurrentMember(property));
var eventDecl = DoDecompile(@event, decompileRun, decompilationContext.WithCurrentMember(@event)); typeDecl.Members.Add(propDecl);
typeDecl.Members.Add(eventDecl); }
} }
} foreach (var @event in typeDef.Events) {
foreach (var method in typeDef.Methods) { if (!@event.MetadataToken.IsNil && !MemberIsHidden(module.PEFile, @event.MetadataToken, settings)) {
if (!method.MetadataToken.IsNil && !MemberIsHidden(module.PEFile, method.MetadataToken, settings)) { var eventDecl = DoDecompile(@event, decompileRun, decompilationContext.WithCurrentMember(@event));
var memberDecl = DoDecompile(method, decompileRun, decompilationContext.WithCurrentMember(method)); typeDecl.Members.Add(eventDecl);
typeDecl.Members.Add(memberDecl); }
typeDecl.Members.AddRange(AddInterfaceImplHelpers(memberDecl, method, typeSystemAstBuilder));
} }
} foreach (var method in typeDef.Methods) {
if (typeDecl.Members.OfType<IndexerDeclaration>().Any(idx => idx.PrivateImplementationType.IsNull)) { if (!method.MetadataToken.IsNil && !MemberIsHidden(module.PEFile, method.MetadataToken, settings)) {
// Remove the [DefaultMember] attribute if the class contains indexers var memberDecl = DoDecompile(method, decompileRun, decompilationContext.WithCurrentMember(method));
RemoveAttribute(typeDecl, KnownAttribute.DefaultMember); typeDecl.Members.Add(memberDecl);
} typeDecl.Members.AddRange(AddInterfaceImplHelpers(memberDecl, method, typeSystemAstBuilder));
if (settings.IntroduceRefModifiersOnStructs) {
if (FindAttribute(typeDecl, KnownAttribute.Obsolete, out var attr)) {
if (obsoleteAttributePattern.IsMatch(attr)) {
if (attr.Parent is AttributeSection section && section.Attributes.Count == 1)
section.Remove();
else
attr.Remove();
} }
} }
} if (typeDecl.Members.OfType<IndexerDeclaration>().Any(idx => idx.PrivateImplementationType.IsNull)) {
if (typeDecl.ClassType == ClassType.Enum) { // Remove the [DefaultMember] attribute if the class contains indexers
switch (DetectBestEnumValueDisplayMode(typeDef, module.PEFile)) { RemoveAttribute(typeDecl, KnownAttribute.DefaultMember);
case EnumValueDisplayMode.FirstOnly: }
foreach (var enumMember in typeDecl.Members.OfType<EnumMemberDeclaration>().Skip(1)) { if (settings.IntroduceRefModifiersOnStructs) {
enumMember.Initializer = null; if (FindAttribute(typeDecl, KnownAttribute.Obsolete, out var attr)) {
if (obsoleteAttributePattern.IsMatch(attr)) {
if (attr.Parent is AttributeSection section && section.Attributes.Count == 1)
section.Remove();
else
attr.Remove();
} }
break; }
case EnumValueDisplayMode.None: }
foreach (var enumMember in typeDecl.Members.OfType<EnumMemberDeclaration>()) { if (typeDecl.ClassType == ClassType.Enum) {
enumMember.Initializer = null; switch (DetectBestEnumValueDisplayMode(typeDef, module.PEFile)) {
if (enumMember.GetSymbol() is IField f && f.ConstantValue == null) { case EnumValueDisplayMode.FirstOnly:
typeDecl.InsertChildBefore(enumMember, new Comment(" error: enumerator has no value"), Roles.Comment); foreach (var enumMember in typeDecl.Members.OfType<EnumMemberDeclaration>().Skip(1)) {
enumMember.Initializer = null;
} }
} break;
break; case EnumValueDisplayMode.None:
case EnumValueDisplayMode.All: foreach (var enumMember in typeDecl.Members.OfType<EnumMemberDeclaration>()) {
// nothing needs to be changed. enumMember.Initializer = null;
break; if (enumMember.GetSymbol() is IField f && f.ConstantValue == null) {
default: typeDecl.InsertChildBefore(enumMember, new Comment(" error: enumerator has no value"), Roles.Comment);
throw new ArgumentOutOfRangeException(); }
}
break;
case EnumValueDisplayMode.All:
// nothing needs to be changed.
break;
default:
throw new ArgumentOutOfRangeException();
}
} }
return typeDecl;
} catch (Exception innerException) when (!(innerException is OperationCanceledException || innerException is DecompilerException)) {
throw new DecompilerException(module, typeDef, innerException);
} }
return typeDecl;
} }
enum EnumValueDisplayMode enum EnumValueDisplayMode
@ -1189,8 +1197,8 @@ namespace ICSharpCode.Decompiler.CSharp
RemoveAttribute(entityDecl, KnownAttribute.AsyncStateMachine); RemoveAttribute(entityDecl, KnownAttribute.AsyncStateMachine);
RemoveAttribute(entityDecl, KnownAttribute.DebuggerStepThrough); RemoveAttribute(entityDecl, KnownAttribute.DebuggerStepThrough);
} }
} catch (Exception innerException) when (!(innerException is OperationCanceledException)) { } catch (Exception innerException) when (!(innerException is OperationCanceledException || innerException is DecompilerException)) {
throw new DecompilerException(module.PEFile, (MethodDefinitionHandle)method.MetadataToken, innerException); throw new DecompilerException(module, method, innerException);
} }
} }
@ -1241,51 +1249,55 @@ namespace ICSharpCode.Decompiler.CSharp
EntityDeclaration DoDecompile(IField field, DecompileRun decompileRun, ITypeResolveContext decompilationContext) EntityDeclaration DoDecompile(IField field, DecompileRun decompileRun, ITypeResolveContext decompilationContext)
{ {
Debug.Assert(decompilationContext.CurrentMember == field); Debug.Assert(decompilationContext.CurrentMember == field);
var typeSystemAstBuilder = CreateAstBuilder(decompilationContext); try {
if (decompilationContext.CurrentTypeDefinition.Kind == TypeKind.Enum) { var typeSystemAstBuilder = CreateAstBuilder(decompilationContext);
var enumDec = new EnumMemberDeclaration { Name = field.Name }; if (decompilationContext.CurrentTypeDefinition.Kind == TypeKind.Enum) {
if (field.ConstantValue != null) { var enumDec = new EnumMemberDeclaration { Name = field.Name };
long initValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, field.ConstantValue, false); if (field.ConstantValue != null) {
enumDec.Initializer = typeSystemAstBuilder.ConvertConstantValue(decompilationContext.CurrentTypeDefinition.EnumUnderlyingType, field.ConstantValue); long initValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, field.ConstantValue, false);
if (enumDec.Initializer is PrimitiveExpression primitive enumDec.Initializer = typeSystemAstBuilder.ConvertConstantValue(decompilationContext.CurrentTypeDefinition.EnumUnderlyingType, field.ConstantValue);
&& initValue >= 0 && (decompilationContext.CurrentTypeDefinition.HasAttribute(KnownAttribute.Flags) if (enumDec.Initializer is PrimitiveExpression primitive
|| (initValue > 9 && (unchecked(initValue & (initValue - 1)) == 0 || unchecked(initValue & (initValue + 1)) == 0)))) { && initValue >= 0 && (decompilationContext.CurrentTypeDefinition.HasAttribute(KnownAttribute.Flags)
primitive.SetValue(initValue, $"0x{initValue:X}"); || (initValue > 9 && (unchecked(initValue & (initValue - 1)) == 0 || unchecked(initValue & (initValue + 1)) == 0)))) {
primitive.SetValue(initValue, $"0x{initValue:X}");
}
} }
enumDec.Attributes.AddRange(field.GetAttributes().Select(a => new AttributeSection(typeSystemAstBuilder.ConvertAttribute(a))));
enumDec.AddAnnotation(new MemberResolveResult(null, field));
return enumDec;
} }
enumDec.Attributes.AddRange(field.GetAttributes().Select(a => new AttributeSection(typeSystemAstBuilder.ConvertAttribute(a)))); typeSystemAstBuilder.UseSpecialConstants = !field.DeclaringType.Equals(field.ReturnType);
enumDec.AddAnnotation(new MemberResolveResult(null, field)); var fieldDecl = typeSystemAstBuilder.ConvertEntity(field);
return enumDec; SetNewModifier(fieldDecl);
} if (settings.FixedBuffers && IsFixedField(field, out var elementType, out var elementCount)) {
typeSystemAstBuilder.UseSpecialConstants = !field.DeclaringType.Equals(field.ReturnType); var fixedFieldDecl = new FixedFieldDeclaration();
var fieldDecl = typeSystemAstBuilder.ConvertEntity(field); fieldDecl.Attributes.MoveTo(fixedFieldDecl.Attributes);
SetNewModifier(fieldDecl); fixedFieldDecl.Modifiers = fieldDecl.Modifiers;
if (settings.FixedBuffers && IsFixedField(field, out var elementType, out var elementCount)) { fixedFieldDecl.ReturnType = typeSystemAstBuilder.ConvertType(elementType);
var fixedFieldDecl = new FixedFieldDeclaration(); fixedFieldDecl.Variables.Add(new FixedVariableInitializer(field.Name, new PrimitiveExpression(elementCount)));
fieldDecl.Attributes.MoveTo(fixedFieldDecl.Attributes); fixedFieldDecl.Variables.Single().CopyAnnotationsFrom(((FieldDeclaration)fieldDecl).Variables.Single());
fixedFieldDecl.Modifiers = fieldDecl.Modifiers; fixedFieldDecl.CopyAnnotationsFrom(fieldDecl);
fixedFieldDecl.ReturnType = typeSystemAstBuilder.ConvertType(elementType); RemoveAttribute(fixedFieldDecl, KnownAttribute.FixedBuffer);
fixedFieldDecl.Variables.Add(new FixedVariableInitializer(field.Name, new PrimitiveExpression(elementCount))); return fixedFieldDecl;
fixedFieldDecl.Variables.Single().CopyAnnotationsFrom(((FieldDeclaration)fieldDecl).Variables.Single());
fixedFieldDecl.CopyAnnotationsFrom(fieldDecl);
RemoveAttribute(fixedFieldDecl, KnownAttribute.FixedBuffer);
return fixedFieldDecl;
}
var fieldDefinition = metadata.GetFieldDefinition((FieldDefinitionHandle)field.MetadataToken);
if (fieldDefinition.HasFlag(System.Reflection.FieldAttributes.HasFieldRVA)) {
// Field data as specified in II.16.3.2 of ECMA-335 6th edition:
// .data I_X = int32(123)
// .field public static int32 _x at I_X
string message;
try {
var initVal = fieldDefinition.GetInitialValue(module.PEFile.Reader, TypeSystem);
message = string.Format(" Not supported: data({0}) ", BitConverter.ToString(initVal.ReadBytes(initVal.RemainingBytes)).Replace('-', ' '));
} catch (BadImageFormatException ex) {
message = ex.Message;
} }
((FieldDeclaration)fieldDecl).Variables.Single().AddChild(new Comment(message, CommentType.MultiLine), Roles.Comment); var fieldDefinition = metadata.GetFieldDefinition((FieldDefinitionHandle)field.MetadataToken);
if (fieldDefinition.HasFlag(System.Reflection.FieldAttributes.HasFieldRVA)) {
// Field data as specified in II.16.3.2 of ECMA-335 6th edition:
// .data I_X = int32(123)
// .field public static int32 _x at I_X
string message;
try {
var initVal = fieldDefinition.GetInitialValue(module.PEFile.Reader, TypeSystem);
message = string.Format(" Not supported: data({0}) ", BitConverter.ToString(initVal.ReadBytes(initVal.RemainingBytes)).Replace('-', ' '));
} catch (BadImageFormatException ex) {
message = ex.Message;
}
((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);
} }
return fieldDecl;
} }
internal static bool IsFixedField(IField field, out IType type, out int elementCount) internal static bool IsFixedField(IField field, out IType type, out int elementCount)
@ -1306,55 +1318,63 @@ namespace ICSharpCode.Decompiler.CSharp
EntityDeclaration DoDecompile(IProperty property, DecompileRun decompileRun, ITypeResolveContext decompilationContext) EntityDeclaration DoDecompile(IProperty property, DecompileRun decompileRun, ITypeResolveContext decompilationContext)
{ {
Debug.Assert(decompilationContext.CurrentMember == property); Debug.Assert(decompilationContext.CurrentMember == property);
var typeSystemAstBuilder = CreateAstBuilder(decompilationContext); try {
EntityDeclaration propertyDecl = typeSystemAstBuilder.ConvertEntity(property); var typeSystemAstBuilder = CreateAstBuilder(decompilationContext);
if (property.IsExplicitInterfaceImplementation && !property.IsIndexer) { EntityDeclaration propertyDecl = typeSystemAstBuilder.ConvertEntity(property);
int lastDot = property.Name.LastIndexOf('.'); if (property.IsExplicitInterfaceImplementation && !property.IsIndexer) {
propertyDecl.Name = property.Name.Substring(lastDot + 1); int lastDot = property.Name.LastIndexOf('.');
} propertyDecl.Name = property.Name.Substring(lastDot + 1);
FixParameterNames(propertyDecl); }
Accessor getter, setter; FixParameterNames(propertyDecl);
if (propertyDecl is PropertyDeclaration) { Accessor getter, setter;
getter = ((PropertyDeclaration)propertyDecl).Getter; if (propertyDecl is PropertyDeclaration) {
setter = ((PropertyDeclaration)propertyDecl).Setter; getter = ((PropertyDeclaration)propertyDecl).Getter;
} else { setter = ((PropertyDeclaration)propertyDecl).Setter;
getter = ((IndexerDeclaration)propertyDecl).Getter; } else {
setter = ((IndexerDeclaration)propertyDecl).Setter; getter = ((IndexerDeclaration)propertyDecl).Getter;
} setter = ((IndexerDeclaration)propertyDecl).Setter;
if (property.CanGet && property.Getter.HasBody) { }
DecompileBody(property.Getter, getter, decompileRun, decompilationContext); if (property.CanGet && property.Getter.HasBody) {
} DecompileBody(property.Getter, getter, decompileRun, decompilationContext);
if (property.CanSet && property.Setter.HasBody) { }
DecompileBody(property.Setter, setter, decompileRun, decompilationContext); if (property.CanSet && property.Setter.HasBody) {
DecompileBody(property.Setter, setter, decompileRun, decompilationContext);
}
var accessorHandle = (MethodDefinitionHandle)(property.Getter ?? property.Setter).MetadataToken;
var accessor = metadata.GetMethodDefinition(accessorHandle);
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);
} }
var accessorHandle = (MethodDefinitionHandle)(property.Getter ?? property.Setter).MetadataToken;
var accessor = metadata.GetMethodDefinition(accessorHandle);
if (!accessorHandle.GetMethodImplementations(metadata).Any() && accessor.HasFlag(System.Reflection.MethodAttributes.Virtual) == accessor.HasFlag(System.Reflection.MethodAttributes.NewSlot))
SetNewModifier(propertyDecl);
return propertyDecl;
} }
EntityDeclaration DoDecompile(IEvent ev, DecompileRun decompileRun, ITypeResolveContext decompilationContext) EntityDeclaration DoDecompile(IEvent ev, DecompileRun decompileRun, ITypeResolveContext decompilationContext)
{ {
Debug.Assert(decompilationContext.CurrentMember == ev); Debug.Assert(decompilationContext.CurrentMember == ev);
var typeSystemAstBuilder = CreateAstBuilder(decompilationContext); try {
typeSystemAstBuilder.UseCustomEvents = ev.DeclaringTypeDefinition.Kind != TypeKind.Interface; var typeSystemAstBuilder = CreateAstBuilder(decompilationContext);
var eventDecl = typeSystemAstBuilder.ConvertEntity(ev); typeSystemAstBuilder.UseCustomEvents = ev.DeclaringTypeDefinition.Kind != TypeKind.Interface;
int lastDot = ev.Name.LastIndexOf('.'); var eventDecl = typeSystemAstBuilder.ConvertEntity(ev);
if (ev.IsExplicitInterfaceImplementation) { int lastDot = ev.Name.LastIndexOf('.');
eventDecl.Name = ev.Name.Substring(lastDot + 1); if (ev.IsExplicitInterfaceImplementation) {
} eventDecl.Name = ev.Name.Substring(lastDot + 1);
if (ev.CanAdd && ev.AddAccessor.HasBody) { }
DecompileBody(ev.AddAccessor, ((CustomEventDeclaration)eventDecl).AddAccessor, decompileRun, decompilationContext); if (ev.CanAdd && ev.AddAccessor.HasBody) {
} DecompileBody(ev.AddAccessor, ((CustomEventDeclaration)eventDecl).AddAccessor, decompileRun, decompilationContext);
if (ev.CanRemove && ev.RemoveAccessor.HasBody) { }
DecompileBody(ev.RemoveAccessor, ((CustomEventDeclaration)eventDecl).RemoveAccessor, decompileRun, decompilationContext); if (ev.CanRemove && ev.RemoveAccessor.HasBody) {
} DecompileBody(ev.RemoveAccessor, ((CustomEventDeclaration)eventDecl).RemoveAccessor, decompileRun, decompilationContext);
var accessor = metadata.GetMethodDefinition((MethodDefinitionHandle)(ev.AddAccessor ?? ev.RemoveAccessor).MetadataToken); }
if (accessor.HasFlag(System.Reflection.MethodAttributes.Virtual) == accessor.HasFlag(System.Reflection.MethodAttributes.NewSlot)) { var accessor = metadata.GetMethodDefinition((MethodDefinitionHandle)(ev.AddAccessor ?? ev.RemoveAccessor).MetadataToken);
SetNewModifier(eventDecl); if (accessor.HasFlag(System.Reflection.MethodAttributes.Virtual) == accessor.HasFlag(System.Reflection.MethodAttributes.NewSlot)) {
SetNewModifier(eventDecl);
}
return eventDecl;
} catch (Exception innerException) when (!(innerException is OperationCanceledException || innerException is DecompilerException)) {
throw new DecompilerException(module, ev, innerException);
} }
return eventDecl;
} }
#region Sequence Points #region Sequence Points

20
ICSharpCode.Decompiler/DecompilerException.cs

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

Loading…
Cancel
Save