diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 7f4a5ba82..600ca0b84 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -29,6 +29,7 @@ using ICSharpCode.Decompiler.CSharp.Resolver; using ICSharpCode.Decompiler.CSharp.Syntax; using ICSharpCode.Decompiler.CSharp.Transforms; using ICSharpCode.Decompiler.IL; +using ICSharpCode.Decompiler.IL.Patterns; using ICSharpCode.Decompiler.IL.Transforms; using ICSharpCode.Decompiler.Semantics; using ICSharpCode.Decompiler.TypeSystem; @@ -5387,6 +5388,16 @@ namespace ICSharpCode.Decompiler.CSharp .WithILInstruction(matchInstruction); } case Comp comp: + if (comp.MatchLogicNot(out var operand) && MatchInstruction.IsPatternMatch(operand, out _, settings)) + { + // logic.not as a pattern + Expression sub = TranslatePattern(operand, leftHandType).Expression; + if (sub is UnaryOperatorExpression { Operator: UnaryOperatorType.PatternNot } uoe) + { + return uoe.Expression.Detach().WithILInstruction(comp); + } + return new UnaryOperatorExpression(UnaryOperatorType.PatternNot, sub).WithILInstruction(comp); + } TranslatedExpression constantValue; if (comp.Right is DefaultValue dv) { diff --git a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs index 9638eaa99..949d3e334 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs @@ -599,18 +599,15 @@ namespace ICSharpCode.Decompiler.IL.Transforms { context.Step("conditional operator", inst); IType type = v.Type; - // Try to tighten the type; this matters esp. for logic.and/logic.or: + // Try to tighten the type to `bool`; this matters esp. for logic.and/logic.or: IType type1 = value1.InferType(context.TypeSystem); IType type2 = value2.InferType(context.TypeSystem); - if (type1.IsKnownType(KnownTypeCode.Boolean) && ( - type2.IsKnownType(KnownTypeCode.Boolean) - || value2 is LdcI4 { Value: 0 or 1 } - )) + if (type1.IsKnownType(KnownTypeCode.Boolean) + && (type2.IsKnownType(KnownTypeCode.Boolean) || value2 is LdcI4 { Value: 0 or 1 })) { type = type1; } - else if (type2.IsKnownType(KnownTypeCode.Boolean) - && value1 is LdcI4 { Value: 0 or 1 }) + else if (type2.IsKnownType(KnownTypeCode.Boolean) && value1 is LdcI4 { Value: 0 or 1 }) { type = type2; } @@ -1024,5 +1021,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms context.EndStep(condition); } } + + protected internal override void VisitMatchInstruction(MatchInstruction inst) + { + inst.TestedOperand.AcceptVisitor(this); + // Do not recurse into the sub-patterns: patterns are restricted to use only certain ILInstructions, + // and arbitrary transforms might not stay within that allowed set of instructions. + } } } diff --git a/ILSpy-tests b/ILSpy-tests index 4ccc3f010..9668d49b9 160000 --- a/ILSpy-tests +++ b/ILSpy-tests @@ -1 +1 @@ -Subproject commit 4ccc3f0108007242c95025590edd4cc6ef1fb731 +Subproject commit 9668d49b9f71b40045e5417b55d20e330be95921