Browse Source

Fix #3010: Remove compiler-generated attributes for required members with custom ctors.

pull/3018/head
Siegfried Pammer 2 years ago
parent
commit
d57b08c79d
  1. 17
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/AutoProperties.cs
  2. 5
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Records.cs
  3. 47
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

17
ICSharpCode.Decompiler.Tests/TestCases/Pretty/AutoProperties.cs

@ -4,6 +4,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -4,6 +4,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
internal class AutoProperties
{
#if CS110
public required int RequiredField;
#endif
public int A { get; } = 1;
public int B { get; set; } = 2;
@ -22,9 +25,23 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -22,9 +25,23 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public int issue1319 { get; }
#if CS110
public required int RequiredProperty { get; set; }
#endif
public AutoProperties(int issue1319)
{
this.issue1319 = issue1319;
#if CS110
RequiredProperty = 42;
RequiredField = 42;
#endif
}
}
#if !NET70
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
internal sealed class RequiredMemberAttribute : Attribute
{
}
#endif
}

5
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Records.cs

@ -256,10 +256,13 @@ namespace System.Runtime.CompilerServices @@ -256,10 +256,13 @@ namespace System.Runtime.CompilerServices
internal class IsExternalInit
{
}
#endif
#if !NET70
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
internal sealed class RequiredMemberAttribute : Attribute
{
}
#endif
#if !NET60
}
#endif

47
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -1397,16 +1397,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1397,16 +1397,7 @@ namespace ICSharpCode.Decompiler.CSharp
}
if (settings.IntroduceRefModifiersOnStructs)
{
if (FindAttribute(typeDecl, KnownAttribute.Obsolete, out var attr))
{
if (obsoleteAttributePattern.IsMatch(attr))
{
if (attr.Parent is AttributeSection section && section.Attributes.Count == 1)
section.Remove();
else
attr.Remove();
}
}
RemoveObsoleteAttribute(typeDecl, "Types with embedded references are not supported in this version of your compiler.");
RemoveCompilerFeatureRequiredAttribute(typeDecl, "RefStructs");
}
if (settings.RequiredMembers)
@ -1584,14 +1575,6 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1584,14 +1575,6 @@ namespace ICSharpCode.Decompiler.CSharp
return firstValue == 0 ? EnumValueDisplayMode.None : EnumValueDisplayMode.FirstOnly;
}
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) }
}
};
EntityDeclaration DoDecompile(IMethod method, DecompileRun decompileRun, ITypeResolveContext decompilationContext)
{
Debug.Assert(decompilationContext.CurrentMember == method);
@ -1645,6 +1628,10 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1645,6 +1628,10 @@ namespace ICSharpCode.Decompiler.CSharp
methodDecl.Modifiers &= ~(Modifiers.New | Modifiers.Virtual);
methodDecl.Modifiers |= Modifiers.Override;
}
if (method.IsConstructor && settings.RequiredMembers && RemoveCompilerFeatureRequiredAttribute(methodDecl, "RequiredMembers"))
{
RemoveObsoleteAttribute(methodDecl, "Constructors of types with required members are not supported in this version of your compiler.");
}
return methodDecl;
bool IsTypeHierarchyKnown(IType type)
@ -1877,6 +1864,30 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1877,6 +1864,30 @@ namespace ICSharpCode.Decompiler.CSharp
return found;
}
internal static bool RemoveObsoleteAttribute(EntityDeclaration entityDecl, string message)
{
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 == KnownAttribute.Obsolete.GetTypeName()
&& attr.Arguments.Count >= 1 && attr.Arguments.First() is PrimitiveExpression pe
&& pe.Value is string s && s == message)
{
attr.Remove();
found = true;
}
}
if (section.Attributes.Count == 0)
{
section.Remove();
}
}
return found;
}
bool FindAttribute(EntityDeclaration entityDecl, KnownAttribute attributeType, out Syntax.Attribute attribute)
{
attribute = null;

Loading…
Cancel
Save