diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/CombineQueryExpressions.cs b/ICSharpCode.Decompiler/CSharp/Transforms/CombineQueryExpressions.cs index ad92d1a27..55d6dec35 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/CombineQueryExpressions.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/CombineQueryExpressions.cs @@ -16,12 +16,12 @@ // 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.Linq; using ICSharpCode.Decompiler.CSharp.Syntax; using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching; +using ICSharpCode.Decompiler.Util; namespace ICSharpCode.Decompiler.CSharp.Transforms { @@ -54,12 +54,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms next = child.NextSibling; CombineQueries(child, fromOrLetIdentifiers); } - QueryExpression query = node as QueryExpression; - if (query != null) + if (node is QueryExpression query) { QueryFromClause fromClause = (QueryFromClause)query.Clauses.First(); - QueryExpression innerQuery = fromClause.Expression as QueryExpression; - if (innerQuery != null) + if (fromClause.Expression is QueryExpression innerQuery) { if (TryRemoveTransparentIdentifier(query, fromClause, innerQuery, fromOrLetIdentifiers)) { @@ -165,21 +163,17 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms { RemoveTransparentIdentifierReferences(child, fromOrLetIdentifiers); } - MemberReferenceExpression mre = node as MemberReferenceExpression; - if (mre != null) + if (node is MemberReferenceExpression mre && mre.Target is IdentifierExpression ident + && CSharpDecompiler.IsTransparentIdentifier(ident.Identifier)) { - IdentifierExpression ident = mre.Target as IdentifierExpression; - if (ident != null && CSharpDecompiler.IsTransparentIdentifier(ident.Identifier)) - { - IdentifierExpression newIdent = new IdentifierExpression(mre.MemberName); - mre.TypeArguments.MoveTo(newIdent.TypeArguments); - newIdent.CopyAnnotationsFrom(mre); - newIdent.RemoveAnnotations(); // remove the reference to the property of the anonymous type - if (fromOrLetIdentifiers.TryGetValue(mre.MemberName, out var annotation)) - newIdent.AddAnnotation(annotation); - mre.ReplaceWith(newIdent); - return; - } + IdentifierExpression newIdent = new IdentifierExpression(mre.MemberName); + mre.TypeArguments.MoveTo(newIdent.TypeArguments); + newIdent.CopyAnnotationsFrom(mre); + newIdent.RemoveAnnotations(); // remove the reference to the property of the anonymous type + if (fromOrLetIdentifiers.TryGetValue(mre.MemberName, out var annotation)) + newIdent.AddAnnotation(annotation); + mre.ReplaceWith(newIdent); + return; } } } diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs b/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs index 8e5e55368..1590b2ab3 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs @@ -17,10 +17,10 @@ // DEALINGS IN THE SOFTWARE. using System; -using System.Diagnostics; using System.Linq; using ICSharpCode.Decompiler.CSharp.Syntax; +using ICSharpCode.Decompiler.IL; namespace ICSharpCode.Decompiler.CSharp.Transforms { @@ -54,13 +54,14 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms while (IsDegenerateQuery(innerQuery)) { QueryFromClause innerFromClause = (QueryFromClause)innerQuery.Clauses.First(); - if (fromClause.Identifier != innerFromClause.Identifier) - break; + ILVariable innerVariable = innerFromClause.Annotation()?.Variable; + ILVariable rangeVariable = fromClause.Annotation()?.Variable; // Replace the fromClause with all clauses from the inner query fromClause.Remove(); QueryClause insertionPos = null; foreach (var clause in innerQuery.Clauses) { + CombineRangeVariables(clause, innerVariable, rangeVariable); query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach()); } fromClause = innerFromClause; @@ -69,6 +70,20 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms } } + private void CombineRangeVariables(QueryClause clause, ILVariable oldVariable, ILVariable newVariable) + { + foreach (var identifier in clause.DescendantNodes().OfType()) + { + var variable = identifier.Parent.Annotation()?.Variable; + if (variable == oldVariable) + { + identifier.Parent.RemoveAnnotations(); + identifier.Parent.AddAnnotation(new ILVariableResolveResult(newVariable)); + identifier.ReplaceWith(Identifier.Create(newVariable.Name)); + } + } + } + bool IsDegenerateQuery(QueryExpression query) { if (query == null)