public static CompletionItem Create(INamedTypeSymbol typeSymbol, string containingNamespace, string genericTypeSuffix) { PooledDictionary <string, string> propertyBuilder = null; if (typeSymbol.Arity > 0) { propertyBuilder = PooledDictionary <string, string> .GetInstance(); propertyBuilder.Add(TypeAritySuffixName, GetAritySuffix(typeSymbol.Arity)); } // Add tildes (ASCII: 126) to name and namespace as sort text: // 1. '~' before type name makes import items show after in-scope items // 2. ' ' before namespace makes types with identical type name but from different namespace all show up in the list, // it also makes sure type with shorter name shows first, e.g. 'SomeType` before 'SomeTypeWithLongerName'. var sortTextBuilder = PooledStringBuilder.GetInstance(); sortTextBuilder.Builder.AppendFormat(SortTextFormat, typeSymbol.Name, containingNamespace); return(CompletionItem.Create( displayText: typeSymbol.Name, filterText: typeSymbol.Name, sortText: sortTextBuilder.ToStringAndFree(), properties: propertyBuilder?.ToImmutableDictionaryAndFree(), tags: GlyphTags.GetTags(typeSymbol.GetGlyph()), rules: CompletionItemRules.Default, displayTextPrefix: null, displayTextSuffix: typeSymbol.Arity == 0 ? string.Empty : genericTypeSuffix, inlineDescription: containingNamespace)); }
public static CompletionItem Create(INamedTypeSymbol typeSymbol, string containingNamespace) { PooledDictionary <string, string> propertyBuilder = null; if (typeSymbol.Arity > 0) { propertyBuilder = PooledDictionary <string, string> .GetInstance(); propertyBuilder.Add(TypeAritySuffixName, GetAritySuffix(typeSymbol.Arity)); } // Hack: add tildes (ASCII: 126) to name and namespace as sort text: // 1. '~' before type name makes import items show after in-scope items // 2. ' ' before namespace makes types with identical type name but from different namespace all show up in the list, // it also makes sure type with shorter name shows first, e.g. 'SomeType` before 'SomeTypeWithLongerName'. var sortTextBuilder = PooledStringBuilder.GetInstance(); sortTextBuilder.Builder.AppendFormat(SortTextFormat, typeSymbol.Name, containingNamespace); // TODO: // 1. Suffix should be language specific, i.e. `(Of ...)` if triggered from VB. // 2. Sort the import items to be after in-scope symbols in a less hacky way. // 3. Editor support for resolving item text conflicts? return(CompletionItem.Create( displayText: typeSymbol.Name, filterText: typeSymbol.Name, sortText: sortTextBuilder.ToStringAndFree(), properties: propertyBuilder?.ToImmutableDictionaryAndFree(), tags: GlyphTags.GetTags(typeSymbol.GetGlyph()), rules: CompletionItemRules.Default, displayTextPrefix: null, displayTextSuffix: typeSymbol.Arity == 0 ? string.Empty : "<>", inlineDescription: containingNamespace)); }
protected async Task CheckResultsAsync( Document document, int position, string expectedItemOrNull, string expectedDescriptionOrNull, bool usePreviousCharAsTrigger, bool checkForAbsence, int?glyph, int?matchPriority, bool?hasSuggestionModeItem, string displayTextSuffix) { var code = (await document.GetTextAsync()).ToString(); var trigger = CompletionTrigger.Invoke; if (usePreviousCharAsTrigger) { trigger = CompletionTrigger.CreateInsertionTrigger(insertedCharacter: code.ElementAt(position - 1)); } var completionService = GetCompletionService(document.Project.Solution.Workspace); var completionList = await GetCompletionListAsync(completionService, document, position, trigger); var items = completionList == null ? ImmutableArray <CompletionItem> .Empty : completionList.Items; if (hasSuggestionModeItem != null) { Assert.Equal(hasSuggestionModeItem.Value, completionList.SuggestionModeItem != null); } if (checkForAbsence) { if (items == null) { return; } if (expectedItemOrNull == null) { Assert.Empty(items); } else { AssertEx.None( items, c => CompareItems(c.DisplayText, expectedItemOrNull) && (expectedDescriptionOrNull != null ? completionService.GetDescriptionAsync(document, c).Result.Text == expectedDescriptionOrNull : true)); } } else { if (expectedItemOrNull == null) { Assert.NotEmpty(items); } else { AssertEx.Any(items, c => CompareItems(c.DisplayText, expectedItemOrNull) && CompareItems(c.DisplayTextSuffix, displayTextSuffix ?? "") && (expectedDescriptionOrNull != null ? completionService.GetDescriptionAsync(document, c).Result.Text == expectedDescriptionOrNull : true) && (glyph.HasValue ? c.Tags.SequenceEqual(GlyphTags.GetTags((Glyph)glyph.Value)) : true) && (matchPriority.HasValue ? (int)c.Rules.MatchPriority == matchPriority.Value : true)); } } }
private static ImmutableDictionary <string, ImmutableDictionary <string, Glyph> > InitializeDictionary() { var builder = ImmutableDictionary.CreateBuilder <string, ImmutableDictionary <string, Glyph> >(); foreach (var glyph in (Glyph[])Enum.GetValues(typeof(Glyph))) { var tags = GlyphTags.GetTags((Microsoft.CodeAnalysis.Glyph)glyph); if (tags.IsDefaultOrEmpty) { continue; } var firstTag = tags[0]; var secondTag = tags.Length == 2 ? tags[1] : string.Empty; var inner = builder.GetValueOrDefault(firstTag); if (inner == null) { inner = ImmutableDictionary <string, Glyph> .Empty.Add(secondTag, glyph); } builder[firstTag] = inner.SetItem(secondTag, glyph); } return(builder.ToImmutable()); }
public override DefinitionItem GetThirdPartyDefinitionItem( Solution solution, ISymbol definition) { var symbolNavigationService = solution.Workspace.Services.GetService <ISymbolNavigationService>(); if (!symbolNavigationService.WouldNavigateToSymbol(definition, solution, out var filePath, out var lineNumber, out var charOffset)) { return(null); } var displayParts = GetDisplayParts(filePath, lineNumber, charOffset); return(new ExternalDefinitionItem( GlyphTags.GetTags(definition.GetGlyph()), displayParts, _serviceProvider, filePath, lineNumber, charOffset)); }
private static DefinitionItem CreateDefinitionItem( Solution solution, ReferencedSymbol referencedSymbol, HashSet <DocumentLocation> uniqueLocations) { var definition = referencedSymbol.Definition; var displayParts = definition.ToDisplayParts(s_definitionDisplayFormat).ToTaggedText(); return(CreateDefinitionItem( GlyphTags.GetTags(definition.GetGlyph()), displayParts, definition.ShouldShowWithNoReferenceLocations(), solution, definition, uniqueLocations)); }
private static async Task FindSymbolMonikerReferencesAsync( IFindSymbolMonikerUsagesService monikerUsagesService, ISymbol definition, IFindUsagesContext context, CancellationToken cancellationToken) { var moniker = SymbolMoniker.TryCreate(definition); if (moniker == null) { return; } // Let the find-refs window know we have outstanding work await using var _ = await context.ProgressTracker.AddSingleItemAsync().ConfigureAwait(false); var displayParts = GetDisplayParts(definition).AddRange(new[] { new TaggedText(TextTags.Space, " "), new TaggedText(TextTags.Text, EditorFeaturesResources.external), }); var definitionItem = DefinitionItem.CreateNonNavigableItem( tags: GlyphTags.GetTags(definition.GetGlyph()), displayParts, originationParts: DefinitionItem.GetOriginationParts(definition)); var monikers = ImmutableArray.Create(moniker); var first = true; await foreach (var referenceItem in monikerUsagesService.FindReferencesByMoniker( definitionItem, monikers, context.ProgressTracker, cancellationToken)) { if (first) { // found some results. Add the definition item to the context. first = false; await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false); } await context.OnExternalReferenceFoundAsync(referenceItem).ConfigureAwait(false); } }
public static CompletionItem Create(string name, int arity, string containingNamespace, Glyph glyph, string genericTypeSuffix, CompletionItemFlags flags, string?symbolKeyData) { ImmutableDictionary <string, string>?properties = null; if (symbolKeyData != null || arity > 0) { var builder = PooledDictionary <string, string> .GetInstance(); if (symbolKeyData != null) { builder.Add(SymbolKeyData, symbolKeyData); } else { // We don't need arity to recover symbol if we already have SymbolKeyData or it's 0. // (but it still needed below to decide whether to show generic suffix) builder.Add(TypeAritySuffixName, AbstractDeclaredSymbolInfoFactoryService.GetMetadataAritySuffix(arity)); } properties = builder.ToImmutableDictionaryAndFree(); } // Add tildes (ASCII: 126) to name and namespace as sort text: // 1. '~' before type name makes import items show after in-scope items // 2. ' ' before namespace makes types with identical type name but from different namespace all show up in the list, // it also makes sure type with shorter name shows first, e.g. 'SomeType` before 'SomeTypeWithLongerName'. var sortTextBuilder = PooledStringBuilder.GetInstance(); sortTextBuilder.Builder.AppendFormat(SortTextFormat, name, containingNamespace); var item = CompletionItem.Create( displayText: name, sortText: sortTextBuilder.ToStringAndFree(), properties: properties, tags: GlyphTags.GetTags(glyph), rules: CompletionItemRules.Default, displayTextPrefix: null, displayTextSuffix: arity == 0 ? string.Empty : genericTypeSuffix, inlineDescription: containingNamespace); item.Flags = flags; return(item); }
public static CompletionItem Create( string displayText, string displayTextSuffix, CompletionItemRules rules, Glyph?glyph = null, ImmutableArray <SymbolDisplayPart> description = default, string sortText = null, string filterText = null, bool showsWarningIcon = false, ImmutableDictionary <string, string> properties = null, ImmutableArray <string> tags = default) { tags = tags.NullToEmpty(); if (glyph != null) { // put glyph tags first tags = GlyphTags.GetTags(glyph.Value).AddRange(tags); } if (showsWarningIcon) { tags = tags.Add(WellKnownTags.Warning); } properties = properties ?? ImmutableDictionary <string, string> .Empty; if (!description.IsDefault && description.Length > 0) { properties = properties.Add("Description", EncodeDescription(description)); } return(CompletionItem.Create( displayText: displayText, displayTextSuffix: displayTextSuffix, filterText: filterText, sortText: sortText, properties: properties, tags: tags, rules: rules)); }
public static ImmutableArray <string> GetTags(FSharpGlyph glyph) { return(GlyphTags.GetTags(FSharpGlyphHelpers.ConvertTo(glyph))); }
public static DefinitionItem ToDefinitionItem( this ISymbol definition, Solution solution, bool includeHiddenLocations, HashSet <DocumentSpan> uniqueSpans = null) { // Ensure we're working with the original definition for the symbol. I.e. When we're // creating definition items, we want to create them for types like Dictionary<TKey,TValue> // not some random instantiation of that type. // // This ensures that the type will both display properly to the user, as well as ensuring // that we can accurately resolve the type later on when we try to navigate to it. definition = definition.OriginalDefinition; var displayParts = definition.ToDisplayParts(GetFormat(definition)).ToTaggedText(); var nameDisplayParts = definition.ToDisplayParts(s_namePartsFormat).ToTaggedText(); var tags = GlyphTags.GetTags(definition.GetGlyph()); var displayIfNoReferences = definition.ShouldShowWithNoReferenceLocations( showMetadataSymbolsWithoutReferences: false); var sourceLocations = ArrayBuilder <DocumentSpan> .GetInstance(); // If it's a namespace, don't create any normal location. Namespaces // come from many different sources, but we'll only show a single // root definition node for it. That node won't be navigable. if (definition.Kind != SymbolKind.Namespace) { foreach (var location in definition.Locations) { if (location.IsInMetadata) { return(DefinitionItem.CreateMetadataDefinition( tags, displayParts, nameDisplayParts, solution, definition, displayIfNoReferences)); } else if (location.IsInSource) { if (!location.IsVisibleSourceLocation() && !includeHiddenLocations) { continue; } var document = solution.GetDocument(location.SourceTree); if (document != null) { var documentLocation = new DocumentSpan(document, location.SourceSpan); if (sourceLocations.Count == 0) { sourceLocations.Add(documentLocation); } else { if (uniqueSpans == null || uniqueSpans.Add(documentLocation)) { sourceLocations.Add(documentLocation); } } } } } } if (sourceLocations.Count == 0) { // If we got no definition locations, then create a sentinel one // that we can display but which will not allow navigation. return(DefinitionItem.CreateNonNavigableItem( tags, displayParts, DefinitionItem.GetOriginationParts(definition), displayIfNoReferences)); } return(DefinitionItem.Create( tags, displayParts, sourceLocations.ToImmutableAndFree(), nameDisplayParts, displayIfNoReferences)); }
public override async Task ProvideCompletionsAsync(CompletionContext context) { try { var document = context.Document; var position = context.Position; var cancellationToken = context.CancellationToken; var syntaxTree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (syntaxTree.IsInNonUserCode(position, cancellationToken)) { return; } var token = syntaxTree .FindTokenOnLeftOfPosition(position, cancellationToken) .GetPreviousTokenIfTouchingWord(position); if (!token.IsKind(SyntaxKind.OpenBracketToken, SyntaxKind.CommaToken)) { return; } if (token.Parent is not FunctionPointerUnmanagedCallingConventionListSyntax callingConventionList) { return; } var contextPosition = token.SpanStart; var semanticModel = await document.ReuseExistingSpeculativeModelAsync(callingConventionList, cancellationToken).ConfigureAwait(false); var completionItems = new HashSet <CompletionItem>(CompletionItemComparer.Instance); AddTypes(completionItems, contextPosition, semanticModel, cancellationToken); // Even if we didn't have types, there are four magic calling conventions recognized regardless. // We add these after doing the type lookup so if we had types we can show that instead foreach (var callingConvention in s_predefinedCallingConventions) { completionItems.Add(CompletionItem.Create(callingConvention, tags: GlyphTags.GetTags(Glyph.Keyword))); } context.AddItems(completionItems); } catch (Exception e) when(FatalError.ReportWithoutCrashUnlessCanceled(e)) { // nop } }
public static DefinitionItem ToDefinitionItem( this ISymbol definition, Solution solution, HashSet <DocumentSpan> uniqueSpans = null) { var displayParts = definition.ToDisplayParts(GetFormat(definition)).ToTaggedText(); var tags = GlyphTags.GetTags(definition.GetGlyph()); var displayIfNoReferences = definition.ShouldShowWithNoReferenceLocations( showMetadataSymbolsWithoutReferences: false); var sourceLocations = ArrayBuilder <DocumentSpan> .GetInstance(); // If it's a namespace, don't create any normal lcoation. Namespaces // come from many different sources, but we'll only show a single // root definition node for it. That node won't be navigable. if (definition.Kind != SymbolKind.Namespace) { foreach (var location in definition.Locations) { if (location.IsInMetadata) { return(DefinitionItem.CreateMetadataDefinition( tags, displayParts, solution, definition, displayIfNoReferences)); } else if (location.IsVisibleSourceLocation()) { var document = solution.GetDocument(location.SourceTree); if (document != null) { var documentLocation = new DocumentSpan(document, location.SourceSpan); if (sourceLocations.Count == 0) { sourceLocations.Add(documentLocation); } else { if (uniqueSpans == null || uniqueSpans.Add(documentLocation)) { sourceLocations.Add(documentLocation); } } } } } } if (sourceLocations.Count == 0) { // If we got no definition locations, then create a sentinel one // that we can display but which will not allow navigation. return(DefinitionItem.CreateNonNavigableItem( tags, displayParts, DefinitionItem.GetOriginationParts(definition), displayIfNoReferences)); } return(DefinitionItem.Create( tags, displayParts, sourceLocations.ToImmutableAndFree(), displayIfNoReferences)); }
private async Task CheckResultsAsync( Document document, int position, string expectedItemOrNull, string expectedDescriptionOrNull, bool usePreviousCharAsTrigger, bool checkForAbsence, Glyph?glyph) { var code = (await document.GetTextAsync()).ToString(); CompletionTrigger trigger = CompletionTrigger.Default; if (usePreviousCharAsTrigger) { trigger = CompletionTrigger.CreateInsertionTrigger(insertedCharacter: code.ElementAt(position - 1)); } var completionService = GetCompletionService(document.Project.Solution.Workspace); var completionList = await GetCompletionListAsync(completionService, document, position, trigger); var items = completionList == null ? default(ImmutableArray <CompletionItem>) : completionList.Items; if (checkForAbsence) { if (items == null) { return; } if (expectedItemOrNull == null) { Assert.Empty(items); } else { AssertEx.None( items, c => CompareItems(c.DisplayText, expectedItemOrNull) && (expectedDescriptionOrNull != null ? completionService.GetDescriptionAsync(document, c).Result.Text == expectedDescriptionOrNull : true)); } } else { if (expectedItemOrNull == null) { Assert.NotEmpty(items); } else { AssertEx.Any(items, c => CompareItems(c.DisplayText, expectedItemOrNull) && (expectedDescriptionOrNull != null ? completionService.GetDescriptionAsync(document, c).Result.Text == expectedDescriptionOrNull : true) && (glyph.HasValue ? CompletionHelper.TagsEqual(c.Tags, GlyphTags.GetTags(glyph.Value)) : true)); } } }
private static async Task <DefinitionItem> ToDefinitionItemAsync( this ISymbol definition, Project project, bool includeHiddenLocations, bool includeClassifiedSpans, FindReferencesSearchOptions options, CancellationToken cancellationToken) { // Ensure we're working with the original definition for the symbol. I.e. When we're // creating definition items, we want to create them for types like Dictionary<TKey,TValue> // not some random instantiation of that type. // // This ensures that the type will both display properly to the user, as well as ensuring // that we can accurately resolve the type later on when we try to navigate to it. definition = definition.OriginalDefinition; var displayParts = definition.ToDisplayParts(GetFormat(definition)).ToTaggedText(); var nameDisplayParts = definition.ToDisplayParts(s_namePartsFormat).ToTaggedText(); var tags = GlyphTags.GetTags(definition.GetGlyph()); var displayIfNoReferences = definition.ShouldShowWithNoReferenceLocations( options, showMetadataSymbolsWithoutReferences: false); using var sourceLocationsDisposer = ArrayBuilder <DocumentSpan> .GetInstance(out var sourceLocations); var properties = GetProperties(definition); var displayableProperties = AbstractReferenceFinder.GetAdditionalFindUsagesProperties(definition); // If it's a namespace, don't create any normal location. Namespaces // come from many different sources, but we'll only show a single // root definition node for it. That node won't be navigable. if (definition.Kind != SymbolKind.Namespace) { foreach (var location in definition.Locations) { if (location.IsInMetadata) { return(DefinitionItem.CreateMetadataDefinition( tags, displayParts, nameDisplayParts, project, definition, properties, displayIfNoReferences)); } else if (location.IsInSource) { if (!location.IsVisibleSourceLocation() && !includeHiddenLocations) { continue; } var document = project.Solution.GetDocument(location.SourceTree); if (document != null) { var documentLocation = !includeClassifiedSpans ? new DocumentSpan(document, location.SourceSpan) : await ClassifiedSpansAndHighlightSpanFactory.GetClassifiedDocumentSpanAsync( document, location.SourceSpan, cancellationToken).ConfigureAwait(false); sourceLocations.Add(documentLocation); } } } } if (sourceLocations.Count == 0) { // If we got no definition locations, then create a sentinel one // that we can display but which will not allow navigation. return(DefinitionItem.CreateNonNavigableItem( tags, displayParts, DefinitionItem.GetOriginationParts(definition), properties, displayIfNoReferences)); } return(DefinitionItem.Create( tags, displayParts, sourceLocations.ToImmutable(), nameDisplayParts, properties, displayableProperties, displayIfNoReferences)); }
public override async Task ProvideCompletionsAsync(CompletionContext context) { // This provider is exported for all workspaces - so limit it to just our workspace & the debugger's intellisense workspace if (context.Document.Project.Solution.Workspace.Kind != WorkspaceKind.AnyCodeRoslynWorkspace && context.Document.Project.Solution.Workspace.Kind != StringConstants.DebuggerIntellisenseWorkspaceKind) { return; } var lspClient = _roslynLspClientServiceFactory.ActiveLanguageServerClient; if (lspClient == null) { return; } var text = await context.Document.GetTextAsync(context.CancellationToken).ConfigureAwait(false); var completionParams = new LSP.CompletionParams { TextDocument = ProtocolConversions.DocumentToTextDocumentIdentifier(context.Document), Position = ProtocolConversions.LinePositionToPosition(text.Lines.GetLinePosition(context.Position)), Context = new LSP.CompletionContext { TriggerCharacter = context.Trigger.Character.ToString(), TriggerKind = GetTriggerKind(context.Trigger) } }; var completionObject = await lspClient.RequestAsync(LSP.Methods.TextDocumentCompletion.ToLSRequest(), completionParams, context.CancellationToken).ConfigureAwait(false); if (completionObject == null) { return; } var completionList = ((JToken)completionObject).ToObject <RoslynCompletionItem[]>(); foreach (var item in completionList) { ImmutableArray <string> tags; if (item.Tags != null) { tags = item.Tags.AsImmutable(); } else { var glyph = ProtocolConversions.CompletionItemKindToGlyph(item.Kind); tags = GlyphTags.GetTags(glyph); } var properties = ImmutableDictionary.CreateBuilder <string, string>(); if (!string.IsNullOrEmpty(item.Detail)) { // The display text is encoded as TaggedText | value properties.Add("Description", $"Text|{item.Detail}"); } properties.Add("InsertionText", item.InsertText); properties.Add("ResolveData", JToken.FromObject(item).ToString()); var completionItem = CompletionItem.Create(item.Label, item.FilterText, item.SortText, properties: properties.ToImmutable(), tags: tags); context.AddItem(completionItem); } }
private static async Task <DefinitionItem> ToDefinitionItemAsync( this ISymbol definition, Solution solution, bool isPrimary, bool includeHiddenLocations, bool includeClassifiedSpans, FindReferencesSearchOptions options, CancellationToken cancellationToken) { // Ensure we're working with the original definition for the symbol. I.e. When we're // creating definition items, we want to create them for types like Dictionary<TKey,TValue> // not some random instantiation of that type. // // This ensures that the type will both display properly to the user, as well as ensuring // that we can accurately resolve the type later on when we try to navigate to it. if (!definition.IsTupleField()) { // In an earlier implementation of the compiler APIs, tuples and tuple fields symbols were definitions // We pretend this is still the case definition = definition.OriginalDefinition; } var displayParts = GetDisplayParts(definition); var nameDisplayParts = definition.ToDisplayParts(s_namePartsFormat).ToTaggedText(); var tags = GlyphTags.GetTags(definition.GetGlyph()); var displayIfNoReferences = definition.ShouldShowWithNoReferenceLocations( options, showMetadataSymbolsWithoutReferences: false); using var sourceLocationsDisposer = ArrayBuilder <DocumentSpan> .GetInstance(out var sourceLocations); var properties = GetProperties(definition, isPrimary); // If it's a namespace, don't create any normal location. Namespaces // come from many different sources, but we'll only show a single // root definition node for it. That node won't be navigable. if (definition.Kind != SymbolKind.Namespace) { foreach (var location in definition.Locations) { if (location.IsInMetadata) { return(DefinitionItem.CreateMetadataDefinition( tags, displayParts, nameDisplayParts, solution, definition, properties, displayIfNoReferences)); } else if (location.IsInSource) { if (!location.IsVisibleSourceLocation() && !includeHiddenLocations) { continue; } var document = solution.GetDocument(location.SourceTree); if (document != null) { var documentLocation = !includeClassifiedSpans ? new DocumentSpan(document, location.SourceSpan) : await ClassifiedSpansAndHighlightSpanFactory.GetClassifiedDocumentSpanAsync( document, location.SourceSpan, cancellationToken).ConfigureAwait(false); sourceLocations.Add(documentLocation); } else { // Was this a source generated tree? If so, we don't have a document representaion (yet) so // we'll create a metadata symbol which will later be handled by the symbol navigation service // that way. Once we represent generated source trees as propery documents, we'll update the code above // to correctly make this item. var project = solution.GetOriginatingProject(definition); var generatorRunResult = await project.GetGeneratorDriverRunResultAsync(cancellationToken).ConfigureAwait(false); if (generatorRunResult.TryGetGeneratorAndHint(location.SourceTree, out _, out _)) { return(DefinitionItem.CreateMetadataDefinition( tags, displayParts, nameDisplayParts, solution, definition, properties, displayIfNoReferences)); } } } } } if (sourceLocations.Count == 0) { // If we got no definition locations, then create a sentinel one // that we can display but which will not allow navigation. return(DefinitionItem.CreateNonNavigableItem( tags, displayParts, DefinitionItem.GetOriginationParts(definition), properties, displayIfNoReferences)); } var displayableProperties = AbstractReferenceFinder.GetAdditionalFindUsagesProperties(definition); return(DefinitionItem.Create( tags, displayParts, sourceLocations.ToImmutable(), nameDisplayParts, properties, displayableProperties, displayIfNoReferences)); }