提交 8921fa9d 编写于 作者: M Manish Vasani

AnalyzerDiagnosticUpdateSource - Working implementation

上级 817a7ae1
......@@ -25,8 +25,8 @@ internal class AnalyzerManager
// This map stores the tasks to compute HostSessionStartAnalysisScope for session wide analyzer actions, i.e. AnalyzerActions registered by analyzer's Initialize method.
// These are run only once per every analyzer.
private ImmutableDictionary<DiagnosticAnalyzer, Task<HostSessionStartAnalysisScope>> _sessionScopeMap =
ImmutableDictionary<DiagnosticAnalyzer, Task<HostSessionStartAnalysisScope>>.Empty;
private ConditionalWeakTable<DiagnosticAnalyzer, Task<HostSessionStartAnalysisScope>> _sessionScopeMap =
new ConditionalWeakTable<DiagnosticAnalyzer, Task<HostSessionStartAnalysisScope>>();
// This map stores the tasks to compute HostCompilationStartAnalysisScope for per-compilation analyzer actions, i.e. AnalyzerActions registered by analyzer's CompilationStartActions.
// Compilation start actions will get executed once per-each compilation as user might want to return different set of custom actions for each compilation.
......@@ -75,16 +75,8 @@ internal class AnalyzerManager
}, cancellationToken);
};
var task = ImmutableInterlocked.GetOrAdd(ref _sessionScopeMap, analyzer, getTask);
// Retry cancelled task.
if (task.Status == TaskStatus.Canceled)
{
ImmutableInterlocked.TryUpdate(ref _sessionScopeMap, analyzer, getTask(analyzer), task);
return _sessionScopeMap[analyzer];
}
return task;
var callback = new ConditionalWeakTable<DiagnosticAnalyzer, Task<HostSessionStartAnalysisScope>>.CreateValueCallback(getTask);
return _sessionScopeMap.GetValue(analyzer, callback);
}
/// <summary>
......@@ -115,7 +107,6 @@ internal class AnalyzerManager
/// </summary>
public ImmutableArray<DiagnosticDescriptor> GetSupportedDiagnosticDescriptors(
DiagnosticAnalyzer analyzer,
Action<Diagnostic> addDiagnostic,
Func<Exception, DiagnosticAnalyzer, bool> continueOnAnalyzerException,
CancellationToken cancellationToken)
{
......
......@@ -27,7 +27,7 @@ private static IEnumerable<Diagnostic> GetDiagnostics(DiagnosticAnalyzer analyze
var analyzer = analyzerOpt ?? DiagnosticExtensions.GetCompilerDiagnosticAnalyzer(project.Language);
var exceptionDiagnostics = new List<Diagnostic>();
EventHandler<AnalyzerExceptionDiagnosticArgs> addExceptionDiagnostic = (sender, args) =>
EventHandler<WorkspaceAnalyzerExceptionDiagnosticArgs> addExceptionDiagnostic = (sender, args) =>
{
if (args.FaultedAnalyzer == analyzer)
{
......@@ -35,7 +35,7 @@ private static IEnumerable<Diagnostic> GetDiagnostics(DiagnosticAnalyzer analyze
}
};
AnalyzerDriverHelper.AnalyzerExceptionDiagnostic += addExceptionDiagnostic;
DiagnosticAnalyzerDriver.AnalyzerExceptionDiagnostic += addExceptionDiagnostic;
if (getDocumentDiagnostics)
{
......@@ -101,7 +101,7 @@ private static IEnumerable<Diagnostic> GetDiagnostics(DiagnosticAnalyzer analyze
}
}
AnalyzerDriverHelper.AnalyzerExceptionDiagnostic -= addExceptionDiagnostic;
DiagnosticAnalyzerDriver.AnalyzerExceptionDiagnostic -= addExceptionDiagnostic;
return documentDiagnostics.Concat(projectDiagnostics).Concat(exceptionDiagnostics);
}
......
......@@ -19,12 +19,16 @@ internal sealed class AnalyzerDiagnosticUpdateSource : IDiagnosticUpdateSource
[ImportingConstructor]
public AnalyzerDiagnosticUpdateSource()
{
BaseDiagnosticIncrementalAnalyzer.AnalyzerExceptionDiagnostic += OnAnalyzerExceptionDiagnostic;
// Register for exception diagnostics from both engines.
EngineV1.DiagnosticAnalyzerDriver.AnalyzerExceptionDiagnostic += OnAnalyzerExceptionDiagnostic;
EngineV2.DiagnosticIncrementalAnalyzer.AnalyzerExceptionDiagnostic += OnAnalyzerExceptionDiagnostic;
}
~AnalyzerDiagnosticUpdateSource()
{
BaseDiagnosticIncrementalAnalyzer.AnalyzerExceptionDiagnostic -= OnAnalyzerExceptionDiagnostic;
// Unregister for exception diagnostics from both engines.
EngineV1.DiagnosticAnalyzerDriver.AnalyzerExceptionDiagnostic -= OnAnalyzerExceptionDiagnostic;
EngineV2.DiagnosticIncrementalAnalyzer.AnalyzerExceptionDiagnostic -= OnAnalyzerExceptionDiagnostic;
}
public bool SupportGetDiagnostics
......@@ -56,12 +60,33 @@ private void OnAnalyzerExceptionDiagnostic(object sender, WorkspaceAnalyzerExcep
Contract.ThrowIfFalse(AnalyzerDriverHelper.IsAnalyzerExceptionDiagnostic(args.Diagnostic));
var diagnosticData = DiagnosticData.Create(args.Workspace, args.Diagnostic);
ImmutableArray<DiagnosticData> existingDiagnostics;
if (_analyzerExceptionDiagnosticsMap.TryGetValue(args.FaultedAnalyzer, out existingDiagnostics))
{
if (existingDiagnostics.Contains(diagnosticData))
{
// don't fire duplicate diagnostics.
return;
}
}
else
{
existingDiagnostics = ImmutableArray<DiagnosticData>.Empty;
}
var dxs = ImmutableInterlocked.AddOrUpdate(ref _analyzerExceptionDiagnosticsMap,
args.FaultedAnalyzer,
ImmutableArray.Create(diagnosticData),
(a, existing) => existing.Add(diagnosticData).Distinct());
(a, existing) =>
{
var newDiags = existing.Add(diagnosticData).Distinct();
return newDiags.Length == existing.Length ? existing : newDiags;
});
RaiseDiagnosticsUpdated(MakeArgs(args.FaultedAnalyzer, dxs, args.Workspace));
if (dxs.Length > existingDiagnostics.Length)
{
RaiseDiagnosticsUpdated(MakeArgs(args.FaultedAnalyzer, dxs, args.Workspace, args.Project));
}
}
public void ClearDiagnostics(DiagnosticAnalyzer analyzer, Workspace workspace)
......@@ -69,19 +94,19 @@ public void ClearDiagnostics(DiagnosticAnalyzer analyzer, Workspace workspace)
ImmutableArray<DiagnosticData> existing;
if (ImmutableInterlocked.TryRemove(ref _analyzerExceptionDiagnosticsMap, analyzer, out existing))
{
RaiseDiagnosticsUpdated(MakeArgs(analyzer, ImmutableArray<DiagnosticData>.Empty, workspace));
RaiseDiagnosticsUpdated(MakeArgs(analyzer, ImmutableArray<DiagnosticData>.Empty, workspace, project: null));
}
}
private DiagnosticsUpdatedArgs MakeArgs(DiagnosticAnalyzer analyzer, ImmutableArray<DiagnosticData> items, Workspace workspace)
private DiagnosticsUpdatedArgs MakeArgs(DiagnosticAnalyzer analyzer, ImmutableArray<DiagnosticData> items, Workspace workspace, Project project)
{
var id = WorkspaceAnalyzerManager.GetUniqueIdForAnalyzer(analyzer);
return new DiagnosticsUpdatedArgs(
id: Tuple.Create(this, id),
workspace: workspace,
solution: null,
projectId: null,
solution: project?.Solution,
projectId: project?.Id,
documentId: null,
diagnostics: items);
}
......
// 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;
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using System.Threading;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Diagnostics
{
[Export(typeof(IDiagnosticUpdateSource))]
[Export(typeof(AnalyzerExceptionDiagnosticUpdateSource))]
[Shared]
internal sealed class AnalyzerExceptionDiagnosticUpdateSource : IDiagnosticUpdateSource
{
private static ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<DiagnosticData>> _analyzerExceptionDiagnosticsMap =
ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<DiagnosticData>>.Empty;
public bool SupportGetDiagnostics
{
get
{
return false;
}
}
public ImmutableArray<DiagnosticData> GetDiagnostics(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, CancellationToken cancellationToken)
{
return ImmutableArray<DiagnosticData>.Empty;
}
public event EventHandler<DiagnosticsUpdatedArgs> DiagnosticsUpdated;
private void RaiseDiagnosticsUpdated(DiagnosticsUpdatedArgs args)
{
var updated = this.DiagnosticsUpdated;
if (updated != null)
{
updated(this, args);
}
}
public void ReportDiagnostics(DiagnosticAnalyzer analyzer, ImmutableArray<Diagnostic> diagnostics, Project project)
{
Contract.ThrowIfFalse(diagnostics.All(AnalyzerDriverHelper.IsAnalyzerExceptionDiagnostic));
var dxs = diagnostics.Select(d => DiagnosticData.Create(project, d)).Distinct().ToImmutableArray();
dxs = ImmutableInterlocked.AddOrUpdate(ref _analyzerExceptionDiagnosticsMap,
analyzer,
dxs,
(a, existing) => existing.AddRange(dxs).Distinct());
RaiseDiagnosticsUpdated(MakeArgs(analyzer, dxs, project.Solution.Workspace, project));
}
public void ClearDiagnostics(DiagnosticAnalyzer analyzer, Workspace workspace)
{
ImmutableArray<DiagnosticData> existing;
if (ImmutableInterlocked.TryRemove(ref _analyzerExceptionDiagnosticsMap, analyzer, out existing))
{
RaiseDiagnosticsUpdated(MakeArgs(analyzer, ImmutableArray<DiagnosticData>.Empty, workspace, project: null));
}
}
private DiagnosticsUpdatedArgs MakeArgs(DiagnosticAnalyzer analyzer, ImmutableArray<DiagnosticData> items, Workspace workspace, Project project)
{
var id = WorkspaceAnalyzerManager.GetUniqueIdForAnalyzer(analyzer);
return new DiagnosticsUpdatedArgs(
id: Tuple.Create(this, id),
workspace: workspace,
solution: project != null ? project.Solution : workspace.CurrentSolution,
projectId: project?.Id,
documentId: null,
diagnostics: items);
}
internal ImmutableArray<DiagnosticData> TestOnly_GetExceptionDiagnostics(DiagnosticAnalyzer analyzer)
{
ImmutableArray<DiagnosticData> diagnostics;
if (!_analyzerExceptionDiagnosticsMap.TryGetValue(analyzer, out diagnostics))
{
diagnostics = ImmutableArray<DiagnosticData>.Empty;
}
return diagnostics;
}
}
}
......@@ -16,12 +16,6 @@ internal abstract class BaseDiagnosticIncrementalAnalyzer : IIncrementalAnalyzer
protected BaseDiagnosticIncrementalAnalyzer(Workspace workspace)
{
this.Workspace = workspace;
AnalyzerDriverHelper.AnalyzerExceptionDiagnostic += OnAnalyzerExceptionDiagnostic;
}
~BaseDiagnosticIncrementalAnalyzer()
{
AnalyzerDriverHelper.AnalyzerExceptionDiagnostic -= OnAnalyzerExceptionDiagnostic;
}
#region IIncrementalAnalyzer
......@@ -56,18 +50,5 @@ public virtual bool NeedsReanalysisOnOptionChanged(object sender, OptionChangedE
public virtual void LogAnalyzerCountSummary()
{
}
internal static event EventHandler<WorkspaceAnalyzerExceptionDiagnosticArgs> AnalyzerExceptionDiagnostic;
private void OnAnalyzerExceptionDiagnostic(object sender, AnalyzerExceptionDiagnosticArgs args)
{
var workspaceArgs = new WorkspaceAnalyzerExceptionDiagnosticArgs(args, Workspace);
AnalyzerExceptionDiagnostic?.Invoke(this, workspaceArgs);
}
internal static void OnAnalyzerExceptionDiagnostic(object sender, WorkspaceAnalyzerExceptionDiagnosticArgs args)
{
AnalyzerExceptionDiagnostic?.Invoke(sender, args);
}
}
}
......@@ -294,6 +294,7 @@ public static DiagnosticData Create(Workspace workspace, Diagnostic diagnostic)
diagnostic.Descriptor.IsEnabledByDefault,
diagnostic.WarningLevel,
diagnostic.Descriptor.CustomTags.AsImmutableOrEmpty(),
diagnostic.Properties,
workspace,
projectId: null,
title: diagnostic.Descriptor.Title.ToString(CultureInfo.CurrentUICulture),
......
......@@ -44,6 +44,8 @@ internal class DiagnosticAnalyzerDriver
private AnalyzerOptions _analyzerOptions = null;
internal static event EventHandler<WorkspaceAnalyzerExceptionDiagnosticArgs> AnalyzerExceptionDiagnostic;
public DiagnosticAnalyzerDriver(Document document, TextSpan? span, SyntaxNode root, LogAggregator logAggregator, CancellationToken cancellationToken)
: this(document, span, root, document.Project.LanguageServices.GetService<ISyntaxNodeAnalyzerService>(), cancellationToken)
{
......@@ -134,6 +136,26 @@ public ISyntaxNodeAnalyzerService SyntaxNodeAnalyzerService
}
}
private EventHandler<AnalyzerExceptionDiagnosticArgs> RegisterAnalyzerExceptionDiagnosticHandler(DiagnosticAnalyzer analyzer)
{
EventHandler<AnalyzerExceptionDiagnosticArgs> handler = (sender, args) =>
{
if (args.FaultedAnalyzer == analyzer)
{
var workspaceArgs = new WorkspaceAnalyzerExceptionDiagnosticArgs(args, this.Project.Solution.Workspace, this.Project);
AnalyzerExceptionDiagnostic?.Invoke(this, workspaceArgs);
}
};
AnalyzerDriverHelper.AnalyzerExceptionDiagnostic += handler;
return handler;
}
private void UnregisterAnalyzerExceptionDiagnosticHandler(EventHandler<AnalyzerExceptionDiagnosticArgs> handler)
{
AnalyzerDriverHelper.AnalyzerExceptionDiagnostic -= handler;
}
private ImmutableArray<DeclarationInfo> GetDeclarationInfos(SemanticModel model)
{
if (_lazyDeclarationInfos == null)
......@@ -265,7 +287,9 @@ public async Task<ImmutableArray<Diagnostic>> GetSyntaxDiagnosticsAsync(Diagnost
}
}
var analyzerActions = await this.GetAnalyzerActionsAsync(analyzer).ConfigureAwait(false);
var handler = RegisterAnalyzerExceptionDiagnosticHandler(analyzer);
var analyzerActions = await this.GetAnalyzerActionsCoreAsync(analyzer).ConfigureAwait(false);
DiagnosticAnalyzerLogger.UpdateAnalyzerTypeCount(analyzer, analyzerActions, (DiagnosticLogAggregator)_logAggregator);
......@@ -283,6 +307,7 @@ public async Task<ImmutableArray<Diagnostic>> GetSyntaxDiagnosticsAsync(Diagnost
return ImmutableArray<Diagnostic>.Empty;
}
UnregisterAnalyzerExceptionDiagnosticHandler(handler);
return GetFilteredDocumentDiagnostics(diagnostics, compilation).ToImmutableArray();
}
}
......@@ -325,15 +350,23 @@ internal void ReportAnalyzerExceptionDiagnostic(DiagnosticAnalyzer analyzer, Dia
}
}
var args = new WorkspaceAnalyzerExceptionDiagnosticArgs(analyzer, exceptionDiagnostic, this.Project.Solution.Workspace);
DiagnosticIncrementalAnalyzer.OnAnalyzerExceptionDiagnostic(this, args);
var workspaceArgs = new WorkspaceAnalyzerExceptionDiagnosticArgs(analyzer, exceptionDiagnostic, this.Project.Solution.Workspace, this.Project);
AnalyzerExceptionDiagnostic?.Invoke(this, workspaceArgs);
}
public async Task<AnalyzerActions> GetAnalyzerActionsAsync(DiagnosticAnalyzer analyzer)
{
Contract.ThrowIfFalse(_project.SupportsCompilation);
var handler = RegisterAnalyzerExceptionDiagnosticHandler(analyzer);
var actions = await GetAnalyzerActionsCoreAsync(analyzer).ConfigureAwait(false);
UnregisterAnalyzerExceptionDiagnosticHandler(handler);
return actions;
}
var compilation = await _project.GetCompilationAsync(_cancellationToken).ConfigureAwait(false);
private async Task<AnalyzerActions> GetAnalyzerActionsCoreAsync(DiagnosticAnalyzer analyzer)
{
var compilation = _project.SupportsCompilation ?
await _project.GetCompilationAsync(_cancellationToken).ConfigureAwait(false) :
null;
var analyzerActions = await AnalyzerManager.Default.GetAnalyzerActionsAsync(analyzer, compilation, _analyzerOptions, CatchAnalyzerException, _cancellationToken).ConfigureAwait(false);
DiagnosticAnalyzerLogger.UpdateAnalyzerTypeCount(analyzer, analyzerActions, (DiagnosticLogAggregator)_logAggregator);
return analyzerActions;
......@@ -373,8 +406,9 @@ public async Task<ImmutableArray<Diagnostic>> GetSemanticDiagnosticsAsync(Diagno
}
else
{
var analyzerActions = await GetAnalyzerActionsAsync(analyzer).ConfigureAwait(false);
var handler = RegisterAnalyzerExceptionDiagnosticHandler(analyzer);
var analyzerActions = await GetAnalyzerActionsCoreAsync(analyzer).ConfigureAwait(false);
if (analyzerActions != null)
{
// SemanticModel actions.
......@@ -409,6 +443,8 @@ public async Task<ImmutableArray<Diagnostic>> GetSemanticDiagnosticsAsync(Diagno
}
}
}
UnregisterAnalyzerExceptionDiagnosticHandler(handler);
}
return GetFilteredDocumentDiagnostics(diagnostics, compilation).ToImmutableArray();
......@@ -464,8 +500,10 @@ private async Task GetCompilationDiagnosticsAsync(DiagnosticAnalyzer analyzer, L
{
var localDiagnostics = pooledObject.Object;
var handler = RegisterAnalyzerExceptionDiagnosticHandler(analyzer);
// Get all the analyzer actions, including the per-compilation actions.
var analyzerActions = await GetAnalyzerActionsAsync(analyzer).ConfigureAwait(false);
var analyzerActions = await GetAnalyzerActionsCoreAsync(analyzer).ConfigureAwait(false);
if (analyzerActions.CompilationEndActionsCount > 0 && analyzerActions.CompilationStartActionsCount > 0 && forceAnalyzeAllDocuments != null)
{
......@@ -485,6 +523,8 @@ private async Task GetCompilationDiagnosticsAsync(DiagnosticAnalyzer analyzer, L
// CompilationEnd actions.
var compilation = await _project.GetCompilationAsync(_cancellationToken).ConfigureAwait(false);
AnalyzerDriverHelper.ExecuteCompilationEndActions(analyzerActions, compilation, _analyzerOptions, localDiagnostics.Add, CatchAnalyzerException, _cancellationToken);
UnregisterAnalyzerExceptionDiagnosticHandler(handler);
var filteredDiagnostics = CompilationWithAnalyzers.GetEffectiveDiagnostics(localDiagnostics, compilation);
diagnostics.AddRange(filteredDiagnostics);
}
......
// 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;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
......@@ -16,6 +17,8 @@ internal class DiagnosticIncrementalAnalyzer : BaseDiagnosticIncrementalAnalyzer
private readonly DiagnosticAnalyzerService _owner;
private readonly WorkspaceAnalyzerManager _workspaceAnalyzerManager;
internal static event EventHandler<WorkspaceAnalyzerExceptionDiagnosticArgs> AnalyzerExceptionDiagnostic;
public DiagnosticIncrementalAnalyzer(DiagnosticAnalyzerService owner, int correlationId, Workspace workspace, WorkspaceAnalyzerManager workspaceAnalyzerManager)
: base(workspace)
{
......@@ -155,11 +158,37 @@ private async Task<ImmutableArray<DiagnosticData>> GetProjectDiagnosticsAsync(Pr
var analyzers = _workspaceAnalyzerManager.CreateDiagnosticAnalyzers(project);
var handler = RegisterAnalyzerExceptionDiagnosticHandler(analyzers, project);
var compilationWithAnalyzer = compilation.WithAnalyzers(analyzers, project.AnalyzerOptions, cancellationToken);
// REVIEW: this API is a bit strange.
// if getting diagnostic is cancelled, it has to create new compilation and do everything from scretch again?
return GetDiagnosticData(project, await compilationWithAnalyzer.GetAnalyzerDiagnosticsAsync().ConfigureAwait(false)).ToImmutableArrayOrEmpty();
var dxs = GetDiagnosticData(project, await compilationWithAnalyzer.GetAnalyzerDiagnosticsAsync().ConfigureAwait(false)).ToImmutableArrayOrEmpty();
UnregisterAnalyzerExceptionDiagnosticHandler(handler);
return dxs;
}
private EventHandler<AnalyzerExceptionDiagnosticArgs> RegisterAnalyzerExceptionDiagnosticHandler(ImmutableArray<DiagnosticAnalyzer> analyzers, Project project)
{
EventHandler<AnalyzerExceptionDiagnosticArgs> handler = (sender, args) =>
{
if (analyzers.Contains(args.FaultedAnalyzer))
{
var workspaceArgs = new WorkspaceAnalyzerExceptionDiagnosticArgs(args, project.Solution.Workspace, project);
AnalyzerExceptionDiagnostic?.Invoke(this, workspaceArgs);
}
};
AnalyzerDriverHelper.AnalyzerExceptionDiagnostic += handler;
return handler;
}
private void UnregisterAnalyzerExceptionDiagnosticHandler(EventHandler<AnalyzerExceptionDiagnosticArgs> handler)
{
AnalyzerDriverHelper.AnalyzerExceptionDiagnostic -= handler;
}
private IEnumerable<DiagnosticData> GetDiagnosticData(Project project, ImmutableArray<Diagnostic> diagnostics)
......
......@@ -9,17 +9,19 @@ internal class WorkspaceAnalyzerExceptionDiagnosticArgs : EventArgs
public readonly Diagnostic Diagnostic;
public readonly DiagnosticAnalyzer FaultedAnalyzer;
public readonly Workspace Workspace;
public readonly Project Project;
public WorkspaceAnalyzerExceptionDiagnosticArgs(AnalyzerExceptionDiagnosticArgs args, Workspace workspace)
: this(args.FaultedAnalyzer, args.Diagnostic, workspace)
public WorkspaceAnalyzerExceptionDiagnosticArgs(AnalyzerExceptionDiagnosticArgs args, Workspace workspace, Project project)
: this(args.FaultedAnalyzer, args.Diagnostic, workspace, project)
{
}
public WorkspaceAnalyzerExceptionDiagnosticArgs(DiagnosticAnalyzer analyzer, Diagnostic diagnostic, Workspace workspace)
public WorkspaceAnalyzerExceptionDiagnosticArgs(DiagnosticAnalyzer analyzer, Diagnostic diagnostic, Workspace workspace, Project project)
{
this.FaultedAnalyzer = analyzer;
this.Diagnostic = diagnostic;
this.Workspace = workspace;
this.Project = project;
}
}
}
......@@ -77,10 +77,9 @@ public string GetAnalyzerReferenceIdentity(AnalyzerReference reference)
public ImmutableArray<DiagnosticDescriptor> GetDiagnosticDescriptors(DiagnosticAnalyzer analyzer)
{
// TODO: report diagnostics from exceptions thrown in DiagnosticAnalyzer.SupportedDiagnostics
Action<Diagnostic> dummyAddDiagnostic = _ => { };
Func<Exception, DiagnosticAnalyzer, bool> continueOnAnalyzerException = (ex, a) => !AnalyzerHelper.IsBuiltInAnalyzer(analyzer);
return AnalyzerManager.Default.GetSupportedDiagnosticDescriptors(analyzer, dummyAddDiagnostic, continueOnAnalyzerException, CancellationToken.None);
return AnalyzerManager.Default.GetSupportedDiagnosticDescriptors(analyzer, continueOnAnalyzerException, CancellationToken.None);
}
/// <summary>
......
......@@ -536,11 +536,13 @@
<Compile Include="CodeFixes\Suppression\SuppressionCodeAction.cs" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<PublicAPI Include="PublicAPI.txt" />
</ItemGroup>
<Import Project="..\..\Compilers\Core\AnalyzerDriver\AnalyzerDriver.projitems" Label="Shared" />
<ImportGroup Label="Targets">
<Import Project="..\..\Tools\Microsoft.CodeAnalysis.Toolset.Open\Targets\VSL.Imports.targets" />
<Import Project="..\..\..\build\VSL.Imports.Closed.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
</ImportGroup>
</Project>
</Project>
\ No newline at end of file
......@@ -27,11 +27,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 = AnalyzerManager.Default.GetAnalyzerActionsAsync(analyzer,
null,
null,
driver.CatchAnalyzerExceptionHandler,
driver.CancellationToken).WaitAndGetResult(driver.CancellationToken);
var analyzerActions = driver.GetAnalyzerActionsAsync(analyzer).WaitAndGetResult(driver.CancellationToken);
if (analyzerActions != null)
{
if (analyzerActions.SyntaxTreeActionsCount > 0)
......
......@@ -125,6 +125,8 @@ public void Dispose()
{
_hostDiagnosticUpdateSource.ClearDiagnosticsForProject(_projectId, this);
}
_hostDiagnosticUpdateSource.ClearAnalyzerSpecificDiagnostics((AnalyzerFileReference)_analyzerReference, _language);
}
_analyzerLoadErrors = null;
......
......@@ -17,14 +17,17 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.TaskList
internal sealed class HostDiagnosticUpdateSource : IDiagnosticUpdateSource
{
private readonly VisualStudioWorkspaceImpl _workspace;
private readonly AnalyzerDiagnosticUpdateSource _analyzerDiagnosticsSource;
private readonly Dictionary<ProjectId, HashSet<object>> _diagnosticMap = new Dictionary<ProjectId, HashSet<object>>();
[ImportingConstructor]
public HostDiagnosticUpdateSource(
VisualStudioWorkspaceImpl workspace)
VisualStudioWorkspaceImpl workspace,
AnalyzerDiagnosticUpdateSource analyzerDiagnosticsSource)
{
_workspace = workspace;
_analyzerDiagnosticsSource = analyzerDiagnosticsSource;
}
public event EventHandler<DiagnosticsUpdatedArgs> DiagnosticsUpdated;
......@@ -77,7 +80,7 @@ public void ClearAllDiagnosticsForProject(ProjectId projectId)
{
RaiseDiagnosticsUpdatedForProject(projectId, key, SpecializedCollections.EmptyEnumerable<DiagnosticData>());
}
}
}
}
public void ClearDiagnosticsForProject(ProjectId projectId, object key)
......@@ -94,5 +97,13 @@ public void ClearDiagnosticsForProject(ProjectId projectId, object key)
}
}
}
public void ClearAnalyzerSpecificDiagnostics(AnalyzerFileReference analyzerReference, string language)
{
foreach (var analyzer in analyzerReference.GetAnalyzers(language))
{
_analyzerDiagnosticsSource.ClearDiagnostics(analyzer, _workspace);
}
}
}
}
......@@ -22,7 +22,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim
<Fact, Trait(Traits.Feature, Traits.Features.Diagnostics)>
Public Sub AnalyzerErrorsAreUpdated()
Dim hostDiagnosticUpdateSource = New HostDiagnosticUpdateSource(Nothing)
Dim hostDiagnosticUpdateSource = New HostDiagnosticUpdateSource(Nothing, Nothing)
Dim file = Path.GetTempFileName()
Dim eventHandler = New EventHandlers(file)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册