在 s 中访问MSBuild属性和元数据实际上与在s/ sDiagnosticAnalyzer
中读取和测试它们的方式非常相似,因为源生成器在技术上也是.NET 分析器。ISourceGenerator
IIncrementalGenerator
我假设您提到的文档是Source Generators Cookbook。
首先,我们需要使MSBuild属性可用于分析器的全局分析器配置选项:
<Project>
<ItemGroup>
<CompilerVisibleProperty Include="MyAnalyzer_MyProperty" />
</ItemGroup>
</Project>
然后,我们可以从AnalyzerConfigOptionsProvider中读取该属性的值GlobalOptions
。AnalysisContext.Register*
您可以在覆盖方法中使用的您选择的方法的参数中找到它DiagnosticAnalyzer.Initialize(AnalysisContext)
。例如RegisterCompilationAction
:
bool isEnabled = false;
if (compilationAnalysisContext.Options.AnalyzerConfigOptionsProvider.GlobalOptions.TryGetValue("build_property.MyAnalyzer_MyProperty", out string? value))
{
isEnabled = value.Equals("true", StringComparison.OrdinalIgnoreCase) || value.Equals("enable", StringComparison.OrdinalIgnoreCase);
}
ImmutableDictionary<string, string?>.Builder properties = ImmutableDictionary.CreateBuilder<string, string?>();
if (isEnabled)
{
properties.Add("IsEnabled", value);
}
var diagnostic = Diagnostic.Create(Rule, location, properties.ToImmutable());
compilationAnalysisContext.ReportDiagnostic(diagnostic);
' CodeFixProvider
sCodeFixContext
没有专用AnalyzerOptions Options
属性,但您可以通过以下方式传递值Diagnostic.Properties
:
foreach (Diagnostic diagnostic in context.Diagnostics)
{
if (diagnostic.Properties.TryGetValue("IsEnabled", out string? value))
{
var action = CodeAction.Create(Title, cancellationToken => OnCreateChangedDocument(context.Document, cancellationToken), diagnostic.Id);
context.RegisterCodeFix(action, diagnostic);
}
}
...或者,我在撰写此答案时刚刚发现的内容,访问AnalyzerConfigOptionsProvider
through CodeFixContext.Document.Project.AnalyzerOptions
。这适用于您有Document
(或Project
)可用的任何地方:
public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
bool hasValue = context.Document.Project.AnalyzerOptions.AnalyzerConfigOptionsProvider.GlobalOptions.TryGetValue("build_property.MyAnalyzer_MyProperty", out string? value);
}
此外,它适用于CodeRefactoringProvider
:
public override Task ComputeRefactoringsAsync(CodeRefactoringContext context)
{
bool hasValue = context.Document.Project.AnalyzerOptions.AnalyzerConfigOptionsProvider.GlobalOptions.TryGetValue("build_property.MyAnalyzer_MyProperty", out string? value);
return Task.CompletedTask;
}
...并与CompletionProvider
:
public override Task ProvideCompletionsAsync(CompletionContext context)
{
bool hasValue = context.Document.Project.AnalyzerOptions.AnalyzerConfigOptionsProvider.GlobalOptions.TryGetValue("build_property.MyAnalyzer_MyProperty", out string? value);
return Task.CompletedTask;
}
...还有DiagnosticSuppressor
:
public override void ReportSuppressions(SuppressionAnalysisContext context)
{
bool hasValue = context.Options.AnalyzerConfigOptionsProvider.GlobalOptions.TryGetValue("build_property.MyAnalyzer_MyProperty", out string? value);
}
对于通过Microsoft.CodeAnalysis.Testing进行测试,您可以通过 的ProjectState.AnalyzerConfigFiles
属性添加全局分析器配置选项:AnalyzerTest<TVerifier>
SolutionState TestState
string config = $"is_global = true{Environment.NewLine}build_property.MyAnalyzer_MyProperty = {true}";
analyzerTest.TestState.AnalyzerConfigFiles.Add(("/.globalconfig", config));
上面我描述了自定义 MSBuild 属性的用法MyAnalyzer_MyProperty
,但当然它也适用于众所周知的ImplicitUsings
属性。