Browse Source

Improve LINQ decompiler to support combining lambda parameter names if they syntactically refer to the same range variable

pull/3416/head
Siegfried Pammer 3 months ago
parent
commit
0481c7d1ee
  1. 32
      ICSharpCode.Decompiler/CSharp/Transforms/CombineQueryExpressions.cs
  2. 21
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs

32
ICSharpCode.Decompiler/CSharp/Transforms/CombineQueryExpressions.cs

@ -16,12 +16,12 @@ @@ -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 @@ -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 @@ -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<Semantics.MemberResolveResult>(); // 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<Semantics.MemberResolveResult>(); // 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;
}
}
}

21
ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs

@ -17,10 +17,10 @@ @@ -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 @@ -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<ILVariableResolveResult>()?.Variable;
ILVariable rangeVariable = fromClause.Annotation<ILVariableResolveResult>()?.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 @@ -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<Identifier>())
{
var variable = identifier.Parent.Annotation<ILVariableResolveResult>()?.Variable;
if (variable == oldVariable)
{
identifier.Parent.RemoveAnnotations<ILVariableResolveResult>();
identifier.Parent.AddAnnotation(new ILVariableResolveResult(newVariable));
identifier.ReplaceWith(Identifier.Create(newVariable.Name));
}
}
}
bool IsDegenerateQuery(QueryExpression query)
{
if (query == null)

Loading…
Cancel
Save