bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery) { if (!IsTransparentIdentifier(fromClause.Identifier)) { return(false); } Match match = selectTransparentIdentifierPattern.Match(innerQuery.Clauses.Last()); if (!match.Success) { return(false); } QuerySelectClause selectClause = (QuerySelectClause)innerQuery.Clauses.Last(); NamedArgumentExpression nae1 = match.Get <NamedArgumentExpression>("nae1").Single(); NamedArgumentExpression nae2 = match.Get <NamedArgumentExpression>("nae2").Single(); if (nae1.Identifier != ((IdentifierExpression)nae1.Expression).Identifier) { return(false); } IdentifierExpression nae2IdentExpr = nae2.Expression as IdentifierExpression; if (nae2IdentExpr != null && nae2.Identifier == nae2IdentExpr.Identifier) { // from * in (from x in ... select new { x = x, y = y }) ... // => // from x in ... ... fromClause.Remove(); selectClause.Remove(); // Move clauses from innerQuery to query QueryClause insertionPos = null; foreach (var clause in innerQuery.Clauses) { query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach()); } } else { // from * in (from x in ... select new { x = x, y = expr }) ... // => // from x in ... let y = expr ... fromClause.Remove(); selectClause.Remove(); // Move clauses from innerQuery to query QueryClause insertionPos = null; foreach (var clause in innerQuery.Clauses) { query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach()); } query.Clauses.InsertAfter(insertionPos, new QueryLetClause { Identifier = nae2.Identifier, Expression = nae2.Expression.Detach() }); } return(true); }
bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery, Dictionary <string, object> letClauses) { if (!IsTransparentIdentifier(fromClause.Identifier)) { return(false); } QuerySelectClause selectClause = innerQuery.Clauses.Last() as QuerySelectClause; Match match = selectTransparentIdentifierPattern.Match(selectClause); if (!match.Success) { return(false); } // from * in (from x in ... select new { members of anonymous type }) ... // => // from x in ... { let x = ... } ... fromClause.Remove(); selectClause.Remove(); // Move clauses from innerQuery to query QueryClause insertionPos = null; foreach (var clause in innerQuery.Clauses) { query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach()); } foreach (var expr in match.Get <Expression>("expr")) { switch (expr) { case IdentifierExpression identifier: // nothing to add continue; case NamedExpression namedExpression: if (namedExpression.Expression is IdentifierExpression identifierExpression && namedExpression.Name == identifierExpression.Identifier) { letClauses[namedExpression.Name] = identifierExpression.Annotation <ILVariableResolveResult>(); continue; } QueryLetClause letClause = new QueryLetClause { Identifier = namedExpression.Name, Expression = namedExpression.Expression.Detach() }; var annotation = new LetIdentifierAnnotation(); letClause.AddAnnotation(annotation); letClauses[namedExpression.Name] = annotation; query.Clauses.InsertAfter(insertionPos, letClause); break; } } return(true); }
public void Run(AstNode rootNode, TransformContext context) { if (!context.Settings.QueryExpressions) { return; } this.context = context; DecompileQueries(rootNode); // After all queries were decompiled, detect degenerate queries (queries not property terminated with 'select' or 'group') // and fix them, either by adding a degenerate select, or by combining them with another query. foreach (QueryExpression query in rootNode.Descendants.OfType <QueryExpression>()) { QueryFromClause fromClause = (QueryFromClause)query.Clauses.First(); if (IsDegenerateQuery(query)) { // introduce select for degenerate query query.Clauses.Add(new QuerySelectClause { Expression = new IdentifierExpression(fromClause.Identifier).CopyAnnotationsFrom(fromClause) }); } // See if the data source of this query is a degenerate query, // and combine the queries if possible. QueryExpression innerQuery = fromClause.Expression as QueryExpression; while (IsDegenerateQuery(innerQuery)) { QueryFromClause innerFromClause = (QueryFromClause)innerQuery.Clauses.First(); if (fromClause.Identifier != innerFromClause.Identifier) { break; } // Replace the fromClause with all clauses from the inner query fromClause.Remove(); QueryClause insertionPos = null; foreach (var clause in innerQuery.Clauses) { query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach()); } fromClause = innerFromClause; innerQuery = fromClause.Expression as QueryExpression; } } }
bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery) { if (!IsTransparentIdentifier(fromClause.Identifier)) { return(false); } Match match = selectTransparentIdentifierPattern.Match(innerQuery.Clauses.Last()); if (!match.Success) { return(false); } QuerySelectClause selectClause = (QuerySelectClause)innerQuery.Clauses.Last(); NamedExpression nae1 = match.Get <NamedExpression>("nae1").SingleOrDefault(); NamedExpression nae2 = match.Get <NamedExpression>("nae2").SingleOrDefault(); if (nae1 != null && nae1.Name != ((IdentifierExpression)nae1.Expression).Identifier) { return(false); } Expression nae2Expr = match.Get <Expression>("nae2Expr").Single(); IdentifierExpression nae2IdentExpr = nae2Expr as IdentifierExpression; if (nae2IdentExpr != null && (nae2 == null || nae2.Name == nae2IdentExpr.Identifier)) { // from * in (from x in ... select new { x = x, y = y }) ... // => // from x in ... ... fromClause.Remove(); selectClause.Remove(); // Move clauses from innerQuery to query QueryClause insertionPos = null; foreach (var clause in innerQuery.Clauses) { query.Clauses.InsertAfter(insertionPos, insertionPos = Detach(clause)); } } else { // from * in (from x in ... select new { x = x, y = expr }) ... // => // from x in ... let y = expr ... fromClause.Remove(); selectClause.Remove(); // Move clauses from innerQuery to query QueryClause insertionPos = null; foreach (var clause in innerQuery.Clauses) { query.Clauses.InsertAfter(insertionPos, insertionPos = Detach(clause)); } string ident; if (nae2 != null) { ident = nae2.Name; } else if (nae2Expr is MemberReferenceExpression) { ident = ((MemberReferenceExpression)nae2Expr).MemberName; } else { throw new InvalidOperationException("Could not infer name from initializer in AnonymousTypeCreateExpression"); } query.Clauses.InsertAfter(insertionPos, new QueryLetClause { Identifier = ident, Expression = Detach(nae2Expr) }); } return(true); }
bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery, string continuationIdentifier, out string transparentIdentifier) { transparentIdentifier = fromClause.Identifier; Match match = selectTransparentIdentifierPattern.Match(innerQuery.Clauses.Last()); if (!match.Success) return false; QuerySelectClause selectClause = (QuerySelectClause)innerQuery.Clauses.Last(); Expression nae1 = match.Get<Expression>("nae1").SingleOrDefault(); string nae1Name = ExtractExpressionName(ref nae1); if (nae1Name == null) return false; Expression nae2 = match.Get<Expression>("nae2").SingleOrDefault(); string nae2Name = ExtractExpressionName(ref nae2); if (nae2Name == null) return false; bool introduceLetClause = true; var nae1Identifier = nae1 as IdentifierExpression; var nae2Identifier = nae2 as IdentifierExpression; if (nae1Identifier != null && nae2Identifier != null && nae1Identifier.Identifier == nae1Name && nae2Identifier.Identifier == nae2Name) { introduceLetClause = false; } if (nae1Name != continuationIdentifier) { if (nae2Name == continuationIdentifier) { //Members are in reversed order string tempName = nae1Name; Expression tempNae = nae1; nae1Name = nae2Name; nae1 = nae2; nae2Name = tempName; nae2 = tempNae; } else { return false; } } if (introduceLetClause && innerQuery.Clauses.OfType<QueryFromClause>().Any(from => from.Identifier == nae2Name)) { return false; } if (introduceLetClause && innerQuery.Clauses.OfType<QueryJoinClause>().Any(join => join.JoinIdentifier == nae2Name)) { return false; } // from * in (from x in ... select new { x = x, y = expr }) ... // => // from x in ... let y = expr ... fromClause.Remove(); selectClause.Remove(); // Move clauses from innerQuery to query QueryClause insertionPos = null; foreach (var clause in innerQuery.Clauses) { query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach()); } if (introduceLetClause) { query.Clauses.InsertAfter(insertionPos, new QueryLetClause { Identifier = nae2Name, Expression = nae2.Detach() }); } return true; }
bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery) { if (!IsTransparentIdentifier(fromClause.Identifier)) return false; Match match = selectTransparentIdentifierPattern.Match(innerQuery.Clauses.Last()); if (!match.Success) return false; QuerySelectClause selectClause = (QuerySelectClause)innerQuery.Clauses.Last(); NamedExpression nae1 = match.Get<NamedExpression>("nae1").SingleOrDefault(); NamedExpression nae2 = match.Get<NamedExpression>("nae2").SingleOrDefault(); if (nae1 != null && nae1.Name != ((IdentifierExpression)nae1.Expression).Identifier) return false; Expression nae2Expr = match.Get<Expression>("nae2Expr").Single(); IdentifierExpression nae2IdentExpr = nae2Expr as IdentifierExpression; if (nae2IdentExpr != null && (nae2 == null || nae2.Name == nae2IdentExpr.Identifier)) { // from * in (from x in ... select new { x = x, y = y }) ... // => // from x in ... ... fromClause.Remove(); selectClause.Remove(); // Move clauses from innerQuery to query QueryClause insertionPos = null; foreach (var clause in innerQuery.Clauses) { query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach()); } } else { // from * in (from x in ... select new { x = x, y = expr }) ... // => // from x in ... let y = expr ... fromClause.Remove(); selectClause.Remove(); // Move clauses from innerQuery to query QueryClause insertionPos = null; foreach (var clause in innerQuery.Clauses) { query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach()); } string ident; if (nae2 != null) ident = nae2.Name; else if (nae2Expr is IdentifierExpression) ident = ((IdentifierExpression)nae2Expr).Identifier; else if (nae2Expr is MemberReferenceExpression) ident = ((MemberReferenceExpression)nae2Expr).MemberName; else throw new InvalidOperationException("Could not infer name from initializer in AnonymousTypeCreateExpression"); query.Clauses.InsertAfter(insertionPos, new QueryLetClause { Identifier = ident, Expression = nae2Expr.Detach() }); } return true; }
bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery, out string transparentIdentifier) { transparentIdentifier = fromClause.Identifier; Match match = selectTransparentIdentifierPattern.Match(innerQuery.Clauses.Last()); if (!match.Success) return false; QuerySelectClause selectClause = (QuerySelectClause)innerQuery.Clauses.Last(); Expression nae1 = match.Get<Expression>("nae1").SingleOrDefault(); string nae1Name = ExtractExpressionName(ref nae1); if (nae1Name == null) return false; Expression nae2 = match.Get<Expression>("nae2").SingleOrDefault(); string nae2Name = ExtractExpressionName(ref nae2); if (nae1Name == null) return false; // from * in (from x in ... select new { x = x, y = expr }) ... // => // from x in ... let y = expr ... fromClause.Remove(); selectClause.Remove(); // Move clauses from innerQuery to query QueryClause insertionPos = null; foreach (var clause in innerQuery.Clauses) { query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach()); } query.Clauses.InsertAfter(insertionPos, new QueryLetClause { Identifier = nae2Name, Expression = nae2.Detach() }); return true; }
bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery) { if (!IsTransparentIdentifier(fromClause.Identifier)) return false; Match match = selectTransparentIdentifierPattern.Match(innerQuery.Clauses.Last()); if (!match.Success) return false; QuerySelectClause selectClause = (QuerySelectClause)innerQuery.Clauses.Last(); NamedArgumentExpression nae1 = match.Get<NamedArgumentExpression>("nae1").Single(); NamedArgumentExpression nae2 = match.Get<NamedArgumentExpression>("nae2").Single(); if (nae1.Identifier != ((IdentifierExpression)nae1.Expression).Identifier) return false; IdentifierExpression nae2IdentExpr = nae2.Expression as IdentifierExpression; if (nae2IdentExpr != null && nae2.Identifier == nae2IdentExpr.Identifier) { // from * in (from x in ... select new { x = x, y = y }) ... // => // from x in ... ... fromClause.Remove(); selectClause.Remove(); // Move clauses from innerQuery to query QueryClause insertionPos = null; foreach (var clause in innerQuery.Clauses) { query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach()); } } else { // from * in (from x in ... select new { x = x, y = expr }) ... // => // from x in ... let y = expr ... fromClause.Remove(); selectClause.Remove(); // Move clauses from innerQuery to query QueryClause insertionPos = null; foreach (var clause in innerQuery.Clauses) { query.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach()); } query.Clauses.InsertAfter(insertionPos, new QueryLetClause { Identifier = nae2.Identifier, Expression = nae2.Expression.Detach() }); } return true; }