提交 9fc80d30 编写于 作者: H Heejae Chang 提交者: GitHub

Merge pull request #19561 from heejaechang/fsharpbuild

tweak how we merge build and live errors for language such as F#
......@@ -5,9 +5,11 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.SolutionCrawler;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Composition;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
......@@ -138,6 +140,71 @@ public async Task TestOpenFileOnlyAnalyzerDiagnostics()
await listener.CreateWaitTask().ConfigureAwait(false);
}
[Fact]
public async Task TestSynchronizeWithBuild()
{
var workspace = new AdhocWorkspace(MefV1HostServices.Create(TestExportProvider.ExportProviderWithCSharpAndVisualBasic.AsExportProvider()));
var language = Workspaces.NoCompilationConstants.LanguageName;
var project = workspace.AddProject(
ProjectInfo.Create(
ProjectId.CreateNewId(),
VersionStamp.Create(),
"NoNameProject",
"NoNameProject",
language));
var filePath = "NoNameDoc.other";
var document = workspace.AddDocument(
DocumentInfo.Create(
DocumentId.CreateNewId(project.Id),
"Empty",
loader: TextLoader.From(TextAndVersion.Create(SourceText.From(""), VersionStamp.Create(), filePath)),
filePath: filePath));
// create listener/service/analyzer
var listener = new AsynchronousOperationListener();
var service = new MyDiagnosticAnalyzerService(new NoNameAnalyzer(), listener, language);
var analyzer = service.CreateIncrementalAnalyzer(workspace);
bool syntax = false;
// listen to events
service.DiagnosticsUpdated += (s, a) =>
{
switch (a.Diagnostics.Length)
{
case 0:
return;
case 1:
syntax |= a.Diagnostics[0].Id == NoNameAnalyzer.s_syntaxRule.Id;
return;
default:
AssertEx.Fail("shouldn't reach here");
return;
}
};
// cause analysis
await service.SynchronizeWithBuildAsync(
workspace,
ImmutableDictionary<ProjectId, ImmutableArray<DiagnosticData>>.Empty.Add(
document.Project.Id,
ImmutableArray.Create(
Diagnostic.Create(
NoNameAnalyzer.s_syntaxRule,
Location.Create(document.FilePath, TextSpan.FromBounds(0, 0), new LinePositionSpan(new LinePosition(0, 0), new LinePosition(0, 0)))).ToDiagnosticData(project))));
// wait for all events to raised
await listener.CreateWaitTask().ConfigureAwait(false);
// two should have been called.
Assert.True(syntax);
// we should reach here without crashing
}
private static Document GetDocumentFromIncompleteProject(AdhocWorkspace workspace)
{
var project = workspace.AddProject(
......@@ -160,11 +227,11 @@ private static async Task RunAllAnalysisAsync(IIncrementalAnalyzer analyzer, Doc
private class MyDiagnosticAnalyzerService : DiagnosticAnalyzerService
{
internal MyDiagnosticAnalyzerService(DiagnosticAnalyzer analyzer, IAsynchronousOperationListener listener)
internal MyDiagnosticAnalyzerService(DiagnosticAnalyzer analyzer, IAsynchronousOperationListener listener, string language = LanguageNames.CSharp)
: base(new HostAnalyzerManager(
ImmutableArray.Create<AnalyzerReference>(
new TestAnalyzerReferenceByLanguage(
ImmutableDictionary<string, ImmutableArray<DiagnosticAnalyzer>>.Empty.Add(LanguageNames.CSharp, ImmutableArray.Create(analyzer)))),
ImmutableDictionary<string, ImmutableArray<DiagnosticAnalyzer>>.Empty.Add(language, ImmutableArray.Create(analyzer)))),
hostDiagnosticUpdateSource: null),
hostDiagnosticUpdateSource: null,
registrationService: new MockDiagnosticUpdateSourceRegistrationService(),
......@@ -210,5 +277,23 @@ public bool OpenFileOnly(Workspace workspace)
return true;
}
}
private class NoNameAnalyzer : DocumentDiagnosticAnalyzer
{
internal static readonly DiagnosticDescriptor s_syntaxRule = new DiagnosticDescriptor("syntax", "test", "test", "test", DiagnosticSeverity.Error, isEnabledByDefault: true);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(s_syntaxRule);
public override async Task<ImmutableArray<Diagnostic>> AnalyzeSyntaxAsync(Document document, CancellationToken cancellationToken)
{
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
return ImmutableArray.Create(Diagnostic.Create(s_syntaxRule, Location.Create(document.FilePath, TextSpan.FromBounds(0, 0), new LinePositionSpan(new LinePosition(0, 0), new LinePosition(0, 0)))));
}
public override Task<ImmutableArray<Diagnostic>> AnalyzeSemanticsAsync(Document document, CancellationToken cancellationToken)
{
return SpecializedTasks.Default<ImmutableArray<Diagnostic>>();
}
}
}
}
......@@ -122,6 +122,14 @@ public StateSet GetOrCreateStateSet(Project project, DiagnosticAnalyzer analyzer
/// </summary>
public ImmutableArray<StateSet> CreateBuildOnlyProjectStateSet(Project project)
{
if (!project.SupportsCompilation)
{
// languages which don't use our compilation model but diagnostic framework,
// all their analyzer should be host analyzers. return all host analyzers
// for the language
return _hostStates.GetOrCreateStateSets(project.Language).ToImmutableArray();
}
// create project analyzer reference identity map
var referenceIdentities = project.AnalyzerReferences.Select(r => _analyzerManager.GetAnalyzerReferenceIdentity(r)).ToSet();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册