Browse Source

Refactor DoDecompile(ITypeDefinition): Extract handling of members and types into local function. Order of output no longer depends on the order of decompilation, which will become relevant in the next commit.

pull/2684/head
Siegfried Pammer 3 years ago
parent
commit
1532d2fc29
  1. 127
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

127
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -1244,9 +1244,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1244,9 +1244,11 @@ namespace ICSharpCode.Decompiler.CSharp
{
Debug.Assert(decompilationContext.CurrentTypeDefinition == typeDef);
var watch = System.Diagnostics.Stopwatch.StartNew();
MultiDictionary<IEntity, EntityDeclaration> entityMap = new();
TypeSystemAstBuilder typeSystemAstBuilder;
try
{
var typeSystemAstBuilder = CreateAstBuilder(decompileRun.Settings);
typeSystemAstBuilder = CreateAstBuilder(decompileRun.Settings);
var entityDecl = typeSystemAstBuilder.ConvertEntity(typeDef);
var typeDecl = entityDecl as TypeDeclaration;
if (typeDecl == null)
@ -1289,16 +1291,6 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1289,16 +1291,6 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
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);
}
}
decompileRun.EnumValueDisplayMode = typeDef.Kind == TypeKind.Enum
? DetectBestEnumValueDisplayMode(typeDef, module.PEFile)
: null;
@ -1309,60 +1301,20 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1309,60 +1301,20 @@ namespace ICSharpCode.Decompiler.CSharp
// For COM interop scenarios, the relative order of virtual functions/properties matters:
IEnumerable<IMember> allOrderedMembers = RequiresNativeOrdering(typeDef) ? GetMembersWithNativeOrdering(typeDef) :
fieldsAndProperties.Concat<IMember>(typeDef.Events).Concat<IMember>(typeDef.Methods);
fieldsAndProperties.Concat(typeDef.Events).Concat(typeDef.Methods);
var allOrderedEntities = typeDef.NestedTypes.Concat<IEntity>(allOrderedMembers);
foreach (var member in allOrderedMembers)
foreach (var member in allOrderedEntities)
{
if (member is IField || member is IProperty)
{
var fieldOrProperty = member;
if (fieldOrProperty.MetadataToken.IsNil || MemberIsHidden(module.PEFile, fieldOrProperty.MetadataToken, settings))
{
continue;
}
if (fieldOrProperty is IField field)
{
if (typeDef.Kind == TypeKind.Enum && !field.IsConst)
continue;
var memberDecl = DoDecompile(field, decompileRun, decompilationContext.WithCurrentMember(field));
typeDecl.Members.Add(memberDecl);
}
else if (fieldOrProperty is IProperty property)
{
if (recordDecompiler?.PropertyIsGenerated(property) == true)
{
continue;
}
var propDecl = DoDecompile(property, decompileRun, decompilationContext.WithCurrentMember(property));
typeDecl.Members.Add(propDecl);
}
}
else if (member is IMethod method)
{
if (recordDecompiler?.MethodIsGenerated(method) == true)
{
continue;
}
if (!method.MetadataToken.IsNil && !MemberIsHidden(module.PEFile, method.MetadataToken, settings))
{
var memberDecl = DoDecompile(method, decompileRun, decompilationContext.WithCurrentMember(method));
typeDecl.Members.Add(memberDecl);
typeDecl.Members.AddRange(AddInterfaceImplHelpers(memberDecl, method, typeSystemAstBuilder));
}
}
else if (member is IEvent @event)
{
if (!@event.MetadataToken.IsNil && !MemberIsHidden(module.PEFile, @event.MetadataToken, settings))
{
var eventDecl = DoDecompile(@event, decompileRun, decompilationContext.WithCurrentMember(@event));
typeDecl.Members.Add(eventDecl);
}
}
else
{
throw new ArgumentOutOfRangeException("Unexpected member type");
}
DoDecompileMember(member, recordDecompiler);
}
foreach (var member in allOrderedEntities)
{
typeDecl.Members.AddRange(entityMap[member]);
}
if (typeDecl.Members.OfType<IndexerDeclaration>().Any(idx => idx.PrivateImplementationType.IsNull))
{
// Remove the [DefaultMember] attribute if the class contains indexers
@ -1421,6 +1373,57 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1421,6 +1373,57 @@ namespace ICSharpCode.Decompiler.CSharp
watch.Stop();
Instrumentation.DecompilerEventSource.Log.DoDecompileTypeDefinition(typeDef.FullName, watch.ElapsedMilliseconds);
}
void DoDecompileMember(IEntity entity, RecordDecompiler recordDecompiler)
{
EntityDeclaration entityDecl;
if (entity.MetadataToken.IsNil || MemberIsHidden(module.PEFile, entity.MetadataToken, settings))
{
return;
}
switch (entity)
{
case IField field:
if (typeDef.Kind == TypeKind.Enum && !field.IsConst)
{
return;
}
entityDecl = DoDecompile(field, decompileRun, decompilationContext.WithCurrentMember(field));
entityMap.Add(field, entityDecl);
break;
case IProperty property:
if (recordDecompiler?.PropertyIsGenerated(property) == true)
{
return;
}
entityDecl = DoDecompile(property, decompileRun, decompilationContext.WithCurrentMember(property));
entityMap.Add(property, entityDecl);
break;
case IMethod method:
if (recordDecompiler?.MethodIsGenerated(method) == true)
{
return;
}
entityDecl = DoDecompile(method, decompileRun, decompilationContext.WithCurrentMember(method));
entityMap.Add(method, entityDecl);
foreach (var helper in AddInterfaceImplHelpers(entityDecl, method, typeSystemAstBuilder))
{
entityMap.Add(method, helper);
}
break;
case IEvent @event:
entityDecl = DoDecompile(@event, decompileRun, decompilationContext.WithCurrentMember(@event));
entityMap.Add(@event, entityDecl);
break;
case ITypeDefinition type:
var nestedType = DoDecompile(type, decompileRun, decompilationContext.WithCurrentTypeDefinition(type));
SetNewModifier(nestedType);
entityMap.Add(type, nestedType);
break;
default:
throw new ArgumentOutOfRangeException("Unexpected member type");
}
}
}
EnumValueDisplayMode DetectBestEnumValueDisplayMode(ITypeDefinition typeDef, PEFile module)

Loading…
Cancel
Save