public void TestDipWithProxies() { var gc = new GlobalContext(); WorkingGraph graph = gc.CurrentGraph; using (var f = DisposingFile.CreateTempFileWithTail(".dip")) { using (TextWriter tw = new StreamWriter(f.FileName)) { tw.Write(@"$ NKK(Name:Key1:Key2) NKK:a:keyA1:? => ;1;0;0;src.abc|1 => NKK:?:keyA1:? NKK:?:keyA1:? => ;2;1;0;src.abc|3;example123 => NKK:a:keyA2:? NKK:a:keyA2:? => ;3;0;0;src.abc|5 => NKK:a:keyA1:KEYa1 NKK:?:?:KEYa2 => ;4;0;0;src.abc|7 => NKK:a:keyA2:KEYa2 NKK:?:keyA2:KEYa2 => ;5;1;0;src.abc|9 => NKK:b::KEYb NKK:?:?:KEYb => ;6;0;0;src.abc|11 => NKK:?:?:KEYa1 NKK:?::KEYb => ;7;0;0;src.abc|13 => NKK:?:keyA2:?"); } IEnumerable <Dependency> dependencies = new DipReaderFactory().CreateReader(f.FileName, false).ReadDependencies(gc.CurrentGraph, 0, ignoreCase: false); Assert.IsNotNull(dependencies); Item[] items = dependencies.SelectMany(d => new[] { d.UsingItem, d.UsedItem }).Distinct().ToArray(); Assert.AreEqual(3, items.Length); Assert.IsTrue(items.Contains(graph.CreateItem(ItemType.Find("NKK"), "a", "keyA1", "KEYa1"))); Assert.IsTrue(items.Contains(graph.CreateItem(ItemType.Find("NKK"), "a", "keyA2", "KEYa2"))); Assert.IsTrue(items.Contains(graph.CreateItem(ItemType.Find("NKK"), "b", "", "KEYb"))); } }
public void TestToTooFewFields() { var pi = new ProjectItems((p, i) => new ProjectItems.SelfOptimizingPrefixTrieProjector(p, i, 2, "prefixTrie")); var gc = new GlobalContext(); const string THREE_FIELDS = "THREE_FIELDS"; pi.Configure(gc, $@"{{ -pl $ {THREE_FIELDS}(F1:F2:F3) ---% {THREE_FIELDS} ! a:b:c ---% :: ! a:b ---% : // this threw an exception before a fix ! a ---% }}", forceReload: false); ItemType threeFields = ItemType.Find(THREE_FIELDS); WorkingGraph graph = gc.CurrentGraph; Item abc = graph.CreateItem(threeFields, "a:b:c"); Item ab = graph.CreateItem(threeFields, "a:b:-"); Item a = graph.CreateItem(threeFields, "a:-:-"); var result = new List <Dependency>(); pi.Transform(gc, new[] { graph.CreateDependency(abc, abc, null, "abc", 1), graph.CreateDependency(ab, ab, null, "ab", 1), graph.CreateDependency(a, a, null, "a", 1), }, "", result, s => null); Assert.AreEqual(0, result.Count); }
private static void SetupLinks() { foreach (var item in byCode.Values) { if (item.type1Code != null) { item.type1 = ItemType.Find(item.type1Code); } if (item.type2Code != null) { item.type2 = ItemType.Find(item.type2Code); } item.type = item.type1 != null ? item.type1 : item.type2; item.uniques = UniqueItem.sheet.FindAll(uniq => uniq.code == item.code); item.setItems = SetItem.sheet.FindAll(setItem => setItem.itemCode == item.code); } }
public ItemPattern([CanBeNull] ItemType itemTypeHintOrNull, [NotNull] string itemPattern, int upperBoundOfGroupCount, bool ignoreCase, bool anyWhereMatcherOk) { const string UNCOLLECTED_GROUP = "(?:"; const string UNCOLLECTED_GROUP_MASK = "(?#@#"; IEnumerable <string> parts = itemPattern.Replace(UNCOLLECTED_GROUP, UNCOLLECTED_GROUP_MASK) .Split(':') .Select(p => p.Replace(UNCOLLECTED_GROUP_MASK, UNCOLLECTED_GROUP)) .ToArray(); bool allowNamedPattern; ItemType type = ItemType.Find(parts.First()); if (type != null) { parts = parts.Skip(1); _itemType = type; allowNamedPattern = true; } else if (itemTypeHintOrNull != null) { // Rules may optionally start with the correct type name (when they are copied from e.g. from a violation textfile). if (parts.First() == itemTypeHintOrNull.Name) { parts = parts.Skip(1); } _itemType = itemTypeHintOrNull; allowNamedPattern = true; } else { // No type found form pattern, no itemTypeHint - we guess a generic type. _itemType = ItemType.Generic(parts.Count(), ignoreCase); allowNamedPattern = false; } var result = new List <IMatcher>(); if (parts.Any(p => p.Contains("="))) { if (!allowNamedPattern) { throw new ApplicationException( $"No named patterns possible if type of pattern must be guessed; specify item type in pattern in {itemPattern}"); } // We ignore empty segments which might be included for "clarity" parts = parts.Where(p => p != ""); if (!parts.All(p => p.Contains("="))) { throw new ApplicationException( $"Pattern must either use names for all fields, or no names. Mixing positional and named parts is not allowed in {itemPattern}"); } IMatcher[] matchers = Enumerable.Repeat(_alwaysMatcher, _itemType.Keys.Length).ToArray(); foreach (var p in parts) { string[] nameAndPattern = p.Split(new[] { '=' }, 2); string[] keyAndSubkey = nameAndPattern[0].Split('.'); int i = _itemType.IndexOf(keyAndSubkey[0].Trim(), keyAndSubkey.Length > 1 ? "." + keyAndSubkey[1].Trim() : ""); if (i < 0) { throw new ApplicationException($"Key '{nameAndPattern[0]}' not defined in item type {_itemType.Name}; keys are {_itemType.KeysAndSubkeys()}"); } matchers[i] = CreateMatcher(nameAndPattern[1].Trim(), 0, ignoreCase); } _matchers = new MatcherVector(matchers); } else if (anyWhereMatcherOk && parts.Count() == 1 && !Regex.IsMatch(parts.First().Trim('*'), @"[;(\\*^$]")) { // If there is only a single pattern without any special chars in it - except leading or trailing * _matchers = new AnyWhereMatcher(CreateMatcher(parts.First(), 0, ignoreCase)); } else { int j = 0; foreach (var p in parts) { foreach (var s in p.Split(';')) { result.Add(CreateMatcher(s, upperBoundOfGroupCount, ignoreCase)); j++; } while (j > 0 && j < _itemType.Keys.Length && _itemType.Keys[j - 1] == _itemType.Keys[j]) { result.Add(_alwaysMatcher); j++; } } while (j < _itemType.Keys.Length) { result.Add(_alwaysMatcher); j++; } _matchers = new MatcherVector(result.Take(_itemType.Keys.Length).ToArray()); } }