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); }
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 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); }
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); }
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); }