提交 26f16e2a 编写于 作者: D David Barbet

Remove thread context variable as we cannot switch to the main thread

safely across a streamjsonrpc boundary.
上级 ce9f143c
......@@ -28,13 +28,12 @@ public CodeActionsHandler(ICodeFixService codeFixService, ICodeRefactoringServic
}
public async Task<object[]> HandleRequestAsync(Solution solution, LSP.CodeActionParams request,
LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken, bool keepThreadContext = false)
LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
{
var codeActions = await GetCodeActionsAsync(solution,
request.TextDocument.Uri,
request.Range,
keepThreadContext,
cancellationToken).ConfigureAwait(keepThreadContext);
request.TextDocument.Uri,
request.Range,
cancellationToken).ConfigureAwait(false);
// Filter out code actions with options since they'll show dialogs and we can't remote the UI and the options.
codeActions = codeActions.Where(c => !(c is CodeActionWithOptions));
......@@ -49,7 +48,7 @@ public CodeActionsHandler(ICodeFixService codeFixService, ICodeRefactoringServic
foreach (var codeAction in codeActions)
{
// If we have a codeaction with a single applychangesoperation, we want to send the codeaction with the edits.
var operations = await codeAction.GetOperationsAsync(cancellationToken).ConfigureAwait(keepThreadContext);
var operations = await codeAction.GetOperationsAsync(cancellationToken).ConfigureAwait(false);
if (clientSupportsWorkspaceEdits && operations.Length == 1 && operations.First() is ApplyChangesOperation applyChangesOperation)
{
var workspaceEdit = new LSP.WorkspaceEdit { Changes = new Dictionary<string, LSP.TextEdit[]>() };
......@@ -60,8 +59,8 @@ public CodeActionsHandler(ICodeFixService codeFixService, ICodeRefactoringServic
{
var newDoc = applyChangesOperation.ChangedSolution.GetDocument(docId);
var oldDoc = solution.GetDocument(docId);
var oldText = await oldDoc.GetTextAsync(cancellationToken).ConfigureAwait(keepThreadContext);
var textChanges = await newDoc.GetTextChangesAsync(oldDoc).ConfigureAwait(keepThreadContext);
var oldText = await oldDoc.GetTextAsync(cancellationToken).ConfigureAwait(false);
var textChanges = await newDoc.GetTextChangesAsync(oldDoc).ConfigureAwait(false);
var edits = textChanges.Select(tc => new LSP.TextEdit
{
......
......@@ -26,7 +26,7 @@ public CodeActionsHandlerBase(ICodeFixService codeFixService, ICodeRefactoringSe
_codeRefactoringService = codeRefactoringService ?? throw new ArgumentNullException(nameof(codeRefactoringService));
}
public async Task<IEnumerable<CodeAction>> GetCodeActionsAsync(Solution solution, Uri documentUri, LSP.Range selection, bool keepThreadContext, CancellationToken cancellationToken)
public async Task<IEnumerable<CodeAction>> GetCodeActionsAsync(Solution solution, Uri documentUri, LSP.Range selection, CancellationToken cancellationToken)
{
var document = solution.GetDocumentFromURI(documentUri);
if (document == null)
......@@ -34,11 +34,11 @@ public async Task<IEnumerable<CodeAction>> GetCodeActionsAsync(Solution solution
return ImmutableArray<CodeAction>.Empty;
}
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(keepThreadContext);
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
var textSpan = ProtocolConversions.RangeToTextSpan(selection, text);
var codeFixCollections = await _codeFixService.GetFixesAsync(document, textSpan, true, cancellationToken).ConfigureAwait(keepThreadContext);
var codeRefactorings = await _codeRefactoringService.GetRefactoringsAsync(document, textSpan, cancellationToken).ConfigureAwait(keepThreadContext);
var codeFixCollections = await _codeFixService.GetFixesAsync(document, textSpan, true, cancellationToken).ConfigureAwait(false);
var codeRefactorings = await _codeRefactoringService.GetRefactoringsAsync(document, textSpan, cancellationToken).ConfigureAwait(false);
var codeActions = codeFixCollections.SelectMany(c => c.Fixes.Select(f => f.Action)).Concat(
codeRefactorings.SelectMany(r => r.CodeActions.Select(ca => ca.action)));
......
......@@ -24,20 +24,19 @@ public RunCodeActionsHandler(ICodeFixService codeFixService, ICodeRefactoringSer
}
public async Task<object> HandleRequestAsync(Solution solution, LSP.ExecuteCommandParams request, LSP.ClientCapabilities clientCapabilities,
CancellationToken cancellationToken, bool keepThreadContext = false)
CancellationToken cancellationToken)
{
var runRequest = ((JToken)request.Arguments.Single()).ToObject<RunCodeActionParams>();
var codeActions = await GetCodeActionsAsync(solution,
runRequest.CodeActionParams.TextDocument.Uri,
runRequest.CodeActionParams.Range,
keepThreadContext,
cancellationToken).ConfigureAwait(keepThreadContext);
runRequest.CodeActionParams.TextDocument.Uri,
runRequest.CodeActionParams.Range,
cancellationToken).ConfigureAwait(false);
var actionToRun = codeActions?.FirstOrDefault(a => a.Title == runRequest.Title);
if (actionToRun != null)
{
foreach (var operation in await actionToRun.GetOperationsAsync(cancellationToken).ConfigureAwait(keepThreadContext))
foreach (var operation in await actionToRun.GetOperationsAsync(cancellationToken).ConfigureAwait(false))
{
operation.Apply(solution.Workspace, cancellationToken);
}
......
......@@ -40,7 +40,7 @@ public ExecuteWorkspaceCommandHandler([ImportMany] IEnumerable<Lazy<IExecuteWork
/// by delegating to a handler for the specific command requested.
/// </summary>
public Task<object> HandleRequestAsync(Solution solution, LSP.ExecuteCommandParams request, LSP.ClientCapabilities clientCapabilities,
CancellationToken cancellationToken, bool keepThreadContext = false)
CancellationToken cancellationToken)
{
var commandName = request.Command;
if (string.IsNullOrEmpty(commandName) || !_executeCommandHandlers.TryGetValue(commandName, out var executeCommandHandler))
......@@ -48,7 +48,7 @@ public ExecuteWorkspaceCommandHandler([ImportMany] IEnumerable<Lazy<IExecuteWork
throw new ArgumentException(string.Format("Command name ({0}) is invalid", commandName));
}
return executeCommandHandler.Value.HandleRequestAsync(solution, request, clientCapabilities, cancellationToken, keepThreadContext);
return executeCommandHandler.Value.HandleRequestAsync(solution, request, clientCapabilities, cancellationToken);
}
}
}
......@@ -11,6 +11,6 @@ internal interface IExecuteWorkspaceCommandHandler
/// <summary>
/// Handles a specific command from a <see cref="Methods.WorkspaceExecuteCommandName"/> request.
/// </summary>
Task<object> HandleRequestAsync(Solution solution, ExecuteCommandParams request, ClientCapabilities clientCapabilities, CancellationToken cancellationToken, bool keepThreadContext = false);
Task<object> HandleRequestAsync(Solution solution, ExecuteCommandParams request, ClientCapabilities clientCapabilities, CancellationToken cancellationToken);
}
}
......@@ -22,7 +22,7 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler
internal class CompletionHandler : IRequestHandler<LSP.CompletionParams, object>
{
public async Task<object> HandleRequestAsync(Solution solution, LSP.CompletionParams request, LSP.ClientCapabilities clientCapabilities,
CancellationToken cancellationToken, bool keepThreadContext = false)
CancellationToken cancellationToken)
{
var document = solution.GetDocumentFromURI(request.TextDocument.Uri);
if (document == null)
......@@ -30,10 +30,10 @@ internal class CompletionHandler : IRequestHandler<LSP.CompletionParams, object>
return Array.Empty<LSP.CompletionItem>();
}
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(keepThreadContext);
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false);
var completionService = document.Project.LanguageServices.GetService<CompletionService>();
var list = await completionService.GetCompletionsAsync(document, position, cancellationToken: cancellationToken).ConfigureAwait(keepThreadContext);
var list = await completionService.GetCompletionsAsync(document, position, cancellationToken: cancellationToken).ConfigureAwait(false);
if (list == null)
{
return Array.Empty<LSP.CompletionItem>();
......
......@@ -20,7 +20,7 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler
internal class CompletionResolveHandler : IRequestHandler<LSP.CompletionItem, LSP.CompletionItem>
{
public async Task<LSP.CompletionItem> HandleRequestAsync(Solution solution, LSP.CompletionItem completionItem,
LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken, bool keepThreadContext)
LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
{
CompletionResolveData data;
if (completionItem.Data is CompletionResolveData)
......@@ -40,10 +40,10 @@ internal class CompletionResolveHandler : IRequestHandler<LSP.CompletionItem, LS
return completionItem;
}
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(keepThreadContext);
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false);
var completionService = document.Project.LanguageServices.GetService<CompletionService>();
var list = await completionService.GetCompletionsAsync(document, position, cancellationToken: cancellationToken).ConfigureAwait(keepThreadContext);
var list = await completionService.GetCompletionsAsync(document, position, cancellationToken: cancellationToken).ConfigureAwait(false);
if (list == null)
{
return completionItem;
......@@ -55,7 +55,7 @@ internal class CompletionResolveHandler : IRequestHandler<LSP.CompletionItem, LS
return completionItem;
}
var description = await completionService.GetDescriptionAsync(document, selectedItem, cancellationToken).ConfigureAwait(keepThreadContext);
var description = await completionService.GetDescriptionAsync(document, selectedItem, cancellationToken).ConfigureAwait(false);
var lspVSClientCapability = clientCapabilities?.HasVisualStudioLspCapability() == true;
LSP.CompletionItem resolvedCompletionItem;
......
......@@ -18,9 +18,9 @@ public GoToDefinitionHandler(IMetadataAsSourceFileService metadataAsSourceFileSe
}
public async Task<object> HandleRequestAsync(Solution solution, LSP.TextDocumentPositionParams request,
LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken, bool keepThreadContext = true)
LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
{
return await GetDefinitionAsync(solution, request, typeOnly: false, keepThreadContext, cancellationToken).ConfigureAwait(keepThreadContext);
return await GetDefinitionAsync(solution, request, typeOnly: false, cancellationToken: cancellationToken).ConfigureAwait(false);
}
}
}
......@@ -21,7 +21,7 @@ public GoToDefinitionHandlerBase(IMetadataAsSourceFileService metadataAsSourceFi
_metadataAsSourceFileService = metadataAsSourceFileService;
}
protected async Task<LSP.Location[]> GetDefinitionAsync(Solution solution, LSP.TextDocumentPositionParams request, bool typeOnly, bool keepThreadContext, CancellationToken cancellationToken)
protected async Task<LSP.Location[]> GetDefinitionAsync(Solution solution, LSP.TextDocumentPositionParams request, bool typeOnly, CancellationToken cancellationToken)
{
var locations = ArrayBuilder<LSP.Location>.GetInstance();
......@@ -31,10 +31,10 @@ protected async Task<LSP.Location[]> GetDefinitionAsync(Solution solution, LSP.T
return locations.ToArrayAndFree();
}
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(keepThreadContext);
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false);
var definitionService = document.Project.LanguageServices.GetService<IGoToDefinitionService>();
var definitions = await definitionService.FindDefinitionsAsync(document, position, cancellationToken).ConfigureAwait(keepThreadContext);
var definitions = await definitionService.FindDefinitionsAsync(document, position, cancellationToken).ConfigureAwait(false);
if (definitions != null && definitions.Count() > 0)
{
foreach (var definition in definitions)
......@@ -44,7 +44,7 @@ protected async Task<LSP.Location[]> GetDefinitionAsync(Solution solution, LSP.T
continue;
}
var definitionText = await definition.Document.GetTextAsync(cancellationToken).ConfigureAwait(keepThreadContext);
var definitionText = await definition.Document.GetTextAsync(cancellationToken).ConfigureAwait(false);
locations.Add(new LSP.Location
{
Uri = definition.Document.GetURI(),
......@@ -55,12 +55,12 @@ protected async Task<LSP.Location[]> GetDefinitionAsync(Solution solution, LSP.T
else if (document.SupportsSemanticModel && _metadataAsSourceFileService != null)
{
// No definition found - see if we can get metadata as source but that's only applicable for C#\VB.
var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position, cancellationToken).ConfigureAwait(keepThreadContext);
var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position, cancellationToken).ConfigureAwait(false);
if (symbol != null && symbol.Locations != null && !symbol.Locations.IsEmpty && symbol.Locations.First().IsInMetadata)
{
if (!typeOnly || symbol is ITypeSymbol)
{
var declarationFile = await _metadataAsSourceFileService.GetGeneratedFileAsync(document.Project, symbol, false, cancellationToken).ConfigureAwait(keepThreadContext);
var declarationFile = await _metadataAsSourceFileService.GetGeneratedFileAsync(document.Project, symbol, false, cancellationToken).ConfigureAwait(false);
var linePosSpan = declarationFile.IdentifierLocation.GetLineSpan().Span;
locations.Add(new LSP.Location
......
......@@ -18,9 +18,9 @@ public GoToTypeDefinitionHandler(IMetadataAsSourceFileService metadataAsSourceFi
}
public async Task<LSP.Location[]> HandleRequestAsync(Solution solution, LSP.TextDocumentPositionParams request,
LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken, bool keepThreadContext)
LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
{
return await GetDefinitionAsync(solution, request, typeOnly: true, keepThreadContext, cancellationToken).ConfigureAwait(keepThreadContext);
return await GetDefinitionAsync(solution, request, typeOnly: true, cancellationToken: cancellationToken).ConfigureAwait(false);
}
}
}
......@@ -14,7 +14,7 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler
internal class FoldingRangesHandler : IRequestHandler<FoldingRangeParams, FoldingRange[]>
{
public async Task<FoldingRange[]> HandleRequestAsync(Solution solution, FoldingRangeParams request,
ClientCapabilities clientCapabilities, CancellationToken cancellationToken, bool keepThreadContext = false)
ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
{
var foldingRanges = ArrayBuilder<FoldingRange>.GetInstance();
......@@ -30,13 +30,13 @@ internal class FoldingRangesHandler : IRequestHandler<FoldingRangeParams, Foldin
return foldingRanges.ToArrayAndFree();
}
var blockStructure = await blockStructureService.GetBlockStructureAsync(document, cancellationToken).ConfigureAwait(keepThreadContext);
var blockStructure = await blockStructureService.GetBlockStructureAsync(document, cancellationToken).ConfigureAwait(false);
if (blockStructure == null)
{
return foldingRanges.ToArrayAndFree();
}
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(keepThreadContext);
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
foreach (var span in blockStructure.Spans)
{
......
......@@ -12,9 +12,9 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler
internal class FormatDocumentHandler : FormatDocumentHandlerBase, IRequestHandler<LSP.DocumentFormattingParams, LSP.TextEdit[]>
{
public async Task<LSP.TextEdit[]> HandleRequestAsync(Solution solution, LSP.DocumentFormattingParams request, LSP.ClientCapabilities clientCapabilities,
CancellationToken cancellationToken, bool keepThreadContext = false)
CancellationToken cancellationToken)
{
return await GetTextEdits(solution, request.TextDocument.Uri, keepThreadContext, cancellationToken).ConfigureAwait(keepThreadContext);
return await GetTextEdits(solution, request.TextDocument.Uri, cancellationToken).ConfigureAwait(false);
}
}
}
......@@ -15,7 +15,7 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler
{
internal class FormatDocumentHandlerBase
{
protected async Task<LSP.TextEdit[]> GetTextEdits(Solution solution, Uri documentUri, bool keepThreadContext, CancellationToken cancellationToken, LSP.Range range = null)
protected async Task<LSP.TextEdit[]> GetTextEdits(Solution solution, Uri documentUri, CancellationToken cancellationToken, LSP.Range range = null)
{
var edits = new ArrayBuilder<LSP.TextEdit>();
var document = solution.GetDocumentFromURI(documentUri);
......@@ -23,14 +23,14 @@ protected async Task<LSP.TextEdit[]> GetTextEdits(Solution solution, Uri documen
if (document != null)
{
var formattingService = document.Project.LanguageServices.GetService<IEditorFormattingService>();
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(keepThreadContext);
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
TextSpan? textSpan = null;
if (range != null)
{
textSpan = ProtocolConversions.RangeToTextSpan(range, text);
}
var textChanges = await formattingService.GetFormattingChangesAsync(document, textSpan, cancellationToken).ConfigureAwait(keepThreadContext);
var textChanges = await formattingService.GetFormattingChangesAsync(document, textSpan, cancellationToken).ConfigureAwait(false);
edits.AddRange(textChanges.Select(change => ProtocolConversions.TextChangeToTextEdit(change, text)));
}
......
......@@ -18,14 +18,14 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler
internal class FormatDocumentOnTypeHandler : IRequestHandler<DocumentOnTypeFormattingParams, TextEdit[]>
{
public async Task<TextEdit[]> HandleRequestAsync(Solution solution, DocumentOnTypeFormattingParams request, ClientCapabilities clientCapabilities,
CancellationToken cancellationToken, bool keepThreadContext = false)
CancellationToken cancellationToken)
{
var edits = new ArrayBuilder<TextEdit>();
var document = solution.GetDocumentFromURI(request.TextDocument.Uri);
if (document != null)
{
var formattingService = document.Project.LanguageServices.GetService<IEditorFormattingService>();
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(keepThreadContext);
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false);
if (string.IsNullOrEmpty(request.Character))
{
......@@ -35,14 +35,14 @@ internal class FormatDocumentOnTypeHandler : IRequestHandler<DocumentOnTypeForma
IList<TextChange> textChanges;
if (SyntaxFacts.IsNewLine(request.Character[0]))
{
textChanges = await formattingService.GetFormattingChangesOnReturnAsync(document, position, cancellationToken).ConfigureAwait(keepThreadContext);
textChanges = await formattingService.GetFormattingChangesOnReturnAsync(document, position, cancellationToken).ConfigureAwait(false);
}
else
{
textChanges = await formattingService.GetFormattingChangesAsync(document, request.Character[0], position, cancellationToken).ConfigureAwait(keepThreadContext);
textChanges = await formattingService.GetFormattingChangesAsync(document, request.Character[0], position, cancellationToken).ConfigureAwait(false);
}
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(keepThreadContext);
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
if (textChanges != null)
{
edits.AddRange(textChanges.Select(change => ProtocolConversions.TextChangeToTextEdit(change, text)));
......
......@@ -12,9 +12,9 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler
internal class FormatDocumentRangeHandler : FormatDocumentHandlerBase, IRequestHandler<DocumentRangeFormattingParams, TextEdit[]>
{
public async Task<TextEdit[]> HandleRequestAsync(Solution solution, DocumentRangeFormattingParams request, ClientCapabilities clientCapabilities,
CancellationToken cancellationToken, bool keepThreadContext = false)
CancellationToken cancellationToken)
{
return await GetTextEdits(solution, request.TextDocument.Uri, keepThreadContext, cancellationToken, range: request.Range).ConfigureAwait(keepThreadContext);
return await GetTextEdits(solution, request.TextDocument.Uri, cancellationToken, range: request.Range).ConfigureAwait(false);
}
}
}
......@@ -16,7 +16,7 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler
internal class DocumentHighlightsHandler : IRequestHandler<TextDocumentPositionParams, DocumentHighlight[]>
{
public async Task<DocumentHighlight[]> HandleRequestAsync(Solution solution, TextDocumentPositionParams request,
ClientCapabilities clientCapabilities, CancellationToken cancellationToken, bool keepThreadContext)
ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
{
var document = solution.GetDocumentFromURI(request.TextDocument.Uri);
if (document == null)
......@@ -25,19 +25,19 @@ internal class DocumentHighlightsHandler : IRequestHandler<TextDocumentPositionP
}
var documentHighlightService = document.Project.LanguageServices.GetService<IDocumentHighlightsService>();
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(keepThreadContext);
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false);
var highlights = await documentHighlightService.GetDocumentHighlightsAsync(
document,
position,
ImmutableHashSet.Create(document),
cancellationToken).ConfigureAwait(keepThreadContext);
cancellationToken).ConfigureAwait(false);
if (!highlights.IsDefaultOrEmpty)
{
// LSP requests are only for a single document. So just get the highlights for the requested document.
var highlightsForDocument = highlights.FirstOrDefault(h => h.Document.Id == document.Id);
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(keepThreadContext);
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
return highlightsForDocument.HighlightSpans.Select(h => new DocumentHighlight
{
......
......@@ -15,7 +15,7 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler
internal class HoverHandler : IRequestHandler<TextDocumentPositionParams, Hover>
{
public async Task<Hover> HandleRequestAsync(Solution solution, TextDocumentPositionParams request,
ClientCapabilities clientCapabilities, CancellationToken cancellationToken, bool keepThreadContext = false)
ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
{
var document = solution.GetDocumentFromURI(request.TextDocument.Uri);
if (document == null)
......@@ -23,16 +23,16 @@ internal class HoverHandler : IRequestHandler<TextDocumentPositionParams, Hover>
return null;
}
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(keepThreadContext);
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false);
var quickInfoService = document.Project.LanguageServices.GetService<QuickInfoService>();
var info = await quickInfoService.GetQuickInfoAsync(document, position, cancellationToken).ConfigureAwait(keepThreadContext);
var info = await quickInfoService.GetQuickInfoAsync(document, position, cancellationToken).ConfigureAwait(false);
if (info == null)
{
return null;
}
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(keepThreadContext);
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
return new Hover
{
Range = ProtocolConversions.TextSpanToRange(info.Span, text),
......
......@@ -22,8 +22,7 @@ internal interface IRequestHandler<RequestType, ResponseType> : IRequestHandler
/// <param name="request">the lsp request.</param>
/// <param name="clientCapabilities">the client capabilities for the request.</param>
/// <param name="cancellationToken">a cancellation token.</param>
/// <param name="keepThreadContext">a value to set if the threading context in the handler should be kept from the caller.</param>
/// <returns>the lps response.</returns>
Task<ResponseType> HandleRequestAsync(Solution solution, RequestType request, ClientCapabilities clientCapabilities, CancellationToken cancellationToken, bool keepThreadContext = false);
/// <returns>the LSP response.</returns>
Task<ResponseType> HandleRequestAsync(Solution solution, RequestType request, ClientCapabilities clientCapabilities, CancellationToken cancellationToken);
}
}
......@@ -33,7 +33,7 @@ internal class InitializeHandler : IRequestHandler<InitializeParams, InitializeR
}
};
public Task<InitializeResult> HandleRequestAsync(Solution solution, InitializeParams request, ClientCapabilities clientCapabilities, CancellationToken cancellationToken, bool keepThreadContext = false)
public Task<InitializeResult> HandleRequestAsync(Solution solution, InitializeParams request, ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
=> Task.FromResult(s_initializeResult);
}
}
......@@ -15,7 +15,7 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler
internal class FindImplementationsHandler : IRequestHandler<LSP.TextDocumentPositionParams, object>
{
public async Task<object> HandleRequestAsync(Solution solution, LSP.TextDocumentPositionParams request,
LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken, bool keepThreadContext = false)
LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
{
var locations = ArrayBuilder<LSP.Location>.GetInstance();
......@@ -26,11 +26,11 @@ internal class FindImplementationsHandler : IRequestHandler<LSP.TextDocumentPosi
}
var findUsagesService = document.Project.LanguageServices.GetService<IFindUsagesService>();
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(keepThreadContext);
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false);
var context = new SimpleFindUsagesContext(cancellationToken);
await findUsagesService.FindImplementationsAsync(document, position, context).ConfigureAwait(keepThreadContext);
await findUsagesService.FindImplementationsAsync(document, position, context).ConfigureAwait(false);
foreach (var definition in context.GetDefinitions())
{
......@@ -39,11 +39,11 @@ internal class FindImplementationsHandler : IRequestHandler<LSP.TextDocumentPosi
{
if (clientCapabilities?.HasVisualStudioLspCapability() == true)
{
locations.Add(await ProtocolConversions.DocumentSpanToLocationWithTextAsync(sourceSpan, text, cancellationToken).ConfigureAwait(keepThreadContext));
locations.Add(await ProtocolConversions.DocumentSpanToLocationWithTextAsync(sourceSpan, text, cancellationToken).ConfigureAwait(false));
}
else
{
locations.Add(await ProtocolConversions.DocumentSpanToLocationAsync(sourceSpan, cancellationToken).ConfigureAwait(keepThreadContext));
locations.Add(await ProtocolConversions.DocumentSpanToLocationAsync(sourceSpan, cancellationToken).ConfigureAwait(false));
}
}
}
......
......@@ -27,9 +27,8 @@ internal class FindAllReferencesHandler : IRequestHandler<LSP.ReferenceParams, o
/// <param name="request"></param>
/// <param name="clientCapabilities"></param>
/// <param name="cancellationToken"></param>
/// <param name="keepThreadContext"></param>
/// <returns></returns>
public async Task<object[]> HandleRequestAsync(Solution solution, LSP.ReferenceParams request, LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken, bool keepThreadContext = true)
public async Task<object[]> HandleRequestAsync(Solution solution, LSP.ReferenceParams request, LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
{
var locations = ArrayBuilder<LSP.Location>.GetInstance();
var document = solution.GetDocumentFromURI(request.TextDocument.Uri);
......@@ -39,19 +38,19 @@ public async Task<object[]> HandleRequestAsync(Solution solution, LSP.ReferenceP
}
var findUsagesService = document.Project.LanguageServices.GetService<IFindUsagesService>();
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(keepThreadContext);
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false);
var context = new SimpleFindUsagesContext(cancellationToken);
await findUsagesService.FindReferencesAsync(document, position, context).ConfigureAwait(keepThreadContext);
await findUsagesService.FindReferencesAsync(document, position, context).ConfigureAwait(false);
if (clientCapabilities.HasVisualStudioLspCapability())
{
return await GetReferenceGroupsAsync(request, context, cancellationToken).ConfigureAwait(keepThreadContext);
return await GetReferenceGroupsAsync(request, context, cancellationToken).ConfigureAwait(false);
}
else
{
return await GetLocationsAsync(request, context, cancellationToken).ConfigureAwait(keepThreadContext);
return await GetLocationsAsync(request, context, cancellationToken).ConfigureAwait(false);
}
}
......
......@@ -28,7 +28,7 @@ public SignatureHelpHandler([ImportMany] IEnumerable<Lazy<ISignatureHelpProvider
}
public async Task<LSP.SignatureHelp> HandleRequestAsync(Solution solution, LSP.TextDocumentPositionParams request,
LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken, bool keepThreadContext = false)
LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
{
var document = solution.GetDocumentFromURI(request.TextDocument.Uri);
if (document == null)
......@@ -36,14 +36,14 @@ public SignatureHelpHandler([ImportMany] IEnumerable<Lazy<ISignatureHelpProvider
return new LSP.SignatureHelp();
}
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(keepThreadContext);
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false);
var providers = _allProviders.Where(p => p.Metadata.Language == document.Project.Language);
var triggerInfo = new SignatureHelpTriggerInfo(SignatureHelpTriggerReason.InvokeSignatureHelpCommand);
foreach (var provider in providers)
{
var items = await provider.Value.GetItemsAsync(document, position, triggerInfo, cancellationToken).ConfigureAwait(keepThreadContext);
var items = await provider.Value.GetItemsAsync(document, position, triggerInfo, cancellationToken).ConfigureAwait(false);
if (items != null)
{
......
......@@ -21,7 +21,7 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler
internal class DocumentSymbolsHandler : IRequestHandler<DocumentSymbolParams, object[]>
{
public async Task<object[]> HandleRequestAsync(Solution solution, DocumentSymbolParams request,
ClientCapabilities clientCapabilities, CancellationToken cancellationToken, bool keepThreadContext = false)
ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
{
var document = solution.GetDocumentFromURI(request.TextDocument.Uri);
if (document == null)
......@@ -32,15 +32,15 @@ internal class DocumentSymbolsHandler : IRequestHandler<DocumentSymbolParams, ob
var symbols = ArrayBuilder<object>.GetInstance();
var navBarService = document.Project.LanguageServices.GetService<INavigationBarItemService>();
var navBarItems = await navBarService.GetItemsAsync(document, cancellationToken).ConfigureAwait(keepThreadContext);
var navBarItems = await navBarService.GetItemsAsync(document, cancellationToken).ConfigureAwait(false);
if (navBarItems.Count == 0)
{
return symbols.ToArrayAndFree();
}
var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(keepThreadContext);
var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(keepThreadContext);
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(keepThreadContext);
var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
// TODO - Return more than 2 levels of symbols.
// https://github.com/dotnet/roslyn/projects/45#card-20033869
......@@ -49,7 +49,7 @@ internal class DocumentSymbolsHandler : IRequestHandler<DocumentSymbolParams, ob
foreach (var item in navBarItems)
{
// only top level ones
symbols.Add(await GetDocumentSymbolAsync(item, compilation, tree, text, keepThreadContext, cancellationToken).ConfigureAwait(keepThreadContext));
symbols.Add(await GetDocumentSymbolAsync(item, compilation, tree, text, cancellationToken).ConfigureAwait(false));
}
}
else
......@@ -110,7 +110,7 @@ static SymbolInformation Create(NavigationBarItem item, TextSpan span, string co
/// Get a document symbol from a specified nav bar item.
/// </summary>
private static async Task<DocumentSymbol> GetDocumentSymbolAsync(NavigationBarItem item, Compilation compilation, SyntaxTree tree,
SourceText text, bool keepThreadContext, CancellationToken cancellationToken)
SourceText text, CancellationToken cancellationToken)
{
// it is actually symbol location getter. but anyway.
var location = GetLocation(item, compilation, tree, cancellationToken);
......@@ -119,7 +119,7 @@ static SymbolInformation Create(NavigationBarItem item, TextSpan span, string co
return null;
}
var symbol = await GetSymbolAsync(location, compilation, keepThreadContext, cancellationToken).ConfigureAwait(keepThreadContext);
var symbol = await GetSymbolAsync(location, compilation, cancellationToken).ConfigureAwait(false);
if (symbol == null)
{
return null;
......@@ -133,25 +133,25 @@ static SymbolInformation Create(NavigationBarItem item, TextSpan span, string co
Deprecated = symbol.GetAttributes().Any(x => x.AttributeClass.MetadataName == "ObsoleteAttribute"),
Range = ProtocolConversions.TextSpanToRange(item.Spans.First(), text),
SelectionRange = ProtocolConversions.TextSpanToRange(location.SourceSpan, text),
Children = await GetChildrenAsync(item.ChildItems, compilation, tree, text, keepThreadContext, cancellationToken).ConfigureAwait(keepThreadContext),
Children = await GetChildrenAsync(item.ChildItems, compilation, tree, text, cancellationToken).ConfigureAwait(false),
};
static async Task<DocumentSymbol[]> GetChildrenAsync(IEnumerable<NavigationBarItem> items, Compilation compilation, SyntaxTree tree,
SourceText text, bool keepThreadContext, CancellationToken cancellationToken)
SourceText text, CancellationToken cancellationToken)
{
var list = new ArrayBuilder<DocumentSymbol>();
foreach (var item in items)
{
list.Add(await GetDocumentSymbolAsync(item, compilation, tree, text, keepThreadContext, cancellationToken).ConfigureAwait(keepThreadContext));
list.Add(await GetDocumentSymbolAsync(item, compilation, tree, text, cancellationToken).ConfigureAwait(false));
}
return list.ToArrayAndFree();
}
static async Task<ISymbol> GetSymbolAsync(Location location, Compilation compilation, bool keepThreadContext, CancellationToken cancellationToken)
static async Task<ISymbol> GetSymbolAsync(Location location, Compilation compilation, CancellationToken cancellationToken)
{
var model = compilation.GetSemanticModel(location.SourceTree);
var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(keepThreadContext);
var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
var node = root.FindNode(location.SourceSpan);
while (node != null)
......
......@@ -15,13 +15,13 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler
internal class WorkspaceSymbolsHandler : IRequestHandler<WorkspaceSymbolParams, SymbolInformation[]>
{
public async Task<SymbolInformation[]> HandleRequestAsync(Solution solution, WorkspaceSymbolParams request,
ClientCapabilities clientCapabilities, CancellationToken cancellationToken, bool keepThreadContext = false)
ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
{
var searchTasks = Task.WhenAll(solution.Projects.Select(project => SearchProjectAsync(project, request, keepThreadContext, cancellationToken)));
return (await searchTasks.ConfigureAwait(keepThreadContext)).SelectMany(s => s).ToArray();
var searchTasks = Task.WhenAll(solution.Projects.Select(project => SearchProjectAsync(project, request, cancellationToken)));
return (await searchTasks.ConfigureAwait(false)).SelectMany(s => s).ToArray();
// local functions
static async Task<ImmutableArray<SymbolInformation>> SearchProjectAsync(Project project, WorkspaceSymbolParams request, bool keepThreadContext, CancellationToken cancellationToken)
static async Task<ImmutableArray<SymbolInformation>> SearchProjectAsync(Project project, WorkspaceSymbolParams request, CancellationToken cancellationToken)
{
var searchService = project.LanguageServices.GetService<INavigateToSearchService_RemoveInterfaceAboveAndRenameThisAfterInternalsVisibleToUsersUpdate>();
if (searchService != null)
......@@ -33,20 +33,20 @@ static async Task<ImmutableArray<SymbolInformation>> SearchProjectAsync(Project
ImmutableArray<Document>.Empty,
request.Query,
searchService.KindsProvided,
cancellationToken).ConfigureAwait(keepThreadContext);
var projectSymbolsTasks = Task.WhenAll(items.Select(item => CreateSymbolInformation(item, keepThreadContext, cancellationToken)));
return (await projectSymbolsTasks.ConfigureAwait(keepThreadContext)).ToImmutableArray();
cancellationToken).ConfigureAwait(false);
var projectSymbolsTasks = Task.WhenAll(items.Select(item => CreateSymbolInformation(item, cancellationToken)));
return (await projectSymbolsTasks.ConfigureAwait(false)).ToImmutableArray();
}
return ImmutableArray.Create<SymbolInformation>();
static async Task<SymbolInformation> CreateSymbolInformation(INavigateToSearchResult result, bool keepThreadContext, CancellationToken cancellationToken)
static async Task<SymbolInformation> CreateSymbolInformation(INavigateToSearchResult result, CancellationToken cancellationToken)
{
return new SymbolInformation
{
Name = result.Name,
Kind = ProtocolConversions.NavigateToKindToSymbolKind(result.Kind),
Location = await ProtocolConversions.TextSpanToLocationAsync(result.NavigableItem.Document, result.NavigableItem.SourceSpan, cancellationToken).ConfigureAwait(keepThreadContext),
Location = await ProtocolConversions.TextSpanToLocationAsync(result.NavigableItem.Document, result.NavigableItem.SourceSpan, cancellationToken).ConfigureAwait(false),
};
}
}
......
......@@ -4,8 +4,10 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.LanguageServer.Handler;
using Roslyn.Utilities;
using LSP = Microsoft.VisualStudio.LanguageServer.Protocol;
......@@ -20,12 +22,14 @@ namespace Microsoft.CodeAnalysis.LanguageServer
[Export(typeof(LanguageServerProtocol))]
internal sealed class LanguageServerProtocol
{
private readonly IThreadingContext _threadingContext;
private readonly ImmutableDictionary<string, Lazy<IRequestHandler, IRequestHandlerMetadata>> _requestHandlers;
[ImportingConstructor]
public LanguageServerProtocol([ImportMany] IEnumerable<Lazy<IRequestHandler, IRequestHandlerMetadata>> requestHandlers)
public LanguageServerProtocol([ImportMany] IEnumerable<Lazy<IRequestHandler, IRequestHandlerMetadata>> requestHandlers, IThreadingContext threadingContext)
{
_requestHandlers = CreateMethodToHandlerMap(requestHandlers);
_threadingContext = threadingContext;
}
private static ImmutableDictionary<string, Lazy<IRequestHandler, IRequestHandlerMetadata>> CreateMethodToHandlerMap(IEnumerable<Lazy<IRequestHandler, IRequestHandlerMetadata>> requestHandlers)
......@@ -52,7 +56,7 @@ public LanguageServerProtocol([ImportMany] IEnumerable<Lazy<IRequestHandler, IRe
var handler = (IRequestHandler<RequestType, ResponseType>)_requestHandlers[methodName]?.Value;
Contract.ThrowIfNull(handler, string.Format("Request handler not found for method {0}", methodName));
return handler.HandleRequestAsync(solution, request, clientCapabilities, cancellationToken);
return handler.HandleRequestAsync(solution, request, clientCapabilities, cancellationToken: cancellationToken);
}
/// <summary>
......
......@@ -85,15 +85,10 @@ public void Exit()
{
}
/// <summary>
/// Go to definition calls to get third party definitions (xaml) and to get those definitions it expectes to be called on the UI thread.
/// <see cref="VisualStudioSymbolNavigationService.WouldNotifyToSpecificSymbol"/>
/// </summary>
[JsonRpcMethod(Methods.TextDocumentDefinitionName)]
public async Task<object> GetTextDocumentDefinitionAsync(JToken input, CancellationToken cancellationToken)
{
var textDocumentPositionParams = input.ToObject<TextDocumentPositionParams>();
await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
return await this._protocol.GoToDefinitionAsync(_workspace.CurrentSolution, textDocumentPositionParams, _clientCapabilities, cancellationToken).ConfigureAwait(false);
}
......
......@@ -28,10 +28,9 @@ public async Task<LSP.TextEdit[]> HandleAsync(RunCodeActionParams request, Reque
var edits = ArrayBuilder<LSP.TextEdit>.GetInstance();
var solution = requestContext.Context;
var codeActions = await GetCodeActionsAsync(solution,
request.CodeActionParams.TextDocument.Uri,
request.CodeActionParams.Range,
keepThreadContext: false,
cancellationToken).ConfigureAwait(false);
request.CodeActionParams.TextDocument.Uri,
request.CodeActionParams.Range,
cancellationToken).ConfigureAwait(false);
var actionToRun = codeActions?.FirstOrDefault(a => a.Title == request.Title);
......
......@@ -27,7 +27,7 @@ public AbstractLiveShareHandlerShim(IEnumerable<Lazy<IRequestHandler, IRequestHa
public virtual Task<ResponseType> HandleAsync(RequestType param, RequestContext<Solution> requestContext, CancellationToken cancellationToken)
{
return ((IRequestHandler<RequestType, ResponseType>)LazyRequestHandler.Value).HandleRequestAsync(requestContext.Context, param, requestContext.ClientCapabilities?.ToObject<VSClientCapabilities>(), cancellationToken);
return ((IRequestHandler<RequestType, ResponseType>)LazyRequestHandler.Value).HandleRequestAsync(requestContext.Context, param, requestContext.ClientCapabilities?.ToObject<VSClientCapabilities>(), cancellationToken: cancellationToken);
}
protected Lazy<IRequestHandler, IRequestHandlerMetadata> GetRequestHandler(IEnumerable<Lazy<IRequestHandler, IRequestHandlerMetadata>> requestHandlers, string methodName)
......@@ -57,7 +57,7 @@ public override async Task<ResponseType> HandleAsync(RequestType param, RequestC
/// </summary>
private Task<ResponseType> HandleAsyncPreserveThreadContext(RequestType param, RequestContext<Solution> requestContext, CancellationToken cancellationToken)
{
return ((IRequestHandler<RequestType, ResponseType>)LazyRequestHandler.Value).HandleRequestAsync(requestContext.Context, param, requestContext.ClientCapabilities?.ToObject<ClientCapabilities>(), cancellationToken, keepThreadContext: true);
return ((IRequestHandler<RequestType, ResponseType>)LazyRequestHandler.Value).HandleRequestAsync(requestContext.Context, param, requestContext.ClientCapabilities?.ToObject<ClientCapabilities>(), cancellationToken: cancellationToken);
}
}
}
......@@ -31,7 +31,7 @@ public override async Task<SymbolInformation[]> HandleAsync(DocumentSymbolParams
}
var handler = (IRequestHandler<DocumentSymbolParams, object[]>)LazyRequestHandler.Value;
var response = await handler.HandleRequestAsync(requestContext.Context, param, clientCapabilities, cancellationToken).ConfigureAwait(false);
var response = await handler.HandleRequestAsync(requestContext.Context, param, clientCapabilities, cancellationToken: cancellationToken).ConfigureAwait(false);
// Since hierarchicalSupport will never be true, it is safe to cast the response to SymbolInformation[]
return response?.Select(obj => (SymbolInformation)obj).ToArray();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册