Browse Source

IntroduceQueryExpressions: Inline variable declarations and use pattern matching syntax where possible.

pull/1937/head
Siegfried Pammer 5 years ago
parent
commit
95beaddc80
  1. 50
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs

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

@ -76,7 +76,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
node.ReplaceWith(query); node.ReplaceWith(query);
AstNode next; AstNode next;
for (AstNode child = (query ?? node).FirstChild; child != null; child = next) { for (AstNode child = (query ?? node).FirstChild; child != null; child = next) {
// store referece to next child before transformation // store reference to next child before transformation
next = child.NextSibling; next = child.NextSibling;
DecompileQueries(child); DecompileQueries(child);
} }
@ -95,10 +95,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
return null; return null;
if (!IsComplexQuery(mre)) if (!IsComplexQuery(mre))
return null; return null;
ParameterDeclaration parameter;
Expression body;
Expression expr = invocation.Arguments.Single(); Expression expr = invocation.Arguments.Single();
if (MatchSimpleLambda(expr, out parameter, out body)) { if (MatchSimpleLambda(expr, out ParameterDeclaration parameter, out Expression body)) {
QueryExpression query = new QueryExpression(); QueryExpression query = new QueryExpression();
query.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach())); query.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach()));
query.Clauses.Add(new QuerySelectClause { Expression = WrapExpressionInParenthesesIfNecessary(body.Detach(), parameter.Name) }.CopyAnnotationsFrom(expr)); query.Clauses.Add(new QuerySelectClause { Expression = WrapExpressionInParenthesesIfNecessary(body.Detach(), parameter.Name) }.CopyAnnotationsFrom(expr));
@ -109,21 +107,16 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
case "GroupBy": case "GroupBy":
{ {
if (invocation.Arguments.Count == 2) { if (invocation.Arguments.Count == 2) {
ParameterDeclaration parameter1, parameter2; if (MatchSimpleLambda(invocation.Arguments.ElementAt(0), out ParameterDeclaration parameter1, out Expression keySelector)
Expression keySelector, elementSelector; && MatchSimpleLambda(invocation.Arguments.ElementAt(1), out ParameterDeclaration parameter2, out Expression elementSelector)
if (MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameter1, out keySelector) && parameter1.Name == parameter2.Name) {
&& MatchSimpleLambda(invocation.Arguments.ElementAt(1), out parameter2, out elementSelector)
&& parameter1.Name == parameter2.Name)
{
QueryExpression query = new QueryExpression(); QueryExpression query = new QueryExpression();
query.Clauses.Add(MakeFromClause(parameter1, mre.Target.Detach())); query.Clauses.Add(MakeFromClause(parameter1, mre.Target.Detach()));
query.Clauses.Add(new QueryGroupClause { Projection = elementSelector.Detach(), Key = keySelector.Detach() }); query.Clauses.Add(new QueryGroupClause { Projection = elementSelector.Detach(), Key = keySelector.Detach() });
return query; return query;
} }
} else if (invocation.Arguments.Count == 1) { } else if (invocation.Arguments.Count == 1) {
ParameterDeclaration parameter; if (MatchSimpleLambda(invocation.Arguments.Single(), out ParameterDeclaration parameter, out Expression keySelector)) {
Expression keySelector;
if (MatchSimpleLambda(invocation.Arguments.Single(), out parameter, out keySelector)) {
QueryExpression query = new QueryExpression(); QueryExpression query = new QueryExpression();
query.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach())); query.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach()));
query.Clauses.Add(new QueryGroupClause { Projection = new IdentifierExpression(parameter.Name).CopyAnnotationsFrom(parameter), Key = keySelector.Detach() }); query.Clauses.Add(new QueryGroupClause { Projection = new IdentifierExpression(parameter.Name).CopyAnnotationsFrom(parameter), Key = keySelector.Detach() });
@ -136,9 +129,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
{ {
if (invocation.Arguments.Count != 2) if (invocation.Arguments.Count != 2)
return null; return null;
ParameterDeclaration parameter; if (!MatchSimpleLambda(invocation.Arguments.ElementAt(0), out ParameterDeclaration parameter, out Expression collectionSelector))
Expression collectionSelector;
if (!MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameter, out collectionSelector))
return null; return null;
if (IsNullConditional(collectionSelector)) if (IsNullConditional(collectionSelector))
return null; return null;
@ -162,10 +153,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
return null; return null;
if (!IsComplexQuery(mre)) if (!IsComplexQuery(mre))
return null; return null;
ParameterDeclaration parameter;
Expression body;
Expression expr = invocation.Arguments.Single(); Expression expr = invocation.Arguments.Single();
if (MatchSimpleLambda(expr, out parameter, out body)) { if (MatchSimpleLambda(expr, out ParameterDeclaration parameter, out Expression body)) {
QueryExpression query = new QueryExpression(); QueryExpression query = new QueryExpression();
query.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach())); query.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach()));
query.Clauses.Add(new QueryWhereClause { Condition = body.Detach() }.CopyAnnotationsFrom(expr)); query.Clauses.Add(new QueryWhereClause { Condition = body.Detach() }.CopyAnnotationsFrom(expr));
@ -182,12 +171,9 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
return null; return null;
if (!IsComplexQuery(mre)) if (!IsComplexQuery(mre))
return null; return null;
ParameterDeclaration parameter; if (MatchSimpleLambda(invocation.Arguments.Single(), out ParameterDeclaration parameter, out Expression orderExpression)) {
Expression orderExpression;
if (MatchSimpleLambda(invocation.Arguments.Single(), out parameter, out orderExpression)) {
if (ValidateThenByChain(invocation, parameter.Name)) { if (ValidateThenByChain(invocation, parameter.Name)) {
QueryOrderClause orderClause = new QueryOrderClause(); QueryOrderClause orderClause = new QueryOrderClause();
InvocationExpression tmp = invocation;
while (mre.MemberName == "ThenBy" || mre.MemberName == "ThenByDescending") { while (mre.MemberName == "ThenBy" || mre.MemberName == "ThenByDescending") {
// insert new ordering at beginning // insert new ordering at beginning
orderClause.Orderings.InsertAfter( orderClause.Orderings.InsertAfter(
@ -196,7 +182,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
Direction = (mre.MemberName == "ThenBy" ? QueryOrderingDirection.None : QueryOrderingDirection.Descending) Direction = (mre.MemberName == "ThenBy" ? QueryOrderingDirection.None : QueryOrderingDirection.Descending)
}); });
tmp = (InvocationExpression)mre.Target; InvocationExpression tmp = (InvocationExpression)mre.Target;
mre = (MemberReferenceExpression)tmp.Target; mre = (MemberReferenceExpression)tmp.Target;
MatchSimpleLambda(tmp.Arguments.Single(), out parameter, out orderExpression); MatchSimpleLambda(tmp.Arguments.Single(), out parameter, out orderExpression);
} }
@ -224,11 +210,9 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
Expression source2 = invocation.Arguments.ElementAt(0); Expression source2 = invocation.Arguments.ElementAt(0);
if (IsNullConditional(source2)) if (IsNullConditional(source2))
return null; return null;
ParameterDeclaration element1, element2; if (!MatchSimpleLambda(invocation.Arguments.ElementAt(1), out ParameterDeclaration element1, out Expression key1))
Expression key1, key2;
if (!MatchSimpleLambda(invocation.Arguments.ElementAt(1), out element1, out key1))
return null; return null;
if (!MatchSimpleLambda(invocation.Arguments.ElementAt(2), out element2, out key2)) if (!MatchSimpleLambda(invocation.Arguments.ElementAt(2), out ParameterDeclaration element2, out Expression key2))
return null; return null;
LambdaExpression lambda = invocation.Arguments.ElementAt(3) as LambdaExpression; LambdaExpression lambda = invocation.Arguments.ElementAt(3) as LambdaExpression;
if (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression) { if (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression) {
@ -316,12 +300,9 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
{ {
if (invocation == null || invocation.Arguments.Count != 1) if (invocation == null || invocation.Arguments.Count != 1)
return false; return false;
MemberReferenceExpression mre = invocation.Target as MemberReferenceExpression; if (!(invocation.Target is MemberReferenceExpression mre))
if (mre == null)
return false; return false;
ParameterDeclaration parameter; if (!MatchSimpleLambda(invocation.Arguments.Single(), out ParameterDeclaration parameter, out _))
Expression body;
if (!MatchSimpleLambda(invocation.Arguments.Single(), out parameter, out body))
return false; return false;
if (parameter.Name != expectedParameterName) if (parameter.Name != expectedParameterName)
return false; return false;
@ -337,8 +318,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
/// <summary>Matches simple lambdas of the form "a => b"</summary> /// <summary>Matches simple lambdas of the form "a => b"</summary>
bool MatchSimpleLambda(Expression expr, out ParameterDeclaration parameter, out Expression body) bool MatchSimpleLambda(Expression expr, out ParameterDeclaration parameter, out Expression body)
{ {
var lambda = expr as LambdaExpression; if (expr is LambdaExpression lambda && lambda.Parameters.Count == 1 && lambda.Body is Expression) {
if (lambda != null && lambda.Parameters.Count == 1 && lambda.Body is Expression) {
ParameterDeclaration p = lambda.Parameters.Single(); ParameterDeclaration p = lambda.Parameters.Single();
if (p.ParameterModifier == ParameterModifier.None) { if (p.ParameterModifier == ParameterModifier.None) {
parameter = p; parameter = p;

Loading…
Cancel
Save