File: Navigation\INavigableItem.cs
Web Access
Project: src\src\Features\Core\Portable\Microsoft.CodeAnalysis.Features.csproj (Microsoft.CodeAnalysis.Features)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
 
namespace Microsoft.CodeAnalysis.Navigation;
 
internal interface INavigableItem
{
    Glyph Glyph { get; }
 
    /// <summary>
    /// The tagged parts to display for this item. If default, the line of text from <see
    /// cref="Document"/> is used.
    /// </summary>
    ImmutableArray<TaggedText> DisplayTaggedParts { get; }
 
    /// <summary>
    /// Return true to display the file path of <see cref="Document"/> and the span of <see
    /// cref="SourceSpan"/> when displaying this item.
    /// </summary>
    bool DisplayFileLocation { get; }
 
    /// <summary>
    /// his is intended for symbols that are ordinary symbols in the language sense, and may be
    /// used by code, but that are simply declared implicitly rather than with explicit language
    /// syntax.  For example, a default synthesized constructor in C# when the class contains no
    /// explicit constructors.
    /// </summary>
    bool IsImplicitlyDeclared { get; }
 
    NavigableDocument Document { get; }
    TextSpan SourceSpan { get; }
 
    /// <summary>
    /// True if this search result represents an item that existed in the past, but which may
    /// not exist currently, or which may have moved to a different location.  Consumers should
    /// be resilient to that being the case and not being able to necessarily navigate to the
    /// <see cref="SourceSpan"/> provided.
    /// </summary>
    bool IsStale { get; }
 
    ImmutableArray<INavigableItem> ChildItems { get; }
 
    public record NavigableDocument(NavigableProject Project, string Name, string? FilePath, IReadOnlyList<string> Folders, DocumentId Id, SourceGeneratedDocumentIdentity? SourceGeneratedDocumentIdentity, Workspace? Workspace)
    {
        public static NavigableDocument FromDocument(Document document)
            => new(
                NavigableProject.FromProject(document.Project),
                document.Name,
                document.FilePath,
                document.Folders,
                document.Id,
                SourceGeneratedDocumentIdentity: (document as SourceGeneratedDocument)?.Identity,
                document.Project.Solution.TryGetWorkspace());
 
        /// <summary>
        /// Get the <see cref="CodeAnalysis.Document"/> within <paramref name="solution"/> which is referenced by
        /// this navigable item. The document is required to exist within the solution, e.g. a case where the
        /// navigable item was constructed during a Find Symbols operation on the same solution instance.
        /// </summary>
        internal ValueTask<Document> GetRequiredDocumentAsync(Solution solution, CancellationToken cancellationToken)
            => solution.GetRequiredDocumentAsync(Id, includeSourceGenerated: SourceGeneratedDocumentIdentity is not null, cancellationToken);
 
        /// <summary>
        /// Get the <see cref="SourceText"/> of the <see cref="CodeAnalysis.Document"/> within
        /// <paramref name="solution"/> which is referenced by this navigable item. The document is required to
        /// exist within the solution, e.g. a case where the navigable item was constructed during a Find Symbols
        /// operation on the same solution instance.
        /// </summary>
        internal async ValueTask<SourceText> GetTextAsync(Solution solution, CancellationToken cancellationToken)
        {
            var document = await GetRequiredDocumentAsync(solution, cancellationToken).ConfigureAwait(false);
            return await document.GetValueTextAsync(cancellationToken).ConfigureAwait(false);
        }
 
        internal SourceText? TryGetTextSynchronously(Solution solution, CancellationToken cancellationToken)
        {
            var document = solution.GetDocument(Id);
            return document?.GetTextSynchronously(cancellationToken);
        }
    }
 
    public record struct NavigableProject(string Name, ProjectId Id)
    {
        public static NavigableProject FromProject(Project project)
            => new(project.Name, project.Id);
    }
}