如何将额外的文件添加到专门的Roslyn工作区中,以将它们公开给分析器
本文关键字:工作区 分析器 文件 添加 Roslyn | 更新日期: 2023-09-27 18:25:25
我正在创建一些Roslyn分析器,它们使用AdditionFiles
功能来访问设置文件。我正在尝试测试分析仪是否正确使用此功能。
我有一种方法可以设置一个临时测试工作区,我尝试通过两种途径添加额外的文档:
private static Project CreateProject(IEnumerable<string> sources)
{
var projectId = ProjectId.CreateNewId(TestProjectName);
var solution = new AdhocWorkspace()
.CurrentSolution
.AddProject(projectId, TestProjectName, TestProjectName, LanguageNames.CSharp)
.AddMetadataReference(projectId, CorlibReference)
.AddMetadataReference(projectId, SystemCoreReference)
.AddAdditionalDocument(DocumentInfo.Create(DocumentId.CreateNewId(projectId),
"arnolyzer.yaml",
filePath: @"..'..'arnolyzer.yaml"));
var count = 0;
foreach (var source in sources)
{
var newFileName = $"{DefaultFilePathPrefix}{count++}.{CSharpDefaultFileExt}";
var documentId = DocumentId.CreateNewId(projectId, newFileName);
solution = solution.AddDocument(documentId, newFileName, SourceText.From(source));
}
var settingsFileId = DocumentId.CreateNewId(projectId, "arnolyzer.yaml");
solution = solution.AddAdditionalDocument(settingsFileId, "arnolyzer.yaml", SourceText.From(@"..'..'arnolyzer.yaml"));
return solution.GetProject(projectId);
}
检查Project
实例,我可以看到已经添加了两个附加文档。
然而,当在AnalysisContext.RegisterCompilationStartAction
动作内检查CompilationStartAnalysisContext.Options.AdditionalFiles
时,AdditionalFiles
为空。
有人知道这种方法是否有效,因此我是否在某个地方出错了吗?还是添加到Project
的附加文档与AditionalFiles
功能无关?
这不会直接回答您的问题,但您提到您正在尝试测试分析器是否使用附加文件。因此,以下是我们解决问题的方法:
var compilationWithAnalyzer = compilation.WithAnalyzers(
diagnosticAnalyzers,
new AnalyzerOptions(ImmutableArray.Create<AdditionalText>(new AnalyzerAdditionalFile(configuration.Path))),
tokenSource.Token);
var diagnostics = await compilationWithAnalyzer.GetAnalyzerDiagnosticsAsync();
其中AnalyzerAdditionalFile
仅扩展AdditionalText
:
public sealed class AnalyzerAdditionalFile : AdditionalText
{
private readonly string path;
public AnalyzerAdditionalFile(string path)
{
this.path = path;
}
public override string Path => path;
public override SourceText GetText(CancellationToken cancellationToken)
{
return SourceText.From(File.ReadAllText(path));
}
}