private static void SmallTestForPrefixOptimizedProjector(Func <Projection[], bool, ProjectItems.IProjector> createProjector)
        {
            var          pi    = new ProjectItems(createProjector);
            var          gc    = new GlobalContext();
            WorkingGraph graph = gc.CurrentGraph;

            pi.Configure(gc, @"{ -pl
    $ (Ignore:Name) ---% SIMPLE

    ! :a* ---% A
    > :ab ---% AB
    ! :b* ---% B
    ! :c* ---% C
    ! :** ---% 
}", forceReload: false);

            ItemType generic2 = ItemType.Generic(2, ignoreCase: false);
            Item     a        = graph.CreateItem(generic2, "x:a");
            Item     ab       = graph.CreateItem(generic2, "x:ab");
            Item     ac       = graph.CreateItem(generic2, "x:ac");
            Item     ca       = graph.CreateItem(generic2, "x:ca");
            Item     cb       = graph.CreateItem(generic2, "x:cb");
            Item     s        = graph.CreateItem(generic2, "m:s");
            Item     t        = graph.CreateItem(generic2, "m:t");

            var result = new List <Dependency>();

            pi.Transform(gc, new ProjectItems.ConfigureOptions(), new ProjectItems.TransformOptions(), new[] {
                graph.CreateDependency(a, a, null, "a_a", 1),     // the first surviving dependency
                graph.CreateDependency(a, s, null, "a_s", 1),     // vanishes, because s is not mapped
                graph.CreateDependency(ab, s, null, "ab_s", 1),   // same
                graph.CreateDependency(ca, s, null, "ca_s", 1),   // etc.
                graph.CreateDependency(cb, cb, null, "cb_cb", 1), // the second surviving dependency
                graph.CreateDependency(cb, t, null, "cb_t", 1),   // vanishes, because t is not mapped
                graph.CreateDependency(a, t, null, "a_t", 1),
                graph.CreateDependency(ac, t, null, "ac_t", 1),
                graph.CreateDependency(a, s, null, "a_s", 1),

                // Counts:
                // !a  5
                // >ab 0
                // !ac 1
                // !b  0
                // !ca 1
                // !cb 3
                // !s  4
                // !t  3
            }, result);

            Assert.AreEqual(2, result.Count);
            Assert.AreEqual("A", result[0].UsingItem.Values[0]);
            Assert.AreEqual("A", result[0].UsedItem.Values[0]);
            Assert.AreEqual("C", result[1].UsingItem.Values[0]);
            Assert.AreEqual("C", result[1].UsedItem.Values[0]);
        }
Beispiel #2
0
        private static WorkingGraph CreateGraphWithLongTail()
        {
            var          gc    = new GlobalContext();
            WorkingGraph graph = gc.CurrentGraph;
            ItemType     g2    = ItemType.Generic(2, ignoreCase: true);
            Item         a     = graph.CreateItem(g2, "a:");
            Item         b     = graph.CreateItem(g2, "b:0");
            Item         c     = graph.CreateItem(g2, "c:");
            Item         b1    = graph.CreateItem(g2, "b:1");
            Item         b2    = graph.CreateItem(g2, "b:2");
            Item         b3    = graph.CreateItem(g2, "b:3");
            Item         b4    = graph.CreateItem(g2, "b:4");
            Item         b5    = graph.CreateItem(g2, "b:5");

            graph.AddDependencies(new[] {
                graph.CreateDependency(a, b, null, "", 1), graph.CreateDependency(b, b, null, "", 1),
                graph.CreateDependency(b, c, null, "", 1), graph.CreateDependency(b, b1, null, "", 1),
                graph.CreateDependency(b1, b2, null, "", 1), graph.CreateDependency(b2, b3, null, "", 1),
                graph.CreateDependency(b3, b4, null, "", 1), graph.CreateDependency(b4, b5, null, "", 1),
            });
            return(graph);
        }
        public void TestBackProjectSmallCycle()
        {
            ItemType     generic2 = ItemType.Generic(2, ignoreCase: false);
            var          gc       = new GlobalContext();
            WorkingGraph graph    = gc.CurrentGraph;

            Item a1 = graph.CreateItem(generic2, "a:1");
            Item b1 = graph.CreateItem(generic2, "b:1");
            Item a2 = graph.CreateItem(generic2, "a:2");
            Item b2 = graph.CreateItem(generic2, "b:2");
            Item b3 = graph.CreateItem(generic2, "b:3");

            var deps = new[] {
                Dep(graph, a1, b1), Dep(graph, b1, a2), Dep(graph, b2, a2), Dep(graph, a1, b3)
            };

            List <Dependency> backProjectedDeps = ProjectMarkCyclesAndBackProject(deps, gc);

            Assert.IsTrue(Find(backProjectedDeps, a1, b1).MarkersContain("C0"));
            Assert.IsTrue(Find(backProjectedDeps, a1, b3).MarkersContain("C0"));
            Assert.IsTrue(Find(backProjectedDeps, b1, a2).MarkersContain("C0"));
            Assert.IsTrue(Find(backProjectedDeps, b2, a2).MarkersContain("C0"));

            var pw = new FlatPathWriter();

            using (var t = DisposingFile.CreateTempFileWithTail(".txt")) {
                pw.Render(gc, backProjectedDeps, $"{{ {FlatPathWriter.PathMarkerOption} C* }}".Replace(" ", Environment.NewLine),
                          new WriteTarget(t.FileName, append: false, limitLinesForConsole: 100), ignoreCase: false);

                using (var sr = new StreamReader(t.FileName)) {
                    var o = sr.ReadToEnd();

                    //Console.WriteLine(o);
                    Assert.IsTrue(o.Contains("a:1"));
                    Assert.IsTrue(o.Contains("<= a:2 $"));
                }
            }
        }
        public void TestBackProjectCycle()
        {
            ItemType generic2 = ItemType.Generic(2, ignoreCase: false);

            var          gc    = new GlobalContext();
            WorkingGraph graph = gc.CurrentGraph;

            Item a1 = graph.CreateItem(generic2, "a:1");
            Item b1 = graph.CreateItem(generic2, "b:1");
            Item c1 = graph.CreateItem(generic2, "c:1");
            Item d1 = graph.CreateItem(generic2, "d:1");
            Item e1 = graph.CreateItem(generic2, "e:1");
            Item a2 = graph.CreateItem(generic2, "a:2");
            Item b2 = graph.CreateItem(generic2, "b:2");
            Item c2 = graph.CreateItem(generic2, "c:2");
            Item d2 = graph.CreateItem(generic2, "d:2");
            Item e2 = graph.CreateItem(generic2, "e:2");
            Item x2 = graph.CreateItem(generic2, "x:2");

            var deps = new[] {
                Dep(graph, a1, b1), Dep(graph, b1, c1), Dep(graph, c1, d1), Dep(graph, d1, e1), Dep(graph, d1, b1),
                Dep(graph, a2, x2), Dep(graph, b2, x2), Dep(graph, c2, x2), Dep(graph, d2, x2), Dep(graph, e2, x2),
            };

            List <Dependency> backProjectedDeps = ProjectMarkCyclesAndBackProject(deps, gc);

            Assert.IsFalse(Find(backProjectedDeps, a1, b1).MarkersContain("C0"));
            Assert.IsTrue(Find(backProjectedDeps, b1, c1).MarkersContain("C0"));
            Assert.IsTrue(Find(backProjectedDeps, c1, d1).MarkersContain("C0"));
            Assert.IsFalse(Find(backProjectedDeps, d1, e1).MarkersContain("C0"));
            Assert.IsTrue(Find(backProjectedDeps, d1, b1).MarkersContain("C0"));

            Assert.IsFalse(Find(backProjectedDeps, a2, x2).MarkersContain("C0"));
            Assert.IsFalse(Find(backProjectedDeps, b2, x2).MarkersContain("C0"));
            Assert.IsFalse(Find(backProjectedDeps, c2, x2).MarkersContain("C0"));
            Assert.IsFalse(Find(backProjectedDeps, d2, x2).MarkersContain("C0"));
            Assert.IsFalse(Find(backProjectedDeps, e2, x2).MarkersContain("C0"));
        }
        public void TestSmallSelfOptimizingPrefixTrieProjector2()
        {
            // This test found a problem in TrieNode.SetProjectors.
            var pi = new ProjectItems((p, i) => new ProjectItems.SelfOptimizingPrefixTrieProjector(p, i, 2, "prefixTrie"));
            var gc = new GlobalContext();

            pi.Configure(gc, @"{ -pl
    $ (:Name) ---% SIMPLE

    ! :abc ---% ADetail
    ! :a*  ---% A
    ! :t   ---% T
    ! :**  ---% 
}", forceReload: false);

            ItemType     generic2 = ItemType.Generic(2, ignoreCase: false);
            WorkingGraph graph    = gc.CurrentGraph;
            Item         a        = graph.CreateItem(generic2, "x:a");
            Item         ab       = graph.CreateItem(generic2, "x:ab");
            Item         abc      = graph.CreateItem(generic2, "x:abc");
            Item         abcd     = graph.CreateItem(generic2, "x:abcd");
            Item         t        = graph.CreateItem(generic2, "m:t");

            var result = new List <Dependency>();

            pi.Transform(gc, new[] {
                graph.CreateDependency(a, t, null, "a_t", 1),       // A_T
                graph.CreateDependency(ab, t, null, "ab_t", 1),     // A_ T
                graph.CreateDependency(abc, t, null, "abc_t", 1),   // ADetail _T
                graph.CreateDependency(abcd, t, null, "abcd_t", 1), // A _ T
            }, "", result, s => null);

            Assert.AreEqual(2, result.Count);
            Assert.AreEqual("A", result[0].UsingItem.Values[0]);
            Assert.AreEqual(3, result[0].Ct);
            Assert.AreEqual("ADetail", result[1].UsingItem.Values[0]);
            Assert.AreEqual(1, result[1].Ct);
        }
Beispiel #6
0
        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());
            }
        }