private static async Task AddMetadataDeclarationsWithNormalQueryAsync( Project project, IAssemblySymbol assembly, PortableExecutableReference referenceOpt, SearchQuery query, SymbolFilter filter, ArrayBuilder <SymbolAndProjectId> list, CancellationToken cancellationToken) { // All entrypoints to this function are Find functions that are only searching // for specific strings (i.e. they never do a custom search). Debug.Assert(query.Kind != SearchKind.Custom); using (Logger.LogBlock(FunctionId.SymbolFinder_Assembly_AddDeclarationsAsync, cancellationToken)) { if (referenceOpt != null) { var info = await SymbolTreeInfo.TryGetInfoForMetadataReferenceAsync( project.Solution, referenceOpt, loadOnly : false, cancellationToken : cancellationToken).ConfigureAwait(false); if (info != null) { var symbols = await info.FindAsync( query, assembly, project.Id, filter, cancellationToken).ConfigureAwait(false); list.AddRange(symbols); } } } }
private static async Task FindImmediateMatchingMetadataTypesInMetadataReferenceAsync( SymbolAndProjectIdSet metadataTypes, Project project, Func <SymbolAndProjectIdSet, INamedTypeSymbol, bool> metadataTypeMatches, Compilation compilation, PortableExecutableReference reference, SymbolAndProjectIdSet result, CancellationToken cancellationToken) { // We store an index in SymbolTreeInfo of the *simple* metadata type name // to the names of the all the types that either immediately derive or // implement that type. Because the mapping is from the simple name // we might get false positives. But that's fine as we still use // 'metadataTypeMatches' to make sure the match is correct. var symbolTreeInfo = await SymbolTreeInfo.TryGetInfoForMetadataReferenceAsync( project.Solution, reference, loadOnly : false, cancellationToken : cancellationToken).ConfigureAwait(false); if (symbolTreeInfo == null) { return; } // For each type we care about, see if we can find any derived types // in this index. foreach (var metadataType in metadataTypes) { var baseTypeName = metadataType.Symbol.Name; // For each derived type we find, see if we can map that back // to an actual symbol. Then check if that symbol actually fits // our criteria. foreach (var derivedType in symbolTreeInfo.GetDerivedMetadataTypes(baseTypeName, compilation, cancellationToken)) { if (derivedType != null && derivedType.Locations.Any(s_isInMetadata)) { if (metadataTypeMatches(metadataTypes, derivedType)) { result.Add(SymbolAndProjectId.Create(derivedType, project.Id)); } } } } }