private IEnumerable <Holder> FindCandidates(MethodDeclaration right, int count) { var rights_primitives = right.AllPrimitiveExpressions(); // Find all PrimitiveExpressions except the keyword 'null' IEnumerable <PrimitiveExpression> primitives = rights_primitives.Where(x => x.ValueType != null); // find the position of each primitive var prims_with_position = from p in primitives select new { p.Value, p.ValueType, Index = rights_primitives.IndexOf(p) }; // Group them together by literal value. The groups then are candidates for replacement by a single param. var prim_groups = from p in prims_with_position group p by new { p.Value, p.ValueType } into g select new PrimExpSet { Value = g.Key.Value, ValueType = g.Key.ValueType, Positions = g.Select(x => x.Index) }; // The powerset of the primitive positions is all the possible ways a single primitive value can be converted to a param. var all_param_possibles = from pes in prim_groups let expanded = from positions in Sets <int> .PowerSet(pes.Positions.ToArray()) select new PrimExpSet { Value = pes.Value, ValueType = pes.ValueType, Positions = positions } select expanded; foreach (var e1 in Sets <PrimExpSet> .CartesianProduct(all_param_possibles, count)) { // If count is neg, let anything through. if (count < 0 || e1.Count() == count) { var md = MakePermutation(right, e1); const string QUOTE = "\""; var parameters = e1.Select(x => x.ValueType == typeof(string) ? QUOTE + x.Value + QUOTE : x.Value).ToList(); yield return(new Holder { md = md, parameters = parameters }); } } }
private MethodDeclaration MakePermutation(MethodDeclaration right, IEnumerable <PrimExpSet> prim_groups) { ResetNameCount(); right = right.DeepCopy(); var rights_primitives = right.AllPrimitiveExpressions(); foreach (var prim_grp in prim_groups) { var param_name = NextName(); var typeRef = new TypeReference(prim_grp.ValueType.FullName); right.Parameters.Add(new ParameterDeclarationExpression(typeRef, param_name)); var replacer = new PrimitiveReplacer(); foreach (var pos in prim_grp.Positions) { replacer.AddReplacement(rights_primitives[pos], new IdentifierExpression(param_name)); } right.AcceptVisitor(replacer, null); } return(right); }