private async Task ComputeDocumentDiagnosticsAsync( ImmutableArray <DiagnosticAnalyzer> analyzers, AnalysisKind kind, TextSpan?span, ArrayBuilder <DiagnosticData> list, CancellationToken cancellationToken) { if (analyzers.IsEmpty) { return; } var analysisScope = new DocumentAnalysisScope(_document, span, analyzers, kind); var executor = new DocumentAnalysisExecutor(analysisScope, _compilationWithAnalyzers, _owner._diagnosticAnalyzerRunner, logPerformanceInfo: false); foreach (var analyzer in analyzers) { cancellationToken.ThrowIfCancellationRequested(); var analyzerTypeName = analyzer.GetType().Name; using (_addOperationScope?.Invoke(analyzerTypeName)) using (_addOperationScope is object?RoslynEventSource.LogInformationalBlock(FunctionId.DiagnosticAnalyzerService_GetDiagnosticsForSpanAsync, analyzerTypeName, cancellationToken) : default) { var dx = await executor.ComputeDiagnosticsAsync(analyzer, cancellationToken).ConfigureAwait(false); if (dx != null) { // no state yet list.AddRange(dx.Where(ShouldInclude)); } } } }
async Task <ImmutableArray <CodeRefactoring> > ICodeRefactoringService.GetRefactoringsAsync( Document document, TextSpan state, bool isBlocking, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.Refactoring_CodeRefactoringService_GetRefactoringsAsync, cancellationToken)) { var extensionManager = document.Project.Solution.Workspace.Services.GetService <IExtensionManager>(); var tasks = new List <Task <CodeRefactoring> >(); foreach (var provider in GetProviders(document)) { tasks.Add(Task.Run( () => { using (RoslynEventSource.LogInformationalBlock(FunctionId.Refactoring_CodeRefactoringService_GetRefactoringsAsync, provider, cancellationToken)) { return(GetRefactoringFromProviderAsync(document, state, provider, extensionManager, isBlocking, cancellationToken)); } }, cancellationToken)); } var results = await Task.WhenAll(tasks).ConfigureAwait(false); return(results.WhereNotNull().ToImmutableArray()); } }
public async Task <ImmutableArray <CodeRefactoring> > GetRefactoringsAsync( Document document, TextSpan state, bool isBlocking, Func <string, IDisposable?> addOperationScope, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.Refactoring_CodeRefactoringService_GetRefactoringsAsync, cancellationToken)) { var extensionManager = document.Project.Solution.Workspace.Services.GetRequiredService <IExtensionManager>(); using var _ = ArrayBuilder <Task <CodeRefactoring?> > .GetInstance(out var tasks); foreach (var provider in GetProviders(document)) { tasks.Add(Task.Run( () => { var providerName = provider.GetType().Name; using (addOperationScope(providerName)) using (RoslynEventSource.LogInformationalBlock(FunctionId.Refactoring_CodeRefactoringService_GetRefactoringsAsync, providerName, cancellationToken)) { return(GetRefactoringFromProviderAsync(document, state, provider, extensionManager, isBlocking, cancellationToken)); } }, cancellationToken)); } var results = await Task.WhenAll(tasks).ConfigureAwait(false); return(results.WhereNotNull().ToImmutableArray()); } }
protected override TRoot Recover(CancellationToken cancellationToken) { Contract.ThrowIfNull(_storage); using (RoslynEventSource.LogInformationalBlock(FunctionId.Workspace_Recoverable_RecoverRoot, _containingTree.FilePath, cancellationToken)) { using var stream = _storage.ReadStream(cancellationToken); return(RecoverRoot(stream, cancellationToken)); } }
protected override async Task <TRoot> RecoverAsync(CancellationToken cancellationToken) { Contract.ThrowIfNull(_storage); using (RoslynEventSource.LogInformationalBlock(FunctionId.Workspace_Recoverable_RecoverRootAsync, _containingTree.FilePath, cancellationToken)) { using var stream = await _storage.ReadStreamAsync(cancellationToken).ConfigureAwait(false); return(RecoverRoot(stream, cancellationToken)); } }
public async Task <bool> TryGetAsync(List <DiagnosticData> list, Func <string, IDisposable?>?addOperationScope, CancellationToken cancellationToken) { try { var containsFullResult = true; foreach (var stateSet in _stateSets) { var analyzerTypeName = stateSet.Analyzer.GetType().Name; using (addOperationScope?.Invoke(analyzerTypeName)) using (addOperationScope is object?RoslynEventSource.LogInformationalBlock(FunctionId.DiagnosticAnalyzerService_GetDiagnosticsForSpanAsync, analyzerTypeName, cancellationToken) : default) { cancellationToken.ThrowIfCancellationRequested(); containsFullResult &= await TryGetSyntaxAndSemanticDiagnosticsAsync(stateSet, list, cancellationToken).ConfigureAwait(false); // check whether compilation end code fix is enabled if (!_document.Project.Solution.Workspace.Options.GetOption(InternalDiagnosticsOptions.CompilationEndCodeFix)) { continue; } // check whether heuristic is enabled if (_blockForData && _document.Project.Solution.Workspace.Options.GetOption(InternalDiagnosticsOptions.UseCompilationEndCodeFixHeuristic)) { var avoidLoadingData = true; var state = stateSet.GetOrCreateProjectState(_project.Id); var result = await state.GetAnalysisDataAsync(_owner.PersistentStorageService, _document, avoidLoadingData, cancellationToken).ConfigureAwait(false); // no previous compilation end diagnostics in this file. var version = await GetDiagnosticVersionAsync(_project, cancellationToken).ConfigureAwait(false); if (state.IsEmpty(_document.Id) || result.Version != version) { continue; } } containsFullResult &= await TryGetProjectDiagnosticsAsync(stateSet, list, cancellationToken).ConfigureAwait(false); } } // if we are blocked for data, then we should always have full result. Debug.Assert(!_blockForData || containsFullResult); return(containsFullResult); } catch (Exception e) when(FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }
private async Task AppendConfigurationsAsync( Document document, TextSpan diagnosticsSpan, IEnumerable<DiagnosticData> diagnostics, ArrayBuilder<CodeFixCollection> result, CancellationToken cancellationToken) { if (!_configurationProvidersMap.TryGetValue(document.Project.Language, out var lazyConfigurationProviders) || lazyConfigurationProviders.Value == null) { return; } // append CodeFixCollection for each CodeFixProvider foreach (var provider in lazyConfigurationProviders.Value) { using (RoslynEventSource.LogInformationalBlock(FunctionId.CodeFixes_GetCodeFixesAsync, provider, cancellationToken)) { await AppendFixesOrConfigurationsAsync( document, diagnosticsSpan, diagnostics, fixAllForInSpan: false, result, provider, hasFix: d => provider.IsFixableDiagnostic(d), getFixes: dxs => provider.GetFixesAsync( document, diagnosticsSpan, dxs, cancellationToken), cancellationToken: cancellationToken).ConfigureAwait(false); } } }
private async Task AppendFixesAsync( Document document, TextSpan span, IEnumerable<DiagnosticData> diagnostics, bool fixAllForInSpan, bool isBlocking, ArrayBuilder<CodeFixCollection> result, Func<string, IDisposable?> addOperationScope, CancellationToken cancellationToken) { var hasAnySharedFixer = _workspaceFixersMap.TryGetValue(document.Project.Language, out var fixerMap); var projectFixersMap = GetProjectFixers(document.Project); var hasAnyProjectFixer = projectFixersMap.Any(); if (!hasAnySharedFixer && !hasAnyProjectFixer) { return; } var allFixers = new List<CodeFixProvider>(); // TODO (https://github.com/dotnet/roslyn/issues/4932): Don't restrict CodeFixes in Interactive var isInteractive = document.Project.Solution.Workspace.Kind == WorkspaceKind.Interactive; // gather CodeFixProviders for all distinct diagnostics found for current span foreach (var diagnosticId in diagnostics.Select(d => d.Id).Distinct()) { cancellationToken.ThrowIfCancellationRequested(); if (hasAnySharedFixer && fixerMap.Value.TryGetValue(diagnosticId, out var workspaceFixers)) { if (isInteractive) { allFixers.AddRange(workspaceFixers.Where(IsInteractiveCodeFixProvider)); } else { allFixers.AddRange(workspaceFixers); } } if (hasAnyProjectFixer && projectFixersMap.TryGetValue(diagnosticId, out var projectFixers)) { Debug.Assert(!isInteractive); allFixers.AddRange(projectFixers); } } var extensionManager = document.Project.Solution.Workspace.Services.GetService<IExtensionManager>(); // run each CodeFixProvider to gather individual CodeFixes for reported diagnostics foreach (var fixer in allFixers.Distinct()) { cancellationToken.ThrowIfCancellationRequested(); await AppendFixesOrConfigurationsAsync( document, span, diagnostics, fixAllForInSpan, result, fixer, hasFix: d => this.GetFixableDiagnosticIds(fixer, extensionManager).Contains(d.Id), getFixes: dxs => { var fixerName = fixer.GetType().Name; using (addOperationScope(fixerName)) using (RoslynEventSource.LogInformationalBlock(FunctionId.CodeFixes_GetCodeFixesAsync, fixerName, cancellationToken)) { if (fixAllForInSpan) { var primaryDiagnostic = dxs.First(); return GetCodeFixesAsync(document, primaryDiagnostic.Location.SourceSpan, fixer, isBlocking, ImmutableArray.Create(primaryDiagnostic), cancellationToken); } else { return GetCodeFixesAsync(document, span, fixer, isBlocking, dxs, cancellationToken); } } }, cancellationToken: cancellationToken).ConfigureAwait(false); // Just need the first result if we are doing fix all in span if (fixAllForInSpan && result.Any()) return; } }