public static (IQueueItem, Task <TResponseType?>) Create(
                bool mutatesSolutionState,
                bool requiresLSPSolution,
                ClientCapabilities clientCapabilities,
                string methodName,
                TextDocumentIdentifier?textDocument,
                TRequestType request,
                IRequestHandler <TRequestType, TResponseType> handler,
                Guid activityId,
                ILspLogger logger,
                RequestTelemetryLogger telemetryLogger,
                CancellationToken cancellationToken)
            {
                var queueItem = new QueueItem <TRequestType, TResponseType>(
                    mutatesSolutionState,
                    requiresLSPSolution,
                    clientCapabilities,
                    methodName,
                    textDocument,
                    request,
                    handler,
                    activityId,
                    logger,
                    telemetryLogger,
                    cancellationToken);

                return(queueItem, queueItem._completionSource.Task);
            }
Exemple #2
0
            public QueueItem(
                bool mutatesSolutionState,
                bool requiresLSPSolution,
                ClientCapabilities clientCapabilities,
                string?clientName,
                string methodName,
                TextDocumentIdentifier?textDocument,
                Guid activityId,
                ILspLogger logger,
                RequestTelemetryLogger telemetryLogger,
                Action <Exception> handleQueueFailure,
                Func <RequestContext?, CancellationToken, Task> callbackAsync,
                CancellationToken cancellationToken)
            {
                Metrics = new RequestMetrics(methodName, telemetryLogger);

                _callbackAsync = callbackAsync;
                _logger        = logger;

                ActivityId           = activityId;
                MutatesSolutionState = mutatesSolutionState;
                RequiresLSPSolution  = requiresLSPSolution;
                ClientCapabilities   = clientCapabilities;
                ClientName           = clientName;
                MethodName           = methodName;
                TextDocument         = textDocument;
                HandleQueueFailure   = handleQueueFailure;
                CancellationToken    = cancellationToken;
            }
            public QueueItem(
                bool mutatesSolutionState,
                bool requiresLSPSolution,
                ClientCapabilities clientCapabilities,
                string methodName,
                TextDocumentIdentifier?textDocument,
                TRequestType request,
                IRequestHandler <TRequestType, TResponseType> handler,
                Guid activityId,
                ILspLogger logger,
                RequestTelemetryLogger telemetryLogger,
                CancellationToken cancellationToken)
            {
                _completionSource = new TaskCompletionSource <TResponseType?>();
                // Set the tcs state to cancelled if the token gets cancelled outside of our callback (for example the server shutting down).
                cancellationToken.Register(() => _completionSource.TrySetCanceled(cancellationToken));

                Metrics = new RequestMetrics(methodName, telemetryLogger);

                _handler = handler;
                _logger  = logger;
                _request = request;

                ActivityId           = activityId;
                MutatesSolutionState = mutatesSolutionState;
                RequiresLSPSolution  = requiresLSPSolution;
                ClientCapabilities   = clientCapabilities;
                MethodName           = methodName;
                TextDocument         = textDocument;
            }
Exemple #4
0
 public static RequestContext Create(
     bool requiresLSPSolution,
     TextDocumentIdentifier?textDocument,
     string?clientName,
     ClientCapabilities clientCapabilities,
     ILspWorkspaceRegistrationService lspWorkspaceRegistrationService,
     Dictionary <Workspace, (Solution workspaceSolution, Solution lspSolution)>?solutionCache,
Exemple #5
0
 public CompletionItemData(
     TextDocumentIdentifier?textDocument = null, QsQualifiedName?qualifiedName = null, string?sourceFile = null)
 {
     this.TextDocument = textDocument;
     this.@namespace   = qualifiedName?.Namespace;
     this.name         = qualifiedName?.Name;
     this.SourceFile   = sourceFile;
 }
 protected override DiagnosticReport CreateReport(
     TextDocumentIdentifier?identifier,
     VSDiagnostic[]?diagnostics,
     string?resultId
     ) => new DiagnosticReport
 {
     Diagnostics = diagnostics, ResultId = resultId
 };
 public QueueItem(bool mutatesSolutionState, ClientCapabilities clientCapabilities, string?clientName, TextDocumentIdentifier?textDocument, Func <RequestContext, CancellationToken, Task> callbackAsync, CancellationToken cancellationToken)
 {
     MutatesSolutionState = mutatesSolutionState;
     ClientCapabilities   = clientCapabilities;
     ClientName           = clientName;
     TextDocument         = textDocument;
     CallbackAsync        = callbackAsync;
     CancellationToken    = cancellationToken;
 }
 protected override WorkspaceDiagnosticReport CreateReport(TextDocumentIdentifier?identifier, VSDiagnostic[]?diagnostics, string?resultId)
 => new WorkspaceDiagnosticReport
 {
     TextDocument = identifier,
     Diagnostics  = diagnostics,
     ResultId     = resultId,
     // Mark these diagnostics as having come from us.  They will be superseded by any diagnostics for the
     // same file produced by the DocumentPullDiagnosticHandler.
     Identifier = WorkspaceDiagnosticIdentifier,
 };
 protected override DiagnosticReport CreateReport(TextDocumentIdentifier?identifier, VSDiagnostic[]?diagnostics, string?resultId)
 => new DiagnosticReport
 {
     Diagnostics = diagnostics,
     ResultId    = resultId,
     Identifier  = DocumentDiagnosticIdentifier,
     // Mark these diagnostics as superseding any diagnostics for the same document from the
     // WorkspacePullDiagnosticHandler. We are always getting completely accurate and up to date diagnostic
     // values for a particular file, so our results should always be preferred over the workspace-pull
     // values which are cached and may be out of date.
     Supersedes = WorkspaceDiagnosticIdentifier,
 };
 /// <summary>
 /// Creates the <see cref="VSInternalDiagnosticReport"/> instance we'll report back to clients to let them know our
 /// progress.
 /// </summary>
 protected abstract TReport CreateReport(TextDocumentIdentifier?identifier, VSDiagnostic[]?diagnostics, string?resultId);
Exemple #11
0
        public static (Document?, Solution) GetDocumentAndSolution(this ILspSolutionProvider provider, TextDocumentIdentifier?textDocument, string?clientName)
        {
            var solution = provider.GetCurrentSolutionForMainWorkspace();

            if (textDocument != null)
            {
                var document           = provider.GetDocument(textDocument, clientName);
                var solutionOfDocument = document?.Project.Solution;

                return(document, solutionOfDocument ?? solution);
            }

            return(null, solution);
        }
Exemple #12
0
 protected override VSInternalWorkspaceDiagnosticReport CreateReport(TextDocumentIdentifier?identifier, VSDiagnostic[]?diagnostics, string?resultId)
 => new VSInternalWorkspaceDiagnosticReport
 {
     TextDocument = identifier, Diagnostics = diagnostics, ResultId = resultId
 };
Exemple #13
0
        public static RequestContext?Create(
            bool requiresLSPSolution,
            TextDocumentIdentifier?textDocument,
            string?clientName,
            ILspLogger logger,
            ClientCapabilities clientCapabilities,
            LspWorkspaceManager lspWorkspaceManager,
            IDocumentChangeTracker documentChangeTracker,
            ImmutableArray <string> supportedLanguages,
            IGlobalOptionService globalOptions)
        {
            // Retrieve the current LSP tracked text as of this request.
            // This is safe as all creation of request contexts cannot happen concurrently.
            var trackedDocuments = lspWorkspaceManager.GetTrackedLspText();

            // If the handler doesn't need an LSP solution we do two important things:
            // 1. We don't bother building the LSP solution for perf reasons
            // 2. We explicitly don't give the handler a solution or document, even if we could
            //    so they're not accidentally operating on stale solution state.
            if (!requiresLSPSolution)
            {
                return(new RequestContext(solution: null, logger, clientCapabilities, clientName, document: null, documentChangeTracker, trackedDocuments, supportedLanguages, globalOptions));
            }

            // Go through each registered workspace, find the solution that contains the document that
            // this request is for, and then updates it based on the state of the world as we know it, based on the
            // text content in the document change tracker.

            Document?document          = null;
            var      workspaceSolution = lspWorkspaceManager.TryGetHostLspSolution();

            if (textDocument is not null)
            {
                // we were given a request associated with a document.  Find the corresponding roslyn
                // document for this.  If we can't, we cannot proceed.
                document = lspWorkspaceManager.GetLspDocument(textDocument, clientName);
                if (document != null)
                {
                    workspaceSolution = document.Project.Solution;
                }
            }

            if (workspaceSolution == null)
            {
                logger.TraceError("Could not find appropriate solution for operation");
                return(null);
            }

            var context = new RequestContext(
                workspaceSolution,
                logger,
                clientCapabilities,
                clientName,
                document,
                documentChangeTracker,
                trackedDocuments,
                supportedLanguages,
                globalOptions);

            return(context);
        }
        public static async Task <RequestContext?> CreateAsync(
            bool requiresLSPSolution,
            TextDocumentIdentifier?textDocument,
            WellKnownLspServerKinds serverKind,
            ILspLogger logger,
            ClientCapabilities clientCapabilities,
            LspWorkspaceManager lspWorkspaceManager,
            ILanguageServerNotificationManager notificationManager,
            IDocumentChangeTracker documentChangeTracker,
            ImmutableArray <string> supportedLanguages,
            IGlobalOptionService globalOptions,
            CancellationToken queueCancellationToken,
            CancellationToken requestCancellationToken)
        {
            // Retrieve the current LSP tracked text as of this request.
            // This is safe as all creation of request contexts cannot happen concurrently.
            var trackedDocuments = lspWorkspaceManager.GetTrackedLspText();

            // If the handler doesn't need an LSP solution we do two important things:
            // 1. We don't bother building the LSP solution for perf reasons
            // 2. We explicitly don't give the handler a solution or document, even if we could
            //    so they're not accidentally operating on stale solution state.
            if (!requiresLSPSolution)
            {
                return(new RequestContext(
                           solution: null, logger: logger, clientCapabilities: clientCapabilities, serverKind: serverKind, document: null,
                           documentChangeTracker: documentChangeTracker, trackedDocuments: trackedDocuments, supportedLanguages: supportedLanguages, globalOptions: globalOptions,
                           notificationManager: notificationManager, queueCancellationToken: queueCancellationToken));
            }

            Solution?workspaceSolution;
            Document?document = null;

            if (textDocument is not null)
            {
                // we were given a request associated with a document.  Find the corresponding roslyn document for this.
                // There are certain cases where we may be asked for a document that does not exist (for example a document is removed)
                // For example, document pull diagnostics can ask us after removal to clear diagnostics for a document.
                document = await lspWorkspaceManager.GetLspDocumentAsync(textDocument, requestCancellationToken).ConfigureAwait(false);
            }

            workspaceSolution = document?.Project.Solution ?? await lspWorkspaceManager.TryGetHostLspSolutionAsync(requestCancellationToken).ConfigureAwait(false);

            if (workspaceSolution == null)
            {
                logger.TraceError("Could not find appropriate solution for operation");
                return(null);
            }

            var context = new RequestContext(
                workspaceSolution,
                logger,
                clientCapabilities,
                serverKind,
                document,
                documentChangeTracker,
                trackedDocuments,
                supportedLanguages,
                globalOptions,
                notificationManager,
                queueCancellationToken);

            return(context);
        }