Exemple #1
0
        internal async Task <ImmutableArray <ISymbol> > FindNavigableSourceSymbolsAsync(
            Project project, CancellationToken cancellationToken)
        {
            var declarations = await DeclarationFinder.FindSourceDeclarationsWithPatternAsync(
                project, _searchPattern, SymbolFilter.TypeAndMember, cancellationToken).ConfigureAwait(false);

            var symbols = declarations.SelectAsArray(d => d.Symbol);

            var results = ArrayBuilder <ISymbol> .GetInstance();

            foreach (var symbol in symbols)
            {
                cancellationToken.ThrowIfCancellationRequested();

                // Ignore constructors and namespaces.  We don't want to expose them through this API.
                if (symbol.IsConstructor() ||
                    symbol.IsStaticConstructor() ||
                    symbol is INamespaceSymbol)
                {
                    continue;
                }

                // Ignore symbols that have no source location.  We don't want to expose them through this API.
                if (!symbol.Locations.Any(loc => loc.IsInSource))
                {
                    continue;
                }

                results.Add(symbol);

                // also report matching constructors (using same match result as type)
                var namedType = symbol as INamedTypeSymbol;
                if (namedType != null)
                {
                    foreach (var constructor in namedType.Constructors)
                    {
                        // only constructors that were explicitly declared
                        if (!constructor.IsImplicitlyDeclared)
                        {
                            results.Add(constructor);
                        }
                    }
                }

                // report both parts of partial methods
                var method = symbol as IMethodSymbol;
                if (method != null && method.PartialImplementationPart != null)
                {
                    results.Add(method);
                }
            }

            return(results.ToImmutableAndFree());
        }
Exemple #2
0
        internal async Task <ImmutableArray <ISymbol> > FindNavigableSourceSymbolsAsync(
            Project project, CancellationToken cancellationToken)
        {
            ImmutableArray <ISymbol> declarations;

            // FindSourceDeclarationsWithPatternAsync calls into OOP to do the search; if something goes badly it
            // throws a SoftCrashException which inherits from OperationCanceledException. This is unfortunate, because
            // it means that other bits of code see this as a cancellation and then may crash because they expect that if this
            // method is raising cancellation, it's because cancellationToken requested the cancellation. The intent behind
            // SoftCrashException was since it inherited from OperationCancelled it would make things safer, but in this case
            // it's violating other invariants in the process which creates other problems.
            //
            // https://github.com/dotnet/roslyn/issues/40476 tracks removing SoftCrashException. When it is removed, the
            // catch here can be removed and simply let the exception propagate; our Progression code is hardened to
            // handle exceptions and report them gracefully.
            try
            {
                declarations = await DeclarationFinder.FindSourceDeclarationsWithPatternAsync(
                    project, _searchPattern, SymbolFilter.TypeAndMember, cancellationToken).ConfigureAwait(false);
            }
            catch (SoftCrashException ex) when(ex.InnerException != null)
            {
                ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                throw ExceptionUtilities.Unreachable;
            }

            using var _ = ArrayBuilder <ISymbol> .GetInstance(out var results);

            foreach (var declaration in declarations)
            {
                cancellationToken.ThrowIfCancellationRequested();

                var symbol = declaration;

                // Ignore constructors and namespaces.  We don't want to expose them through this API.
                if (symbol.IsConstructor() ||
                    symbol.IsStaticConstructor() ||
                    symbol is INamespaceSymbol)
                {
                    continue;
                }

                // Ignore symbols that have no source location.  We don't want to expose them through this API.
                if (!symbol.Locations.Any(loc => loc.IsInSource))
                {
                    continue;
                }

                results.Add(declaration);

                // also report matching constructors (using same match result as type)
                if (symbol is INamedTypeSymbol namedType)
                {
                    foreach (var constructor in namedType.Constructors)
                    {
                        // only constructors that were explicitly declared
                        if (!constructor.IsImplicitlyDeclared)
                        {
                            results.Add(constructor);
                        }
                    }
                }

                // report both parts of partial methods
                if (symbol is IMethodSymbol method && method.PartialImplementationPart != null)
                {
                    results.Add(method);
                }
            }

            return(results.ToImmutable());
        }