/// <summary> /// Given a list of symbols, and a mapping from each symbol to its original SemanticModel, /// creates the list of completion items for them. /// </summary> private ImmutableArray <CompletionItem> CreateItems( CompletionContext completionContext, IEnumerable <ISymbol> symbols, Func <ISymbol, SyntaxContext> contextLookup, Dictionary <ISymbol, List <ProjectId> > invalidProjectMap, List <ProjectId> totalProjects, bool preselect, Lazy <ImmutableArray <ITypeSymbol> > inferredTypes, TelemetryCounter telemetryCounter) { // We might get symbol w/o name but CanBeReferencedByName is still set to true, // need to filter them out. // https://github.com/dotnet/roslyn/issues/47690 var symbolGroups = from symbol in symbols let texts = GetDisplayAndSuffixAndInsertionText(symbol, contextLookup(symbol)) where !string.IsNullOrWhiteSpace(texts.displayText) group symbol by texts into g select g; var itemListBuilder = ImmutableArray.CreateBuilder <CompletionItem>(); var typeConvertibilityCache = new Dictionary <ITypeSymbol, bool>(SymbolEqualityComparer.Default); foreach (var symbolGroup in symbolGroups) { var arbitraryFirstContext = contextLookup(symbolGroup.First()); var item = CreateItem( completionContext, symbolGroup.Key.displayText, symbolGroup.Key.suffix, symbolGroup.Key.insertionText, symbolGroup.ToList(), arbitraryFirstContext, invalidProjectMap, totalProjects, preselect); if (IsTargetTypeCompletionFilterExperimentEnabled(arbitraryFirstContext.Workspace)) { var tick = Environment.TickCount; foreach (var symbol in symbolGroup) { var syntaxContext = contextLookup(symbol); if (ShouldIncludeInTargetTypedCompletionList(symbol, inferredTypes.Value, syntaxContext.SemanticModel, syntaxContext.Position, typeConvertibilityCache)) { item = item.AddTag(WellKnownTags.TargetTypeMatch); break; } } telemetryCounter.AddTick(Environment.TickCount - tick); } itemListBuilder.Add(item); } return(itemListBuilder.ToImmutable()); }
/// <summary> /// Given a list of symbols, and a mapping from each symbol to its original SemanticModel, /// creates the list of completion items for them. /// </summary> private ImmutableArray <CompletionItem> CreateItems( IEnumerable <ISymbol> symbols, Func <ISymbol, SyntaxContext> contextLookup, Dictionary <ISymbol, List <ProjectId> > invalidProjectMap, List <ProjectId> totalProjects, bool preselect, Lazy <ImmutableArray <ITypeSymbol> > inferredTypes, TelemetryCounter telemetryCounter) { var symbolGroups = from symbol in symbols let texts = GetDisplayAndSuffixAndInsertionText(symbol, contextLookup(symbol)) group symbol by texts into g select g; var itemListBuilder = ImmutableArray.CreateBuilder <CompletionItem>(); var typeConvertibilityCache = new Dictionary <ITypeSymbol, bool>(); foreach (var symbolGroup in symbolGroups) { var arbitraryFirstContext = contextLookup(symbolGroup.First()); var item = this.CreateItem( symbolGroup.Key.displayText, symbolGroup.Key.suffix, symbolGroup.Key.insertionText, symbolGroup.ToList(), arbitraryFirstContext, invalidProjectMap, totalProjects, preselect); if (IsTargetTypeCompletionFilterExperimentEnabled(arbitraryFirstContext.Workspace)) { var tick = Environment.TickCount; var inferredTypesWithoutNullability = inferredTypes.Value.SelectAsArray(t => t.WithoutNullability()); foreach (var symbol in symbolGroup) { var syntaxContext = contextLookup(symbol); if (ShouldIncludeInTargetTypedCompletionList(symbol, inferredTypesWithoutNullability, syntaxContext.SemanticModel, syntaxContext.Position, typeConvertibilityCache)) { item = item.AddTag(WellKnownTags.TargetTypeMatch); break; } } telemetryCounter.AddTick(Environment.TickCount - tick); } itemListBuilder.Add(item); } return(itemListBuilder.ToImmutable()); }