Ian*_*emp 6 c# roslyn roslyn-code-analysis
以下面的代码为例:
public class Thing
{
public int Item { get; }
public Thing(int item)
{
Item = Item; // note incorrect assignment: rhs should be item, the passed-in arg, hence analyzer should warn
}
public Thing(Thing other)
{
Item = other.Item; // correct assignment, should NOT trigger analyzer
}
}
Run Code Online (Sandbox Code Playgroud)
我正在编写一个Roslyn分析器来检测和报告这些可能错误的自我分配的情况,以下相关部分:
public override void Initialize(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(MistakenSelfAssignment, SyntaxKind.SimpleAssignmentExpression);
}
private static void MistakenSelfAssignment(SyntaxNodeAnalysisContext context)
{
var assignment = context.Node as AssignmentExpressionSyntax;
if (assignment == null)
{
return;
}
var leftToken = GetIdentifierToken(assignment.Left);
var rightToken = GetIdentifierToken(assignment.Right);
if (leftToken != null && leftToken.IsEquivalentTo(rightToken)) // this never works
{
var diagnostic = Diagnostic.Create(Rule, assignment.GetLocation());
context.ReportDiagnostic(diagnostic);
}
}
private static SyntaxToken GetIdentifierToken(ExpressionSyntax syntax)
{
var identifierName = syntax as IdentifierNameSyntax;
if (identifierName != null)
{
return identifierName.Identifier;
}
var identifierAccess = syntax as MemberAccessExpressionSyntax;
if (identifierAccess != null)
{
return identifierAccess.Name.Identifier;
}
return default(SyntaxToken);
}
Run Code Online (Sandbox Code Playgroud)
但我无法弄清楚如何确定赋值的LHS和RHS是否是相同的标记 - SyntaxToken.IsEquivalentTo似乎是我想要的方法,但它总是返回false,就像SyntaxToken.Equals和==.
确定令牌是否指向自身的正确方法是什么?
我不认为你能在这个SyntaxToken层面上做到这一点。起初,我认为语义模型会在这里帮助你,但在这两种情况下,符号指的是同一事物,所以你不能用它来区分。
但是,您可以做的只是调查SimpleAssignmentExpression,检查两个操作数是否都是标识符,并通过 Marcus 提到的相同方法检查它们的等价性SyntaxFactory.AreEquivalent()。我得到了这个(请参阅此要点以获取完整的 LINQPad 查询):
假设您编写了这个方法:
private static bool IsAssignmentBad(AssignmentExpressionSyntax assignmentNode)
{
if (!assignmentNode.IsKind(SyntaxKind.SimpleAssignmentExpression))
{
return false;
}
var lhs = assignmentNode.Left;
if (!lhs.IsKind(SyntaxKind.IdentifierName))
{
return false;
}
var rhs = assignmentNode.Right;
if (!rhs.IsKind(SyntaxKind.IdentifierName))
{
return false;
}
return SyntaxFactory.AreEquivalent(lhs, rhs);
}
Run Code Online (Sandbox Code Playgroud)
然后用这个运行它会得到你想要的,我认为:
var tree = CSharpSyntaxTree.ParseText(
@"public class Thing
{
public int Item { get; }
public Thing(int item)
{
Item = Item; // note incorrect assignment: rhs should be item, the passed-in arg, hence analyzer should warn
}
public Thing(Thing other)
{
Item = other.Item; // correct assignment, should NOT trigger analyzer
}
}");
var root = tree.GetRoot();
var incorrectAssignment = root.DescendantNodes().OfType<AssignmentExpressionSyntax>().First();
var correctAssignment = root.DescendantNodes().OfType<AssignmentExpressionSyntax>().Last();
var b1 = IsAssignmentBad(correctAssignment); // doesn't consider the assignment bad
var b2 = IsAssignmentBad(incorrectAssignment); // this one does
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
223 次 |
| 最近记录: |