Browse Source

Fixed an issue where the logic of moving the initialization statement of class members in the constructor to the class member declaration was incompatible with complex expressions using parameters.

Here's an example:
```cs
    public struct FromBinaryOperator
    {
        public int Leet;

        public FromBinaryOperator(int dummy1, int dummy2)
        {
            Leet = dummy1 + dummy2;
        }
    }

    public struct FromCall
    {
        public int Leet;

        public FromCall(int dummy1, int dummy2)
        {
            Leet = Math.Max(dummy1, dummy2);
        }
    }

    public struct FromConvert
    {
        public int Leet;

        public FromConvert(double dummy1, double dummy2)
        {
            Leet = (int)Math.Min(dummy1, dummy2);
        }
    }
```
pull/3598/head
sonyps5201314 2 months ago
parent
commit
851a1f3af5
  1. 42
      ICSharpCode.Decompiler/CSharp/Transforms/TransformFieldAndConstructorInitializers.cs

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

@ -229,17 +229,55 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -229,17 +229,55 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
// 'this'/'base' cannot be used in initializers
if (initializer.DescendantsAndSelf.Any(n => n is ThisReferenceExpression || n is BaseReferenceExpression))
break;
bool assignFromParameters = false;
var v = initializer.Annotation<ILVariableResolveResult>()?.Variable;
if (v == null)
{
v = (initializer.Annotation<ByReferenceResolveResult>()?.ElementResult as ILVariableResolveResult)?.Variable;
}
if (v?.Kind == IL.VariableKind.Parameter)
if (v != null)
{
assignFromParameters = v.Kind == IL.VariableKind.Parameter;
}
else
{
v = default(IL.ILVariable); // Used as a placeholder to represent that it comes from the result of a complex expression.
// If we didn't get an ILVariableResolveResult for the whole initializer expression,
// walk its descendants and try to find any reference that corresponds to a
// constructor parameter. We consider both ILVariable annotations (including
// by-reference wrappers) and high-level parameter symbols.
foreach (var node in initializer.DescendantsAndSelf)
{
var localVar = node.Annotation<ILVariableResolveResult>()?.Variable
?? (node.Annotation<ByReferenceResolveResult>()?.ElementResult as ILVariableResolveResult)?.Variable;
if (localVar != null)
{
if (localVar.Kind == IL.VariableKind.Parameter)
{
assignFromParameters = true;
break;
}
}
// Also check for high-level parameter symbols in case no IL annotation is present
var sym = node.GetSymbol();
if (sym is IParameter)
{
assignFromParameters = true;
break;
}
}
}
if (assignFromParameters)
{
isStructPrimaryCtor = record?.PrimaryConstructor != null;
if (!isStructPrimaryCtor)
{
// When there is no primary constructor, assignments from constructor parameters to fields or properties cannot be transferred.
// When there is no primary constructor, assignments from constructor parameters to class members cannot be transferred.
break;
}
if (fieldOrPropertyOrEvent is IField f)

Loading…
Cancel
Save