Browse Source

Fix #1784: Move RemoveEmbeddedAttributes transform to ICSharpCode.Decompiler and do no longer decompile embedded attributes in WholeProjectDecompiler and PortablePdbWriter.

pull/2832/head
Siegfried Pammer 3 years ago
parent
commit
c3d0e5ecc2
  1. 30
      ICSharpCode.Decompiler.Tests/Helpers/RemoveCompilerAttribute.cs
  2. 8
      ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs
  3. 38
      ICSharpCode.Decompiler/CSharp/Transforms/EscapeInvalidIdentifiers.cs
  4. 19
      ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs
  5. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/KnownAttributes.cs

30
ICSharpCode.Decompiler.Tests/Helpers/RemoveCompilerAttribute.cs

@ -34,36 +34,6 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
} }
} }
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 class RemoveNamespaceMy : DepthFirstAstVisitor, IAstTransform
{ {
public override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration) public override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)

8
ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs

@ -169,9 +169,13 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
{ {
var metadata = module.Metadata; var metadata = module.Metadata;
var typeDef = metadata.GetTypeDefinition(type); 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; 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 false;
return true; return true;
} }

38
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 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
using System.Linq; using System.Linq;
using ICSharpCode.Decompiler.CSharp.Syntax; using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.Semantics; using ICSharpCode.Decompiler.Semantics;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.CSharp.Transforms namespace ICSharpCode.Decompiler.CSharp.Transforms
{ {
@ -151,4 +153,40 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
} }
} }
} }
/// <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
ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs

@ -26,6 +26,7 @@ using System.Linq;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable; using System.Reflection.PortableExecutable;
using System.Runtime;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
@ -34,6 +35,7 @@ using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.CSharp.OutputVisitor; using ICSharpCode.Decompiler.CSharp.OutputVisitor;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler; using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.Decompiler.CSharp.Syntax; using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.CSharp.Transforms;
using ICSharpCode.Decompiler.IL; using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
@ -50,6 +52,21 @@ namespace ICSharpCode.Decompiler.DebugInfo
return file.Reader.ReadDebugDirectory().Any(entry => entry.Type == DebugDirectoryEntryType.CodeView); 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( public static void WritePdb(
PEFile file, PEFile file,
CSharpDecompiler decompiler, CSharpDecompiler decompiler,
@ -80,7 +97,7 @@ namespace ICSharpCode.Decompiler.DebugInfo
return Path.Combine(ns, WholeProjectDecompiler.CleanUpFileName(typeName.Name) + ".cs"); 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() { DecompilationProgress currentProgress = new() {
TotalUnits = sourceFiles.Count, TotalUnits = sourceFiles.Count,
UnitsCompleted = 0, UnitsCompleted = 0,

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

@ -44,6 +44,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
NullablePublicOnly, NullablePublicOnly,
Conditional, Conditional,
Obsolete, Obsolete,
Embedded,
IsReadOnly, IsReadOnly,
SpecialName, SpecialName,
DebuggerHidden, DebuggerHidden,
@ -122,6 +123,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
new TopLevelTypeName("System.Runtime.CompilerServices", "NullablePublicOnlyAttribute"), new TopLevelTypeName("System.Runtime.CompilerServices", "NullablePublicOnlyAttribute"),
new TopLevelTypeName("System.Diagnostics", nameof(ConditionalAttribute)), new TopLevelTypeName("System.Diagnostics", nameof(ConditionalAttribute)),
new TopLevelTypeName("System", nameof(ObsoleteAttribute)), new TopLevelTypeName("System", nameof(ObsoleteAttribute)),
new TopLevelTypeName("Microsoft.CodeAnalysis", "EmbeddedAttribute"),
new TopLevelTypeName("System.Runtime.CompilerServices", "IsReadOnlyAttribute"), new TopLevelTypeName("System.Runtime.CompilerServices", "IsReadOnlyAttribute"),
new TopLevelTypeName("System.Runtime.CompilerServices", nameof(SpecialNameAttribute)), new TopLevelTypeName("System.Runtime.CompilerServices", nameof(SpecialNameAttribute)),
new TopLevelTypeName("System.Diagnostics", nameof(DebuggerHiddenAttribute)), new TopLevelTypeName("System.Diagnostics", nameof(DebuggerHiddenAttribute)),

Loading…
Cancel
Save