private async Task AnalyzeBodyDocumentAsync(Document document, SyntaxNode member, VersionArgument versions, CancellationToken cancellationToken) { try { // syntax facts service must exist, otherwise, this method won't have called. var syntaxFacts = document.Project.LanguageServices.GetService <ISyntaxFactsService>(); var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var memberId = syntaxFacts.GetMethodLevelMemberId(root, member); var spanBasedDriver = new DiagnosticAnalyzerDriver(document, member.FullSpan, root, this, cancellationToken); var documentBasedDriver = new DiagnosticAnalyzerDriver(document, root.FullSpan, root, this, cancellationToken); foreach (var stateSet in _stateManger.GetOrUpdateStateSets(document.Project)) { if (spanBasedDriver.IsAnalyzerSuppressed(stateSet.Analyzer)) { await ClearExistingDiagnostics(document, stateSet, StateType.Document, cancellationToken).ConfigureAwait(false); continue; } if (await ShouldRunAnalyzerForStateTypeAsync(spanBasedDriver, stateSet.Analyzer, StateType.Document).ConfigureAwait(false)) { var supportsSemanticInSpan = await stateSet.Analyzer.SupportsSpanBasedSemanticDiagnosticAnalysisAsync(spanBasedDriver).ConfigureAwait(false); var userDiagnosticDriver = supportsSemanticInSpan ? spanBasedDriver : documentBasedDriver; var ranges = _memberRangeMap.GetSavedMemberRange(stateSet.Analyzer, document); var data = await _executor.GetDocumentBodyAnalysisDataAsync( stateSet, versions, userDiagnosticDriver, root, member, memberId, supportsSemanticInSpan, ranges).ConfigureAwait(false); _memberRangeMap.UpdateMemberRange(stateSet.Analyzer, document, versions.TextVersion, memberId, member.FullSpan, ranges); var state = stateSet.GetState(StateType.Document); await state.PersistAsync(document, data.ToPersistData(), cancellationToken).ConfigureAwait(false); if (data.FromCache) { RaiseDiagnosticsUpdated(StateType.Document, document.Id, stateSet, new SolutionArgument(document), data.Items); continue; } RaiseDocumentDiagnosticsUpdatedIfNeeded(StateType.Document, document, stateSet, data.OldItems, data.Items); } } } catch (Exception e) when(FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }
private async Task AnalyzeBodyDocumentAsync(Document document, SyntaxNode member, VersionArgument versions, CancellationToken cancellationToken) { try { // syntax facts service must exist, otherwise, this method won't have called. var syntaxFacts = document.Project.LanguageServices.GetService <ISyntaxFactsService>(); var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var memberId = syntaxFacts.GetMethodLevelMemberId(root, member); var spanBasedDriver = new DiagnosticAnalyzerDriver(document, member.FullSpan, root, _diagnosticLogAggregator, cancellationToken); var documentBasedDriver = new DiagnosticAnalyzerDriver(document, root.FullSpan, root, _diagnosticLogAggregator, cancellationToken); var options = document.Project.CompilationOptions; foreach (var providerAndId in await _analyzersAndState.GetAllProviderAndIdsAsync(document.Project, cancellationToken).ConfigureAwait(false)) { var provider = providerAndId.Key; var providerId = providerAndId.Value; bool supportsSemanticInSpan; if (IsAnalyzerSuppressed(provider, options, spanBasedDriver)) { await HandleSuppressedAnalyzerAsync(document, StateType.Document, providerId, provider, cancellationToken).ConfigureAwait(false); } else if (ShouldRunProviderForStateType(StateType.Document, provider, spanBasedDriver, out supportsSemanticInSpan)) { var userDiagnosticDriver = supportsSemanticInSpan ? spanBasedDriver : documentBasedDriver; var ranges = _memberRangeMap.GetSavedMemberRange(providerId, document); var data = await _executor.GetDocumentBodyAnalysisDataAsync( provider, providerId, versions, userDiagnosticDriver, root, member, memberId, supportsSemanticInSpan, ranges).ConfigureAwait(false); _memberRangeMap.UpdateMemberRange(providerId, document, versions.TextVersion, memberId, member.FullSpan, ranges); var state = _analyzersAndState.GetOrCreateDiagnosticState(StateType.Document, providerId, provider, document.Project.Id, document.Project.Language); await state.PersistAsync(document, data.ToPersistData(), cancellationToken).ConfigureAwait(false); if (data.FromCache) { RaiseDiagnosticsUpdated(StateType.Document, document.Id, providerId, new SolutionArgument(document), data.Items); continue; } RaiseDiagnosticsUpdatedIfNeeded(StateType.Document, document, providerId, data.OldItems, data.Items); } } } catch (Exception e) when(FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }