提交 5bb84cfa 编写于 作者: M Manish Vasani

Merge pull request #1881 from mavasani/MakeAsync

Make DiagnosticAnalyzerExtensions.GetDiagnosticAnalyzerCategory async to avoid force computing registered analyzer actions in the IDE.
......@@ -132,7 +132,7 @@ private async Task AnalyzeSyntaxAsync(Document document, ImmutableHashSet<string
{
await HandleSuppressedAnalyzerAsync(document, stateSet, StateType.Syntax, cancellationToken).ConfigureAwait(false);
}
else if (ShouldRunAnalyzerForStateType(userDiagnosticDriver, stateSet.Analyzer, StateType.Syntax, diagnosticIds) &&
else if (await ShouldRunAnalyzerForStateTypeAsync(userDiagnosticDriver, stateSet.Analyzer, StateType.Syntax, diagnosticIds).ConfigureAwait(false) &&
(skipClosedFileChecks || ShouldRunAnalyzerForClosedFile(openedDocument, stateSet.Analyzer)))
{
var data = await _executor.GetSyntaxAnalysisDataAsync(userDiagnosticDriver, stateSet, versions).ConfigureAwait(false);
......@@ -204,13 +204,13 @@ private async Task AnalyzeBodyDocumentAsync(Document document, SyntaxNode member
foreach (var stateSet in _stateManger.GetOrUpdateStateSets(document.Project))
{
bool supportsSemanticInSpan;
if (spanBasedDriver.IsAnalyzerSuppressed(stateSet.Analyzer))
{
await HandleSuppressedAnalyzerAsync(document, stateSet, StateType.Document, cancellationToken).ConfigureAwait(false);
}
else if (ShouldRunAnalyzerForStateType(spanBasedDriver, stateSet.Analyzer, StateType.Document, out supportsSemanticInSpan))
else 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);
......@@ -254,7 +254,7 @@ private async Task AnalyzeDocumentAsync(Document document, VersionArgument versi
{
await HandleSuppressedAnalyzerAsync(document, stateSet, StateType.Document, cancellationToken).ConfigureAwait(false);
}
else if (ShouldRunAnalyzerForStateType(userDiagnosticDriver, stateSet.Analyzer, StateType.Document, diagnosticIds) &&
else if (await ShouldRunAnalyzerForStateTypeAsync(userDiagnosticDriver, stateSet.Analyzer, StateType.Document, diagnosticIds).ConfigureAwait(false) &&
(skipClosedFileChecks || ShouldRunAnalyzerForClosedFile(openedDocument, stateSet.Analyzer)))
{
var data = await _executor.GetDocumentAnalysisDataAsync(userDiagnosticDriver, stateSet, versions).ConfigureAwait(false);
......@@ -308,7 +308,7 @@ private async Task AnalyzeProjectAsync(Project project, ImmutableHashSet<string>
{
await HandleSuppressedAnalyzerAsync(project, stateSet, cancellationToken).ConfigureAwait(false);
}
else if (ShouldRunAnalyzerForStateType(analyzerDriver, stateSet.Analyzer, StateType.Project, diagnosticIds) &&
else if (await ShouldRunAnalyzerForStateTypeAsync(analyzerDriver, stateSet.Analyzer, StateType.Project, diagnosticIds).ConfigureAwait(false) &&
(skipClosedFileChecks || ShouldRunAnalyzerForClosedFile(openedDocument: false, analyzer: stateSet.Analyzer)))
{
var data = await _executor.GetProjectAnalysisDataAsync(analyzerDriver, stateSet, versions).ConfigureAwait(false);
......@@ -436,20 +436,17 @@ private bool ShouldRunAnalyzerForClosedFile(bool openedDocument, DiagnosticAnaly
return Owner.GetDiagnosticDescriptors(analyzer).Any(d => d.DefaultSeverity != DiagnosticSeverity.Hidden);
}
private bool ShouldRunAnalyzerForStateType(DiagnosticAnalyzerDriver driver, DiagnosticAnalyzer analyzer,
StateType stateTypeId, ImmutableHashSet<string> diagnosticIds)
private async Task<bool> ShouldRunAnalyzerForStateTypeAsync(DiagnosticAnalyzerDriver driver, DiagnosticAnalyzer analyzer, StateType stateTypeId, ImmutableHashSet<string> diagnosticIds)
{
bool discarded;
return ShouldRunAnalyzerForStateType(driver, analyzer, stateTypeId, out discarded, diagnosticIds, Owner.GetDiagnosticDescriptors);
return await ShouldRunAnalyzerForStateTypeAsync(driver, analyzer, stateTypeId, diagnosticIds, Owner.GetDiagnosticDescriptors).ConfigureAwait(false);
}
private static bool ShouldRunAnalyzerForStateType(DiagnosticAnalyzerDriver driver, DiagnosticAnalyzer analyzer, StateType stateTypeId,
out bool supportsSemanticInSpan, ImmutableHashSet<string> diagnosticIds = null, Func<DiagnosticAnalyzer, ImmutableArray<DiagnosticDescriptor>> getDescriptor = null)
private static async Task<bool> ShouldRunAnalyzerForStateTypeAsync(DiagnosticAnalyzerDriver driver, DiagnosticAnalyzer analyzer, StateType stateTypeId,
ImmutableHashSet<string> diagnosticIds = null, Func<DiagnosticAnalyzer, ImmutableArray<DiagnosticDescriptor>> getDescriptors = null)
{
Debug.Assert(!driver.IsAnalyzerSuppressed(analyzer));
supportsSemanticInSpan = false;
if (diagnosticIds != null && getDescriptor(analyzer).All(d => !diagnosticIds.Contains(d.Id)))
if (diagnosticIds != null && getDescriptors(analyzer).All(d => !diagnosticIds.Contains(d.Id)))
{
return false;
}
......@@ -457,13 +454,13 @@ private bool ShouldRunAnalyzerForClosedFile(bool openedDocument, DiagnosticAnaly
switch (stateTypeId)
{
case StateType.Syntax:
return analyzer.SupportsSyntaxDiagnosticAnalysis(driver);
return await analyzer.SupportsSyntaxDiagnosticAnalysisAsync(driver).ConfigureAwait(false);
case StateType.Document:
return analyzer.SupportsSemanticDiagnosticAnalysis(driver, out supportsSemanticInSpan);
return await analyzer.SupportsSemanticDiagnosticAnalysisAsync(driver).ConfigureAwait(false);
case StateType.Project:
return analyzer.SupportsProjectDiagnosticAnalysis(driver);
return await analyzer.SupportsProjectDiagnosticAnalysisAsync(driver).ConfigureAwait(false);
default:
throw ExceptionUtilities.Unreachable;
......
......@@ -441,7 +441,7 @@ private async Task AppendDiagnosticsOfStateTypeAsync(object documentOrProject, S
cancellationToken.ThrowIfCancellationRequested();
if (driver.IsAnalyzerSuppressed(stateSet.Analyzer) ||
!this.Owner.ShouldRunAnalyzerForStateType(driver, stateSet.Analyzer, stateType, this.DiagnosticIds))
!(await this.Owner.ShouldRunAnalyzerForStateTypeAsync(driver, stateSet.Analyzer, stateType, this.DiagnosticIds).ConfigureAwait(false)))
{
continue;
}
......
......@@ -8,6 +8,7 @@
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
using Microsoft.CodeAnalysis.Shared.Extensions;
namespace Microsoft.CodeAnalysis.Diagnostics.EngineV1
{
......@@ -110,13 +111,13 @@ public async Task<bool> TryGetAsync()
StateSet stateSet, StateType stateType, Func<VersionStamp, VersionStamp, bool> versionCheck,
Func<DiagnosticAnalyzerDriver, DiagnosticAnalyzer, Task<IEnumerable<DiagnosticData>>> getDiagnostics)
{
bool supportsSemanticInSpan;
if (_spanBasedDriver.IsAnalyzerSuppressed(stateSet.Analyzer) ||
!ShouldRunAnalyzerForStateType(stateSet, stateType, out supportsSemanticInSpan))
!(await ShouldRunAnalyzerForStateTypeAsync(stateSet, stateType).ConfigureAwait(false)))
{
return true;
}
bool supportsSemanticInSpan = await stateSet.Analyzer.SupportsSpanBasedSemanticDiagnosticAnalysisAsync(_spanBasedDriver).ConfigureAwait(false);
var analyzerDriver = GetAnalyzerDriverBasedOnStateType(stateType, supportsSemanticInSpan);
Func<DiagnosticData, bool> shouldInclude = d => d.DocumentId == _document.Id && _range.IntersectsWith(d.TextSpan);
......@@ -153,14 +154,14 @@ public async Task<bool> TryGetAsync()
return true;
}
private bool ShouldRunAnalyzerForStateType(StateSet stateSet, StateType stateType, out bool supportsSemanticInSpan)
private async Task<bool> ShouldRunAnalyzerForStateTypeAsync(StateSet stateSet, StateType stateType)
{
if (stateType == StateType.Project)
{
return DiagnosticIncrementalAnalyzer.ShouldRunAnalyzerForStateType(_projectDriver, stateSet.Analyzer, stateType, out supportsSemanticInSpan);
return await DiagnosticIncrementalAnalyzer.ShouldRunAnalyzerForStateTypeAsync(_projectDriver, stateSet.Analyzer, stateType).ConfigureAwait(false);
}
return DiagnosticIncrementalAnalyzer.ShouldRunAnalyzerForStateType(_spanBasedDriver, stateSet.Analyzer, stateType, out supportsSemanticInSpan);
return await DiagnosticIncrementalAnalyzer.ShouldRunAnalyzerForStateTypeAsync(_spanBasedDriver, stateSet.Analyzer, stateType).ConfigureAwait(false);
}
private bool BlockForData(StateType stateType, bool supportsSemanticInSpan)
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Immutable;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Diagnostics.EngineV1;
using Roslyn.Utilities;
using System;
namespace Microsoft.CodeAnalysis.Shared.Extensions
{
internal static class DiagnosticAnalyzerExtensions
{
public static DiagnosticAnalyzerCategory GetDiagnosticAnalyzerCategory(this DiagnosticAnalyzer analyzer, DiagnosticAnalyzerDriver driver)
public static async Task<DiagnosticAnalyzerCategory> GetDiagnosticAnalyzerCategoryAsync(this DiagnosticAnalyzer analyzer, DiagnosticAnalyzerDriver driver)
{
var category = DiagnosticAnalyzerCategory.None;
......@@ -27,7 +28,7 @@ public static DiagnosticAnalyzerCategory GetDiagnosticAnalyzerCategory(this Diag
// to be able to operate on a limited span of the document. In practical terms, no analyzer
// can have both SemanticDocumentAnalysis and SemanticSpanAnalysis as categories.
bool cantSupportSemanticSpanAnalysis = false;
var analyzerActions = driver.GetAnalyzerActionsAsync(analyzer).WaitAndGetResult(driver.CancellationToken);
var analyzerActions = await driver.GetAnalyzerActionsAsync(analyzer).ConfigureAwait(false);
if (analyzerActions != null)
{
if (analyzerActions.SyntaxTreeActionsCount > 0)
......@@ -76,29 +77,27 @@ private static bool HasSemanticDocumentActions(AnalyzerActions analyzerActions)
analyzerActions.CodeBlockStartActionsCount > 0;
}
public static bool SupportsSyntaxDiagnosticAnalysis(this DiagnosticAnalyzer analyzer, DiagnosticAnalyzerDriver driver)
public static async Task<bool> SupportsSyntaxDiagnosticAnalysisAsync(this DiagnosticAnalyzer analyzer, DiagnosticAnalyzerDriver driver)
{
var category = analyzer.GetDiagnosticAnalyzerCategory(driver);
var category = await analyzer.GetDiagnosticAnalyzerCategoryAsync(driver).ConfigureAwait(false);
return (category & DiagnosticAnalyzerCategory.SyntaxAnalysis) != 0;
}
public static bool SupportsSemanticDiagnosticAnalysis(this DiagnosticAnalyzer analyzer, DiagnosticAnalyzerDriver driver, out bool supportsSemanticSpanAnalysis)
public static async Task<bool> SupportsSemanticDiagnosticAnalysisAsync(this DiagnosticAnalyzer analyzer, DiagnosticAnalyzerDriver driver)
{
var category = analyzer.GetDiagnosticAnalyzerCategory(driver);
supportsSemanticSpanAnalysis = (category & DiagnosticAnalyzerCategory.SemanticSpanAnalysis) != 0;
return supportsSemanticSpanAnalysis ||
(category & DiagnosticAnalyzerCategory.SemanticDocumentAnalysis) != 0;
var category = await analyzer.GetDiagnosticAnalyzerCategoryAsync(driver).ConfigureAwait(false);
return (category & (DiagnosticAnalyzerCategory.SemanticSpanAnalysis | DiagnosticAnalyzerCategory.SemanticDocumentAnalysis)) != 0;
}
public static bool SupportsSemanticDiagnosticAnalysis(this DiagnosticAnalyzer analyzer, DiagnosticAnalyzerDriver driver)
public static async Task<bool> SupportsSpanBasedSemanticDiagnosticAnalysisAsync(this DiagnosticAnalyzer analyzer, DiagnosticAnalyzerDriver driver)
{
bool discarded;
return analyzer.SupportsSemanticDiagnosticAnalysis(driver, out discarded);
var category = await analyzer.GetDiagnosticAnalyzerCategoryAsync(driver).ConfigureAwait(false);
return (category & DiagnosticAnalyzerCategory.SemanticSpanAnalysis) != 0;
}
public static bool SupportsProjectDiagnosticAnalysis(this DiagnosticAnalyzer analyzer, DiagnosticAnalyzerDriver driver)
public static async Task<bool> SupportsProjectDiagnosticAnalysisAsync(this DiagnosticAnalyzer analyzer, DiagnosticAnalyzerDriver driver)
{
var category = analyzer.GetDiagnosticAnalyzerCategory(driver);
var category = await analyzer.GetDiagnosticAnalyzerCategoryAsync(driver).ConfigureAwait(false);
return (category & DiagnosticAnalyzerCategory.ProjectAnalysis) != 0;
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册