diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.cs index 637364b97f..0870735b1d 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.cs @@ -44,6 +44,20 @@ public static Maybe Where(this Maybe a, Func predicate) public class QueryExpressions { + public class MaybeHolder + { + public Maybe Value; + +#if CS60 + public Maybe this[int index] => default(Maybe); +#endif + + public Func> Factory() + { + return () => default(Maybe); + } + } + public class HbmParam { public string Name { get; set; } @@ -217,6 +231,21 @@ private List Issue2545(List arglist) { return arglist?.OrderByDescending((string f) => f.Length).ThenBy((string f) => f.ToLower()).ToList(); } + + public Maybe? NullConditionalValueTypeQuery(MaybeHolder holder) + { + return holder?.Value.Where((int value) => value > 0).Select((int value) => value.ToString()); + } + + public Maybe? NullConditionalNestedInvocationQuery(MaybeHolder holder) + { + return holder?.Factory()().Where((int value) => value > 0).Select((int value) => value.ToString()); + } + + public Maybe? NullConditionalIndexerQuery(MaybeHolder holder) + { + return holder?[0].Where((int value) => value > 0).Select((int value) => value.ToString()); + } #endif public static IEnumerable Issue1310a(bool test) diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs b/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs index 2b07fc7e87..4745061e3b 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs @@ -377,10 +377,13 @@ public override AstNode VisitIdentifier(Identifier identifier) } } - bool IsNullConditional(Expression target) - { - return target is UnaryOperatorExpression uoe && uoe.Operator == UnaryOperatorType.NullConditional; - } + bool IsNullConditional(Expression target) => target switch { + UnaryOperatorExpression { Operator: UnaryOperatorType.NullConditional } => true, + MemberReferenceExpression member => IsNullConditional(member.Target), + InvocationExpression invocation => IsNullConditional(invocation.Target), + IndexerExpression { Target: { } indexerTarget } => IsNullConditional(indexerTarget), + _ => false + }; /// /// This fixes #437: Decompilation of query expression loses material parentheses