gpt4 book ai didi

.net - 有没有办法使用 Roslyn 确定变量的潜在值?

转载 作者:行者123 更新时间:2023-12-03 03:38:27 25 4
gpt4 key购买 nike

我正在使用 Roslyn CTP,我正在尝试确定类中变量的值是否有值。假设我正在尝试检测某人何时使用 BinaryExpressionSyntax 来确定字符串是否等于“”。

例如:

private void StringLiteral(string a)
{
if (a == "") //flagged because we do not see a explicit set of 'a'
{
Console.WriteLine("Empty String");
}
a="42";
if (a == "") //not flagged because 'a' has been set
{
Console.WriteLine("Empty String");
}
}

我可以获取 BinaryExpressionSyntax 并使用语义和语法检查左侧和右侧,但我在调试器中没有看到任何跟踪可能值的内容。我知道这可能会变得粗略,例如:

private void BooleanTest(string a, bool b)
{

if (b)
{
a="";
}
if (!b)
{
a="42";
}
if (a == "") // Maybe 'a' is set maybe it isn't so we will probably not flag this one
{
Console.WriteLine("What Do I Do?");
}
}

Roslyn CTP 是否可以确定变量是否已设置潜在值?我认为这会在 StyleCOp/FxCop 规则中发挥很大作用。

最佳答案

您可以尝试使用SemanticModel.AnalyzeRegionDataFlow()来实现此目的。您给它一个文本范围,它会告诉您有关该文本片段中的数据流的信息,包括必须在 AlwaysAssigned 属性中分配哪些变量。

整个代码(假设您有一个编译单元,而不仅仅是一个方法)可能如下所示:

var tree = SyntaxTree.ParseCompilationUnit(code);

var compilation = Compilation.Create("foo")
.AddSyntaxTrees(tree);

var semanticModel = compilation.GetSemanticModel(tree);

var methods = tree.Root.DescendentNodes().OfType<MethodDeclarationSyntax>();

foreach (var method in methods)
{
Console.WriteLine(method.Identifier.ValueText);

var binaryExpressions = method.DescendentNodes()
.OfType<BinaryExpressionSyntax>()
.Where(e => e.Kind == SyntaxKind.EqualsExpression);

foreach (var binaryExpression in binaryExpressions)
{
Console.WriteLine(binaryExpression);

// get TextSpan that starts at the beginning of the method body
// and ends at the beginning of the binary expression
var textBefore = TextSpan.FromBounds(
method.BodyOpt.Span.Start, binaryExpression.Span.Start);

//Console.WriteLine(tree.Root.GetFullTextAsIText().GetText(textBefore));

var alwaysAssigned = semanticModel.AnalyzeRegionDataFlow(textBefore)
.AlwaysAssigned;

var isAAlwaysAssigned = alwaysAssigned.Any(s => s.Name == "a");

Console.WriteLine(isAAlwaysAssigned);
}

Console.WriteLine();
}

对于您的第一个方法,它正确检测到 a 未在第一个 if 之前分配,但肯定在第二个 if 之前分配>.

对于你的第二种方法,Roslyn 似乎认为不必分配 a 。但这与 C# 编译器的行为方式一致。例如,以下方法将无法编译:

private void BooleanTest(bool b)
{
string a;
if (b)
a = "";
if (!b)
a = "42";
if (a == "")
Console.WriteLine("What Do I Do?");
}

但是如果将第二个 if 替换为 else,它将编译。同样,Roslyn 会检测到该变量始终被赋值。

关于.net - 有没有办法使用 Roslyn 确定变量的潜在值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10130502/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com