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));
                            }
                        }
                }
            }
コード例 #2
0
        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());
            }
        }
コード例 #3
0
        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;
                }
            }
コード例 #7
0
ファイル: CodeFixService.cs プロジェクト: wenming2014/roslyn
        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);
                }
            }
        }
コード例 #8
0
ファイル: CodeFixService.cs プロジェクト: wenming2014/roslyn
        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;
            }
        }