Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make more APIs project-based in diag service. #77122

Merged
merged 13 commits into from
Feb 10, 2025
2 changes: 1 addition & 1 deletion src/EditorFeatures/Test/CodeFixes/CodeFixServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1075,7 +1075,7 @@ await VerifyCachedDiagnosticsAsync(
: root.DescendantNodes().OfType<CodeAnalysis.CSharp.Syntax.InvocationExpressionSyntax>().First().Span;

await analyzerService.GetDiagnosticsForIdsAsync(
sourceDocument.Project.Solution, sourceDocument.Project.Id, sourceDocument.Id, diagnosticIds: null, shouldIncludeAnalyzer: null,
sourceDocument.Project, sourceDocument.Id, diagnosticIds: null, shouldIncludeAnalyzer: null,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

most callers had a project, but would then use it to pass a Solution+ProjectId. Simpler to just pass Project

includeLocalDocumentDiagnostics: true, includeNonLocalDocumentDiagnostics: true, CancellationToken.None);
// await diagnosticIncrementalAnalyzer.GetTestAccessor().TextDocumentOpenAsync(sourceDocument);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public async Task TestHasSuccessfullyLoadedBeingFalse()
var globalOptions = exportProvider.GetExportedValue<IGlobalOptionService>();

var diagnostics = await service.GetDiagnosticsForIdsAsync(
workspace.CurrentSolution, projectId: workspace.CurrentSolution.ProjectIds.Single(), documentId: null, diagnosticIds: null, shouldIncludeAnalyzer: null,
workspace.CurrentSolution.Projects.Single(), documentId: null, diagnosticIds: null, shouldIncludeAnalyzer: null,
includeLocalDocumentDiagnostics: true, includeNonLocalDocumentDiagnostics: false, CancellationToken.None);
Assert.NotEmpty(diagnostics);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ Namespace Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics.UnitTests

For Each project In workspace.CurrentSolution.Projects
actualDiagnostics.AddRange(diagnosticProvider.GetDiagnosticsForIdsAsync(
workspace.CurrentSolution, project.Id, documentId:=Nothing, diagnosticIds:=Nothing, shouldIncludeAnalyzer:=Nothing,
project, documentId:=Nothing, diagnosticIds:=Nothing, shouldIncludeAnalyzer:=Nothing,
includeLocalDocumentDiagnostics:=True, includeNonLocalDocumentDiagnostics:=True, CancellationToken.None).Result)
Next

Expand Down
14 changes: 7 additions & 7 deletions src/EditorFeatures/Test2/Diagnostics/DiagnosticServiceTests.vb
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ Namespace Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics.UnitTests
Assert.Empty(diagnostics)

diagnostics = Await diagnosticService.GetDiagnosticsForIdsAsync(
project.Solution, projectId:=document.Project.Id, documentId:=Nothing, diagnosticIds:=Nothing, shouldIncludeAnalyzer:=Nothing,
project, documentId:=Nothing, diagnosticIds:=Nothing, shouldIncludeAnalyzer:=Nothing,
includeLocalDocumentDiagnostics:=True, includeNonLocalDocumentDiagnostics:=True, CancellationToken.None)
Dim diagnostic = diagnostics.First()
Assert.True(diagnostic.Id = "AD0001")
Expand Down Expand Up @@ -595,7 +595,7 @@ Namespace Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics.UnitTests

Dim document = project.Documents.Single()
Dim diagnostics = Await diagnosticService.GetDiagnosticsForIdsAsync(
project.Solution, project.Id, documentId:=Nothing, diagnosticIds:=Nothing, shouldIncludeAnalyzer:=Nothing,
project, documentId:=Nothing, diagnosticIds:=Nothing, shouldIncludeAnalyzer:=Nothing,
includeLocalDocumentDiagnostics:=True, includeNonLocalDocumentDiagnostics:=True, CancellationToken.None)
Assert.Equal(1, diagnostics.Length)
Dim diagnostic = diagnostics.First()
Expand Down Expand Up @@ -789,7 +789,7 @@ class AnonymousFunctions
' Test "GetDiagnosticsForIdsAsync" does force computation of compilation end diagnostics.
' Verify compilation diagnostics are reported with correct location info when asked for project diagnostics.
Dim projectDiagnostics = Await diagnosticService.GetDiagnosticsForIdsAsync(
project.Solution, project.Id, documentId:=Nothing,
project, documentId:=Nothing,
diagnosticIds:=Nothing, shouldIncludeAnalyzer:=Nothing,
includeLocalDocumentDiagnostics:=True, includeNonLocalDocumentDiagnostics:=True, CancellationToken.None)
Assert.Equal(2, projectDiagnostics.Length)
Expand Down Expand Up @@ -933,7 +933,7 @@ class AnonymousFunctions
' Verify no duplicate analysis/diagnostics.
Dim document = project.Documents.Single()
Dim diagnostics = (Await diagnosticService.GetDiagnosticsForIdsAsync(
project.Solution, project.Id, documentId:=Nothing, diagnosticIds:=Nothing, shouldIncludeAnalyzer:=Nothing,
project, documentId:=Nothing, diagnosticIds:=Nothing, shouldIncludeAnalyzer:=Nothing,
includeLocalDocumentDiagnostics:=True, includeNonLocalDocumentDiagnostics:=True, CancellationToken.None)).
Select(Function(d) d.Id = NamedTypeAnalyzer.DiagDescriptor.Id)

Expand Down Expand Up @@ -1026,7 +1026,7 @@ class AnonymousFunctions

' Verify project diagnostics contains diagnostics reported on both partial definitions.
Dim diagnostics = Await diagnosticService.GetDiagnosticsForIdsAsync(
project.Solution, project.Id, documentId:=Nothing, diagnosticIds:=Nothing, shouldIncludeAnalyzer:=Nothing,
project, documentId:=Nothing, diagnosticIds:=Nothing, shouldIncludeAnalyzer:=Nothing,
includeLocalDocumentDiagnostics:=True, includeNonLocalDocumentDiagnostics:=True, CancellationToken.None)
Assert.Equal(2, diagnostics.Length)
Dim file1HasDiag = False, file2HasDiag = False
Expand Down Expand Up @@ -2117,7 +2117,7 @@ class MyClass

' Get diagnostics explicitly
Dim hiddenDiagnostics = Await diagnosticService.GetDiagnosticsForIdsAsync(
project.Solution, project.Id, documentId:=Nothing, diagnosticIds:=Nothing, shouldIncludeAnalyzer:=Nothing,
project, documentId:=Nothing, diagnosticIds:=Nothing, shouldIncludeAnalyzer:=Nothing,
includeLocalDocumentDiagnostics:=True, includeNonLocalDocumentDiagnostics:=True, CancellationToken.None)
Assert.Equal(1, hiddenDiagnostics.Length)
Assert.Equal(analyzer.Descriptor.Id, hiddenDiagnostics.Single().Id)
Expand Down Expand Up @@ -2202,7 +2202,7 @@ class C
Assert.Equal(1, descriptorsMap.Count)

Dim diagnostics = Await diagnosticService.GetDiagnosticsForIdsAsync(
project.Solution, project.Id, documentId:=Nothing, diagnosticIds:=Nothing, shouldIncludeAnalyzer:=Nothing,
project, documentId:=Nothing, diagnosticIds:=Nothing, shouldIncludeAnalyzer:=Nothing,
includeLocalDocumentDiagnostics:=True, includeNonLocalDocumentDiagnostics:=True, CancellationToken.None)
Assert.Empty(diagnostics)
End Using
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,10 @@ internal interface IDiagnosticAnalyzerService
/// <summary>
/// Get diagnostics of the given diagnostic ids and/or analyzers from the given solution. all diagnostics returned
/// should be up-to-date with respect to the given solution. Note that for project case, this method returns
/// diagnostics from all project documents as well. Use <see cref="GetProjectDiagnosticsForIdsAsync(Solution,
/// ProjectId?, ImmutableHashSet{string}?, Func{DiagnosticAnalyzer, bool}?, bool, CancellationToken)"/> if you want
/// diagnostics from all project documents as well. Use <see cref="GetProjectDiagnosticsForIdsAsync"/> if you want
/// to fetch only project diagnostics without source locations.
/// </summary>
/// <param name="solution">Solution to fetch the diagnostics for.</param>
/// <param name="projectId">Optional project to scope the returned diagnostics.</param>
/// <param name="project">Project to fetch the diagnostics for.</param>
/// <param name="documentId">Optional document to scope the returned diagnostics.</param>
/// <param name="diagnosticIds">Optional set of diagnostic IDs to scope the returned diagnostics.</param>
/// <param name="shouldIncludeAnalyzer">Option callback to filter out analyzers to execute for computing diagnostics.</param>
Expand All @@ -51,16 +49,15 @@ internal interface IDiagnosticAnalyzerService
/// project must be analyzed to get the complete set of non-local document diagnostics.
/// </param>
/// <param name="cancellationToken">Cancellation token.</param>
Task<ImmutableArray<DiagnosticData>> GetDiagnosticsForIdsAsync(Solution solution, ProjectId projectId, DocumentId? documentId, ImmutableHashSet<string>? diagnosticIds, Func<DiagnosticAnalyzer, bool>? shouldIncludeAnalyzer, bool includeLocalDocumentDiagnostics, bool includeNonLocalDocumentDiagnostics, CancellationToken cancellationToken);
Task<ImmutableArray<DiagnosticData>> GetDiagnosticsForIdsAsync(Project project, DocumentId? documentId, ImmutableHashSet<string>? diagnosticIds, Func<DiagnosticAnalyzer, bool>? shouldIncludeAnalyzer, bool includeLocalDocumentDiagnostics, bool includeNonLocalDocumentDiagnostics, CancellationToken cancellationToken);

/// <summary>
/// Get project diagnostics (diagnostics with no source location) of the given diagnostic ids and/or analyzers from
/// the given solution. all diagnostics returned should be up-to-date with respect to the given solution. Note that
/// this method doesn't return any document diagnostics. Use <see cref="GetDiagnosticsForIdsAsync"/> to also fetch
/// those.
/// </summary>
/// <param name="solution">Solution to fetch the diagnostics for.</param>
/// <param name="projectId">Optional project to scope the returned diagnostics.</param>
/// <param name="project">Project to fetch the diagnostics for.</param>
/// <param name="diagnosticIds">Optional set of diagnostic IDs to scope the returned diagnostics.</param>
/// <param name="shouldIncludeAnalyzer">Option callback to filter out analyzers to execute for computing diagnostics.</param>
/// <param name="includeNonLocalDocumentDiagnostics">
Expand All @@ -69,7 +66,7 @@ internal interface IDiagnosticAnalyzerService
/// Entire project must be analyzed to get the complete set of non-local diagnostics.
/// </param>
/// <param name="cancellationToken">Cancellation token.</param>
Task<ImmutableArray<DiagnosticData>> GetProjectDiagnosticsForIdsAsync(Solution solution, ProjectId projectId, ImmutableHashSet<string>? diagnosticIds, Func<DiagnosticAnalyzer, bool>? shouldIncludeAnalyzer, bool includeNonLocalDocumentDiagnostics, CancellationToken cancellationToken);
Task<ImmutableArray<DiagnosticData>> GetProjectDiagnosticsForIdsAsync(Project project, ImmutableHashSet<string>? diagnosticIds, Func<DiagnosticAnalyzer, bool>? shouldIncludeAnalyzer, bool includeNonLocalDocumentDiagnostics, CancellationToken cancellationToken);

/// <summary>
/// Return up to date diagnostics for the given span for the document
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ private async Task<IEnumerable<Diagnostic>> GetDiagnosticsAsync(
{
var text = await document.GetTextAsync().ConfigureAwait(false);
var dxs = await _diagnosticAnalyzerService.GetDiagnosticsForIdsAsync(
project.Solution, project.Id, document.Id, diagnosticIds: null, shouldIncludeAnalyzer: null,
project, document.Id, diagnosticIds: null, shouldIncludeAnalyzer: null,
includeLocalDocumentDiagnostics: true, _includeNonLocalDocumentDiagnostics, CancellationToken.None);
dxs = dxs.WhereAsArray(d => _includeSuppressedDiagnostics || !d.IsSuppressed);
documentDiagnostics = await CodeAnalysis.Diagnostics.Extensions.ToDiagnosticsAsync(
Expand All @@ -62,7 +62,7 @@ filterSpan is null
if (getProjectDiagnostics)
{
var dxs = await _diagnosticAnalyzerService.GetDiagnosticsForIdsAsync(
project.Solution, project.Id, documentId: null, diagnosticIds: null, shouldIncludeAnalyzer: null,
project, documentId: null, diagnosticIds: null, shouldIncludeAnalyzer: null,
includeLocalDocumentDiagnostics: true, _includeNonLocalDocumentDiagnostics, CancellationToken.None);
dxs = dxs.WhereAsArray(d => _includeSuppressedDiagnostics || !d.IsSuppressed);
projectDiagnostics = await CodeAnalysis.Diagnostics.Extensions.ToDiagnosticsAsync(dxs.Where(d => d.DocumentId is null), project, CancellationToken.None);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,8 @@ private ImmutableArray<DiagnosticData> Filter(ImmutableArray<DiagnosticData> dia

public override async Task<IEnumerable<Diagnostic>> GetDocumentDiagnosticsAsync(Document document, CancellationToken cancellationToken)
{
var solution = document.Project.Solution;
var diagnostics = Filter(await _diagnosticService.GetDiagnosticsForIdsAsync(
solution, projectId: document.Project.Id, document.Id, _diagnosticIds, shouldIncludeAnalyzer: null, includeLocalDocumentDiagnostics: true, includeNonLocalDocumentDiagnostics: false, cancellationToken).ConfigureAwait(false));
document.Project, document.Id, _diagnosticIds, shouldIncludeAnalyzer: null, includeLocalDocumentDiagnostics: true, includeNonLocalDocumentDiagnostics: false, cancellationToken).ConfigureAwait(false));
Contract.ThrowIfFalse(diagnostics.All(d => d.DocumentId != null));
return await diagnostics.ToDiagnosticsAsync(document.Project, cancellationToken).ConfigureAwait(false);
}
Expand All @@ -68,15 +67,15 @@ public override async Task<IEnumerable<Diagnostic>> GetAllDiagnosticsAsync(Proje
{
// Get all diagnostics for the entire project, including document diagnostics.
var diagnostics = Filter(await _diagnosticService.GetDiagnosticsForIdsAsync(
project.Solution, project.Id, documentId: null, _diagnosticIds, shouldIncludeAnalyzer: null, includeLocalDocumentDiagnostics: true, includeNonLocalDocumentDiagnostics: false, cancellationToken).ConfigureAwait(false));
project, documentId: null, _diagnosticIds, shouldIncludeAnalyzer: null, includeLocalDocumentDiagnostics: true, includeNonLocalDocumentDiagnostics: false, cancellationToken).ConfigureAwait(false));
return await diagnostics.ToDiagnosticsAsync(project, cancellationToken).ConfigureAwait(false);
}

public override async Task<IEnumerable<Diagnostic>> GetProjectDiagnosticsAsync(Project project, CancellationToken cancellationToken)
{
// Get all no-location diagnostics for the project, doesn't include document diagnostics.
var diagnostics = Filter(await _diagnosticService.GetProjectDiagnosticsForIdsAsync(
project.Solution, project.Id, _diagnosticIds, shouldIncludeAnalyzer: null, includeNonLocalDocumentDiagnostics: false, cancellationToken).ConfigureAwait(false));
project, _diagnosticIds, shouldIncludeAnalyzer: null, includeNonLocalDocumentDiagnostics: false, cancellationToken).ConfigureAwait(false));
Contract.ThrowIfFalse(diagnostics.All(d => d.DocumentId == null));
return await diagnostics.ToDiagnosticsAsync(project, cancellationToken).ConfigureAwait(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.SolutionCrawler;
using Microsoft.CodeAnalysis.Text;
Expand Down Expand Up @@ -100,19 +101,19 @@ public async Task<ImmutableArray<DiagnosticData>> ForceAnalyzeProjectAsync(Proje
}

public Task<ImmutableArray<DiagnosticData>> GetDiagnosticsForIdsAsync(
Solution solution, ProjectId projectId, DocumentId? documentId, ImmutableHashSet<string>? diagnosticIds, Func<DiagnosticAnalyzer, bool>? shouldIncludeAnalyzer, bool includeLocalDocumentDiagnostics, bool includeNonLocalDocumentDiagnostics, CancellationToken cancellationToken)
Project project, DocumentId? documentId, ImmutableHashSet<string>? diagnosticIds, Func<DiagnosticAnalyzer, bool>? shouldIncludeAnalyzer, bool includeLocalDocumentDiagnostics, bool includeNonLocalDocumentDiagnostics, CancellationToken cancellationToken)
{
var analyzer = CreateIncrementalAnalyzer(solution.Workspace);
return analyzer.GetDiagnosticsForIdsAsync(solution, projectId, documentId, diagnosticIds, shouldIncludeAnalyzer, includeLocalDocumentDiagnostics, includeNonLocalDocumentDiagnostics, cancellationToken);
var analyzer = CreateIncrementalAnalyzer(project.Solution.Workspace);
return analyzer.GetDiagnosticsForIdsAsync(project, documentId, diagnosticIds, shouldIncludeAnalyzer, includeLocalDocumentDiagnostics, includeNonLocalDocumentDiagnostics, cancellationToken);
}

public Task<ImmutableArray<DiagnosticData>> GetProjectDiagnosticsForIdsAsync(
Solution solution, ProjectId projectId, ImmutableHashSet<string>? diagnosticIds,
Project project, ImmutableHashSet<string>? diagnosticIds,
Func<DiagnosticAnalyzer, bool>? shouldIncludeAnalyzer,
bool includeNonLocalDocumentDiagnostics, CancellationToken cancellationToken)
{
var analyzer = CreateIncrementalAnalyzer(solution.Workspace);
return analyzer.GetProjectDiagnosticsForIdsAsync(solution, projectId, diagnosticIds, shouldIncludeAnalyzer, includeNonLocalDocumentDiagnostics, cancellationToken);
var analyzer = CreateIncrementalAnalyzer(project.Solution.Workspace);
return analyzer.GetProjectDiagnosticsForIdsAsync(project, diagnosticIds, shouldIncludeAnalyzer, includeNonLocalDocumentDiagnostics, cancellationToken);
}

public TestAccessor GetTestAccessor()
Expand Down
Loading
Loading