Beispiel #1
0
        private async Task <ProjectionResult?> GetProjectionCoreAsync(LSPDocumentSnapshot documentSnapshot, Position position, bool rejectOnNewerParallelRequest, CancellationToken cancellationToken)
        {
            if (documentSnapshot is null)
            {
                throw new ArgumentNullException(nameof(documentSnapshot));
            }

            if (position is null)
            {
                throw new ArgumentNullException(nameof(position));
            }

            // We initialize the logger here instead of the constructor as the projection provider is constructed
            // *before* the language server. Thus, the log hub has yet to be initialized, thus we would be unable to
            // create the logger at that time.
            await InitializeLogHubAsync(cancellationToken).ConfigureAwait(false);

            var languageQueryParams = new RazorLanguageQueryParams()
            {
                Position = position,
                Uri      = documentSnapshot.Uri
            };

            var response = await _requestInvoker.ReinvokeRequestOnServerAsync <RazorLanguageQueryParams, RazorLanguageQueryResponse>(
                documentSnapshot.Snapshot.TextBuffer,
                LanguageServerConstants.RazorLanguageQueryEndpoint,
                RazorLSPConstants.RazorLanguageServerName,
                CheckRazorLanguageQueryCapability,
                languageQueryParams,
                cancellationToken).ConfigureAwait(false);

            var languageResponse = response?.Response;

            if (languageResponse is null)
            {
                _logHubLogger?.LogInformation("The language server is still being spun up. Could not resolve the projection.");
                return(null);
            }

            VirtualDocumentSnapshot virtualDocument;

            if (languageResponse.Kind == RazorLanguageKind.CSharp &&
                documentSnapshot.TryGetVirtualDocument <CSharpVirtualDocumentSnapshot>(out var csharpDoc))
            {
                virtualDocument = csharpDoc;
            }
            else if (languageResponse.Kind == RazorLanguageKind.Html &&
                     documentSnapshot.TryGetVirtualDocument <HtmlVirtualDocumentSnapshot>(out var htmlDoc))
            {
                virtualDocument = htmlDoc;
            }
            else
            {
                _logHubLogger?.LogInformation($"Could not find projection for {languageResponse.Kind:G}.");
                return(null);
            }

            if (languageResponse.HostDocumentVersion is null)
            {
                // There should always be a document version attached to an open document.
                // Log it and move on as if it was synchronized.
                var message = $"Could not find a document version associated with the document '{documentSnapshot.Uri}'";
                _activityLogger.LogVerbose(message);
                _logHubLogger?.LogWarning(message);
            }
            else
            {
                var synchronized = await _documentSynchronizer.TrySynchronizeVirtualDocumentAsync(documentSnapshot.Version, virtualDocument, rejectOnNewerParallelRequest, cancellationToken).ConfigureAwait(false);

                if (!synchronized)
                {
                    _logHubLogger?.LogInformation("Could not synchronize.");
                    return(null);
                }
            }

            var result = new ProjectionResult()
            {
                Uri                 = virtualDocument.Uri,
                Position            = languageResponse.Position,
                PositionIndex       = languageResponse.PositionIndex,
                LanguageKind        = languageResponse.Kind,
                HostDocumentVersion = languageResponse.HostDocumentVersion
            };

            return(result);
        }
        public override async Task <ProjectionResult> GetProjectionAsync(LSPDocumentSnapshot documentSnapshot, Position position, CancellationToken cancellationToken)
        {
            if (documentSnapshot is null)
            {
                throw new ArgumentNullException(nameof(documentSnapshot));
            }

            if (position is null)
            {
                throw new ArgumentNullException(nameof(position));
            }

            var languageQueryParams = new RazorLanguageQueryParams()
            {
                Position = new Position(position.Line, position.Character),
                Uri      = documentSnapshot.Uri
            };

            var languageResponse = await _requestInvoker.RequestServerAsync <RazorLanguageQueryParams, RazorLanguageQueryResponse>(
                LanguageServerConstants.RazorLanguageQueryEndpoint,
                LanguageServerKind.Razor,
                languageQueryParams,
                cancellationToken).ConfigureAwait(false);

            VirtualDocumentSnapshot virtualDocument;

            if (languageResponse.Kind == RazorLanguageKind.CSharp &&
                documentSnapshot.TryGetVirtualDocument <CSharpVirtualDocumentSnapshot>(out var csharpDoc))
            {
                virtualDocument = csharpDoc;
            }
            else if (languageResponse.Kind == RazorLanguageKind.Html &&
                     documentSnapshot.TryGetVirtualDocument <HtmlVirtualDocumentSnapshot>(out var htmlDoc))
            {
                virtualDocument = htmlDoc;
            }
            else
            {
                return(null);
            }

            if (languageResponse.HostDocumentVersion == UndefinedDocumentVersion)
            {
                // There should always be a document version attached to an open document.
                // Log it and move on as if it was synchronized.
                _logger.LogVerbose($"Could not find a document version associated with the document '{documentSnapshot.Uri}'");
            }
            else
            {
                var synchronized = await _documentSynchronizer.TrySynchronizeVirtualDocumentAsync(documentSnapshot.Version, virtualDocument, cancellationToken).ConfigureAwait(false);

                if (!synchronized)
                {
                    // Could not synchronize
                    return(null);
                }
            }

            var result = new ProjectionResult()
            {
                Uri                 = virtualDocument.Uri,
                Position            = languageResponse.Position,
                PositionIndex       = languageResponse.PositionIndex,
                LanguageKind        = languageResponse.Kind,
                HostDocumentVersion = languageResponse.HostDocumentVersion
            };

            return(result);
        }