예제 #1
0
        private static bool IsUnder(NodeQueryMatcher matcher, SearchResult result)
        {
            if (matcher.UnderProject)
            {
                var project = result.Node.GetNearestParent <Project>();
                if (project != null && matcher.IsMatch(project) != null)
                {
                    return(true);
                }

                var projectEvaluation = result.Node.GetNearestParent <ProjectEvaluation>();
                if (projectEvaluation != null && matcher.IsMatch(projectEvaluation) != null)
                {
                    return(true);
                }

                return(false);
            }

            foreach (var parent in result.Node.GetParentChainExcludingThis())
            {
                if (matcher.IsMatch(parent) != null)
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #2
0
        private readonly StringCache stringCache; // only used for validation that all strings are interned (disabled)

        public NodeQueryMatcher(
            string query,
            IEnumerable <string> stringTable,
            CancellationToken cancellationToken = default,
            StringCache stringCache             = null // validation disabled in production
            )
        {
            this.stringCache = stringCache;

            query = PreprocessQuery(query);

            this.Query = query;

            var rawWords = TextUtilities.Tokenize(query);

            this.Words = new List <Term>(rawWords.Count);
            foreach (var rawWord in rawWords)
            {
                var term = Term.Get(rawWord);
                if (term != default)
                {
                    Words.Add(term);
                }
            }

            if (Words.Count == 1 &&
                Words[0].Word is string potentialNodeIndex &&
                potentialNodeIndex.Length > 1 &&
                potentialNodeIndex[0] == '$')
            {
                var nodeIndexText = potentialNodeIndex.Substring(1);
                if (int.TryParse(nodeIndexText, out var nodeIndex))
                {
                    NodeIndex = nodeIndex;
                    Words.RemoveAt(0);
                    return;
                }
            }

            for (int i = Words.Count - 1; i >= 0; i--)
            {
                var word = Words[i].Word;

                if (word == "$time" || word == "$duration")
                {
                    Words.RemoveAt(i);
                    IncludeDuration = true;
                    continue;
                }
                else if (word == "$start" || word == "$starttime")
                {
                    Words.RemoveAt(i);
                    IncludeStart = true;
                    continue;
                }
                else if (word == "$end" || word == "$endtime")
                {
                    Words.RemoveAt(i);
                    IncludeEnd = true;
                    continue;
                }

                if (word.Length > 2 && word[0] == '$' && word[1] != '(' && (TypeKeyword == null || !TypeKeyword.Contains(word.Substring(1).ToLowerInvariant())))
                {
                    Words.RemoveAt(i);
                    TypeKeyword = word.Substring(1).ToLowerInvariant();
                    continue;
                }

                if (word.StartsWith("under(", StringComparison.OrdinalIgnoreCase) && word.EndsWith(")"))
                {
                    word = word.Substring(6, word.Length - 7);
                    Words.RemoveAt(i);
                    var underMatcher = new NodeQueryMatcher(word, stringTable);
                    IncludeMatchers.Add(underMatcher);
                    continue;
                }

                if (word.StartsWith("notunder(", StringComparison.OrdinalIgnoreCase) && word.EndsWith(")"))
                {
                    word = word.Substring(9, word.Length - 10);
                    Words.RemoveAt(i);
                    var underMatcher = new NodeQueryMatcher(word, stringTable);
                    ExcludeMatchers.Add(underMatcher);
                    continue;
                }

                if (word.StartsWith("project(", StringComparison.OrdinalIgnoreCase) && word.EndsWith(")"))
                {
                    word = word.Substring(8, word.Length - 9);
                    Words.RemoveAt(i);

                    var underMatcher = new NodeQueryMatcher(word, stringTable);
                    underMatcher.UnderProject = true;
                    IncludeMatchers.Add(underMatcher);
                    continue;
                }

                if (word.StartsWith("name=", StringComparison.OrdinalIgnoreCase) && word.Length > 5)
                {
                    word = word.Substring(5, word.Length - 5);
                    Words.RemoveAt(i);
                    var term = Term.Get(word);
                    if (term != default)
                    {
                        Words.Insert(i, term);
                        nameToSearch = term;
                    }

                    continue;
                }

                if (word.StartsWith("value=", StringComparison.OrdinalIgnoreCase) && word.Length > 6)
                {
                    word = word.Substring(6, word.Length - 6);
                    Words.RemoveAt(i);
                    var term = Term.Get(word);
                    if (term != default)
                    {
                        Words.Insert(i, term);
                        valueToSearch = term;
                    }

                    continue;
                }
            }

            PrecomputeMatchesInStrings(stringTable, cancellationToken);
        }