Ejemplo n.º 1
0
        private static async Task AddDeclarationsAsync(
            Project project,
            SearchQuery query,
            SymbolFilter filter,
            List <ISymbol> list,
            Compilation startingCompilation,
            IAssemblySymbol startingAssembly,
            CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.SymbolFinder_Project_AddDeclarationsAsync, cancellationToken))
                using (var set = SharedPools.Default <HashSet <ISymbol> >().GetPooledObject())
                {
                    if (!await project.ContainsSymbolsWithNameAsync(query.GetPredicate(), filter, cancellationToken).ConfigureAwait(false))
                    {
                        return;
                    }

                    var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                    if (startingCompilation != null && startingAssembly != null && compilation.Assembly != startingAssembly)
                    {
                        // Return symbols from skeleton assembly in this case so that symbols have the same language as startingCompilation.
                        list.AddRange(
                            FilterByCriteria(compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken), filter)
                            .Select(s => s.GetSymbolKey().Resolve(startingCompilation, cancellationToken: cancellationToken).Symbol).WhereNotNull());
                    }
                    else
                    {
                        list.AddRange(FilterByCriteria(compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken), filter));
                    }
                }
        }
        internal static async Task <ImmutableArray <ISymbol> > FindSourceDeclarationsAsync(
            Project project, SearchQuery query, SymbolFilter filter, CancellationToken cancellationToken)
        {
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            if (query.Name != null && string.IsNullOrWhiteSpace(query.Name))
            {
                return(ImmutableArray <ISymbol> .Empty);
            }

            using (Logger.LogBlock(FunctionId.SymbolFinder_Project_Predicate_FindSourceDeclarationsAsync, cancellationToken))
            {
                if (!await project.ContainsSymbolsWithNameAsync(query.GetPredicate(), filter, cancellationToken).ConfigureAwait(false))
                {
                    return(ImmutableArray <ISymbol> .Empty);
                }

                var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                var unfiltered = compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken).ToImmutableArray();
                return(FilterByCriteria(unfiltered, filter));
            }
        }
Ejemplo n.º 3
0
        internal static async Task <IEnumerable <ISymbol> > FindSourceDeclarationsAsync(Project project, SearchQuery query, SymbolFilter filter, CancellationToken cancellationToken)
        {
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            if (query.Name != null && string.IsNullOrWhiteSpace(query.Name))
            {
                return(SpecializedCollections.EmptyEnumerable <ISymbol>());
            }

            using (Logger.LogBlock(FunctionId.SymbolFinder_Project_Predicate_FindSourceDeclarationsAsync, cancellationToken))
            {
                var result = new List <ISymbol>();
                if (!await project.ContainsSymbolsWithNameAsync(query.GetPredicate(), filter, cancellationToken).ConfigureAwait(false))
                {
                    return(result);
                }

                var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                result.AddRange(FilterByCriteria(compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken), filter));
                return(result);
            }
        }
Ejemplo n.º 4
0
        private static async Task AddCompilationDeclarationsWithNormalQueryAsync(
            Project project,
            SearchQuery query,
            SymbolFilter filter,
            ArrayBuilder <ISymbol> list,
            Compilation startingCompilation,
            IAssemblySymbol startingAssembly,
            CancellationToken cancellationToken)
        {
            Debug.Assert(query.Kind != SearchKind.Custom);

            using (Logger.LogBlock(FunctionId.SymbolFinder_Project_AddDeclarationsAsync, cancellationToken))
            {
                if (!await project.ContainsSymbolsWithNameAsync(query.GetPredicate(), filter, cancellationToken).ConfigureAwait(false))
                {
                    return;
                }

                var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                var symbolsWithName = compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken)
                                      .ToImmutableArray();

                if (startingCompilation != null && startingAssembly != null && compilation.Assembly != startingAssembly)
                {
                    // Return symbols from skeleton assembly in this case so that symbols have
                    // the same language as startingCompilation.
                    symbolsWithName = symbolsWithName.Select(s => s.GetSymbolKey().Resolve(startingCompilation, cancellationToken: cancellationToken).Symbol)
                                      .WhereNotNull()
                                      .ToImmutableArray();
                }

                list.AddRange(FilterByCriteria(symbolsWithName, filter));
            }
        }
Ejemplo n.º 5
0
        private static async Task AddCompilationDeclarationsWithNormalQueryAsync(
            Project project,
            SearchQuery query,
            SymbolFilter filter,
            ArrayBuilder <SymbolAndProjectId> list,
            Compilation startingCompilation,
            IAssemblySymbol startingAssembly,
            CancellationToken cancellationToken)
        {
            Contract.ThrowIfTrue(query.Kind == SearchKind.Custom, "Custom queries are not supported in this API");

            using (Logger.LogBlock(FunctionId.SymbolFinder_Project_AddDeclarationsAsync, cancellationToken))
            {
                var syntaxFacts = project.LanguageServices.GetService <ISyntaxFactsService>();

                // If this is an exact query, we can speed things up by just calling into the
                // compilation entrypoints that take a string directly.
                //
                // the search is 'exact' if it's either an exact-case-sensitive search,
                // or it's an exact-case-insensitive search and we're in a case-insensitive
                // language.
                var isExactNameSearch = query.Kind == SearchKind.Exact ||
                                        (query.Kind == SearchKind.ExactIgnoreCase && !syntaxFacts.IsCaseSensitive);

                // Note: we first call through the project.  This has an optimization where it will
                // use the DeclarationOnlyCompilation if we have one, avoiding needing to build the
                // full compilation if we don't have that.
                var containsSymbol = isExactNameSearch
                    ? await project.ContainsSymbolsWithNameAsync(query.Name, filter, cancellationToken).ConfigureAwait(false)
                    : await project.ContainsSymbolsWithNameAsync(query.GetPredicate(), filter, cancellationToken).ConfigureAwait(false);

                if (!containsSymbol)
                {
                    return;
                }

                var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                var symbols = isExactNameSearch
                    ? compilation.GetSymbolsWithName(query.Name, filter, cancellationToken)
                    : compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken);

                var symbolsWithName = symbols.SelectAsArray(s => new SymbolAndProjectId(s, project.Id));

                if (startingCompilation != null && startingAssembly != null && !Equals(compilation.Assembly, startingAssembly))
                {
                    // Return symbols from skeleton assembly in this case so that symbols have
                    // the same language as startingCompilation.
                    symbolsWithName = symbolsWithName.Select(s => s.WithSymbol(s.Symbol.GetSymbolKey().Resolve(startingCompilation, cancellationToken: cancellationToken).Symbol))
                                      .Where(s => s.Symbol != null)
                                      .ToImmutableArray();
                }

                list.AddRange(FilterByCriteria(symbolsWithName, filter));
            }
        }
        private static async Task <ImmutableArray <ISymbol> > GetUnfilteredSymbolsAsync(
            Project project,
            SearchQuery query,
            SymbolFilter filter,
            Compilation startingCompilation,
            IAssemblySymbol startingAssembly,
            CancellationToken cancellationToken)
        {
            var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            if (startingCompilation != null && startingAssembly != null && compilation.Assembly != startingAssembly)
            {
                // Return symbols from skeleton assembly in this case so that symbols have the same language as startingCompilation.
                return(compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken)
                       .Select(s => s.GetSymbolKey().Resolve(startingCompilation, cancellationToken: cancellationToken).Symbol)
                       .WhereNotNull()
                       .ToImmutableArray());
            }
            else
            {
                return(compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken)
                       .ToImmutableArray());
            }
        }
Ejemplo n.º 7
0
        public Task<IEnumerable<ISymbol>> FindAsync(SearchQuery query, AsyncLazy<IAssemblySymbol> lazyAssembly, CancellationToken cancellationToken)
        {
            // If the query has a specific string provided, then call into the SymbolTreeInfo
            // helpers optimized for lookup based on an exact name.
            switch (query.Kind)
            {
                case SearchKind.Exact:
                    return this.FindAsync(lazyAssembly, query.Name, ignoreCase: false, cancellationToken: cancellationToken);
                case SearchKind.ExactIgnoreCase:
                    return this.FindAsync(lazyAssembly, query.Name, ignoreCase: true, cancellationToken: cancellationToken);
                case SearchKind.Fuzzy:
                    return this.FuzzyFindAsync(lazyAssembly, query.Name, cancellationToken);
                case SearchKind.Custom:
                    // Otherwise, we'll have to do a slow linear search over all possible symbols.
                    return this.FindAsync(lazyAssembly, query.GetPredicate(), cancellationToken);
            }

            throw new InvalidOperationException();
        }
        private static async Task AddDeclarationsAsync(
            Project project,
            SearchQuery query,
            SymbolFilter filter,
            ArrayBuilder <ISymbol> list,
            Compilation startingCompilation,
            IAssemblySymbol startingAssembly,
            CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.SymbolFinder_Project_AddDeclarationsAsync, cancellationToken))
            {
                if (!await project.ContainsSymbolsWithNameAsync(query.GetPredicate(), filter, cancellationToken).ConfigureAwait(false))
                {
                    return;
                }

                var unfilteredSymbols = await GetUnfilteredSymbolsAsync(
                    project, query, filter, startingCompilation, startingAssembly, cancellationToken).ConfigureAwait(false);

                list.AddRange(FilterByCriteria(unfilteredSymbols, filter));
            }
        }
Ejemplo n.º 9
0
        private Task <IEnumerable <ISymbol> > FindAsyncWorker(SearchQuery query, AsyncLazy <IAssemblySymbol> lazyAssembly, CancellationToken cancellationToken)
        {
            // If the query has a specific string provided, then call into the SymbolTreeInfo
            // helpers optimized for lookup based on an exact name.
            switch (query.Kind)
            {
            case SearchKind.Exact:
                return(this.FindAsync(lazyAssembly, query.Name, ignoreCase: false, cancellationToken: cancellationToken));

            case SearchKind.ExactIgnoreCase:
                return(this.FindAsync(lazyAssembly, query.Name, ignoreCase: true, cancellationToken: cancellationToken));

            case SearchKind.Fuzzy:
                return(this.FuzzyFindAsync(lazyAssembly, query.Name, cancellationToken));

            case SearchKind.Custom:
                // Otherwise, we'll have to do a slow linear search over all possible symbols.
                return(this.FindAsync(lazyAssembly, query.GetPredicate(), cancellationToken));
            }

            throw new InvalidOperationException();
        }
Ejemplo n.º 10
0
        private static async Task AddCompilationDeclarationsWithNormalQueryAsync(
            Project project,
            SearchQuery query,
            SymbolFilter filter,
            ArrayBuilder <ISymbol> list,
            Compilation startingCompilation,
            IAssemblySymbol startingAssembly,
            CancellationToken cancellationToken)
        {
            if (!project.SupportsCompilation)
            {
                return;
            }

            Contract.ThrowIfTrue(query.Kind == SearchKind.Custom, "Custom queries are not supported in this API");

            using (Logger.LogBlock(FunctionId.SymbolFinder_Project_AddDeclarationsAsync, cancellationToken))
            {
                var syntaxFacts = project.LanguageServices.GetService <ISyntaxFactsService>();

                // If this is an exact query, we can speed things up by just calling into the
                // compilation entrypoints that take a string directly.
                //
                // the search is 'exact' if it's either an exact-case-sensitive search,
                // or it's an exact-case-insensitive search and we're in a case-insensitive
                // language.
                var isExactNameSearch = query.Kind == SearchKind.Exact ||
                                        (query.Kind == SearchKind.ExactIgnoreCase && !syntaxFacts.IsCaseSensitive);

                // Do a quick syntactic check first using our cheaply built indices.  That will help us avoid creating
                // a compilation here if it's not necessary.  In the case of an exact name search we can call a special
                // overload that quickly uses the direct bloom-filter identifier maps in the index.  If it's nto an
                // exact name search, then we will run the query's predicate over every DeclaredSymbolInfo stored in
                // the doc.
                var containsSymbol = isExactNameSearch
                    ? await project.ContainsSymbolsWithNameAsync(query.Name, cancellationToken).ConfigureAwait(false)
                    : await project.ContainsSymbolsWithNameAsync(query.GetPredicate(), filter, cancellationToken).ConfigureAwait(false);

                if (!containsSymbol)
                {
                    return;
                }

                var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                var symbols = isExactNameSearch
                    ? compilation.GetSymbolsWithName(query.Name, filter, cancellationToken)
                    : compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken);

                var symbolsWithName = symbols.ToImmutableArray();

                if (startingCompilation != null && startingAssembly != null && !Equals(compilation.Assembly, startingAssembly))
                {
                    // Return symbols from skeleton assembly in this case so that symbols have
                    // the same language as startingCompilation.
                    symbolsWithName = symbolsWithName.Select(s => s.GetSymbolKey(cancellationToken).Resolve(startingCompilation, cancellationToken: cancellationToken).Symbol)
                                      .WhereNotNull()
                                      .ToImmutableArray();
                }

                list.AddRange(FilterByCriteria(symbolsWithName, filter));
            }
        }
        internal static async Task<IEnumerable<ISymbol>> FindSourceDeclarationsAsync(Project project, SearchQuery query, SymbolFilter filter, CancellationToken cancellationToken)
        {
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            if (query.Name != null && string.IsNullOrWhiteSpace(query.Name))
            {
                return SpecializedCollections.EmptyEnumerable<ISymbol>();
            }

            using (Logger.LogBlock(FunctionId.SymbolFinder_Project_Predicate_FindSourceDeclarationsAsync, cancellationToken))
            {
                var result = new List<ISymbol>();
                if (!await project.ContainsSymbolsWithNameAsync(query.GetPredicate(), filter, cancellationToken).ConfigureAwait(false))
                {
                    return result;
                }

                var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                result.AddRange(FilterByCriteria(compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken), filter));
                return result;
            }
        }
        private static async Task AddDeclarationsAsync(
            Project project,
            SearchQuery query,
            SymbolFilter filter,
            List<ISymbol> list,
            Compilation startingCompilation,
            IAssemblySymbol startingAssembly,
            CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.SymbolFinder_Project_AddDeclarationsAsync, cancellationToken))
            using (var set = SharedPools.Default<HashSet<ISymbol>>().GetPooledObject())
            {
                if (!await project.ContainsSymbolsWithNameAsync(query.GetPredicate(), filter, cancellationToken).ConfigureAwait(false))
                {
                    return;
                }

                var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
                if (startingCompilation != null && startingAssembly != null && compilation.Assembly != startingAssembly)
                {
                    // Return symbols from skeleton assembly in this case so that symbols have the same language as startingCompilation.
                    list.AddRange(
                        FilterByCriteria(compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken), filter)
                            .Select(s => s.GetSymbolKey().Resolve(startingCompilation, cancellationToken: cancellationToken).Symbol).WhereNotNull());
                }
                else
                {
                    list.AddRange(FilterByCriteria(compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken), filter));
                }
            }
        }
Ejemplo n.º 13
0
        internal static async Task<ImmutableArray<ISymbol>> FindSourceDeclarationsAsync(
            Project project, SearchQuery query, SymbolFilter filter, CancellationToken cancellationToken)
        {
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            if (query.Name != null && string.IsNullOrWhiteSpace(query.Name))
            {
                return ImmutableArray<ISymbol>.Empty;
            }

            using (Logger.LogBlock(FunctionId.SymbolFinder_Project_Predicate_FindSourceDeclarationsAsync, cancellationToken))
            {
                if (!await project.ContainsSymbolsWithNameAsync(query.GetPredicate(), filter, cancellationToken).ConfigureAwait(false))
                {
                    return ImmutableArray<ISymbol>.Empty;
                }

                var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                var unfiltered = compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken).ToImmutableArray();
                return FilterByCriteria(unfiltered, filter);
            }
        }
Ejemplo n.º 14
0
 private static async Task<ImmutableArray<ISymbol>> GetUnfilteredSymbolsAsync(
     Project project,
     SearchQuery query,
     SymbolFilter filter,
     Compilation startingCompilation,
     IAssemblySymbol startingAssembly,
     CancellationToken cancellationToken)
 {
     var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
     if (startingCompilation != null && startingAssembly != null && compilation.Assembly != startingAssembly)
     {
         // Return symbols from skeleton assembly in this case so that symbols have the same language as startingCompilation.
         return compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken)
             .Select(s => s.GetSymbolKey().Resolve(startingCompilation, cancellationToken: cancellationToken).Symbol)
             .WhereNotNull()
             .ToImmutableArray();
     }
     else
     {
         return compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken)
                           .ToImmutableArray();
     }
 }
Ejemplo n.º 15
0
        private static async Task AddDeclarationsAsync(
            Project project,
            SearchQuery query,
            SymbolFilter filter,
            ArrayBuilder<ISymbol> list,
            Compilation startingCompilation,
            IAssemblySymbol startingAssembly,
            CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.SymbolFinder_Project_AddDeclarationsAsync, cancellationToken))
            {
                if (!await project.ContainsSymbolsWithNameAsync(query.GetPredicate(), filter, cancellationToken).ConfigureAwait(false))
                {
                    return;
                }

                var unfilteredSymbols = await GetUnfilteredSymbolsAsync(
                    project, query, filter, startingCompilation, startingAssembly, cancellationToken).ConfigureAwait(false);
                list.AddRange(FilterByCriteria(unfilteredSymbols, filter));
            }
        }