Beispiel #1
0
        private static async Task <ImmutableArray <INavigateToSearchResult> > FindNavigableDeclaredSymbolInfosAsync(
            Project project, Document searchDocument, string pattern, CancellationToken cancellationToken)
        {
            // If the user created a dotted pattern then we'll grab the last part of the name
            var(patternName, patternContainerOpt) = PatternMatcher.GetNameAndContainer(pattern);
            var nameMatcher = PatternMatcher.CreatePatternMatcher(patternName, includeMatchedSpans: true, allowFuzzyMatching: true);

            var containerMatcherOpt = patternContainerOpt != null
                ? PatternMatcher.CreateDotSeparatedContainerMatcher(patternContainerOpt)
                : null;

            using (nameMatcher)
                using (containerMatcherOpt)
                {
                    var nameMatches = ArrayBuilder <PatternMatch> .GetInstance();

                    var containerMatches = ArrayBuilder <PatternMatch> .GetInstance();

                    try
                    {
                        return(await FindNavigableDeclaredSymbolInfosAsync(
                                   project, searchDocument, nameMatcher, containerMatcherOpt,
                                   nameMatches, containerMatches, cancellationToken).ConfigureAwait(false));
                    }
                    finally
                    {
                        nameMatches.Free();
                        containerMatches.Free();
                    }
                }
        }
        private static async Task <ImmutableArray <ISymbol> > FindSourceDeclarationsWithPatternInCurrentProcessAsync(
            string pattern, Func <SearchQuery, Task <ImmutableArray <ISymbol> > > searchAsync)
        {
            // The compiler API only supports a predicate which is given a symbol's name.  Because
            // we only have the name, and nothing else, we need to check it against the last segment
            // of the pattern.  i.e. if the pattern is 'Console.WL' and we are given 'WriteLine', then
            // we don't want to check the whole pattern against it (as it will clearly fail), instead
            // we only want to check the 'WL' portion.  Then, after we get all the candidate symbols
            // we'll check if the full name matches the full pattern.
            var(namePart, containerPart) = PatternMatcher.GetNameAndContainer(pattern);

            // If we don't have a dot in the pattern, just make a pattern matcher for the entire
            // pattern they passed in.  Otherwise, make a pattern matcher just for the part after
            // the dot.
            using var nameMatcher = PatternMatcher.CreatePatternMatcher(namePart, includeMatchedSpans: false);
            using var query       = SearchQuery.CreateCustom(nameMatcher.Matches);

            var symbolAndProjectIds = await searchAsync(query).ConfigureAwait(false);

            if (symbolAndProjectIds.Length == 0 ||
                containerPart == null)
            {
                // If it wasn't a dotted pattern, or we didn't get anything back, then we're done.
                // We can just return whatever set of results we got so far.
                return(symbolAndProjectIds);
            }

            // Ok, we had a dotted pattern.  Have to see if the symbol's container matches the
            // pattern as well.
            using var containerPatternMatcher = PatternMatcher.CreateDotSeparatedContainerMatcher(containerPart);

            return(symbolAndProjectIds.WhereAsArray(t =>
                                                    containerPatternMatcher.Matches(GetContainer(t))));
        }
Beispiel #3
0
        private static IEnumerable <PatternMatch> TryMatchMultiWordPattern(
            string candidate,
            string pattern
            )
        {
            MarkupTestFile.GetSpans(
                candidate,
                out candidate,
                out ImmutableArray <TextSpan> expectedSpans
                );

            using var matchesDisposer = ArrayBuilder <PatternMatch> .GetInstance(out var matches);

            PatternMatcher
            .CreatePatternMatcher(pattern, includeMatchedSpans: true)
            .AddMatches(candidate, matches);

            if (matches.Count == 0)
            {
                Assert.True(expectedSpans.Length == 0);
                return(null);
            }
            else
            {
                var actualSpans = matches
                                  .SelectMany(m => m.MatchedSpans)
                                  .OrderBy(s => s.Start)
                                  .ToList();
                Assert.Equal(expectedSpans, actualSpans);
                return(matches.ToImmutable());
            }
        }
Beispiel #4
0
        private static async Task <ImmutableArray <INavigateToSearchResult> > FindSearchResultsAsync(
            Project project, ImmutableArray <Document> priorityDocuments, Document searchDocument,
            string pattern, IImmutableSet <string> kinds, CancellationToken cancellationToken)
        {
            // If the user created a dotted pattern then we'll grab the last part of the name
            var(patternName, patternContainerOpt) = PatternMatcher.GetNameAndContainer(pattern);
            var nameMatcher = PatternMatcher.CreatePatternMatcher(patternName, includeMatchedSpans: true, allowFuzzyMatching: true);

            var containerMatcherOpt = patternContainerOpt != null
                ? PatternMatcher.CreateDotSeparatedContainerMatcher(patternContainerOpt)
                : null;

            using (nameMatcher)
                using (containerMatcherOpt)
                {
                    using var _1 = ArrayBuilder <PatternMatch> .GetInstance(out var nameMatches);

                    using var _2 = ArrayBuilder <PatternMatch> .GetInstance(out var containerMatches);

                    var declaredSymbolInfoKindsSet = new DeclaredSymbolInfoKindSet(kinds);

                    var searchResults = await ComputeSearchResultsAsync(
                        project, priorityDocuments, searchDocument, nameMatcher, containerMatcherOpt,
                        declaredSymbolInfoKindsSet, nameMatches, containerMatches, cancellationToken).ConfigureAwait(false);

                    return(ImmutableArray <INavigateToSearchResult> .CastUp(searchResults));
                }
        }
        private static async Task <ImmutableArray <INavigateToSearchResult> > FindSearchResultsAsync(
            Project project, ImmutableArray <Document> priorityDocuments, Document searchDocument,
            string pattern, IImmutableSet <string> kinds, CancellationToken cancellationToken)
        {
            // If the user created a dotted pattern then we'll grab the last part of the name
            var(patternName, patternContainerOpt) = PatternMatcher.GetNameAndContainer(pattern);
            var nameMatcher = PatternMatcher.CreatePatternMatcher(patternName, includeMatchedSpans: true, allowFuzzyMatching: true);

            var containerMatcherOpt = patternContainerOpt != null
                ? PatternMatcher.CreateDotSeparatedContainerMatcher(patternContainerOpt)
                : null;

            using (nameMatcher)
                using (containerMatcherOpt)
                {
                    var nameMatches = ArrayBuilder <PatternMatch> .GetInstance();

                    var containerMatches = ArrayBuilder <PatternMatch> .GetInstance();

                    try
                    {
                        var declaredSymbolInfoKindsSet = new DeclaredSymbolInfoKindSet(kinds);

                        // If we're searching a single document, then just do a full search of
                        // that document (we're fast enough to not need to optimize that case).
                        //
                        // If, however, we are searching a project, then see if we could potentially
                        // use the last computed results we have for that project.  If so, it can
                        // be much faster to reuse and filter that result than to compute it from
                        // scratch.
#if true
                        var task = searchDocument != null
                        ? ComputeSearchResultsAsync(project, priorityDocuments, searchDocument, nameMatcher, containerMatcherOpt, declaredSymbolInfoKindsSet, nameMatches, containerMatches, cancellationToken)
                        : TryFilterPreviousSearchResultsAsync(project, priorityDocuments, searchDocument, pattern, nameMatcher, containerMatcherOpt, declaredSymbolInfoKindsSet, nameMatches, containerMatches, cancellationToken);
#else
                        var task = ComputeSearchResultsAsync(project, searchDocument, nameMatcher, containerMatcherOpt, declaredSymbolInfoKindsSet, nameMatches, containerMatches, cancellationToken);
#endif

                        var searchResults = await task.ConfigureAwait(false);

                        return(ImmutableArray <INavigateToSearchResult> .CastUp(searchResults));
                    }
                    finally
                    {
                        nameMatches.Free();
                        containerMatches.Free();
                    }
                }
        }
Beispiel #6
0
        private static PatternMatch?TestNonFuzzyMatch(string candidate, string pattern)
        {
            MarkupTestFile.GetSpans(candidate, out candidate, out ImmutableArray <TextSpan> spans);

            var match = PatternMatcher.CreatePatternMatcher(pattern, includeMatchedSpans: true, allowFuzzyMatching: false)
                        .GetFirstMatch(candidate);

            if (match == null)
            {
                Assert.True(spans.Length == 0);
            }
            else
            {
                Assert.Equal <TextSpan>(match.Value.MatchedSpans, spans);
            }

            return(match);
        }