Sonarqube规则:在一行中识别多个方法调用

时间:2018-05-22 08:35:42

标签: java sonarqube abstract-syntax-tree

我尝试实现自定义SonarQube规则,该规则在.stream调用完成后,在同一代码行中调用多个方法时,识别Java流API使用并检测违规。

示例:

// BAD CODE:
strings.stream().filter(s -> s.length() > 2).sorted()
.map(s -> s.substring(0, 2)).collect(Collectors.toList());

// GOOD CODE:
strings.stream()
.filter(s -> s.length() > 2)
.sorted()
.map(s -> s.substring(0, 2))
.collect(Collectors.toList());

我已经通过MethodInvocationTree访问者识别了不同的方法调用,但是我如何将它们识别为stream()方法调用,告诉他们除了代码中的所有其他方法调用?特别是因为我的参数方法调用也被识别为AST MethodInvocationTree。

是否有一个SonarQube助手类,可以帮助我深入了解AST,或者让我挑选出我需要的AST的确切部分,比如PMD' node.getFirstChildOfType(ASTTree.class)

非常感谢你的帮助!

1 个答案:

答案 0 :(得分:0)

为了回答您的上一个问题,SonarJava API没有提供任何方法来直接从AST类型的AST过滤子项。必须在访问期间完成。

现在,可能有几种方法可以实现您的目标,但您肯定需要使用语法和语义API。请注意,此规则可能需要大量工作才能涵盖所有情况。

我建议你查看MethodInvocationTree的{​​{3}}树,然后从那里检查它是否为methodSelect,获取标识符,然后再次来自所选成员的MethodInvocationTree。通过循环它直到你到达不是方法调用的东西,或直接到达标识符,你应该收集所有的方法调用。现在,问题是如何确保它是来自java.util.stream.Stream的方法。

收集后,对于链的每个方法调用,您可以使用语义API访问与调用的方法对应的MemberSelectExpressionTree。如果方法由语义引擎正确解析(提供字节码用于分析,由引擎正确计算类型推断,符号未标记为symbol()),您应该能够验证的类型该方法的所有者。对于所有这些方法,所有者应为java.util.stream.Stream