diff --git a/ICSharpCode.Decompiler.Tests/Helpers/RemoveCompilerAttribute.cs b/ICSharpCode.Decompiler.Tests/Helpers/RemoveCompilerAttribute.cs index f25a58f36..2ce551e79 100644 --- a/ICSharpCode.Decompiler.Tests/Helpers/RemoveCompilerAttribute.cs +++ b/ICSharpCode.Decompiler.Tests/Helpers/RemoveCompilerAttribute.cs @@ -34,36 +34,6 @@ namespace ICSharpCode.Decompiler.Tests.Helpers } } - public class RemoveEmbeddedAttributes : DepthFirstAstVisitor, IAstTransform - { - HashSet attributeNames = new HashSet() { - "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) diff --git a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs index c49fde67c..b55bbe683 100644 --- a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs @@ -169,9 +169,13 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler { var metadata = module.Metadata; var typeDef = metadata.GetTypeDefinition(type); - if (metadata.GetString(typeDef.Name) == "" || CSharpDecompiler.MemberIsHidden(module, type, Settings)) + string name = metadata.GetString(typeDef.Name); + string ns = metadata.GetString(typeDef.Namespace); + if (name == "" || 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; } diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/EscapeInvalidIdentifiers.cs b/ICSharpCode.Decompiler/CSharp/Transforms/EscapeInvalidIdentifiers.cs index 6ba6b2e8e..1b57569ef 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/EscapeInvalidIdentifiers.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/EscapeInvalidIdentifiers.cs @@ -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 { @@ -151,4 +153,40 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms } } } + + /// + /// This transform is used to remove attributes that are embedded + /// + public class RemoveEmbeddedAttributes : DepthFirstAstVisitor, IAstTransform + { + internal static readonly HashSet attributeNames = new HashSet() { + "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); + } + } + } diff --git a/ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs b/ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs index b0b419aab..0e0026ea8 100644 --- a/ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs +++ b/ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs @@ -26,6 +26,7 @@ using System.Linq; 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; @@ -34,6 +35,7 @@ using ICSharpCode.Decompiler.CSharp; 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; @@ -50,6 +52,21 @@ namespace ICSharpCode.Decompiler.DebugInfo 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 == "" || 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, @@ -80,7 +97,7 @@ namespace ICSharpCode.Decompiler.DebugInfo 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, diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/KnownAttributes.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/KnownAttributes.cs index 6f6dcacaf..f0263c370 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/KnownAttributes.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/KnownAttributes.cs @@ -44,6 +44,7 @@ namespace ICSharpCode.Decompiler.TypeSystem NullablePublicOnly, Conditional, Obsolete, + Embedded, IsReadOnly, SpecialName, DebuggerHidden, @@ -122,6 +123,7 @@ namespace ICSharpCode.Decompiler.TypeSystem 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)),