Skip to content

Commit

Permalink
Fix #1784: Move RemoveEmbeddedAttributes transform to ICSharpCode.Dec…
Browse files Browse the repository at this point in the history
…ompiler and do no longer decompile embedded attributes in WholeProjectDecompiler and PortablePdbWriter.
  • Loading branch information
siegfriedpammer committed Nov 4, 2022
1 parent d9595ca commit c3d0e5e
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 33 deletions.
30 changes: 0 additions & 30 deletions ICSharpCode.Decompiler.Tests/Helpers/RemoveCompilerAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,36 +34,6 @@ public void Run(AstNode rootNode, TransformContext context)
}
}

public class RemoveEmbeddedAttributes : DepthFirstAstVisitor, IAstTransform
{
HashSet<string> attributeNames = new HashSet<string>() {
"System.Runtime.CompilerServices.IsReadOnlyAttribute",
"System.Runtime.CompilerServices.IsByRefLikeAttribute",
"System.Runtime.CompilerServices.IsUnmanagedAttribute",
"System.Runtime.CompilerServices.NullableAttribute",
"System.Runtime.CompilerServices.NullableContextAttribute",
"System.Runtime.CompilerServices.NativeIntegerAttribute",
"System.Runtime.CompilerServices.RefSafetyRulesAttribute",
"Microsoft.CodeAnalysis.EmbeddedAttribute",
};

public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration)
{
var typeDefinition = typeDeclaration.GetSymbol() as ITypeDefinition;
if (typeDefinition == null || !attributeNames.Contains(typeDefinition.FullName))
return;
if (typeDeclaration.Parent is NamespaceDeclaration ns && ns.Members.Count == 1)
ns.Remove();
else
typeDeclaration.Remove();
}

public void Run(AstNode rootNode, TransformContext context)
{
rootNode.AcceptVisitor(this);
}
}

public class RemoveNamespaceMy : DepthFirstAstVisitor, IAstTransform
{
public override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,13 @@ protected virtual bool IncludeTypeWhenDecompilingProject(PEFile module, TypeDefi
{
var metadata = module.Metadata;
var typeDef = metadata.GetTypeDefinition(type);
if (metadata.GetString(typeDef.Name) == "<Module>" || CSharpDecompiler.MemberIsHidden(module, type, Settings))
string name = metadata.GetString(typeDef.Name);
string ns = metadata.GetString(typeDef.Namespace);
if (name == "<Module>" || CSharpDecompiler.MemberIsHidden(module, type, Settings))
return false;
if (metadata.GetString(typeDef.Namespace) == "XamlGeneratedNamespace" && metadata.GetString(typeDef.Name) == "GeneratedInternalTypeHelper")
if (ns == "XamlGeneratedNamespace" && name == "GeneratedInternalTypeHelper")
return false;
if (!typeDef.IsNested && RemoveEmbeddedAttributes.attributeNames.Contains(ns + "." + name))
return false;
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

using System.Collections.Generic;
using System.Linq;

using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.Semantics;
using ICSharpCode.Decompiler.TypeSystem;

namespace ICSharpCode.Decompiler.CSharp.Transforms
{
Expand Down Expand Up @@ -151,4 +153,40 @@ public void Run(AstNode rootNode, TransformContext context)
}
}
}

/// <summary>
/// This transform is used to remove attributes that are embedded
/// </summary>
public class RemoveEmbeddedAttributes : DepthFirstAstVisitor, IAstTransform
{
internal static readonly HashSet<string> attributeNames = new HashSet<string>() {
"System.Runtime.CompilerServices.IsReadOnlyAttribute",
"System.Runtime.CompilerServices.IsByRefLikeAttribute",
"System.Runtime.CompilerServices.IsUnmanagedAttribute",
"System.Runtime.CompilerServices.NullableAttribute",
"System.Runtime.CompilerServices.NullableContextAttribute",
"System.Runtime.CompilerServices.NativeIntegerAttribute",
"System.Runtime.CompilerServices.RefSafetyRulesAttribute",
"Microsoft.CodeAnalysis.EmbeddedAttribute",
};

public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration)
{
var typeDefinition = typeDeclaration.GetSymbol() as ITypeDefinition;
if (typeDefinition == null || !attributeNames.Contains(typeDefinition.FullName))
return;
if (!typeDefinition.HasAttribute(KnownAttribute.Embedded))
return;
if (typeDeclaration.Parent is NamespaceDeclaration ns && ns.Members.Count == 1)
ns.Remove();
else
typeDeclaration.Remove();
}

public void Run(AstNode rootNode, TransformContext context)
{
rootNode.AcceptVisitor(this);
}
}

}
19 changes: 18 additions & 1 deletion ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable;
using System.Runtime;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
Expand All @@ -34,6 +35,7 @@
using ICSharpCode.Decompiler.CSharp.OutputVisitor;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.CSharp.Transforms;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
Expand All @@ -50,6 +52,21 @@ public static bool HasCodeViewDebugDirectoryEntry(PEFile file)
return file.Reader.ReadDebugDirectory().Any(entry => entry.Type == DebugDirectoryEntryType.CodeView);
}

private static bool IncludeTypeWhenGeneratingPdb(PEFile module, TypeDefinitionHandle type, DecompilerSettings settings)
{
var metadata = module.Metadata;
var typeDef = metadata.GetTypeDefinition(type);
string name = metadata.GetString(typeDef.Name);
string ns = metadata.GetString(typeDef.Namespace);
if (name == "<Module>" || CSharpDecompiler.MemberIsHidden(module, type, settings))
return false;
if (ns == "XamlGeneratedNamespace" && name == "GeneratedInternalTypeHelper")
return false;
if (!typeDef.IsNested && RemoveEmbeddedAttributes.attributeNames.Contains(ns + "." + name))
return false;
return true;
}

public static void WritePdb(
PEFile file,
CSharpDecompiler decompiler,
Expand Down Expand Up @@ -80,7 +97,7 @@ string BuildFileNameFromTypeName(TypeDefinitionHandle handle)
return Path.Combine(ns, WholeProjectDecompiler.CleanUpFileName(typeName.Name) + ".cs");
}

var sourceFiles = reader.GetTopLevelTypeDefinitions().GroupBy(BuildFileNameFromTypeName).ToList();
var sourceFiles = reader.GetTopLevelTypeDefinitions().Where(t => IncludeTypeWhenGeneratingPdb(file, t, settings)).GroupBy(BuildFileNameFromTypeName).ToList();
DecompilationProgress currentProgress = new() {
TotalUnits = sourceFiles.Count,
UnitsCompleted = 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public enum KnownAttribute
NullablePublicOnly,
Conditional,
Obsolete,
Embedded,
IsReadOnly,
SpecialName,
DebuggerHidden,
Expand Down Expand Up @@ -122,6 +123,7 @@ public static class KnownAttributes
new TopLevelTypeName("System.Runtime.CompilerServices", "NullablePublicOnlyAttribute"),
new TopLevelTypeName("System.Diagnostics", nameof(ConditionalAttribute)),
new TopLevelTypeName("System", nameof(ObsoleteAttribute)),
new TopLevelTypeName("Microsoft.CodeAnalysis", "EmbeddedAttribute"),
new TopLevelTypeName("System.Runtime.CompilerServices", "IsReadOnlyAttribute"),
new TopLevelTypeName("System.Runtime.CompilerServices", nameof(SpecialNameAttribute)),
new TopLevelTypeName("System.Diagnostics", nameof(DebuggerHiddenAttribute)),
Expand Down

0 comments on commit c3d0e5e

Please sign in to comment.