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

            var resultId = _tokensCache.GetNextResultId();

            // The results from the range handler should not be cached since we don't want to cache
            // partial token results. In addition, a range request is only ever called with a whole
            // document request, so caching range results is unnecessary since the whole document
            // handler will cache the results anyway.
            var tokensData = await SemanticTokensHelpers
                             .ComputeSemanticTokensDataAsync(
                context.Document,
                SemanticTokensCache.TokenTypeToIndex,
                request.Range,
                cancellationToken
                )
                             .ConfigureAwait(false);

            return(new LSP.SemanticTokens {
                ResultId = resultId, Data = tokensData
            });
        }
        public override async Task <LSP.SemanticTokens> HandleRequestAsync(
            LSP.SemanticTokensRangeParams request,
            RequestContext context,
            CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(request.TextDocument, "TextDocument is null.");
            Contract.ThrowIfNull(context.Document, "Document is null.");

            var options = _globalOptions.GetClassificationOptions(context.Document.Project.Language);

            // The results from the range handler should not be cached since we don't want to cache
            // partial token results. In addition, a range request is only ever called with a whole
            // document request, so caching range results is unnecessary since the whole document
            // handler will cache the results anyway.
            var(tokensData, isFinalized) = await SemanticTokensHelpers.ComputeSemanticTokensDataAsync(
                context.Document,
                SemanticTokensHelpers.TokenTypeToIndex,
                request.Range,
                options,
                includeSyntacticClassifications : context.Document.IsRazorDocument(),
                cancellationToken).ConfigureAwait(false);

            return(new RoslynSemanticTokens {
                Data = tokensData, IsFinalized = isFinalized
            });
        }
Example #3
0
        public async Task <LSP.SemanticTokens> HandleRequestAsync(
            LSP.SemanticTokensRangeParams request,
            RequestContext context,
            CancellationToken cancellationToken)
        {
            // Temporary workaround for https://github.com/dotnet/roslyn/issues/54547.
            // We should eventually go back to throwing here if context.Document is null.
            if (context.Document is null)
            {
                return(new LSP.SemanticTokens());
            }

            Contract.ThrowIfNull(request.TextDocument, "TextDocument is null.");

            var resultId = _tokensCache.GetNextResultId();

            // The results from the range handler should not be cached since we don't want to cache
            // partial token results. In addition, a range request is only ever called with a whole
            // document request, so caching range results is unnecessary since the whole document
            // handler will cache the results anyway.
            var tokensData = await SemanticTokensHelpers.ComputeSemanticTokensDataAsync(
                context.Document, SemanticTokensCache.TokenTypeToIndex,
                request.Range, cancellationToken).ConfigureAwait(false);

            return(new LSP.SemanticTokens {
                ResultId = resultId, Data = tokensData
            });
        }
        public async Task <LSP.SemanticTokens> HandleRequestAsync(
            LSP.SemanticTokensParams request,
            RequestContext context,
            CancellationToken cancellationToken)
        {
            // Temporary workaround for https://github.com/dotnet/roslyn/issues/54547:
            // We should eventually go back to throwing here if context.Document is null.
            if (context.Document is null)
            {
                return(new LSP.SemanticTokens());
            }

            Contract.ThrowIfNull(request.TextDocument, "TextDocument is null.");

            var resultId   = _tokensCache.GetNextResultId();
            var tokensData = await SemanticTokensHelpers.ComputeSemanticTokensDataAsync(
                context.Document, SemanticTokensCache.TokenTypeToIndex,
                range : null, cancellationToken).ConfigureAwait(false);

            var tokens = new LSP.SemanticTokens {
                ResultId = resultId, Data = tokensData
            };
            await _tokensCache.UpdateCacheAsync(request.TextDocument.Uri, tokens, cancellationToken).ConfigureAwait(false);

            return(tokens);
        }
Example #5
0
        public async Task <LSP.SemanticTokens> HandleRequestAsync(
            LSP.SemanticTokensParams request,
            RequestContext context,
            CancellationToken cancellationToken
            )
        {
            Contract.ThrowIfNull(request.TextDocument, "TextDocument is null.");
            Contract.ThrowIfNull(context.Document, "Document is null.");

            var resultId   = _tokensCache.GetNextResultId();
            var tokensData = await SemanticTokensHelpers
                             .ComputeSemanticTokensDataAsync(
                context.Document,
                SemanticTokensCache.TokenTypeToIndex,
                range : null,
                cancellationToken
                )
                             .ConfigureAwait(false);

            var tokens = new LSP.SemanticTokens {
                ResultId = resultId, Data = tokensData
            };
            await _tokensCache
            .UpdateCacheAsync(request.TextDocument.Uri, tokens, cancellationToken)
            .ConfigureAwait(false);

            return(tokens);
        }
Example #6
0
        public async Task <SumType <LSP.SemanticTokens, LSP.SemanticTokensEdits> > HandleRequestAsync(
            LSP.SemanticTokensEditsParams request,
            RequestContext context,
            CancellationToken cancellationToken)
        {
            // Temporary workaround for https://github.com/dotnet/roslyn/issues/54547:
            // We should eventually go back to throwing here if context.Document is null.
            if (context.Document is null)
            {
                return(new LSP.SemanticTokens());
            }

            Contract.ThrowIfNull(request.TextDocument, "TextDocument is null.");
            Contract.ThrowIfNull(request.PreviousResultId, "previousResultId 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 SemanticTokensEdits
            {
                Edits    = editArray,
                ResultId = resultId
            };

            return(edits);
        }
Example #7
0
        public async Task <SumType <LSP.SemanticTokens, LSP.SemanticTokensEdits> > HandleRequestAsync(
            LSP.SemanticTokensEditsParams 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.");

            var resultId          = _tokensCache.GetNextResultId();
            var newSemanticTokens = new LSP.SemanticTokens
            {
                ResultId = resultId,
                Data     = newSemanticTokensData
            };

            await _tokensCache
            .UpdateCacheAsync(request.TextDocument.Uri, newSemanticTokens, cancellationToken)
            .ConfigureAwait(false);

            // 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)
            {
                return(newSemanticTokens);
            }

            var edits = new SemanticTokensEdits
            {
                Edits    = ComputeSemanticTokensEdits(oldSemanticTokensData, newSemanticTokensData),
                ResultId = resultId
            };

            return(edits);
        }
        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, isFinalized) = 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. Likewise, if the new
            // token set is empty, there's no need to calculate edits.
            var oldSemanticTokensData = await _tokensCache.GetCachedTokensDataAsync(
                request.TextDocument.Uri, request.PreviousResultId, cancellationToken).ConfigureAwait(false);

            if (oldSemanticTokensData == null || newSemanticTokensData.Length == 0)
            {
                var newResultId   = _tokensCache.GetNextResultId();
                var updatedTokens = new RoslynSemanticTokens
                {
                    ResultId    = newResultId,
                    Data        = newSemanticTokensData,
                    IsFinalized = isFinalized,
                };

                if (newSemanticTokensData.Length > 0)
                {
                    await _tokensCache.UpdateCacheAsync(
                        request.TextDocument.Uri, updatedTokens, cancellationToken).ConfigureAwait(false);
                }

                return(updatedTokens);
            }

            var editArray = await ComputeSemanticTokensEditsAsync(oldSemanticTokensData, newSemanticTokensData).ConfigureAwait(false);

            var resultId = request.PreviousResultId;

            // If we have edits, generate a new ResultId. Otherwise, re-use the previous one.
            if (editArray.Length != 0)
            {
                resultId = _tokensCache.GetNextResultId();
                var updatedTokens = new RoslynSemanticTokens
                {
                    ResultId    = resultId,
                    Data        = newSemanticTokensData,
                    IsFinalized = isFinalized
                };

                await _tokensCache.UpdateCacheAsync(
                    request.TextDocument.Uri, updatedTokens, cancellationToken).ConfigureAwait(false);
            }

            var edits = new RoslynSemanticTokensDelta
            {
                ResultId    = resultId,
                Edits       = editArray,
                IsFinalized = isFinalized
            };

            return(edits);
        }