|
|
|
@ -107,16 +107,24 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
@@ -107,16 +107,24 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
|
|
|
|
|
case "GroupBy": |
|
|
|
|
{ |
|
|
|
|
if (invocation.Arguments.Count == 2) { |
|
|
|
|
if (MatchSimpleLambda(invocation.Arguments.ElementAt(0), out ParameterDeclaration parameter1, out Expression keySelector) |
|
|
|
|
&& MatchSimpleLambda(invocation.Arguments.ElementAt(1), out ParameterDeclaration parameter2, out Expression elementSelector) |
|
|
|
|
Expression keyLambda = invocation.Arguments.ElementAt(0); |
|
|
|
|
Expression projectionLambda = invocation.Arguments.ElementAt(1); |
|
|
|
|
if (MatchSimpleLambda(keyLambda, out ParameterDeclaration parameter1, out Expression keySelector) |
|
|
|
|
&& MatchSimpleLambda(projectionLambda, out ParameterDeclaration parameter2, out Expression elementSelector) |
|
|
|
|
&& parameter1.Name == parameter2.Name) { |
|
|
|
|
QueryExpression query = new QueryExpression(); |
|
|
|
|
query.Clauses.Add(MakeFromClause(parameter1, mre.Target.Detach())); |
|
|
|
|
query.Clauses.Add(new QueryGroupClause { Projection = elementSelector.Detach(), Key = keySelector.Detach() }); |
|
|
|
|
var queryGroupClause = new QueryGroupClause { |
|
|
|
|
Projection = elementSelector.Detach(), |
|
|
|
|
Key = keySelector.Detach() |
|
|
|
|
}; |
|
|
|
|
queryGroupClause.AddAnnotation(new QueryGroupClauseAnnotation(keyLambda.Annotation<IL.ILFunction>(), projectionLambda.Annotation<IL.ILFunction>())); |
|
|
|
|
query.Clauses.Add(queryGroupClause); |
|
|
|
|
return query; |
|
|
|
|
} |
|
|
|
|
} else if (invocation.Arguments.Count == 1) { |
|
|
|
|
if (MatchSimpleLambda(invocation.Arguments.Single(), out ParameterDeclaration parameter, out Expression keySelector)) { |
|
|
|
|
Expression lambda = invocation.Arguments.Single(); |
|
|
|
|
if (MatchSimpleLambda(lambda, out ParameterDeclaration parameter, out Expression keySelector)) { |
|
|
|
|
QueryExpression query = new QueryExpression(); |
|
|
|
|
query.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach())); |
|
|
|
|
query.Clauses.Add(new QueryGroupClause { Projection = new IdentifierExpression(parameter.Name).CopyAnnotationsFrom(parameter), Key = keySelector.Detach() }); |
|
|
|
@ -129,7 +137,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
@@ -129,7 +137,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
|
|
|
|
|
{ |
|
|
|
|
if (invocation.Arguments.Count != 2) |
|
|
|
|
return null; |
|
|
|
|
if (!MatchSimpleLambda(invocation.Arguments.ElementAt(0), out ParameterDeclaration parameter, out Expression collectionSelector)) |
|
|
|
|
var fromExpressionLambda = invocation.Arguments.ElementAt(0); |
|
|
|
|
if (!MatchSimpleLambda(fromExpressionLambda, out ParameterDeclaration parameter, out Expression collectionSelector)) |
|
|
|
|
return null; |
|
|
|
|
if (IsNullConditional(collectionSelector)) |
|
|
|
|
return null; |
|
|
|
@ -140,7 +149,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
@@ -140,7 +149,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
|
|
|
|
|
if (p1.Name == parameter.Name) { |
|
|
|
|
QueryExpression query = new QueryExpression(); |
|
|
|
|
query.Clauses.Add(MakeFromClause(p1, mre.Target.Detach())); |
|
|
|
|
query.Clauses.Add(MakeFromClause(p2, collectionSelector.Detach())); |
|
|
|
|
query.Clauses.Add(MakeFromClause(p2, collectionSelector.Detach()).CopyAnnotationsFrom(fromExpressionLambda)); |
|
|
|
|
query.Clauses.Add(new QuerySelectClause { Expression = WrapExpressionInParenthesesIfNecessary(((Expression)lambda.Body).Detach(), parameter.Name) }); |
|
|
|
|
return query; |
|
|
|
|
} |
|
|
|
@ -171,7 +180,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
@@ -171,7 +180,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
|
|
|
|
|
return null; |
|
|
|
|
if (!IsComplexQuery(mre)) |
|
|
|
|
return null; |
|
|
|
|
if (MatchSimpleLambda(invocation.Arguments.Single(), out ParameterDeclaration parameter, out Expression orderExpression)) { |
|
|
|
|
var lambda = invocation.Arguments.Single(); |
|
|
|
|
if (MatchSimpleLambda(lambda, out ParameterDeclaration parameter, out Expression orderExpression)) { |
|
|
|
|
if (ValidateThenByChain(invocation, parameter.Name)) { |
|
|
|
|
QueryOrderClause orderClause = new QueryOrderClause(); |
|
|
|
|
while (mre.MemberName == "ThenBy" || mre.MemberName == "ThenByDescending") { |
|
|
|
@ -180,18 +190,19 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
@@ -180,18 +190,19 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
|
|
|
|
|
null, new QueryOrdering { |
|
|
|
|
Expression = orderExpression.Detach(), |
|
|
|
|
Direction = (mre.MemberName == "ThenBy" ? QueryOrderingDirection.None : QueryOrderingDirection.Descending) |
|
|
|
|
}); |
|
|
|
|
}.CopyAnnotationsFrom(lambda)); |
|
|
|
|
|
|
|
|
|
InvocationExpression tmp = (InvocationExpression)mre.Target; |
|
|
|
|
mre = (MemberReferenceExpression)tmp.Target; |
|
|
|
|
MatchSimpleLambda(tmp.Arguments.Single(), out parameter, out orderExpression); |
|
|
|
|
lambda = tmp.Arguments.Single(); |
|
|
|
|
MatchSimpleLambda(lambda, out parameter, out orderExpression); |
|
|
|
|
} |
|
|
|
|
// insert new ordering at beginning
|
|
|
|
|
orderClause.Orderings.InsertAfter( |
|
|
|
|
null, new QueryOrdering { |
|
|
|
|
Expression = orderExpression.Detach(), |
|
|
|
|
Direction = (mre.MemberName == "OrderBy" ? QueryOrderingDirection.None : QueryOrderingDirection.Descending) |
|
|
|
|
}); |
|
|
|
|
}.CopyAnnotationsFrom(lambda)); |
|
|
|
|
|
|
|
|
|
QueryExpression query = new QueryExpression(); |
|
|
|
|
query.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach())); |
|
|
|
@ -210,9 +221,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
@@ -210,9 +221,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
|
|
|
|
|
Expression source2 = invocation.Arguments.ElementAt(0); |
|
|
|
|
if (IsNullConditional(source2)) |
|
|
|
|
return null; |
|
|
|
|
if (!MatchSimpleLambda(invocation.Arguments.ElementAt(1), out ParameterDeclaration element1, out Expression key1)) |
|
|
|
|
Expression outerLambda = invocation.Arguments.ElementAt(1); |
|
|
|
|
if (!MatchSimpleLambda(outerLambda, out ParameterDeclaration element1, out Expression key1)) |
|
|
|
|
return null; |
|
|
|
|
if (!MatchSimpleLambda(invocation.Arguments.ElementAt(2), out ParameterDeclaration element2, out Expression key2)) |
|
|
|
|
Expression innerLambda = invocation.Arguments.ElementAt(2); |
|
|
|
|
if (!MatchSimpleLambda(innerLambda, out ParameterDeclaration element2, out Expression key2)) |
|
|
|
|
return null; |
|
|
|
|
LambdaExpression lambda = invocation.Arguments.ElementAt(3) as LambdaExpression; |
|
|
|
|
if (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression) { |
|
|
|
@ -229,6 +242,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
@@ -229,6 +242,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
|
|
|
|
|
if (mre.MemberName == "GroupJoin") { |
|
|
|
|
joinClause.IntoIdentifier = p2.Name; // into p2.Name
|
|
|
|
|
} |
|
|
|
|
joinClause.AddAnnotation(new QueryJoinClauseAnnotation(outerLambda.Annotation<IL.ILFunction>(), innerLambda.Annotation<IL.ILFunction>())); |
|
|
|
|
query.Clauses.Add(joinClause); |
|
|
|
|
query.Clauses.Add(new QuerySelectClause { Expression = ((Expression)lambda.Body).Detach() }.CopyAnnotationsFrom(lambda)); |
|
|
|
|
return query; |
|
|
|
|