Example #1
0
        public async Task <SumType <LSP.SemanticTokens, LSP.SemanticTokensDelta> > HandleRequestAsync(
            LSP.SemanticTokensDeltaParams request,
            RequestContext context,
            CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(request.TextDocument, "TextDocument is null.");
            Contract.ThrowIfNull(request.PreviousResultId, "previousResultId is null.");
            Contract.ThrowIfNull(context.Document, "Document is null.");

            // Even though we want to ultimately pass edits back to LSP, we still need to compute all semantic tokens,
            // both for caching purposes and in order to have a baseline comparison when computing the edits.
            var newSemanticTokensData = await SemanticTokensHelpers.ComputeSemanticTokensDataAsync(
                context.Document, SemanticTokensCache.TokenTypeToIndex,
                range : null, cancellationToken).ConfigureAwait(false);

            Contract.ThrowIfNull(newSemanticTokensData, "newSemanticTokensData is null.");

            // Getting the cached tokens for the document. If we don't have an applicable cached token set,
            // we can't calculate edits, so we must return all semantic tokens instead.
            var oldSemanticTokensData = await _tokensCache.GetCachedTokensDataAsync(
                request.TextDocument.Uri, request.PreviousResultId, cancellationToken).ConfigureAwait(false);

            if (oldSemanticTokensData == null)
            {
                var newResultId = _tokensCache.GetNextResultId();
                return(new LSP.SemanticTokens {
                    ResultId = newResultId, Data = newSemanticTokensData
                });
            }

            var resultId  = request.PreviousResultId;
            var editArray = ComputeSemanticTokensEdits(oldSemanticTokensData, newSemanticTokensData);

            // If we have edits, generate a new ResultId. Otherwise, re-use the previous one.
            if (editArray.Length != 0)
            {
                resultId = _tokensCache.GetNextResultId();
                var updatedTokens = new LSP.SemanticTokens {
                    ResultId = resultId, Data = newSemanticTokensData
                };
                await _tokensCache.UpdateCacheAsync(
                    request.TextDocument.Uri, updatedTokens, cancellationToken).ConfigureAwait(false);
            }

            var edits = new SemanticTokensDelta
            {
                Edits    = editArray,
                ResultId = resultId
            };

            return(edits);
        }
 public TextDocumentIdentifier?GetTextDocumentIdentifier(LSP.SemanticTokensDeltaParams request)
 {
     Contract.ThrowIfNull(request.TextDocument);
     return(request.TextDocument);
 }