Browse Source

#894: Transform IsByRefLikeAttribute and IsReadOnlyAttribute on structs to ref and readonly modifiers, respectively. Remove ObsoleteAttribute.

pull/1087/head
Siegfried Pammer 8 years ago
parent
commit
3dcc388e99
  1. 50
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 20
      ICSharpCode.Decompiler/DecompilerSettings.cs

50
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -33,6 +33,7 @@ using ICSharpCode.Decompiler.TypeSystem; @@ -33,6 +33,7 @@ using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Semantics;
using ICSharpCode.Decompiler.Util;
using System.IO;
using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
namespace ICSharpCode.Decompiler.CSharp
{
@ -667,20 +668,35 @@ namespace ICSharpCode.Decompiler.CSharp @@ -667,20 +668,35 @@ namespace ICSharpCode.Decompiler.CSharp
}
if (typeDecl.Members.OfType<IndexerDeclaration>().Any(idx => idx.PrivateImplementationType.IsNull)) {
// Remove the [DefaultMember] attribute if the class contains indexers
foreach (AttributeSection section in typeDecl.Attributes) {
foreach (var attr in section.Attributes) {
var tr = attr.Type.GetResolveResult().Type;
if (tr.Name == "DefaultMemberAttribute" && tr.Namespace == "System.Reflection") {
RemoveAttribute(typeDecl, new TopLevelTypeName("System.Reflection", "DefaultMemberAttribute"));
}
if (settings.IntroduceRefAndReadonlyModifiersOnStructs && typeDecl.ClassType == ClassType.Struct) {
if (RemoveAttribute(typeDecl, new TopLevelTypeName("System.Runtime.CompilerServices", "IsByRefLikeAttribute"))) {
typeDecl.Modifiers |= Modifiers.Ref;
}
if (RemoveAttribute(typeDecl, new TopLevelTypeName("System.Runtime.CompilerServices", "IsReadOnlyAttribute"))) {
typeDecl.Modifiers |= Modifiers.Readonly;
}
if (FindAttribute(typeDecl, new TopLevelTypeName("System", "ObsoleteAttribute"), out var attr)) {
if (obsoleteAttributePattern.IsMatch(attr)) {
if (attr.Parent is Syntax.AttributeSection section && section.Attributes.Count == 1)
section.Remove();
else
attr.Remove();
}
}
if (section.Attributes.Count == 0)
section.Remove();
}
}
return typeDecl;
}
static readonly Syntax.Attribute obsoleteAttributePattern = new Syntax.Attribute() {
Type = new TypePattern(typeof(ObsoleteAttribute)),
Arguments = {
new PrimitiveExpression("Types with embedded references are not supported in this version of your compiler."),
new Choice() { new PrimitiveExpression(true), new PrimitiveExpression(false) }
}
};
MethodDeclaration GenerateConvHelper(string name, KnownTypeCode source, KnownTypeCode target, TypeSystemAstBuilder typeSystemAstBuilder,
Expression intermediate32, Expression intermediate64)
{
@ -806,19 +822,37 @@ namespace ICSharpCode.Decompiler.CSharp @@ -806,19 +822,37 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
void RemoveAttribute(EntityDeclaration entityDecl, FullTypeName attrName)
bool RemoveAttribute(EntityDeclaration entityDecl, FullTypeName attrName)
{
bool found = false;
foreach (var section in entityDecl.Attributes) {
foreach (var attr in section.Attributes) {
var symbol = attr.Type.GetSymbol();
if (symbol is ITypeDefinition td && td.FullTypeName == attrName) {
attr.Remove();
found = true;
}
}
if (section.Attributes.Count == 0) {
section.Remove();
}
}
return found;
}
bool FindAttribute(EntityDeclaration entityDecl, FullTypeName attrName, out Syntax.Attribute attribute)
{
attribute = null;
foreach (var section in entityDecl.Attributes) {
foreach (var attr in section.Attributes) {
var symbol = attr.Type.GetSymbol();
if (symbol is ITypeDefinition td && td.FullTypeName == attrName) {
attribute = attr;
return true;
}
}
}
return false;
}
HashSet<string> definedSymbols;

20
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -75,6 +75,9 @@ namespace ICSharpCode.Decompiler @@ -75,6 +75,9 @@ namespace ICSharpCode.Decompiler
if (languageVersion < CSharp.LanguageVersion.CSharp7) {
outVariables = false;
}
if (languageVersion < CSharp.LanguageVersion.CSharp7_2) {
introduceRefAndReadonlyModifiersOnStructs = false;
}
}
bool anonymousMethods = true;
@ -520,7 +523,7 @@ namespace ICSharpCode.Decompiler @@ -520,7 +523,7 @@ namespace ICSharpCode.Decompiler
bool outVariables = true;
/// <summary>
/// Gets/Sets whether simple calculated getter-only property declarations should use expression body syntax.
/// Gets/Sets whether out variable declarations should be used when possible.
/// </summary>
public bool OutVariables {
get { return outVariables; }
@ -532,6 +535,21 @@ namespace ICSharpCode.Decompiler @@ -532,6 +535,21 @@ namespace ICSharpCode.Decompiler
}
}
bool introduceRefAndReadonlyModifiersOnStructs = true;
/// <summary>
/// Gets/Sets whether IsByRefLikeAttribute and IsReadOnlyAttribute should be replaced with 'ref' and 'readonly' modifiers on structs.
/// </summary>
public bool IntroduceRefAndReadonlyModifiersOnStructs {
get { return introduceRefAndReadonlyModifiersOnStructs; }
set {
if (introduceRefAndReadonlyModifiersOnStructs != value) {
introduceRefAndReadonlyModifiersOnStructs = value;
OnPropertyChanged();
}
}
}
#region Options to aid VB decompilation
bool introduceIncrementAndDecrement = true;

Loading…
Cancel
Save