【发布时间】:2019-01-22 15:32:04
【问题描述】:
我正在尝试编写一个分析器来阻止用户提供自动提供的参数(例如:由带有[CallerMemberName] 的编译器提供)并且我希望分析器在您提供不应该提供的参数时向您报错提供(告诉不应该提供参数我创建了一个属性:DontProvideAttribute)。
事情是这样自动提供的参数必须是可选的(否则用户提供的值将覆盖自动提供的值)所以我进行了第二次分析以防止用户在非可选上使用[DontProvide]参数。
问题来了,我希望方法调用的错误只有在参数声明没有[DontProvide] should only be used on optional parameters错误时才会出现
foreach (SyntaxReference parameterDefinition in parameter.DeclaringSyntaxReferences)
{
if (parameterDefinition.GetSyntax().ContainsDiagnostics)
{
return;
}
}
应该完成这个,但它似乎没有考虑你自己报告的诊断。
我尝试过的:
-更改诊断的顺序以使声明在方法调用之前被分析
-改用.GetDiagnostics().Count() > 0
-更改分析文档中文本的顺序,使方法声明在方法调用之上
分析器:
public override void Initialize(AnalysisContext context)
{
context.RegisterSymbolAction(AnalyzeParametersDeclaration, SymbolKind.Parameter);
context.RegisterOperationAction(AnalyzeArguments, OperationKind.Argument);
}
private void AnalyzeArguments(OperationAnalysisContext context)
{
IArgumentOperation reference = (IArgumentOperation)context.Operation;
IParameterSymbol parameter = reference.Parameter;
foreach (SyntaxReference parameterDefinition in parameter.DeclaringSyntaxReferences)
{
if (parameterDefinition.GetSyntax().ContainsDiagnostics)
return;
}
foreach (AttributeData attribute in parameter.GetAttributes())
{
if (attribute.AttributeClass.Name == "DontProvideAttribute")
{
context.ReportDiagnostic(Diagnostic.Create(DontProvide, reference.Syntax.GetLocation(), parameter.Name));
}
}
}
private void AnalyzeParametersDeclaration(SymbolAnalysisContext context)
{
IParameterSymbol parameter = (IParameterSymbol)context.Symbol;
if (parameter.GetAttributes().Any(a => a.AttributeClass.Name == "DontProvideAttribute") && !parameter.IsOptional)
{
context.ReportDiagnostic(Diagnostic.Create(DontProvideOnlyForOptional, parameter.Locations[0]))
}
}
一些用于分析的测试代码:
using System;
namespace test
{
internal class Program
{
private static void Main(string[] args)
{
MyClass.MyMethod(null);
}
}
internal class MyClass
{
public static void MyMethod([DontProvide] object parameter)
{
}
}
[AttributeUsage(AttributeTargets.Parameter)]
public class DontProvideAttribute : Attribute
{
}
}
PS : 编译器可能会告诉你 context.RegisterSymbolAction() 与 SymbolKind.Parameter 一起使用不受支持,这是错误的 (see more here)
【问题讨论】:
-
“它似乎没有考虑您自己报告的诊断。”这确实是正确的。现在你的问题是什么?
-
嗯,我的问题基本上是“我认为是真的吗?”既然您回答得很好,我正在寻找一种解决方法,以仍然能够检测参数声明是否具有诊断功能^^
标签: c# visual-studio roslyn static-code-analysis roslyn-code-analysis