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()); }
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()); }