提交 f8491ab5 编写于 作者: H Heejae Chang

doing more basic arrangement for oop

上级 aa6d5faf
// 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.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Diagnostics.EngineV2
{
internal partial class DiagnosticIncrementalAnalyzer : BaseDiagnosticIncrementalAnalyzer
{
// TODO: implement active file state
// this should hold onto local syntax/semantic diagnostics for active file in memory.
// this should also hold onto CompilationWithAnalyzer last time used.
// this should use syntax/semantic version for its version
private class ActiveFileState
{
}
}
}
// 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.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Diagnostics.EngineV2
{
internal partial class DiagnosticIncrementalAnalyzer : BaseDiagnosticIncrementalAnalyzer
{
// TODO: implement project state
// this should hold onto information similar to CompilerDiagnsoticExecutor.AnalysisResult
// this should use dependant project version as its version
// this should only cache opened file diagnostics in memory, and all diagnostics in other place.
// we might just use temporary storage rather than peristant storage. but will see.
// now we don't update individual document incrementally.
// but some data might comes from active file state.
private class ProjectState
{
}
}
}
......@@ -5,10 +5,13 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Options;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Diagnostics.EngineV2
{
// TODO: implement correct events and etc.
internal partial class DiagnosticIncrementalAnalyzer : BaseDiagnosticIncrementalAnalyzer
{
private readonly int _correlationId;
......@@ -24,6 +27,19 @@ internal partial class DiagnosticIncrementalAnalyzer : BaseDiagnosticIncremental
_correlationId = correlationId;
}
private static bool AnalysisEnabled(Document document)
{
// change it to check active file (or visible files), not open files if active file tracking is enabled.
// otherwise, use open file.
return document.IsOpen();
}
private bool FullAnalysisEnabled(Workspace workspace, string language)
{
return workspace.Options.GetOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, language) &&
workspace.Options.GetOption(RuntimeOptions.FullSolutionAnalysis);
}
private async Task<ImmutableArray<DiagnosticData>> GetProjectDiagnosticsAsync(Project project, bool includeSuppressedDiagnostics, CancellationToken cancellationToken)
{
if (project == null)
......
......@@ -8,19 +8,17 @@ namespace Microsoft.CodeAnalysis.Diagnostics.EngineV2
{
internal partial class DiagnosticIncrementalAnalyzer : BaseDiagnosticIncrementalAnalyzer
{
// TODO: this API will be changed to 1 API that gives all diagnostics under a project
// and that will simply replace project state
public override Task SynchronizeWithBuildAsync(DiagnosticAnalyzerService.BatchUpdateToken token, Project project, ImmutableArray<DiagnosticData> diagnostics)
{
// V2 engine doesn't do anything.
// it means live error always win over build errors. build errors that can't be reported by live analyzer
// are already taken cared by engine
// TODO: for now, we dont do anything.
return SpecializedTasks.EmptyTask;
}
public override Task SynchronizeWithBuildAsync(DiagnosticAnalyzerService.BatchUpdateToken token, Document document, ImmutableArray<DiagnosticData> diagnostics)
{
// V2 engine doesn't do anything.
// it means live error always win over build errors. build errors that can't be reported by live analyzer
// are already taken cared by engine
// TODO: for now, we dont do anything.
return SpecializedTasks.EmptyTask;
}
}
......
......@@ -8,6 +8,7 @@
namespace Microsoft.CodeAnalysis.Diagnostics.EngineV2
{
// TODO: need to mimic what V1 does. use cache if possible, otherwise, calculate at the spot.
internal partial class DiagnosticIncrementalAnalyzer : BaseDiagnosticIncrementalAnalyzer
{
public override Task<ImmutableArray<DiagnosticData>> GetSpecificCachedDiagnosticsAsync(Solution solution, object id, bool includeSuppressedDiagnostics = false, CancellationToken cancellationToken = default(CancellationToken))
......
......@@ -9,6 +9,7 @@
namespace Microsoft.CodeAnalysis.Diagnostics.EngineV2
{
// TODO: we need to do what V1 does for LB for span.
internal partial class DiagnosticIncrementalAnalyzer : BaseDiagnosticIncrementalAnalyzer
{
public override async Task<bool> TryAppendDiagnosticsForSpanAsync(Document document, TextSpan range, List<DiagnosticData> result, bool includeSuppressedDiagnostics = false, CancellationToken cancellationToken = default(CancellationToken))
......
// 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.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Diagnostics.EngineV2
{
// TODO: make it to use cache
internal partial class DiagnosticIncrementalAnalyzer : BaseDiagnosticIncrementalAnalyzer
{
public override Task AnalyzeSyntaxAsync(Document document, CancellationToken cancellationToken)
public async override Task AnalyzeSyntaxAsync(Document document, CancellationToken cancellationToken)
{
return SpecializedTasks.EmptyTask;
}
if (!AnalysisEnabled(document))
{
return;
}
public override Task AnalyzeDocumentAsync(Document document, SyntaxNode bodyOpt, CancellationToken cancellationToken)
{
return SpecializedTasks.EmptyTask;
}
// TODO: make active file state to cache compilationWithAnalyzer
// REVIEW: this is really wierd that we need compilation for syntax diagnostics which basically defeat any reason
// we have syntax diagnostics.
var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
public override async Task AnalyzeProjectAsync(Project project, bool semanticsChanged, CancellationToken cancellationToken)
{
var diagnostics = await GetDiagnosticsAsync(project.Solution, project.Id, null, includeSuppressedDiagnostics: true, cancellationToken: cancellationToken).ConfigureAwait(false);
// TODO: make it to use state manager
var analyzers = HostAnalyzerManager.CreateDiagnosticAnalyzers(document.Project);
RaiseEvents(project, diagnostics);
// Create driver that holds onto compilation and associated analyzers
// TODO: use CompilationWithAnalyzerOption instead of AnalyzerOption so that we can have exception filter and etc
var analyzerDriver = compilation.WithAnalyzers(analyzers, document.Project.AnalyzerOptions, cancellationToken);
foreach (var analyzer in analyzers)
{
// TODO: implement perf optimization not to run analyzers that are not needed.
// REVIEW: more unnecessary allocations just to get diagnostics per analyzer
var oneAnalyzers = ImmutableArray.Create(analyzer);
// TODO: use cache for perf optimization
var diagnostics = await analyzerDriver.GetAnalyzerSyntaxDiagnosticsAsync(tree, oneAnalyzers, cancellationToken).ConfigureAwait(false);
// we only care about local diagnostics
var diagnosticData = GetDiagnosticData(document.Project, diagnostics).Where(d => d.DocumentId == document.Id);
// TODO: update using right arguments
Owner.RaiseDiagnosticsUpdated(
this, DiagnosticsUpdatedArgs.DiagnosticsCreated(
ValueTuple.Create(this, "Syntax", document.Id), document.Project.Solution.Workspace, document.Project.Solution, document.Project.Id, document.Id, diagnosticData.ToImmutableArrayOrEmpty()));
}
}
public override Task DocumentOpenAsync(Document document, CancellationToken cancellationToken)
public override async Task AnalyzeDocumentAsync(Document document, SyntaxNode bodyOpt, CancellationToken cancellationToken)
{
return SpecializedTasks.EmptyTask;
if (!AnalysisEnabled(document))
{
return;
}
// TODO: make active file state to cache compilationWithAnalyzer
var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
// TODO: make it to use state manager
var analyzers = HostAnalyzerManager.CreateDiagnosticAnalyzers(document.Project);
// Create driver that holds onto compilation and associated analyzers
// TODO: use CompilationWithAnalyzerOption instead of AnalyzerOption so that we can have exception filter and etc
var analyzerDriver = compilation.WithAnalyzers(analyzers, document.Project.AnalyzerOptions, cancellationToken);
var noSpanFilter = default(TextSpan?);
foreach (var analyzer in analyzers)
{
// REVIEW: more unnecessary allocations just to get diagnostics per analyzer
var oneAnalyzers = ImmutableArray.Create(analyzer);
// TODO: use cache for perf optimization
// REVIEW: I think we don't even need member tracking optimization
var diagnostics = await analyzerDriver.GetAnalyzerSemanticDiagnosticsAsync(model, noSpanFilter, oneAnalyzers, cancellationToken).ConfigureAwait(false);
var diagnosticData = GetDiagnosticData(document.Project, diagnostics).Where(d => d.DocumentId == document.Id);
// TODO: update using right arguments
Owner.RaiseDiagnosticsUpdated(
this, DiagnosticsUpdatedArgs.DiagnosticsCreated(
ValueTuple.Create(this, "Semantic", document.Id), document.Project.Solution.Workspace, document.Project.Solution, document.Project.Id, document.Id, diagnosticData.ToImmutableArrayOrEmpty()));
}
}
public override Task DocumentCloseAsync(Document document, CancellationToken cancellationToken)
{
// TODO: at this event, if file being closed is active file (the one in ActiveFileState), we should put that data into
// ProjectState
return SpecializedTasks.EmptyTask;
}
public override Task DocumentResetAsync(Document document, CancellationToken cancellationToken)
{
return SpecializedTasks.EmptyTask;
}
public override Task NewSolutionSnapshotAsync(Solution solution, CancellationToken cancellationToken)
{
// REVIEW: this should reset both active file and project state the document belong to.
return SpecializedTasks.EmptyTask;
}
public override void RemoveDocument(DocumentId documentId)
{
// TODO: do proper eventing
Owner.RaiseDiagnosticsUpdated(this, DiagnosticsUpdatedArgs.DiagnosticsRemoved(
ValueTuple.Create(this, "Syntax", documentId), Workspace, null, null, null));
Owner.RaiseDiagnosticsUpdated(this, DiagnosticsUpdatedArgs.DiagnosticsRemoved(
ValueTuple.Create(this, "Semantic", documentId), Workspace, null, null, null));
Owner.RaiseDiagnosticsUpdated(this, DiagnosticsUpdatedArgs.DiagnosticsRemoved(
ValueTuple.Create(this, documentId), Workspace, null, null, null));
}
public override async Task AnalyzeProjectAsync(Project project, bool semanticsChanged, CancellationToken cancellationToken)
{
if (!FullAnalysisEnabled(project.Solution.Workspace, project.Language))
{
// TODO: check whether there is existing state, if so, raise events to remove them all.
return;
}
// TODO: make this to use cache.
// TODO: use CompilerDiagnosticExecutor
var diagnostics = await GetDiagnosticsAsync(project.Solution, project.Id, null, includeSuppressedDiagnostics: true, cancellationToken: cancellationToken).ConfigureAwait(false);
// TODO: do proper event
RaiseEvents(project, diagnostics);
}
public override void RemoveProject(ProjectId projectId)
{
// TODO: do proper event
Owner.RaiseDiagnosticsUpdated(this, DiagnosticsUpdatedArgs.DiagnosticsRemoved(
ValueTuple.Create(this, projectId), Workspace, null, null, null));
}
public override Task DocumentOpenAsync(Document document, CancellationToken cancellationToken)
{
// Review: I think we don't need to care about it
return SpecializedTasks.EmptyTask;
}
public override Task NewSolutionSnapshotAsync(Solution solution, CancellationToken cancellationToken)
{
// we don't use this one.
return SpecializedTasks.EmptyTask;
}
}
}
......@@ -180,6 +180,8 @@
<Compile Include="Diagnostics\DiagnosticService_UpdateSourceRegistrationService.cs" />
<Compile Include="Common\UpdatedEventArgs.cs" />
<Compile Include="Diagnostics\EngineV2\CompilerDiagnosticExecutor.cs" />
<Compile Include="Diagnostics\EngineV2\DiagnosticIncrementalAnalyzer.ActiveFileState.cs" />
<Compile Include="Diagnostics\EngineV2\DiagnosticIncrementalAnalyzer.ProjectState.cs" />
<Compile Include="Diagnostics\EngineV2\DiagnosticIncrementalAnalyzer_BuildSynchronization.cs" />
<Compile Include="Diagnostics\EngineV2\DiagnosticIncrementalAnalyzer_GetDiagnostics.cs" />
<Compile Include="Diagnostics\EngineV2\DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册