private async Task<DiagnosticAnalysisResultMap<DiagnosticAnalyzer, DiagnosticAnalysisResult>> AnalyzeOutOfProcAsync( RemoteHostClient client, CompilationWithAnalyzers analyzerDriver, Project project, CancellationToken cancellationToken) { var solution = project.Solution; var snapshotService = solution.Workspace.Services.GetService<ISolutionChecksumService>(); // TODO: this should be moved out var hostChecksums = GetHostAnalyzerReferences(snapshotService, _analyzerService.GetHostAnalyzerReferences(), cancellationToken); var analyzerMap = CreateAnalyzerMap(analyzerDriver.Analyzers.Where(a => !a.MustRunInProcess())); if (analyzerMap.Count == 0) { return DiagnosticAnalysisResultMap.Create(ImmutableDictionary<DiagnosticAnalyzer, DiagnosticAnalysisResult>.Empty, ImmutableDictionary<DiagnosticAnalyzer, AnalyzerTelemetryInfo>.Empty); } // TODO: send telemetry on session using (var session = await client.CreateCodeAnalysisServiceSessionAsync(solution, cancellationToken).ConfigureAwait(false)) { var argument = new DiagnosticArguments( analyzerDriver.AnalysisOptions.ReportSuppressedDiagnostics, analyzerDriver.AnalysisOptions.LogAnalyzerExecutionTime, project.Id, hostChecksums, analyzerMap.Keys.ToArray()); var result = await session.InvokeAsync( WellKnownServiceHubServices.CodeAnalysisService_CalculateDiagnosticsAsync, new object[] { argument }, (s, c) => GetCompilerAnalysisResultAsync(s, analyzerMap, project, c)).ConfigureAwait(false); ReportAnalyzerExceptions(project, result.Exceptions); return result; } }
private static void RegisterWorkspaceHost(Workspace workspace, RemoteHostClient client) { var vsWorkspace = workspace as VisualStudioWorkspaceImpl; if (vsWorkspace == null) { return; } vsWorkspace.ProjectTracker.RegisterWorkspaceHost( new WorkspaceHost(vsWorkspace, client)); }
private async Task <KeepAliveSession> TryGetKeepAliveSessionAsync(RemoteHostClient client, CancellationToken cancellationToken) { using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { if (_sessionDoNotAccessDirectly == null) { _sessionDoNotAccessDirectly = await client.TryCreateCodeAnalysisKeepAliveSessionAsync(cancellationToken).ConfigureAwait(false); } return(_sessionDoNotAccessDirectly); } }
public WorkspaceHost( VisualStudioWorkspaceImpl workspace, RemoteHostClient client) { _workspace = workspace; _client = client; _currentSolutionId = workspace.CurrentSolution.Id; // Ensure that we populate the remote service with the initial state of // the workspace's solution. RegisterPrimarySolutionAsync().Wait(); }
private async Task <IList <TodoComment> > GetTodoCommentsInRemoteHostAsync( RemoteHostClient client, Document document, ImmutableArray <TodoCommentDescriptor> commentDescriptors, CancellationToken cancellationToken) { var keepAliveSession = await TryGetKeepAliveSessionAsync(client, cancellationToken).ConfigureAwait(false); var result = await keepAliveSession.TryInvokeAsync <IList <TodoComment> >( nameof(IRemoteTodoCommentService.GetTodoCommentsAsync), document.Project.Solution, new object[] { document.Id, commentDescriptors }, cancellationToken).ConfigureAwait(false); return(result ?? SpecializedCollections.EmptyList <TodoComment>()); }
> AnalyzeAsync( DocumentAnalysisScope?documentAnalysisScope, Project project, CompilationWithAnalyzers compilationWithAnalyzers, bool forceExecuteAllAnalyzers, bool logPerformanceInfo, bool getTelemetryInfo, CancellationToken cancellationToken ) { var result = await AnalyzeCoreAsync().ConfigureAwait(false); Debug.Assert(getTelemetryInfo || result.TelemetryInfo.IsEmpty); return(result); async Task < DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > AnalyzeCoreAsync() { Contract.ThrowIfFalse(!compilationWithAnalyzers.Analyzers.IsEmpty); var remoteHostClient = await RemoteHostClient .TryGetClientAsync(project, cancellationToken) .ConfigureAwait(false); if (remoteHostClient != null) { return(await AnalyzeOutOfProcAsync( documentAnalysisScope, project, compilationWithAnalyzers, remoteHostClient, forceExecuteAllAnalyzers, logPerformanceInfo, getTelemetryInfo, cancellationToken ) .ConfigureAwait(false)); } return(await AnalyzeInProcAsync( documentAnalysisScope, project, compilationWithAnalyzers, client : null, logPerformanceInfo, getTelemetryInfo, cancellationToken ) .ConfigureAwait(false)); } }
public RemoteUpdateEngine( Workspace workspace, RemoteHostClient client, ISymbolSearchLogService logService, CancellationToken cancellationToken) { _workspace = workspace; _logService = logService; _cancellationToken = cancellationToken; // this engine is stateful service which maintaining a connection to remote host. so // this feature is required to handle remote host recycle situation. _client = client; _client.ConnectionChanged += OnConnectionChanged; }
public async Task <ImmutableArray <ClassifiedSpan> > GetCachedSemanticClassificationsAsync( Document document, TextSpan textSpan, CancellationToken cancellationToken) { var client = await RemoteHostClient.TryGetClientAsync(document.Project.Solution.Workspace, cancellationToken).ConfigureAwait(false); if (client == null) { // We don't do anything if we fail to get the external process. That's the case when something has gone // wrong, or the user is explicitly choosing to run inproc only. In neither of those cases do we want // to bog down the VS process with the work to semantically classify files. return(default);
internal static async Task <ConflictResolution> RenameSymbolAsync( Solution solution, ISymbol symbol, string newName, RenameOptionSet optionSet, ImmutableHashSet <ISymbol>?nonConflictSymbols, CancellationToken cancellationToken) { Contract.ThrowIfNull(solution); Contract.ThrowIfNull(symbol); Contract.ThrowIfTrue(string.IsNullOrEmpty(newName)); cancellationToken.ThrowIfCancellationRequested(); using (Logger.LogBlock(FunctionId.Renamer_RenameSymbolAsync, cancellationToken)) { if (SerializableSymbolAndProjectId.TryCreate(symbol, solution, cancellationToken, out var serializedSymbol)) { var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false); if (client != null) { var options = SerializableRenameOptionSet.Dehydrate(optionSet); var nonConflictSymbolIds = nonConflictSymbols?.SelectAsArray(s => SerializableSymbolAndProjectId.Dehydrate(solution, s, cancellationToken)) ?? default; var result = await client.TryInvokeAsync <IRemoteRenamerService, SerializableConflictResolution?>( solution, (service, solutionInfo, cancellationToken) => service.RenameSymbolAsync( solutionInfo, serializedSymbol, newName, options, nonConflictSymbolIds, cancellationToken), callbackTarget : null, cancellationToken).ConfigureAwait(false); if (result.HasValue && result.Value != null) { return(await result.Value.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false)); } // TODO: do not fall back to in-proc if client is available (https://github.com/dotnet/roslyn/issues/47557) } } } return(await RenameSymbolInCurrentProcessAsync( solution, symbol, newName, optionSet, nonConflictSymbols, cancellationToken).ConfigureAwait(false)); }
private static async Task SearchFullyLoadedProjectAsync( Project project, ImmutableArray <Document> priorityDocuments, string searchPattern, IImmutableSet <string> kinds, Func <INavigateToSearchResult, Task> onResultFound, CancellationToken cancellationToken ) { var solution = project.Solution; var client = await RemoteHostClient .TryGetClientAsync(project, cancellationToken) .ConfigureAwait(false); var onItemFound = GetOnItemFoundCallback(solution, onResultFound, cancellationToken); if (client != null) { var priorityDocumentIds = priorityDocuments.SelectAsArray(d => d.Id); var callback = new NavigateToSearchServiceCallback(onItemFound); await client .TryInvokeAsync <IRemoteNavigateToSearchService>( solution, (service, solutionInfo, callbackId, cancellationToken) => service.SearchFullyLoadedProjectAsync( solutionInfo, project.Id, priorityDocumentIds, searchPattern, kinds.ToImmutableArray(), callbackId, cancellationToken ), callback, cancellationToken ) .ConfigureAwait(false); return; } await SearchFullyLoadedProjectInCurrentProcessAsync( project, priorityDocuments, searchPattern, kinds, onItemFound, cancellationToken ) .ConfigureAwait(false); }
private async Task <KeepAliveSession> TryGetKeepAliveSessionAsync(RemoteHostClient client, CancellationToken cancellation) { using (await _gate.DisposableWaitAsync(cancellation).ConfigureAwait(false)) { if (_sessionDoNotAccessDirectly == null) { // we give cancellation none here since the cancellation will cause KeepAlive session to be shutdown // when raised _sessionDoNotAccessDirectly = await client.TryCreateCodeAnalysisKeepAliveSessionAsync(CancellationToken.None).ConfigureAwait(false); } return(_sessionDoNotAccessDirectly); } }
public async Task <Solution> EncapsulateFieldsAsync( Document document, ImmutableArray <IFieldSymbol> fields, bool updateReferences, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using (Logger.LogBlock(FunctionId.Renamer_FindRenameLocationsAsync, cancellationToken)) { var solution = document.Project.Solution; var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false); if (client != null) { var result = await client.TryRunRemoteAsync <(DocumentId, TextChange[])[]>(
public async Task <ReferenceCount?> GetReferenceCountAsync( Solution solution, DocumentId documentId, SyntaxNode?syntaxNode, int maxSearchResults, CancellationToken cancellationToken ) { using (Logger.LogBlock(FunctionId.CodeLens_GetReferenceCountAsync, cancellationToken)) { if (syntaxNode == null) { return(null); } var client = await RemoteHostClient .TryGetClientAsync(solution.Workspace, cancellationToken) .ConfigureAwait(false); if (client != null) { var result = await client .TryInvokeAsync <IRemoteCodeLensReferencesService, ReferenceCount?>( solution, (service, solutionInfo, cancellationToken) => service.GetReferenceCountAsync( solutionInfo, documentId, syntaxNode.Span, maxSearchResults, cancellationToken ), cancellationToken ) .ConfigureAwait(false); return(result.HasValue ? result.Value : null); } return(await CodeLensReferencesServiceFactory.Instance .GetReferenceCountAsync( solution, documentId, syntaxNode, maxSearchResults, cancellationToken ) .ConfigureAwait(false)); } }
public async ValueTask DiscardSolutionUpdateAsync(CancellationToken cancellationToken) { var client = await RemoteHostClient.TryGetClientAsync(_workspace, cancellationToken).ConfigureAwait(false); if (client == null) { GetLocalService().DiscardSolutionUpdate(_sessionId); return; } await client.TryInvokeAsync <IRemoteEditAndContinueService>( (service, cancellationToken) => service.DiscardSolutionUpdateAsync(_sessionId, cancellationToken), cancellationToken).ConfigureAwait(false); }
public async Task TestDuplicatedAnalyzers() { var code = @"class Test { void Method() { var t = new Test(); } }"; using (var workspace = CreateWorkspace(LanguageNames.CSharp, code)) { var analyzerType = typeof(DuplicateAnalyzer); var analyzerReference = new AnalyzerFileReference(analyzerType.Assembly.Location, new TestAnalyzerAssemblyLoader()); // add host analyzer as global assets var snapshotService = workspace.Services.GetService <IRemotableDataService>(); var assetBuilder = new CustomAssetBuilder(workspace); var asset = assetBuilder.Build(analyzerReference, CancellationToken.None); snapshotService.AddGlobalAsset(analyzerReference, asset, CancellationToken.None); var client = await RemoteHostClient.TryGetClientAsync(workspace, CancellationToken.None).ConfigureAwait(false); Assert.True(await client.TryRunRemoteAsync( WellKnownRemoteHostServices.RemoteHostService, nameof(IRemoteHostService.SynchronizeGlobalAssetsAsync), new[] { new Checksum[] { asset.Checksum } }, workspace.CurrentSolution, callbackTarget: null, cancellationToken: CancellationToken.None)); // run analysis var project = workspace.CurrentSolution.Projects.First().AddAnalyzerReference(analyzerReference); var executor = new DiagnosticIncrementalAnalyzer.InProcOrRemoteHostAnalyzerRunner(owner: null, hostDiagnosticUpdateSource: new MyUpdateSource(workspace)); var analyzerDriver = (await project.GetCompilationAsync()).WithAnalyzers( analyzerReference.GetAnalyzers(project.Language).Where(a => a.GetType() == analyzerType).ToImmutableArray(), new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project.Solution)); var result = await executor.AnalyzeAsync(analyzerDriver, project, forcedAnalysis : false, cancellationToken : CancellationToken.None); var analyzerResult = result.AnalysisResult[analyzerDriver.Analyzers[0]]; // check result var diagnostics = analyzerResult.GetDocumentDiagnostics(analyzerResult.DocumentIds.First(), AnalysisKind.Syntax); Assert.Equal("test", diagnostics[0].Id); } }
private async Task <DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> > AnalyzeOutOfProcAsync( DocumentAnalysisScope?documentAnalysisScope, Project project, CompilationWithAnalyzers compilationWithAnalyzers, RemoteHostClient client, bool forceExecuteAllAnalyzers, bool logPerformanceInfo, bool getTelemetryInfo, CancellationToken cancellationToken) { var solution = project.Solution; using var pooledObject = SharedPools.Default <Dictionary <string, DiagnosticAnalyzer> >().GetPooledObject(); var analyzerMap = pooledObject.Object; var analyzers = documentAnalysisScope?.Analyzers ?? compilationWithAnalyzers.Analyzers.Where(a => forceExecuteAllAnalyzers || !a.IsOpenFileOnly(solution.Options)); analyzerMap.AppendAnalyzerMap(analyzers); if (analyzerMap.Count == 0) { return(DiagnosticAnalysisResultMap <DiagnosticAnalyzer, DiagnosticAnalysisResult> .Empty); } // Use high priority if we are force executing all analyzers for user action OR serving an active document request. var isHighPriority = forceExecuteAllAnalyzers || documentAnalysisScope != null && _documentTrackingService?.TryGetActiveDocument() == documentAnalysisScope.TextDocument.Id; var argument = new DiagnosticArguments( isHighPriority, compilationWithAnalyzers.AnalysisOptions.ReportSuppressedDiagnostics, logPerformanceInfo, getTelemetryInfo, documentAnalysisScope?.TextDocument.Id, documentAnalysisScope?.Span, documentAnalysisScope?.Kind, project.Id, analyzerMap.Keys.ToArray()); return(await client.RunRemoteAsync( WellKnownServiceHubService.CodeAnalysis, nameof(IRemoteDiagnosticAnalyzerService.CalculateDiagnosticsAsync), solution, new object[] { argument }, callbackTarget : null, (s, c) => ReadCompilerAnalysisResultAsync(s, analyzerMap, documentAnalysisScope, project, c), cancellationToken).ConfigureAwait(false)); }
internal static async Task FindLiteralReferencesAsync( object value, TypeCode typeCode, Solution solution, IStreamingFindLiteralReferencesProgress progress, CancellationToken cancellationToken ) { using (Logger.LogBlock(FunctionId.FindReference, cancellationToken)) { var client = await RemoteHostClient .TryGetClientAsync(solution.Workspace, cancellationToken) .ConfigureAwait(false); if (client != null) { // Create a callback that we can pass to the server process to hear about the // results as it finds them. When we hear about results we'll forward them to // the 'progress' parameter which will then update the UI. var serverCallback = new FindLiteralsServerCallback(solution, progress); _ = await client .TryInvokeAsync <IRemoteSymbolFinderService>( solution, (service, solutionInfo, callbackId, cancellationToken) => service.FindLiteralReferencesAsync( solutionInfo, callbackId, value, typeCode, cancellationToken ), serverCallback, cancellationToken ) .ConfigureAwait(false); } else { await FindLiteralReferencesInCurrentProcessAsync( value, solution, progress, cancellationToken ) .ConfigureAwait(false); } } }
public async Task AddSemanticClassificationsAsync(Document document, TextSpan textSpan, List <ClassifiedSpan> result, CancellationToken cancellationToken) { var classificationService = document.GetLanguageService <ISyntaxClassificationService>(); if (classificationService == null) { // When renaming a file's extension through VS when it's opened in editor, // the content type might change and the content type changed event can be // raised before the renaming propagate through VS workspace. As a result, // the document we got (based on the buffer) could still be the one in the workspace // before rename happened. This would cause us problem if the document is supported // by workspace but not a roslyn language (e.g. xaml, F#, etc.), since none of the roslyn // language services would be available. // // If this is the case, we will simply bail out. It's OK to ignore the request // because when the buffer eventually get associated with the correct document in roslyn // workspace, we will be invoked again. // // For example, if you open a xaml from from a WPF project in designer view, // and then rename file extension from .xaml to .cs, then the document we received // here would still belong to the special "-xaml" project. return; } var client = await RemoteHostClient.TryGetClientAsync(document.Project, cancellationToken).ConfigureAwait(false); if (client != null) { var classifiedSpans = await client.TryInvokeAsync <IRemoteSemanticClassificationService, SerializableClassifiedSpans>( document.Project.Solution, (service, solutionInfo, cancellationToken) => service.GetSemanticClassificationsAsync(solutionInfo, document.Id, textSpan, cancellationToken), callbackTarget : null, cancellationToken).ConfigureAwait(false); // if the remote call fails do nothing (error has already been reported) if (classifiedSpans.HasValue) { classifiedSpans.Value.Rehydrate(result); } } else { using var _ = ArrayBuilder <ClassifiedSpan> .GetInstance(out var temp); await AddSemanticClassificationsInCurrentProcessAsync( document, textSpan, temp, cancellationToken).ConfigureAwait(false); AddRange(temp, result); } }
public async Task <ImmutableArray <DocumentHighlights> > GetDocumentHighlightsAsync( Document document, int position, IImmutableSet <Document> documentsToSearch, CancellationToken cancellationToken ) { var solution = document.Project.Solution; var client = await RemoteHostClient .TryGetClientAsync(document.Project, cancellationToken) .ConfigureAwait(false); if (client != null) { var result = await client .TryInvokeAsync < IRemoteDocumentHighlightsService, ImmutableArray <SerializableDocumentHighlights> >( solution, (service, solutionInfo, cancellationToken) => service.GetDocumentHighlightsAsync( solutionInfo, document.Id, position, documentsToSearch.SelectAsArray(d => d.Id), cancellationToken ), cancellationToken ) .ConfigureAwait(false); if (!result.HasValue) { return(ImmutableArray <DocumentHighlights> .Empty); } return(result.Value.SelectAsArray(h => h.Rehydrate(solution))); } return(await GetDocumentHighlightsInCurrentProcessAsync( document, position, documentsToSearch, cancellationToken ) .ConfigureAwait(false)); }
internal static async Task <ConflictResolution> RenameSymbolAsync( Solution solution, ISymbol symbol, string newName, RenameOptionSet optionSet, ImmutableHashSet <ISymbol> nonConflictSymbols, CancellationToken cancellationToken) { Contract.ThrowIfNull(solution); Contract.ThrowIfNull(symbol); Contract.ThrowIfTrue(string.IsNullOrEmpty(newName)); cancellationToken.ThrowIfCancellationRequested(); using (Logger.LogBlock(FunctionId.Renamer_RenameSymbolAsync, cancellationToken)) { var project = solution.GetOriginatingProject(symbol); if (project != null) { var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false); if (client != null) { var result = await client.TryRunRemoteAsync <SerializableConflictResolution>( WellKnownServiceHubServices.CodeAnalysisService, nameof(IRemoteRenamer.RenameSymbolAsync), solution, new object[] { SerializableSymbolAndProjectId.Create(symbol, project, cancellationToken), newName, SerializableRenameOptionSet.Dehydrate(optionSet), nonConflictSymbols?.Select(s => SerializableSymbolAndProjectId.Dehydrate(solution, s, cancellationToken)).ToArray(), }, callbackTarget : null, cancellationToken).ConfigureAwait(false); if (result.HasValue) { return(await result.Value.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false)); } } } } return(await RenameSymbolInCurrentProcessAsync( solution, symbol, newName, optionSet, nonConflictSymbols, cancellationToken).ConfigureAwait(false)); }
internal static async Task FindReferencesAsync( SymbolAndProjectId symbolAndProjectId, Solution solution, IStreamingFindReferencesProgress progress, IImmutableSet <Document> documents, FindReferencesSearchOptions options, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.FindReference, cancellationToken)) { // If ProjectId is null then this is a call through our old public API. We don't have // the necessary data to effectively run the call out of proc. if (symbolAndProjectId.ProjectId != null) { var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false); if (client != null) { // Create a callback that we can pass to the server process to hear about the // results as it finds them. When we hear about results we'll forward them to // the 'progress' parameter which will then update the UI. var serverCallback = new FindReferencesServerCallback(solution, progress, cancellationToken); var success = await client.TryRunRemoteAsync( WellKnownServiceHubServices.CodeAnalysisService, nameof(IRemoteSymbolFinder.FindReferencesAsync), solution, new object[] { SerializableSymbolAndProjectId.Dehydrate(symbolAndProjectId), documents?.Select(d => d.Id).ToArray(), SerializableFindReferencesSearchOptions.Dehydrate(options), }, serverCallback, cancellationToken).ConfigureAwait(false); if (success) { return; } } } // Couldn't effectively search in OOP. Perform the search in-proc. await FindReferencesInCurrentProcessAsync( symbolAndProjectId, solution, progress, documents, options, cancellationToken).ConfigureAwait(false); } }
private async Task <ImmutableArray <SymbolInformation> > GetVsSearchResultsAsync(TestWorkspace workspace, string query) { var solution = workspace.CurrentSolution; using var client = await RemoteHostClient.TryGetClientAsync(workspace, CancellationToken.None).ConfigureAwait(false); Assert.NotNull(client); var document = solution.Projects.First().Documents.First(); await UpdatePrimaryWorkspace(client, solution.WithDocumentFilePath(document.Id, Path.Combine(TempRoot.Root, document.FilePath))); var workspaceSymbolParams = new WorkspaceSymbolParams { Query = query, }; var symbolResultsBuilder = ArrayBuilder <SymbolInformation> .GetInstance(); var threadingContext = workspace.ExportProvider.GetExportedValue <IThreadingContext>(); var awaitableProgress = new ProgressWithCompletion <SymbolInformation[]>( symbols => symbolResultsBuilder.AddRange(symbols), threadingContext.JoinableTaskFactory); workspaceSymbolParams.PartialResultToken = awaitableProgress; var result = await client.RunRemoteAsync <JObject>( WellKnownServiceHubService.RemoteLanguageServer, Methods.InitializeName, solution : null, new object[] { new InitializeParams() }, callbackTarget : null, CancellationToken.None).ConfigureAwait(false); Assert.True(result["capabilities"]["workspaceSymbolProvider"].ToObject <bool>()); _ = await client.RunRemoteAsync <SymbolInformation[]>( WellKnownServiceHubService.RemoteLanguageServer, Methods.WorkspaceSymbolName, solution : null, new object[] { workspaceSymbolParams }, callbackTarget : null, CancellationToken.None).ConfigureAwait(false); await awaitableProgress.WaitAsync(CancellationToken.None); return(symbolResultsBuilder.ToImmutableAndFree()); }
public static async Task <ISymbolSearchUpdateEngine> CreateEngineAsync( Workspace workspace, ISymbolSearchLogService logService, CancellationToken cancellationToken) { var client = await RemoteHostClient.TryGetClientAsync(workspace, cancellationToken).ConfigureAwait(false); if (client != null) { return(new RemoteUpdateEngine(client, logService)); } // Couldn't go out of proc. Just do everything inside the current process. return(CreateEngineInProcess()); }
public static async Task <Optional <T> > TryRunRemoteAsync <T>( Workspace workspace, string targetName, Solution?solution, IReadOnlyList <object?> arguments, CancellationToken cancellationToken ) { var client = await RemoteHostClient .TryGetClientAsync(workspace, cancellationToken) .ConfigureAwait(false); if (client == null) { return(default);
public static async Task FindReferencesAsync( IFindUsagesContext context, ISymbol symbol, Project project, FindReferencesSearchOptions options ) { var cancellationToken = context.CancellationToken; var solution = project.Solution; var client = await RemoteHostClient .TryGetClientAsync(solution.Workspace, cancellationToken) .ConfigureAwait(false); if (client != null) { // Create a callback that we can pass to the server process to hear about the // results as it finds them. When we hear about results we'll forward them to // the 'progress' parameter which will then update the UI. var serverCallback = new FindUsagesServerCallback(solution, context); var symbolAndProjectId = SerializableSymbolAndProjectId.Create( symbol, project, cancellationToken ); _ = await client .TryInvokeAsync <IRemoteFindUsagesService>( solution, (service, solutionInfo, callbackId, cancellationToken) => service.FindReferencesAsync( solutionInfo, callbackId, symbolAndProjectId, options, cancellationToken ), serverCallback, cancellationToken ) .ConfigureAwait(false); } else { // Couldn't effectively search in OOP. Perform the search in-process. await FindReferencesInCurrentProcessAsync(context, symbol, project, options) .ConfigureAwait(false); } }
/// <summary> /// Signals that the extension has been loaded. The server can be started immediately, or wait for user action to start. /// To start the server, invoke the <see cref="StartAsync"/> event; /// </summary> public Task OnLoadedAsync() { var token = _asyncListener.BeginAsyncOperation("OnLoadedAsync"); // set up event stream so that we start LSP server once Roslyn is loaded _eventListener.WorkspaceStarted.ContinueWith(async _ => { // initialize things on UI thread await InitializeOnUIAsync().ConfigureAwait(false); // this might get called before solution is fully loaded and before file is opened. // we delay our OOP start until then, but user might do vsstart before that. so we make sure we start OOP if // it is not running yet. multiple start is no-op ((RemoteHostClientServiceFactory.RemoteHostClientService)_workspace.Services.GetService <IRemoteHostClientService>()).Enable(); // wait until remote host is available before let platform know that they can activate our LSP var client = await RemoteHostClient.TryGetClientAsync(_workspace, CancellationToken.None).ConfigureAwait(false); if (client == null) { // there is no OOP. either user turned it off, or process got killed. // don't ask platform to start LSP return; } // let platform know that they can start us await StartAsync.InvokeAsync(this, EventArgs.Empty).ConfigureAwait(false); }, TaskScheduler.Default).CompletesAsyncOperation(token); return(Task.CompletedTask); async Task InitializeOnUIAsync() { await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(); // this doesn't attempt to solve our JTF and some services being not free-thread issue here, but // try to fix this particular deadlock issue only. we already have long discussion on // how we need to deal with JTF, Roslyn service requirements and VS services reality conflicting // each others. architectural fix should come from the result of that discussion. // Ensure the options persisters are loaded since we have to fetch options from the shell _lazyOptions.Select(o => o.Value); // experimentation service unfortunately uses JTF to jump to UI thread in certain cases // which can cause deadlock if 2 parties try to enable OOP from BG and then FG before // experimentation service tries to jump to UI thread. var experimentationService = _workspace.Services.GetService <IExperimentationService>(); } }
private async Task<ImmutableArray<INavigateToSearchResult>> SearchDocumentInRemoteProcessAsync( RemoteHostClient client, Document document, string searchPattern, CancellationToken cancellationToken) { var solution = document.Project.Solution; using (var session = await client.CreateCodeAnalysisServiceSessionAsync( solution, cancellationToken).ConfigureAwait(false)) { var serializableResults = await session.InvokeAsync<SerializableNavigateToSearchResult[]>( WellKnownServiceHubServices.CodeAnalysisService_SearchDocumentAsync, SerializableDocumentId.Dehydrate(document), searchPattern).ConfigureAwait(false); return serializableResults.Select(r => r.Rehydrate(solution)).ToImmutableArray(); } }
private async Task<ImmutableArray<INavigateToSearchResult>> SearchProjectInRemoteProcessAsync( RemoteHostClient client, Project project, string searchPattern, CancellationToken cancellationToken) { var solution = project.Solution; using (var session = await client.CreateCodeAnalysisServiceSessionAsync( solution, cancellationToken).ConfigureAwait(false)) { var serializableResults = await session.InvokeAsync<SerializableNavigateToSearchResult[]>( nameof(IRemoteNavigateToSearchService.SearchProjectAsync), SerializableProjectId.Dehydrate(project.Id), searchPattern).ConfigureAwait(false); return serializableResults.Select(r => r.Rehydrate(solution)).ToImmutableArray(); } }
private async Task <ImmutableArray <INavigateToSearchResult> > SearchProjectInRemoteProcessAsync( RemoteHostClient client, Project project, string searchPattern, CancellationToken cancellationToken) { var solution = project.Solution; using (var session = await client.CreateCodeAnalysisServiceSessionAsync( solution, cancellationToken).ConfigureAwait(false)) { var serializableResults = await session.InvokeAsync <SerializableNavigateToSearchResult[]>( nameof(IRemoteNavigateToSearchService.SearchProjectAsync), SerializableProjectId.Dehydrate(project.Id), searchPattern).ConfigureAwait(false); return(serializableResults.Select(r => r.Rehydrate(solution)).ToImmutableArray()); } }
public async ValueTask <bool?> IsActiveStatementInExceptionRegionAsync(Solution solution, ManagedInstructionId instructionId, CancellationToken cancellationToken) { var client = await RemoteHostClient.TryGetClientAsync(_workspace.Services, cancellationToken).ConfigureAwait(false); if (client == null) { return(await GetLocalService().IsActiveStatementInExceptionRegionAsync(_sessionId, solution, instructionId, cancellationToken).ConfigureAwait(false)); } var result = await client.TryInvokeAsync <IRemoteEditAndContinueService, bool?>( solution, (service, solutionInfo, cancellationToken) => service.IsActiveStatementInExceptionRegionAsync(solutionInfo, _sessionId, instructionId, cancellationToken), cancellationToken).ConfigureAwait(false); return(result.HasValue ? result.Value : null); }
public async ValueTask <ImmutableArray <ImmutableArray <ActiveStatementSpan> > > GetBaseActiveStatementSpansAsync(Solution solution, ImmutableArray <DocumentId> documentIds, CancellationToken cancellationToken) { var client = await RemoteHostClient.TryGetClientAsync(_workspace, cancellationToken).ConfigureAwait(false); if (client == null) { return(await GetLocalService().GetBaseActiveStatementSpansAsync(_sessionId, solution, documentIds, cancellationToken).ConfigureAwait(false)); } var result = await client.TryInvokeAsync <IRemoteEditAndContinueService, ImmutableArray <ImmutableArray <ActiveStatementSpan> > >( solution, (service, solutionInfo, cancellationToken) => service.GetBaseActiveStatementSpansAsync(solutionInfo, _sessionId, documentIds, cancellationToken), cancellationToken).ConfigureAwait(false); return(result.HasValue ? result.Value : ImmutableArray <ImmutableArray <ActiveStatementSpan> > .Empty); }
public async Task <ImmutableArray <ReferenceMethodDescriptor>?> FindReferenceMethodsAsync( Solution solution, DocumentId documentId, SyntaxNode?syntaxNode, CancellationToken cancellationToken ) { using ( Logger.LogBlock(FunctionId.CodeLens_FindReferenceMethodsAsync, cancellationToken) ) { if (syntaxNode == null) { return(null); } var client = await RemoteHostClient .TryGetClientAsync(solution.Workspace, cancellationToken) .ConfigureAwait(false); if (client != null) { var result = await client .TryInvokeAsync < IRemoteCodeLensReferencesService, ImmutableArray <ReferenceMethodDescriptor>? >( solution, (service, solutionInfo, cancellationToken) => service.FindReferenceMethodsAsync( solutionInfo, documentId, syntaxNode.Span, cancellationToken ), cancellationToken ) .ConfigureAwait(false); return(result.HasValue ? result.Value : null); } return(await CodeLensReferencesServiceFactory.Instance .FindReferenceMethodsAsync(solution, documentId, syntaxNode, cancellationToken) .ConfigureAwait(false)); } }
/// <summary> /// Find the locations that need to be renamed. Can cross process boundaries efficiently to do this. /// </summary> public static async Task <LightweightRenameLocations> FindRenameLocationsAsync( ISymbol symbol, Solution solution, SymbolRenameOptions options, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) { Contract.ThrowIfNull(solution); Contract.ThrowIfNull(symbol); cancellationToken.ThrowIfCancellationRequested(); using (Logger.LogBlock(FunctionId.Renamer_FindRenameLocationsAsync, cancellationToken)) { if (SerializableSymbolAndProjectId.TryCreate(symbol, solution, cancellationToken, out var serializedSymbol)) { var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false); if (client != null) { var result = await client.TryInvokeAsync <IRemoteRenamerService, SerializableRenameLocations?>( solution, (service, solutionInfo, callbackId, cancellationToken) => service.FindRenameLocationsAsync(solutionInfo, callbackId, serializedSymbol, options, cancellationToken), callbackTarget : new RemoteOptionsProvider <CodeCleanupOptions>(solution.Workspace.Services, fallbackOptions), cancellationToken).ConfigureAwait(false); if (result.HasValue && result.Value != null) { var rehydrated = await TryRehydrateAsync( solution, symbol, fallbackOptions, result.Value, cancellationToken).ConfigureAwait(false); if (rehydrated != null) { return(rehydrated); } } // TODO: do not fall back to in-proc if client is available (https://github.com/dotnet/roslyn/issues/47557) } } } // Couldn't effectively search in OOP. Perform the search in-proc. var renameLocations = await HeavyweightRenameLocations.FindLocationsInCurrentProcessAsync( symbol, solution, options, fallbackOptions, cancellationToken).ConfigureAwait(false); return(new LightweightRenameLocations( symbol, solution, options, fallbackOptions, renameLocations.Locations, renameLocations.ImplicitLocations.IsDefault ? null : renameLocations.ImplicitLocations.Select(loc => SerializableReferenceLocation.Dehydrate(loc, cancellationToken)).ToArray(), renameLocations.ReferencedSymbols.IsDefault ? null : renameLocations.ReferencedSymbols.Select(sym => SerializableSymbolAndProjectId.Dehydrate(solution, sym, cancellationToken)).ToArray())); }
public async ValueTask <bool> HasChangesAsync(Solution solution, ActiveStatementSpanProvider activeStatementSpanProvider, string?sourceFilePath, CancellationToken cancellationToken) { var client = await RemoteHostClient.TryGetClientAsync(_workspace, cancellationToken).ConfigureAwait(false); if (client == null) { return(await GetLocalService().HasChangesAsync(_sessionId, solution, activeStatementSpanProvider, sourceFilePath, cancellationToken).ConfigureAwait(false)); } var result = await client.TryInvokeAsync <IRemoteEditAndContinueService, bool>( solution, (service, solutionInfo, callbackId, cancellationToken) => service.HasChangesAsync(solutionInfo, callbackId, _sessionId, sourceFilePath, cancellationToken), callbackTarget : new ActiveStatementSpanProviderCallback(activeStatementSpanProvider), cancellationToken).ConfigureAwait(false); return(result.HasValue ? result.Value : true); }
public async ValueTask <ImmutableArray <ActiveStatementSpan> > GetAdjustedActiveStatementSpansAsync(TextDocument document, ActiveStatementSpanProvider activeStatementSpanProvider, CancellationToken cancellationToken) { var client = await RemoteHostClient.TryGetClientAsync(_workspace, cancellationToken).ConfigureAwait(false); if (client == null) { return(await GetLocalService().GetAdjustedActiveStatementSpansAsync(_sessionId, document, activeStatementSpanProvider, cancellationToken).ConfigureAwait(false)); } var result = await client.TryInvokeAsync <IRemoteEditAndContinueService, ImmutableArray <ActiveStatementSpan> >( document.Project.Solution, (service, solutionInfo, callbackId, cancellationToken) => service.GetAdjustedActiveStatementSpansAsync(solutionInfo, callbackId, _sessionId, document.Id, cancellationToken), callbackTarget : new ActiveStatementSpanProviderCallback(activeStatementSpanProvider), cancellationToken).ConfigureAwait(false); return(result.HasValue ? result.Value : ImmutableArray <ActiveStatementSpan> .Empty); }
public RemoteUpdateEngine(RemoteHostClient.Session session) { _session = session; }