Repository: dotnet/roslyn
File: src/LanguageServer/Protocol/Extensions/Extensions.cs (C#)

Code before:
            {
                return defaultGetter();
            }
        }

        // We either have only one item or have multiple, but none of them  matched our context. In the
        // latter case, we'll just return the first one arbitrarily since this might just be some temporary mis-sync
        // of client and server state.
        return items[0];
    }

    public static T FindDocumentInProjectContext<T>(this ImmutableArray<T> documents, TextDocumentIdentifier documentIdentifier, Func<Solution, DocumentId, T> documentGetter) where T : TextDocument
    {
        return FindItemInProjectContext(documents, documentIdentifier, projectIdGetter: (item) => item.Project.Id, defaultGetter: () =>
        {
            // We were not passed a project context.  This can happen when the LSP powered NavBar is not enabled.
            // This branch should be removed when we're using the LSP based navbar in all scenarios.

            var solution = documents.First().Project.Solution;

            // Lookup which of the linked documents is currently active in the workspace.
            var documentIdInCurrentContext = solution.Workspace.GetDocumentIdInCurrentContext(documents.First().Id);

            var document = documentGetter(solution, documentIdInCurrentContext);

            // When a misc document is loaded into the host workspace, it's project file path is the same as the document file path.
            // We always want to prefer the non-misc document.
            if (IsMiscDocumentInHostWorkspace(document))
            {
                var nonMisc = documents.First(d => d.Id != document.Id);
                return nonMisc;
            }

            return document;
        });
    }

    public static bool IsMiscDocumentInHostWorkspace(this TextDocument document)
    {
        return document.Project.Solution.WorkspaceKind == WorkspaceKind.Host && document.Project.FilePath != null && document.Project.FilePath == document.FilePath;
    }

    public static Project? GetProject(this Solution solution, TextDocumentIdentifier projectIdentifier)
    {
        // We need to parse the URI (scheme, file path) to be able to lookup the URI in the solution.
        if (projectIdentifier.DocumentUri.ParsedUri is null)
        {
            return null;
        }

        var projects = solution.Projects.WhereAsArray(project => project.FilePath == projectIdentifier.DocumentUri.ParsedUri.LocalPath);

Review comment (suggestion):
It feels like this comment should be inside `IsMiscDocumentInHostWorkspace` instead

Code after:
            {
                return defaultGetter();
            }
        }

        // We either have only one item or have multiple, but none of them  matched our context. In the
        // latter case, we'll just return the first one arbitrarily since this might just be some temporary mis-sync
        // of client and server state.
        return items[0];
    }

    public static T FindDocumentInProjectContext<T>(this ImmutableArray<T> documents, TextDocumentIdentifier documentIdentifier, Func<Solution, DocumentId, T> documentGetter) where T : TextDocument
    {
        return FindItemInProjectContext(documents, documentIdentifier, projectIdGetter: (item) => item.Project.Id, defaultGetter: () =>
        {
            // We were not passed a project context.  This can happen when the LSP powered NavBar is not enabled.
            // This branch should be removed when we're using the LSP based navbar in all scenarios.

            var solution = documents.First().Project.Solution;
            // Lookup which of the linked documents is currently active in the workspace.
            var documentIdInCurrentContext = solution.Workspace.GetDocumentIdInCurrentContext(documents.First().Id);
            return documentGetter(solution, documentIdInCurrentContext);
        });
    }

    public static Project? GetProject(this Solution solution, TextDocumentIdentifier projectIdentifier)
    {
        // We need to parse the URI (scheme, file path) to be able to lookup the URI in the solution.
        if (projectIdentifier.DocumentUri.ParsedUri is null)
        {
            return null;
        }

        var projects = solution.Projects.WhereAsArray(project => project.FilePath == projectIdentifier.DocumentUri.ParsedUri.LocalPath);
        return !projects.Any()
            ? null
            : FindItemInProjectContext(projects, projectIdentifier, projectIdGetter: (item) => item.Id, defaultGetter: () => projects[0]);
    }

    public static TextDocument? GetAdditionalDocument(this Solution solution, TextDocumentIdentifier documentIdentifier)
    {
        var documentIds = GetDocumentIds(solution, documentIdentifier.DocumentUri);

        // We don't call GetRequiredAdditionalDocument as the id could be referring to a regular document.
        var additionalDocuments = documentIds.Select(solution.GetAdditionalDocument).WhereNotNull().ToImmutableArray();
        return !additionalDocuments.Any()
            ? null
            : additionalDocuments.FindDocumentInProjectContext(documentIdentifier, (sln, id) => sln.GetRequiredAdditionalDocument(id));
    }

    public static async Task<int> GetPositionFromLinePositionAsync(this TextDocument document, LinePosition linePosition, CancellationToken cancellationToken)