public static List <FilterMember> FindFiltersForTarget(string arg0Lower, object example, object relativeTo, OutputDelegate warn) { Type exampleType = example.GetType(); Type relativeToType = relativeTo == null ? typeof(object) : relativeTo.GetType(); List <FilterMember> firstTry = FindFiltersForExampleSubType(arg0Lower, exampleType, exampleType, relativeToType, warn);; if (firstTry.Count > 0) { return(firstTry); } if ((example is MixinSubObjects)) { List <FilterMember> newPossible = new List <FilterMember>(); MixinSubObjects mso = (MixinSubObjects)example; Type[] types = mso.GetMixedTypes(); foreach (Type type in types) { var possible = FindFiltersForExampleSubType(arg0Lower, exampleType, type, relativeToType, warn); if (possible.Count > 0) { foreach (var p in possible) { FilterMember fm = p; FilterMember member = p; Type subtype = type; fm.Function = (o, arg1, relTo) => member.Function(((MixinSubObjects)o).GetInstance(subtype), arg1, relTo); newPossible.Add(fm); } } } return(newPossible); } return(firstTry); }
public List <SimObject> GetUnionArg(string[] args, out int argsUsed, List <SimObject> prims, ref bool isIntersection, bool negated, MixinSubObjects relativeTo, out bool negateNext) { string arg0Lower = args[0].ToLower(); negateNext = false; if (arg0Lower == "!") { negateNext = true; argsUsed = 1; return(prims); } int used = 0; // Negation if (arg0Lower == "not") { prims = GetUnionExprsn(Parser.SplitOff(args, 1), out used, prims, !negated, relativeTo); argsUsed = 1 + used; return(prims); } else if (arg0Lower == "or" || arg0Lower == "concat") { var secondSet = StartGetUnionExprsn(Parser.SplitOff(args, 1), out used); prims.AddRange(secondSet); argsUsed = used; return(prims); } if (arg0Lower == "[") { var secondSet = StartGetUnionExprsn(Parser.SplitOff(args, 1), out used); argsUsed = 1 + used; return(JoinLists(prims, negated, isIntersection, secondSet)); } if (arg0Lower == "+") { var secondSet = GetSingleArg(Parser.SplitOff(args, 1), out used); argsUsed = 1 + used; return(JoinLists(prims, negated, false, secondSet)); } if (arg0Lower == "keep" || arg0Lower == "max") { int nth; used++; if (int.TryParse(args[1], out nth)) { used++; } int keep = Math.Abs(nth); if (keep > prims.Count) { keep = prims.Count; } if (negated) { keep = prims.Count - keep; } int removeCount = prims.Count - keep; if (nth > 0) { // keep the first few prims.RemoveRange(keep, removeCount); } else { // keep the last few prims.RemoveRange(0, removeCount); } argsUsed = used; return(prims); } else if (arg0Lower == "nth") { used++; int nth = 0; if (int.TryParse(args[1], out nth)) { used++; } if (!negated) { List <SimObject> prims0 = new List <SimObject>(); if (prims.Count >= nth) { prims0.Add(prims[nth - 1]); } prims = prims0; } else { prims = new List <SimObject>(prims); prims.RemoveAt(nth); } argsUsed = used; return(prims); } else if (arg0Lower == "bydist") { used++; List <SimObject> objs = new List <SimObject>(); AsPrimitives(objs, prims); objs.Sort(((SimObject)relativeTo).CompareDistance); if (negated) { objs.Reverse(); } prims = objs; argsUsed = used; return(prims); } else if (arg0Lower == "distfrom") { relativeTo = GetSimObjectS(Parser.SplitOff(args, 1), out used); used++; List <SimObject> objs = new List <SimObject>(); AsPrimitives(objs, prims); objs.Sort(((SimObject)relativeTo).CompareDistance); if (negated) { objs.Reverse(); } prims = objs; argsUsed = used; return(prims); } else if (arg0Lower == "reverse") { used++; prims.Reverse(); argsUsed = used; return(prims); } else { bool nonFilter = arg0Lower.StartsWith("$") || arg0Lower.StartsWith("@") || arg0Lower.StartsWith("primid") || arg0Lower.Substring(1).Contains("-"); ParserFilterFormatException missingFilter = null; if (!nonFilter) { // filters will re-namgate so use the incoming "removeMatches" int usedF; try { return(FilterSpecAttribute.ApplyFilter(args, out argsUsed, ChangeType, prims, relativeTo, negated, Debug, CompareObjectsChar)); } catch (ParserFilterFormatException pff) { missingFilter = pff; } } List <SimObject> rcol = GetSingleArg(args, out argsUsed); if (rcol != null) { return(JoinLists(prims, negated, isIntersection, rcol)); } else { if (missingFilter != null) { argsUsed = 0; // what saort of erro should we make? Debug("no such filter or object: " + arg0Lower); throw missingFilter; } } } return(prims); }
public List <SimObject> GetUnionExprsn(string[] args, out int argsUsed, List <SimObject> prims, bool removeMatches, MixinSubObjects relativeTo) { int consume = args.Length; if (consume == 0) { argsUsed = 0; return(prims); } string arg0Lower = args[0].ToLower(); // terminal if (arg0Lower == "]") { argsUsed = 1; return(prims); } int usedMore = 0; args = (string[])args.Clone(); bool actuallyNegateNext = removeMatches; bool isIntersection = true; while (args.Length > 0) { if (args[0] == "]") { usedMore++; break; } int argsUsed0; bool negateNext; prims = GetUnionArg(args, out argsUsed0, prims, ref isIntersection, actuallyNegateNext, relativeTo, out negateNext); if (argsUsed0 == 0) { throw new ParserFilterFormatException("Cant GetSingleArg: ", args, 0); } usedMore += argsUsed0; actuallyNegateNext = removeMatches; if (negateNext) { actuallyNegateNext = !actuallyNegateNext; } args = Parser.SplitOff(args, argsUsed0); } argsUsed = usedMore; return(prims); }