Browse Source

Add new a.GetValueOrDefault(b) -> a ?? b transform for side-effect-free default values.

pull/3187/head
Siegfried Pammer 1 year ago
parent
commit
9ba47db69b
  1. 12
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
  2. 19
      ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs

12
ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

@ -274,6 +274,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms
protected internal override void VisitCall(Call inst)
{
if (NullableLiftingTransform.MatchGetValueOrDefault(inst, out var nullableValue, out var fallback)
&& SemanticHelper.IsPure(fallback.Flags))
{
context.Step("call Nullable{T}.GetValueOrDefault(a, b) -> a ?? b", inst);
var ldObj = new LdObj(nullableValue, inst.Method.DeclaringType);
var replacement = new NullCoalescingInstruction(NullCoalescingKind.NullableWithValueFallback, ldObj, fallback) {
UnderlyingResultType = fallback.ResultType
};
inst.ReplaceWith(replacement.WithILRange(inst));
replacement.AcceptVisitor(this);
return;
}
base.VisitCall(inst);
TransformAssignment.HandleCompoundAssign(inst, context);
}

19
ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs

@ -16,7 +16,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
@ -1047,6 +1046,24 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return true;
}
/// <summary>
/// Matches 'call nullableValue.GetValueOrDefault(fallback)'
/// </summary>
internal static bool MatchGetValueOrDefault(ILInstruction inst, out ILInstruction nullableValue, out ILInstruction fallback)
{
nullableValue = null;
fallback = null;
if (!(inst is Call call))
return false;
if (call.Method.Name != "GetValueOrDefault" || call.Arguments.Count != 2)
return false;
if (call.Method.DeclaringTypeDefinition?.KnownTypeCode != KnownTypeCode.NullableOfT)
return false;
nullableValue = call.Arguments[0];
fallback = call.Arguments[1];
return true;
}
/// <summary>
/// Matches 'call Nullable{T}.GetValueOrDefault(ldloca v)'
/// </summary>

Loading…
Cancel
Save