public void AddItem(INamedTypeSymbol symbol, string containingNamespace, bool isPublic) { // We want to cache items with EditoBrowsableState == Advanced regardless of current "hide adv members" option value var(isBrowsable, isEditorBrowsableStateAdvanced) = symbol.IsEditorBrowsableWithState( hideAdvancedMembers: false, _editorBrowsableInfo.Compilation, _editorBrowsableInfo); if (!isBrowsable) { // Hide this item from completion return; } var isGeneric = symbol.Arity > 0; // Need to determine if a type is an attribute up front since we want to filter out // non-attribute types when in attribute context. We can't do this lazily since we don't hold // on to symbols. However, the cost of calling `IsAttribute` on every top-level type symbols // is prohibitively high, so we opt for the heuristic that would do the simple textual "Attribute" // suffix check first, then the more expensive symbolic check. As a result, all unimported // attribute types that don't have "Attribute" suffix would be filtered out when in attribute context. var isAttribute = symbol.Name.HasAttributeSuffix(isCaseSensitive: false) && symbol.IsAttribute(); var item = ImportCompletionItem.Create( symbol.Name, symbol.Arity, containingNamespace, symbol.GetGlyph(), _genericTypeSuffix, CompletionItemFlags.CachedAndExpanded, extensionMethodData: null); _itemsBuilder.Add(new TypeImportCompletionItemInfo(item, isPublic, isGeneric, isAttribute, isEditorBrowsableStateAdvanced)); }
static CompletionItem GetAppropriateAttributeItem(CompletionItem attributeItem, bool isCaseSensitive) { if (attributeItem.DisplayText.TryGetWithoutAttributeSuffix(isCaseSensitive: isCaseSensitive, out var attributeNameWithoutSuffix)) { // We don't want to cache this item. return(ImportCompletionItem.CreateAttributeItemWithoutSuffix(attributeItem, attributeNameWithoutSuffix, CompletionItemFlags.Expanded)); } return(attributeItem); }
public ImmutableArray <CompletionItem> GetItemsForContext( string language, string genericTypeSuffix, bool isInternalsVisible, bool isAttributeContext, bool isCaseSensitive, bool hideAdvancedMembers) { var isSameLanguage = Language == language; using var _ = ArrayBuilder <CompletionItem> .GetInstance(out var builder); foreach (var info in ItemInfos) { if (!info.IsPublic && !isInternalsVisible) { continue; } // Option to show advanced members is false so we need to exclude them. if (hideAdvancedMembers && info.IsEditorBrowsableStateAdvanced) { continue; } var item = info.Item; if (isAttributeContext) { // Don't show non attribute item in attribute context if (!info.IsAttribute) { continue; } // We are in attribute context, will not show or complete with "Attribute" suffix. item = GetAppropriateAttributeItem(info.Item, isCaseSensitive); } // C# and VB the display text is different for generics, i.e. <T> and (Of T). For simpllicity, we only cache for one language. // But when we trigger in a project with different language than when the cache entry was created for, we will need to // change the generic suffix accordingly. if (!isSameLanguage && info.IsGeneric) { // We don't want to cache this item. item = ImportCompletionItem.CreateItemWithGenericDisplaySuffix(item, genericTypeSuffix); } builder.Add(item); } return(builder.ToImmutable());
public void AddItem(INamedTypeSymbol symbol, string containingNamespace, bool isPublic) { var isGeneric = symbol.Arity > 0; // Need to determine if a type is an attribute up front since we want to filter out // non-attribute types when in attribute context. We can't do this lazily since we don't hold // on to symbols. However, the cost of calling `IsAttribute` on every top-level type symbols // is prohibitively high, so we opt for the heuristic that would do the simple textual "Attribute" // suffix check first, then the more expensive symbolic check. As a result, all unimported // attribute types that don't have "Attribute" suffix would be filtered out when in attribute context. var isAttribute = symbol.Name.HasAttributeSuffix(isCaseSensitive: false) && symbol.IsAttribute(); var item = ImportCompletionItem.Create(symbol, containingNamespace, _genericTypeSuffix); _itemsBuilder.Add(new TypeImportCompletionItemInfo(item, isPublic, isGeneric, isAttribute)); }
public ImmutableArray <CompletionItem> GetItemsForContext( string language, string genericTypeSuffix, bool isInternalsVisible, bool isAttributeContext, bool isCaseSensitive) { // We will need to adjust some items if the request is made in: // 1. attribute context, then we will not show or complete with "Attribute" suffix. // 2. a project with different langauge than when the cache entry was created, // then we will change the generic suffix accordingly. // Otherwise, we can simply return cached items. var isSameLanguage = Language == language; if (isSameLanguage && !isAttributeContext) { return(ItemInfos.Where(info => info.IsPublic || isInternalsVisible).SelectAsArray(info => info.Item)); } var builder = ArrayBuilder <CompletionItem> .GetInstance(); foreach (var info in ItemInfos) { if (info.IsPublic || isInternalsVisible) { var item = info.Item; if (isAttributeContext) { if (!info.IsAttribute) { continue; } item = GetAppropriateAttributeItem(info.Item, isCaseSensitive); } if (!isSameLanguage && info.IsGeneric) { // We don't want to cache this item. item = ImportCompletionItem.CreateItemWithGenericDisplaySuffix(item, genericTypeSuffix); } builder.Add(item); } } return(builder.ToImmutableAndFree());