Пример #1
0
        private SearchPreProcessResult <T> PreProcessFileSystemNameSearch <T>(SearchParams searchParams,
                                                                              Func <IPathMatcher, T, IPathComparer, bool> matchName,
                                                                              Func <IPathMatcher, T, IPathComparer, bool> matchRelativeName) where T : FileSystemName
        {
            // Regex has its own set of rules for pre-processing
            if (searchParams.Regex)
            {
                return(PreProcessFileSystemNameRegularExpressionSearch(
                           searchParams,
                           matchName,
                           matchRelativeName));
            }

            // Check pattern is not empty
            var pattern = (searchParams.SearchString ?? "").Trim();

            if (string.IsNullOrWhiteSpace(pattern))
            {
                return(null);
            }

            // Split pattern around ";", normalize directory separators and
            // add "*" if not a whole word search
            var patterns = pattern
                           .Split(new[] { ';' })
                           .Where(x => !string.IsNullOrWhiteSpace(x.Trim()))
                           .Select(x => x.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar))
                           .Select(x => {
                // Exception to ".gitignore" syntax: If the search string doesn't contain any special
                // character, surround the pattern with "*" so that we match sub-strings.
                // TODO(rpaquay): What about "."? Special or not?
                if (x.IndexOf(Path.DirectorySeparatorChar) < 0 && x.IndexOf('*') < 0)
                {
                    if (!searchParams.MatchWholeWord)
                    {
                        x = "*" + x + "*";
                    }
                }
                return(x);
            })
                           .ToReadOnlyCollection();

            var matcher = new AnyPathMatcher(patterns.Select(PatternParser.ParsePattern));

            var comparer = searchParams.MatchCase ? PathComparerRegistry.CaseSensitive : PathComparerRegistry.CaseInsensitive;

            if (patterns.Any(x => x.Contains(Path.DirectorySeparatorChar)))
            {
                return(new SearchPreProcessResult <T> {
                    Matcher = (item) => matchRelativeName(matcher, item, comparer)
                });
            }
            else
            {
                return(new SearchPreProcessResult <T> {
                    Matcher = (item) => matchName(matcher, item, comparer)
                });
            }
        }
Пример #2
0
        private static void AssertMatch(MatchKind kind, object[,] expectedResults, bool optimize)
        {
            Debug.WriteLine(string.Format("===================================================================="));
            Debug.WriteLine(string.Format("Verifying expected result for {0} entries with optimization={1}.",
                                          expectedResults.GetLength(0), optimize));
            Debug.WriteLine(string.Format("===================================================================="));
            for (var i = 0; i < expectedResults.GetLength(0); i++)
            {
                var pattern = (string)expectedResults[i, 0];
                var path    = (string)expectedResults[i, 1];
                var result  = (bool)expectedResults[i, 2];
                Debug.WriteLine(string.Format("Matching \"{0}\" pattern \"{1}\" against path \"{2}\" should return {3}.", kind,
                                              pattern, path, result));

                pattern = pattern.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
                path    = path.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);

                IPathMatcher matcher;
                if (optimize)
                {
                    matcher = new AnyPathMatcher(Enumerable.Repeat(PatternParser.ParsePattern(pattern), 1));
                }
                else
                {
                    matcher = PatternParser.ParsePattern(pattern);
                }

                if (kind == MatchKind.Directory)
                {
                    Assert.AreEqual(result, matcher.MatchDirectoryName(new RelativePath(path), SystemPathComparer.Instance));
                }
                else
                {
                    Assert.AreEqual(result, matcher.MatchFileName(new RelativePath(path), SystemPathComparer.Instance));
                }
            }
        }
Пример #3
0
        private SearchPreProcessResult <T> PreProcessFileSystemNameSearch <T>(SearchParams searchParams,
                                                                              Func <IPathMatcher, T, IPathComparer, bool> matchName,
                                                                              Func <IPathMatcher, T, IPathComparer, bool> matchRelativeName)
        {
            // Regex has its own set of rules for pre-processing
            if (searchParams.Regex)
            {
                return(PreProcessFileSystemNameRegularExpressionSearch(
                           searchParams,
                           matchName,
                           matchRelativeName));
            }

            // Check pattern is not empty
            var pattern = (searchParams.SearchString ?? "").Trim();

            if (string.IsNullOrWhiteSpace(pattern))
            {
                return(null);
            }

            // Split pattern around ";", normalize directory separators and
            // add "*" if not a whole word search
            var patterns = pattern
                           .Split(new[] { ';' })
                           .Where(x => !string.IsNullOrWhiteSpace(x.Trim()))
                           .Select(x => x.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar))
                           .ToList();

            // Split patterns into "include" and "exclude" patterns.
            // "exclude" patterns are defined as any pattern starting with "-".
            var includePatterns = patterns
                                  .Where(x => !x.StartsWith("-"))
                                  .ToList();

            var excludePatterns = patterns
                                  .Where(x => x.StartsWith("-"))
                                  .Select(x => x.Substring(1))
                                  .Where(x => !string.IsNullOrWhiteSpace(x))
                                  .ToList();

            // Process qouble quotes, and add implicit wildcards if needed
            includePatterns = MapQuotesAndImplicitWildcards(searchParams, includePatterns).ToList();
            excludePatterns = MapQuotesAndImplicitWildcards(searchParams, excludePatterns).ToList();

            // If no include pattern, assume implicit "*"
            if (includePatterns.Count == 0)
            {
                includePatterns.Add("*");
            }
            var includeMatcher = new AnyPathMatcher(includePatterns.Select(PatternParser.ParsePattern));

            // Perf: Use "null" matcher if exclude pattern list is empty
            var excludeMatcher = (excludePatterns.Count == 0 ?
                                  null :
                                  new AnyPathMatcher(excludePatterns.Select(PatternParser.ParsePattern)));

            var comparer = searchParams.MatchCase ? PathComparerRegistry.CaseSensitive : PathComparerRegistry.CaseInsensitive;

            if (patterns.Any(x => x.Contains(Path.DirectorySeparatorChar)))
            {
                return(new SearchPreProcessResult <T> {
                    Matcher = (item) => {
                        if (excludeMatcher != null && matchRelativeName(excludeMatcher, item, comparer))
                        {
                            return false;
                        }
                        return matchRelativeName(includeMatcher, item, comparer);
                    }
                });
            }
            else
            {
                return(new SearchPreProcessResult <T> {
                    Matcher = (item) => {
                        if (excludeMatcher != null && matchName(excludeMatcher, item, comparer))
                        {
                            return false;
                        }
                        return matchName(includeMatcher, item, comparer);
                    }
                });
            }
        }