Browse Source

Add support for deconstruction to fields

pull/2119/head
Siegfried Pammer 5 years ago
parent
commit
1ecf489597
  1. 12
      ICSharpCode.Decompiler.Tests/TestCases/Correctness/DeconstructionTests.cs
  2. 10
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/DeconstructionTests.cs
  3. 5
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  4. 4
      ICSharpCode.Decompiler/IL/Instructions/DeconstructInstruction.cs

12
ICSharpCode.Decompiler.Tests/TestCases/Correctness/DeconstructionTests.cs

@ -134,6 +134,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -134,6 +134,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
NoDeconstruction_NotUsingConver_Tuple();
NullReferenceException_Field_Deconstruction(out _);
NullReferenceException_RefLocalReferencesField_Deconstruction(out _);
NullReferenceException_RefLocalReferencesArrayElement_Deconstruction(out _, null);
}
public void Property_NoDeconstruction_SwappedAssignments()
@ -211,5 +212,16 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness @@ -211,5 +212,16 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
Console.WriteLine(ex.GetType().FullName);
}
}
public void NullReferenceException_RefLocalReferencesArrayElement_Deconstruction(out int a, int[] arr)
{
try {
ref int i = ref arr[0];
(i, a) = GetSource<int, int>();
} catch (Exception ex) {
a = 0;
Console.WriteLine(ex.GetType().FullName);
}
}
}
}

10
ICSharpCode.Decompiler.Tests/TestCases/Pretty/DeconstructionTests.cs

@ -231,5 +231,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -231,5 +231,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
(a, GetRef<double>()) = GetSource<double, float>();
}
//public void ArrayAssign_FloatToDoubleConversion(double[] arr)
//{
// (arr[0], arr[1], arr[2]) = GetSource<double, float, double>();
//}
public void Field_NoConversion()
{
(Get(0).IntField, Get(1).IntField) = GetSource<int, int>();
}
}
}

5
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -3440,7 +3440,10 @@ namespace ICSharpCode.Decompiler.CSharp @@ -3440,7 +3440,10 @@ namespace ICSharpCode.Decompiler.CSharp
Debug.Assert(call.Arguments.Last().MatchLdLoc(value));
break;
case StObj stobj:
ReplaceAssignmentTarget(stobj.Target);
var target = stobj.Target;
while (target.MatchLdFlda(out var nestedTarget, out _))
target = nestedTarget;
ReplaceAssignmentTarget(target);
Debug.Assert(stobj.Value.MatchLdLoc(value));
break;
default:

4
ICSharpCode.Decompiler/IL/Instructions/DeconstructInstruction.cs

@ -230,13 +230,15 @@ namespace ICSharpCode.Decompiler.IL @@ -230,13 +230,15 @@ namespace ICSharpCode.Decompiler.IL
return true;
case StObj stobj:
var target = stobj.Target;
while (target.MatchLdFlda(out var nestedTarget, out _))
target = nestedTarget;
if (target.Flags == InstructionFlags.None) {
// OK - we accept integer literals, etc.
} else if (target.MatchLdLoc(out var v)) {
} else {
return false;
}
if (target.InferType(typeSystem) is ByReferenceType brt)
if (stobj.Target.InferType(typeSystem) is ByReferenceType brt)
expectedType = brt.ElementType;
else
expectedType = SpecialType.UnknownType;

Loading…
Cancel
Save