public static void Rewrite(RewriteDesign design, RewrittenValueBridge[] args) { var innerValue = args[0]; RewrittenValueBridge outerKeySelector = args[1]; RewrittenValueBridge innerKeySelector = args[2]; if (design.CurrentIterator.IgnoreIterator) { return; } var resultSelectorValue = args[3]; var comparerValue = args.Length == 5 ? args[4] : null; var lookupType = ParseTypeName($"LinqRewrite.Core.SimpleLookup<{innerValue.ItemType(design)},{innerKeySelector.ReturnType(design)}>"); var lookupVariable = CreateGlobalVariable(design, lookupType, lookupType.Access("CreateForJoin") .Invoke(innerValue, innerKeySelector, comparerValue)); var itemValue = design.LastValue; var groupingType = ParseTypeName($"LinqRewrite.Core.SimpleLookup<{innerValue.ItemType(design)},{outerKeySelector.ReturnType(design)}>.Grouping"); var groupingVariable = CreateGlobalVariable(design, groupingType); design.ForAdd(groupingVariable.Assign(lookupVariable.Access("GetGrouping") .Invoke(outerKeySelector.Inline(design, itemValue), false))); design.ForAdd(If(groupingVariable.IsEqual(null), Continue())); var rewritten = new RewrittenValueBridge(((LambdaExpressionSyntax)innerKeySelector.Old).ExpressionBody, groupingVariable); var iteratorVariable = CreateGlobalVariable(design, innerKeySelector.ReturnType(design)); design.IncompleteIterators.ToArray().ForEach(x => { var newIterator = new IteratorDesign(design, new CollectionValueBridge(design, groupingType, innerKeySelector.ReturnType(design), rewritten, true)); x.ForBody.Add(newIterator); design.Iterators.Add(newIterator); design.Iterators.Remove(x); design.CurrentIterator = newIterator; RewriteCollectionEnumeration.RewriteOther(design, design.CurrentIterator.Collection, iteratorVariable); }); design.CurrentIterator = design.Iterators.Last(); design.LastValue = resultSelectorValue.Inline(design, itemValue, design.LastValue); design.ModifiedEnumeration = true; design.ListEnumeration = false; design.SourceSize = null; }
public static void Rewrite(RewriteDesign design, RewrittenValueBridge[] args) { RewrittenValueBridge method = args[0]; var newExpression = (LambdaExpressionSyntax)method.NewVal; if (design.CurrentIterator.IgnoreIterator) { return; } var collectionValue = args.Length switch { _ when newExpression.Invokable1Param(design) => method.Inline(design, design.LastValue), _ => method.Inline(design, design.LastValue, design.Indexer) }; var rewritten = new RewrittenValueBridge(newExpression.ExpressionBody, collectionValue); var iteratorVariable = CreateGlobalVariable(design, method.ReturnItemType(design)); design.IncompleteIterators.ToArray().ForEach(iterator => { var newIterator = new IteratorDesign(design, new CollectionValueBridge(design, method.ReturnType(design), method.ReturnItemType(design), rewritten, true)); iterator.ForBody.Add(newIterator); design.Iterators.Add(newIterator); design.Iterators.Remove(iterator); design.CurrentIterator = newIterator; RewriteCollectionEnumeration.RewriteOther(design, design.CurrentIterator.Collection, iteratorVariable); }); design.CurrentIterator = design.Iterators.Last(); design.LastValue = args.Length switch { 1 => design.LastValue, 2 => args[1].Inline(design, design.LastValue, design.Indexer) }; design.ModifiedEnumeration = true; design.ListEnumeration = false; design.SourceSize = null; } } }
public static LocalVariable CreateGlobalVariable(RewriteDesign design, TypeSyntax type, ValueBridge initial, IteratorDesign iterator) { string variable = "v" + VariableIndex++ % Constants.VariablesPeek; var created = new LocalVariable(variable, type) { IsGlobal = true, IsUsed = true }; design.Variables.Add(created); design.InitialAdd(LocalVariableCreation(variable, type)); iterator.PreFor.Add((StatementBridge)((ValueBridge)variable).Assign(initial)); design.SimpleEnumeration = false; return(created); }