Browse Source

[nullables] Lifting support for: bool? == true, bool? != true, bool? == false, bool? != false

pull/870/head
Daniel Grunwald 8 years ago
parent
commit
02af1b0ab5
  1. 58
      ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs

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

@ -157,6 +157,48 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -157,6 +157,48 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
}
}
if (MatchGetValueOrDefault(condition, out ILVariable v)
&& NullableType.GetUnderlyingType(v.Type).IsKnownType(KnownTypeCode.Boolean))
{
if (MatchHasValueCall(trueInst, v) && falseInst.MatchLdcI4(0)) {
// v.GetValueOrDefault() ? v.HasValue : false
// ==> v == true
context.Step("NullableLiftingTransform: v == true", ifInst);
return new Comp(ComparisonKind.Equality, ComparisonLiftingKind.CSharp,
StackType.I4, Sign.None,
new LdLoc(v) { ILRange = trueInst.ILRange },
new LdcI4(1) { ILRange = falseInst.ILRange }
) { ILRange = ifInst.ILRange };
} else if (trueInst.MatchLdcI4(0) && MatchHasValueCall(falseInst, v)) {
// v.GetValueOrDefault() ? false : v.HasValue
// ==> v == false
context.Step("NullableLiftingTransform: v == false", ifInst);
return new Comp(ComparisonKind.Equality, ComparisonLiftingKind.CSharp,
StackType.I4, Sign.None,
new LdLoc(v) { ILRange = falseInst.ILRange },
trueInst // LdcI4(0)
) { ILRange = ifInst.ILRange };
} else if (MatchNegatedHasValueCall(trueInst, v) && falseInst.MatchLdcI4(1)) {
// v.GetValueOrDefault() ? !v.HasValue : true
// ==> v != true
context.Step("NullableLiftingTransform: v != true", ifInst);
return new Comp(ComparisonKind.Inequality, ComparisonLiftingKind.CSharp,
StackType.I4, Sign.None,
new LdLoc(v) { ILRange = trueInst.ILRange },
falseInst // LdcI4(1)
) { ILRange = ifInst.ILRange };
} else if (trueInst.MatchLdcI4(1) && MatchNegatedHasValueCall(falseInst, v)) {
// v.GetValueOrDefault() ? true : !v.HasValue
// ==> v != false
context.Step("NullableLiftingTransform: v != false", ifInst);
return new Comp(ComparisonKind.Inequality, ComparisonLiftingKind.CSharp,
StackType.I4, Sign.None,
new LdLoc(v) { ILRange = falseInst.ILRange },
new LdcI4(0) { ILRange = trueInst.ILRange }
) { ILRange = ifInst.ILRange };
}
}
return null;
}
@ -432,6 +474,22 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -432,6 +474,22 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return call.Arguments[0].MatchLdLoca(out v);
}
/// <summary>
/// Matches 'call get_HasValue(ldloca v)'
/// </summary>
static bool MatchHasValueCall(ILInstruction inst, ILVariable v)
{
return MatchHasValueCall(inst, out var v2) && v == v2;
}
/// <summary>
/// Matches 'logic.not(call get_HasValue(ldloca v))'
/// </summary>
static bool MatchNegatedHasValueCall(ILInstruction inst, ILVariable v)
{
return inst.MatchLogicNot(out var arg) && MatchHasValueCall(arg, v);
}
/// <summary>
/// Matches 'newobj Nullable{underlyingType}.ctor(arg)'
/// </summary>

Loading…
Cancel
Save