Browse Source

Merge pull request #2684 from icsharpcode/hide-compiler-generated-code

Keep compiler-generated code that is still referenced
pull/2693/head
Daniel Grunwald 3 years ago committed by GitHub
parent
commit
e9a2bf4556
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 150
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 46
      ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs
  3. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/KnownAttributes.cs
  4. 2
      ICSharpCode.Decompiler/Util/MultiDictionary.cs

150
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -1244,9 +1244,12 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1244,9 +1244,12 @@ namespace ICSharpCode.Decompiler.CSharp
{
Debug.Assert(decompilationContext.CurrentTypeDefinition == typeDef);
var watch = System.Diagnostics.Stopwatch.StartNew();
var entityMap = new MultiDictionary<IEntity, EntityDeclaration>();
var workList = new Queue<IEntity>();
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 +1292,6 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1289,16 +1292,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 +1302,38 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1309,60 +1302,38 @@ 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)
// Decompile members that are not compiler-generated.
foreach (var entity in allOrderedEntities)
{
if (member is IField || member is IProperty)
if (entity.MetadataToken.IsNil || MemberIsHidden(module.PEFile, entity.MetadataToken, settings))
{
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);
}
continue;
}
else
DoDecompileMember(entity, recordDecompiler);
}
// Decompile compiler-generated members that are still needed.
while (workList.Count > 0)
{
var entity = workList.Dequeue();
if (entityMap.Contains(entity) || entity.MetadataToken.IsNil)
{
throw new ArgumentOutOfRangeException("Unexpected member type");
// Member is already decompiled.
continue;
}
DoDecompileMember(entity, recordDecompiler);
}
// Add all decompiled members to syntax tree in the correct order.
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 +1392,69 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1421,6 +1392,69 @@ namespace ICSharpCode.Decompiler.CSharp
watch.Stop();
Instrumentation.DecompilerEventSource.Log.DoDecompileTypeDefinition(typeDef.FullName, watch.ElapsedMilliseconds);
}
void DoDecompileMember(IEntity entity, RecordDecompiler recordDecompiler)
{
EntityDeclaration entityDecl;
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:
entityDecl = DoDecompile(type, decompileRun, decompilationContext.WithCurrentTypeDefinition(type));
SetNewModifier(entityDecl);
entityMap.Add(type, entityDecl);
break;
default:
throw new ArgumentOutOfRangeException("Unexpected member type");
}
foreach (var node in entityDecl.Descendants)
{
var rr = node.GetResolveResult();
if (rr is MemberResolveResult mrr
&& mrr.Member.DeclaringTypeDefinition == typeDef
&& !(mrr.Member is IMethod { IsLocalFunction: true }))
{
workList.Enqueue(mrr.Member);
}
else if (rr is TypeResolveResult trr
&& trr.Type.GetDefinition()?.DeclaringTypeDefinition == typeDef)
{
workList.Enqueue(trr.Type.GetDefinition());
}
}
}
}
EnumValueDisplayMode DetectBestEnumValueDisplayMode(ITypeDefinition typeDef, PEFile module)

46
ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs

@ -640,17 +640,19 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -640,17 +640,19 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
propertyDeclaration.Modifiers &= ~Modifiers.Readonly;
propertyDeclaration.Getter.Modifiers &= ~Modifiers.Readonly;
// Add C# 7.3 attributes on backing field:
var attributes = field.GetAttributes()
.Where(a => !attributeTypesToRemoveFromAutoProperties.Contains(a.AttributeType.FullName))
.Select(context.TypeSystemAstBuilder.ConvertAttribute).ToArray();
if (attributes.Length > 0)
var fieldDecl = propertyDeclaration.Parent?.Children.OfType<FieldDeclaration>()
.FirstOrDefault(fd => field.Equals(fd.GetSymbol()));
if (fieldDecl != null)
{
var section = new AttributeSection {
AttributeTarget = "field"
};
section.Attributes.AddRange(attributes);
propertyDeclaration.Attributes.Add(section);
fieldDecl.Remove();
// Add C# 7.3 attributes on backing field:
CSharpDecompiler.RemoveAttribute(fieldDecl, KnownAttribute.CompilerGenerated);
CSharpDecompiler.RemoveAttribute(fieldDecl, KnownAttribute.DebuggerBrowsable);
foreach (var section in fieldDecl.Attributes)
{
section.AttributeTarget = "field";
propertyDeclaration.Attributes.Add(section.Detach());
}
}
}
// Since the property instance is not changed, we can continue in the visitor as usual, so return null
@ -1010,23 +1012,17 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -1010,23 +1012,17 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
ed.Variables.Add(new VariableInitializer(ev.Name));
ed.CopyAnnotationsFrom(ev);
if (ev.GetSymbol() is IEvent eventDef)
var fieldDecl = ev.Parent?.Children.OfType<FieldDeclaration>()
.FirstOrDefault(fd => fd.Variables.Single().Name == ev.Name);
if (fieldDecl != null)
{
IField field = eventDef.DeclaringType.GetFields(f => f.Name == ev.Name, GetMemberOptions.IgnoreInheritedMembers).SingleOrDefault();
if (field != null)
fieldDecl.Remove();
CSharpDecompiler.RemoveAttribute(fieldDecl, KnownAttribute.CompilerGenerated);
CSharpDecompiler.RemoveAttribute(fieldDecl, KnownAttribute.DebuggerBrowsable);
foreach (var section in fieldDecl.Attributes)
{
ed.AddAnnotation(field);
var attributes = field.GetAttributes()
.Where(a => !attributeTypesToRemoveFromAutoEvents.Contains(a.AttributeType.FullName))
.Select(context.TypeSystemAstBuilder.ConvertAttribute).ToArray();
if (attributes.Length > 0)
{
var section = new AttributeSection {
AttributeTarget = "field"
};
section.Attributes.AddRange(attributes);
ed.Attributes.Add(section);
}
section.AttributeTarget = "field";
ed.Attributes.Add(section.Detach());
}
}

2
ICSharpCode.Decompiler/TypeSystem/Implementation/KnownAttributes.cs

@ -48,6 +48,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -48,6 +48,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
SpecialName,
DebuggerHidden,
DebuggerStepThrough,
DebuggerBrowsable,
// Assembly attributes:
AssemblyVersion,
@ -124,6 +125,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -124,6 +125,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
new TopLevelTypeName("System.Runtime.CompilerServices", nameof(SpecialNameAttribute)),
new TopLevelTypeName("System.Diagnostics", nameof(DebuggerHiddenAttribute)),
new TopLevelTypeName("System.Diagnostics", nameof(DebuggerStepThroughAttribute)),
new TopLevelTypeName("System.Diagnostics", nameof(DebuggerBrowsableAttribute)),
// Assembly attributes:
new TopLevelTypeName("System.Reflection", nameof(AssemblyVersionAttribute)),
new TopLevelTypeName("System.Runtime.CompilerServices", nameof(InternalsVisibleToAttribute)),

2
ICSharpCode.Decompiler/Util/MultiDictionary.cs

@ -105,7 +105,7 @@ namespace ICSharpCode.Decompiler.Util @@ -105,7 +105,7 @@ namespace ICSharpCode.Decompiler.Util
get { return this[key]; }
}
bool ILookup<TKey, TValue>.Contains(TKey key)
public bool Contains(TKey key)
{
return dict.ContainsKey(key);
}

Loading…
Cancel
Save