public static async Task FindImplementationsAsync( ISymbol symbol, Project project, IFindUsagesContext context) { 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.FindImplementationsAsync(solutionInfo, callbackId, symbolAndProjectId, cancellationToken), serverCallback, cancellationToken).ConfigureAwait(false); } else { // Couldn't effectively search in OOP. Perform the search in-process. await FindImplementationsInCurrentProcessAsync( symbol, project, context).ConfigureAwait(false); } }
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(await result.Value.SelectAsArrayAsync(h => h.RehydrateAsync(solution)).ConfigureAwait(false)); } return(await GetDocumentHighlightsInCurrentProcessAsync( document, position, documentsToSearch, cancellationToken).ConfigureAwait(false)); }
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.RunRemoteAsync <IList <SerializableDocumentHighlights> >( WellKnownServiceHubService.CodeAnalysis, nameof(IRemoteDocumentHighlights.GetDocumentHighlightsAsync), solution, new object[] { document.Id, position, documentsToSearch.Select(d => d.Id).ToArray() }, callbackTarget : null, cancellationToken).ConfigureAwait(false); return(result.SelectAsArray(h => h.Rehydrate(solution))); } return(await GetDocumentHighlightsInCurrentProcessAsync( document, position, documentsToSearch, cancellationToken).ConfigureAwait(false)); }
public async Task <Solution> EncapsulateFieldsAsync( Document document, ImmutableArray <IFieldSymbol> fields, CleanCodeGenerationOptionsProvider fallbackOptions, 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 fieldSymbolKeys = fields.SelectAsArray(f => SymbolKey.CreateString(f, cancellationToken)); var result = await client.TryInvokeAsync <IRemoteEncapsulateFieldService, ImmutableArray <(DocumentId, ImmutableArray <TextChange>)> >( solution, (service, solutionInfo, callbackId, cancellationToken) => service.EncapsulateFieldsAsync(solutionInfo, callbackId, document.Id, fieldSymbolKeys, updateReferences, cancellationToken), callbackTarget : new RemoteOptionsProvider <CleanCodeGenerationOptions>(solution.Workspace.Services, fallbackOptions), cancellationToken).ConfigureAwait(false); if (!result.HasValue) { return(solution); } return(await RemoteUtilities.UpdateSolutionAsync( solution, result.Value, cancellationToken).ConfigureAwait(false)); } } return(await EncapsulateFieldsInCurrentProcessAsync( document, fields, fallbackOptions, updateReferences, cancellationToken).ConfigureAwait(false)); }
public static async Task <ImmutableArray <INamedTypeSymbol> > FindTypesAsync( INamedTypeSymbol type, Solution solution, IImmutableSet <Project>?projects, bool transitive, DependentTypesKind kind, CancellationToken cancellationToken) { if (SerializableSymbolAndProjectId.TryCreate(type, solution, cancellationToken, out var serializedType)) { var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false); if (client != null) { var projectIds = projects?.Where(p => RemoteSupportedLanguages.IsSupported(p.Language)).SelectAsArray(p => p.Id) ?? default; var result = await client.TryInvokeAsync <IRemoteDependentTypeFinderService, ImmutableArray <SerializableSymbolAndProjectId> >( solution, (service, solutionInfo, cancellationToken) => service.FindTypesAsync(solutionInfo, serializedType, projectIds, transitive, kind, cancellationToken), cancellationToken).ConfigureAwait(false); if (!result.HasValue) { return(ImmutableArray <INamedTypeSymbol> .Empty); } return(await RehydrateAsync(solution, result.Value, cancellationToken).ConfigureAwait(false)); } // TODO: Do not fall back to in-proc https://github.com/dotnet/roslyn/issues/47557 } return(await FindTypesInCurrentProcessAsync(type, solution, projects, transitive, kind, cancellationToken).ConfigureAwait(false)); }
public async Task TestHostAnalyzers() { var code = @"class Test { void Method() { var t = new Test(); } }"; using (var workspace = CreateWorkspace(LanguageNames.CSharp, code)) { var analyzerType = typeof(CSharpUseExplicitTypeDiagnosticAnalyzer); 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.None)); // set option workspace.TryApplyChanges(workspace.CurrentSolution.WithOptions(workspace.Options .WithChangedOption(CSharpCodeStyleOptions.VarWhenTypeIsApparent, new CodeStyleOption <bool>(false, NotificationOption.Suggestion)))); // run analysis var project = workspace.CurrentSolution.Projects.First(); var runner = CreateAnalyzerRunner(workspace); var compilationWithAnalyzers = (await project.GetCompilationAsync()).WithAnalyzers( analyzerReference.GetAnalyzers(project.Language).Where(a => a.GetType() == analyzerType).ToImmutableArray(), new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project.Solution)); // no result for open file only analyzer unless forced var result = await runner.AnalyzeAsync(compilationWithAnalyzers, project, forcedAnalysis : false, cancellationToken : CancellationToken.None); Assert.Empty(result.AnalysisResult); result = await runner.AnalyzeAsync(compilationWithAnalyzers, project, forcedAnalysis : true, cancellationToken : CancellationToken.None); var analyzerResult = result.AnalysisResult[compilationWithAnalyzers.Analyzers[0]]; // check result var diagnostics = analyzerResult.GetDocumentDiagnostics(analyzerResult.DocumentIds.First(), AnalysisKind.Semantic); Assert.Equal(IDEDiagnosticIds.UseExplicitTypeDiagnosticId, diagnostics[0].Id); } }
public async Task AddSemanticClassificationsAsync(Document document, TextSpan textSpan, ClassificationOptions options, ArrayBuilder <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 database = document.Project.Solution.Options.GetPersistentStorageDatabase(); var client = await RemoteHostClient.TryGetClientAsync(document.Project, cancellationToken).ConfigureAwait(false); if (client != null) { // We have an oop connection. If we're not fully loaded, see if we can retrieve a previously cached set // of classifications from the server. Note: this must be a separate call (instead of being part of // service.GetSemanticClassificationsAsync below) as we want to try to read in the cached // classifications without doing any syncing to the OOP process. var isFullyLoaded = IsFullyLoaded(document, cancellationToken); if (await TryGetCachedClassificationsAsync(document, textSpan, result, client, database, isFullyLoaded, cancellationToken).ConfigureAwait(false)) { return; } // Call the project overload. Semantic classification only needs the current project's information // to classify properly. var classifiedSpans = await client.TryInvokeAsync <IRemoteSemanticClassificationService, SerializableClassifiedSpans>( document.Project, (service, solutionInfo, cancellationToken) => service.GetSemanticClassificationsAsync(solutionInfo, document.Id, textSpan, options, database, isFullyLoaded, cancellationToken), cancellationToken).ConfigureAwait(false); // if the remote call fails do nothing (error has already been reported) if (classifiedSpans.HasValue) { classifiedSpans.Value.Rehydrate(result); } } else { await AddSemanticClassificationsInCurrentProcessAsync( document, textSpan, options, result, cancellationToken).ConfigureAwait(false); } }
public static async Task <RazorRemoteHostClient?> CreateAsync(Workspace workspace, CancellationToken cancellationToken = default) { var client = await RemoteHostClient.TryGetClientAsync(workspace.Services, cancellationToken).ConfigureAwait(false); var descriptors = new RazorServiceDescriptorsWrapper("dummy", _ => throw ExceptionUtilities.Unreachable, ImmutableArray <IMessagePackFormatter> .Empty, ImmutableArray <IFormatterResolver> .Empty, Array.Empty <(Type, Type?)>()); return(client == null ? null : new RazorRemoteHostClient((ServiceHubRemoteHostClient)client, descriptors, RazorRemoteServiceCallbackDispatcherRegistry.Empty)); }
public static async Task <ImmutableArray <ISymbol> > FindSourceDeclarationsWithPatternAsync( Project project, string pattern, SymbolFilter criteria, CancellationToken cancellationToken ) { if (project == null) { throw new ArgumentNullException(nameof(project)); } if (pattern == null) { throw new ArgumentNullException(nameof(pattern)); } var client = await RemoteHostClient .TryGetClientAsync(project, cancellationToken) .ConfigureAwait(false); if (client != null) { var result = await client .TryInvokeAsync < IRemoteSymbolFinderService, ImmutableArray <SerializableSymbolAndProjectId> >( project.Solution, (service, solutionInfo, cancellationToken) => service.FindProjectSourceDeclarationsWithPatternAsync( solutionInfo, project.Id, pattern, criteria, cancellationToken ), cancellationToken ) .ConfigureAwait(false); if (!result.HasValue) { return(ImmutableArray <ISymbol> .Empty); } return(await RehydrateAsync(project.Solution, result.Value, cancellationToken) .ConfigureAwait(false)); } return(await FindSourceDeclarationsWithPatternInCurrentProcessAsync( project, pattern, criteria, cancellationToken ) .ConfigureAwait(false)); }
DiagnosticData?syntaxError)> EmitSolutionUpdateAsync( Solution solution, ActiveStatementSpanProvider activeStatementSpanProvider, IDiagnosticAnalyzerService diagnosticService, EditAndContinueDiagnosticUpdateSource diagnosticUpdateSource, CancellationToken cancellationToken) { ManagedModuleUpdates moduleUpdates; ImmutableArray <DiagnosticData> diagnosticData; ImmutableArray <(DocumentId DocumentId, ImmutableArray <RudeEditDiagnostic> Diagnostics)> rudeEdits; DiagnosticData?syntaxError; var client = await RemoteHostClient.TryGetClientAsync(_workspace, cancellationToken).ConfigureAwait(false); if (client == null) { var results = await GetLocalService().EmitSolutionUpdateAsync(_sessionId, solution, activeStatementSpanProvider, cancellationToken).ConfigureAwait(false); moduleUpdates = results.ModuleUpdates; diagnosticData = results.GetDiagnosticData(solution); rudeEdits = results.RudeEdits; syntaxError = results.GetSyntaxErrorData(solution); } else { var result = await client.TryInvokeAsync <IRemoteEditAndContinueService, EmitSolutionUpdateResults.Data>( solution, (service, solutionInfo, callbackId, cancellationToken) => service.EmitSolutionUpdateAsync(solutionInfo, callbackId, _sessionId, cancellationToken), callbackTarget : new ActiveStatementSpanProviderCallback(activeStatementSpanProvider), cancellationToken).ConfigureAwait(false); if (result.HasValue) { moduleUpdates = result.Value.ModuleUpdates; diagnosticData = result.Value.Diagnostics; rudeEdits = result.Value.RudeEdits; syntaxError = result.Value.SyntaxError; } else { moduleUpdates = new ManagedModuleUpdates(ManagedModuleUpdateStatus.Blocked, ImmutableArray <ManagedModuleUpdate> .Empty); diagnosticData = ImmutableArray <DiagnosticData> .Empty; rudeEdits = ImmutableArray <(DocumentId DocumentId, ImmutableArray <RudeEditDiagnostic> Diagnostics)> .Empty; syntaxError = null; } } // clear emit/apply diagnostics reported previously: diagnosticUpdateSource.ClearDiagnostics(); // clear all reported rude edits: diagnosticService.Reanalyze(_workspace, documentIds: rudeEdits.Select(d => d.DocumentId)); // report emit/apply diagnostics: diagnosticUpdateSource.ReportDiagnostics(_workspace, solution, diagnosticData); return(moduleUpdates, diagnosticData, rudeEdits, syntaxError); }
private async Task ReportAnalyzerPerformanceAsync(Document document, CompilationWithAnalyzers?compilation, CancellationToken cancellationToken) { try { if (compilation == null) { return; } var client = await RemoteHostClient.TryGetClientAsync(document.Project.Solution.Workspace, cancellationToken).ConfigureAwait(false); if (client == null) { // no remote support return; } cancellationToken.ThrowIfCancellationRequested(); using var pooledObject = SharedPools.Default <Dictionary <DiagnosticAnalyzer, AnalyzerTelemetryInfo> >().GetPooledObject(); var containsData = false; foreach (var analyzer in compilation.Analyzers) { var telemetryInfo = await compilation.GetAnalyzerTelemetryInfoAsync(analyzer, cancellationToken).ConfigureAwait(false); if (!containsData && telemetryInfo.ExecutionTime.Ticks > 0) { // this is unfortunate tweak due to how GetAnalyzerTelemetryInfoAsync works when analyzers are asked // one by one rather than in bulk. containsData = true; } pooledObject.Object.Add(analyzer, telemetryInfo); } if (!containsData) { // looks like there is no new data from driver. skip reporting. return; } _ = await client.TryRunRemoteAsync( WellKnownServiceHubService.CodeAnalysis, nameof(IRemoteDiagnosticAnalyzerService.ReportAnalyzerPerformance), solution : null, new object[] { pooledObject.Object.ToAnalyzerPerformanceInfo(DiagnosticAnalyzerInfoCache), /* unit count */ 1 }, callbackTarget : null, cancellationToken).ConfigureAwait(false); } catch (Exception ex) when(FatalError.ReportWithoutCrashUnlessCanceled(ex)) { // this is fire and forget method } }
public async ValueTask <ImmutableArray <Diagnostic> > GetDocumentDiagnosticsAsync(Document document, Document designTimeDocument, ActiveStatementSpanProvider activeStatementSpanProvider, CancellationToken cancellationToken) { var client = await RemoteHostClient.TryGetClientAsync(Workspace, cancellationToken).ConfigureAwait(false); if (client == null) { var diagnostics = await GetLocalService().GetDocumentDiagnosticsAsync(document, activeStatementSpanProvider, cancellationToken).ConfigureAwait(false); if (designTimeDocument != document) { diagnostics = diagnostics.SelectAsArray(diagnostic => RemapLocation(designTimeDocument, DiagnosticData.Create(diagnostic, document.Project))); } return(diagnostics); } var diagnosticData = await client.TryInvokeAsync <IRemoteEditAndContinueService, ImmutableArray <DiagnosticData> >( document.Project.Solution, (service, solutionInfo, callbackId, cancellationToken) => service.GetDocumentDiagnosticsAsync(solutionInfo, callbackId, document.Id, cancellationToken), callbackTarget : new ActiveStatementSpanProviderCallback(activeStatementSpanProvider), cancellationToken).ConfigureAwait(false); if (!diagnosticData.HasValue) { return(ImmutableArray <Diagnostic> .Empty); } var project = document.Project; using var _ = ArrayBuilder <Diagnostic> .GetInstance(out var result); foreach (var data in diagnosticData.Value) { Debug.Assert(data.DataLocation != null); Diagnostic diagnostic; // Workaround for solution crawler not supporting mapped locations to make Razor work. // We pretend the diagnostic is in the original document, but use the mapped line span. // Razor will ignore the column (which will be off because #line directives can't currently map columns) and only use the line number. if (designTimeDocument != document && data.DataLocation.IsMapped) { diagnostic = RemapLocation(designTimeDocument, data); } else { diagnostic = await data.ToDiagnosticAsync(document.Project, cancellationToken).ConfigureAwait(false); } result.Add(diagnostic); } return(result.ToImmutable()); }
public async Task <string?> TryGetHostGroupIdAsync(CancellationToken cancellationToken) { var client = await RemoteHostClient.TryGetClientAsync(_workspace, cancellationToken).ConfigureAwait(false); if (client == null) { return(null); } return(client.ClientId); }
public static async Task <RazorRemoteHostClient?> TryGetClientAsync(HostWorkspaceServices services, RazorServiceDescriptorsWrapper serviceDescriptors, RazorRemoteServiceCallbackDispatcherRegistry callbackDispatchers, CancellationToken cancellationToken = default) { var client = await RemoteHostClient.TryGetClientAsync(services, cancellationToken).ConfigureAwait(false); if (client is null) { return(null); } return(new RazorRemoteHostClient((ServiceHubRemoteHostClient)client, serviceDescriptors, callbackDispatchers)); }
public async Task <string> GetHostGroupIdAsync(CancellationToken cancellationToken) { var client = await RemoteHostClient.TryGetClientAsync(_workspace, cancellationToken).ConfigureAwait(false); if (client == null) { // exception is handled by code lens engine throw new InvalidOperationException("remote host doesn't exist"); } return(client.ClientId); }
public static async Task <ImmutableArray <SerializableImportCompletionItem> > GetUnimportedExtensionMethodsAsync( Document document, int position, ITypeSymbol receiverTypeSymbol, ISet <string> namespaceInScope, bool forceIndexCreation, CancellationToken cancellationToken) { SerializableUnimportedExtensionMethods items; var ticks = Environment.TickCount; var project = document.Project; var client = await RemoteHostClient.TryGetClientAsync(project, cancellationToken).ConfigureAwait(false); if (client != null) { var receiverTypeSymbolKeyData = SymbolKey.CreateString(receiverTypeSymbol, cancellationToken); var result = await client.TryInvokeAsync <IRemoteExtensionMethodImportCompletionService, SerializableUnimportedExtensionMethods>( project.Solution, (service, solutionInfo, cancellationToken) => service.GetUnimportedExtensionMethodsAsync( solutionInfo, document.Id, position, receiverTypeSymbolKeyData, namespaceInScope.ToImmutableArray(), forceIndexCreation, cancellationToken), callbackTarget : null, cancellationToken).ConfigureAwait(false); if (!result.HasValue) { return(ImmutableArray <SerializableImportCompletionItem> .Empty); } items = result.Value; } else { items = await GetUnimportedExtensionMethodsInCurrentProcessAsync(document, position, receiverTypeSymbol, namespaceInScope, forceIndexCreation, cancellationToken).ConfigureAwait(false); } // report telemetry: var totalTicks = Environment.TickCount - ticks; CompletionProvidersLogger.LogExtensionMethodCompletionTicksDataPoint(totalTicks); CompletionProvidersLogger.LogExtensionMethodCompletionMethodsProvidedDataPoint(items.CompletionItems.Length); CompletionProvidersLogger.LogExtensionMethodCompletionGetSymbolsTicksDataPoint(items.GetSymbolsTicks); CompletionProvidersLogger.LogExtensionMethodCompletionCreateItemsTicksDataPoint(items.CreateItemsTicks); if (items.IsPartialResult) { CompletionProvidersLogger.LogExtensionMethodCompletionPartialResultCount(); } return(items.CompletionItems); }
> 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 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);
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); }
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)); }
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 <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 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); } }
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); } } }
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); } }
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)); }
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); } }
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 <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);