Browse Source

Fix #2547: decimal const not removed from static constructor.

pull/2549/head
Siegfried Pammer 4 years ago
parent
commit
ea1cea96c4
  1. 19
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.cs
  2. 49
      ICSharpCode.Decompiler/CSharp/Transforms/TransformFieldAndConstructorInitializers.cs

19
ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.cs

@ -36,6 +36,25 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -36,6 +36,25 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
}
public class ClassWithConstant
{
// using decimal constants has the effect that there is a cctor
// generated containing the explicit initialization of this field.
// The type is marked beforefieldinit
private const decimal a = 1.0m;
}
public class ClassWithConstantAndStaticCtor
{
// The type is not marked beforefieldinit
private const decimal a = 1.0m;
static ClassWithConstantAndStaticCtor()
{
}
}
public struct SimpleStruct
{
public int Field1;

49
ICSharpCode.Decompiler/CSharp/Transforms/TransformFieldAndConstructorInitializers.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
@ -304,26 +305,28 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -304,26 +305,28 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
var metadata = context.TypeSystem.MainModule.PEFile.Metadata;
SRM.MethodDefinition ctorMethodDef = metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)ctorMethod.MetadataToken);
SRM.TypeDefinition declaringType = metadata.GetTypeDefinition(ctorMethodDef.GetDeclaringType());
if (declaringType.HasFlag(System.Reflection.TypeAttributes.BeforeFieldInit))
bool declaringTypeIsBeforeFieldInit = declaringType.HasFlag(TypeAttributes.BeforeFieldInit);
while (true)
{
while (true)
ExpressionStatement es = staticCtor.Body.Statements.FirstOrDefault() as ExpressionStatement;
if (es == null)
break;
AssignmentExpression assignment = es.Expression as AssignmentExpression;
if (assignment == null || assignment.Operator != AssignmentOperatorType.Assign)
break;
IMember fieldOrProperty = (assignment.Left.GetSymbol() as IMember)?.MemberDefinition;
if (!(fieldOrProperty is IField || fieldOrProperty is IProperty) || !fieldOrProperty.IsStatic)
break;
var fieldOrPropertyDecl = members.FirstOrDefault(f => f.GetSymbol() == fieldOrProperty) as EntityDeclaration;
if (fieldOrPropertyDecl == null)
break;
if (ctorIsUnsafe && IntroduceUnsafeModifier.IsUnsafe(assignment.Right))
{
fieldOrPropertyDecl.Modifiers |= Modifiers.Unsafe;
}
// Only move fields that are constants, if the declaring type is not marked beforefieldinit.
if (declaringTypeIsBeforeFieldInit || fieldOrProperty is IField { IsConst: true })
{
ExpressionStatement es = staticCtor.Body.Statements.FirstOrDefault() as ExpressionStatement;
if (es == null)
break;
AssignmentExpression assignment = es.Expression as AssignmentExpression;
if (assignment == null || assignment.Operator != AssignmentOperatorType.Assign)
break;
IMember fieldOrProperty = (assignment.Left.GetSymbol() as IMember)?.MemberDefinition;
if (!(fieldOrProperty is IField || fieldOrProperty is IProperty) || !fieldOrProperty.IsStatic)
break;
var fieldOrPropertyDecl = members.FirstOrDefault(f => f.GetSymbol() == fieldOrProperty) as EntityDeclaration;
if (fieldOrPropertyDecl == null)
break;
if (ctorIsUnsafe && IntroduceUnsafeModifier.IsUnsafe(assignment.Right))
{
fieldOrPropertyDecl.Modifiers |= Modifiers.Unsafe;
}
if (fieldOrPropertyDecl is FieldDeclaration fd)
fd.Variables.Single().Initializer = assignment.Right.Detach();
else if (fieldOrPropertyDecl is PropertyDeclaration pd)
@ -332,8 +335,14 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -332,8 +335,14 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
break;
es.Remove();
}
if (staticCtor.Body.Statements.Count == 0)
staticCtor.Remove();
else
{
break;
}
}
if (declaringTypeIsBeforeFieldInit && staticCtor.Body.Statements.Count == 0)
{
staticCtor.Remove();
}
}
}

Loading…
Cancel
Save