Sonarqube 规则:在一行中识别多个方法调用
Sonarqube Rule: Identifying multiple method calls in one line
我正在尝试实现一个自定义的 SonarQube-Rule,它可以识别 Java 流 API 用法并检测违规情况,当在同一代码行中调用多个方法时,在 .stream
呼叫已完成。
示例:
// 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 助手 class,可以帮助我更深入地研究 AST,或者让我挑选出我需要的 AST 的确切部分,例如 PMD node.getFirstChildOfType(ASTTree.class)
?
非常感谢您的帮助!
为了回答你的最后一个问题,SonarJava API 没有提供任何方法来直接从 AST 中按树种过滤子项。必须在访问期间完成。
现在,可能有多种方法可以实现您想要做的事情,但您肯定需要同时使用语法和语义 API。请注意,此规则可能需要大量工作才能涵盖所有情况。
我建议您查看 methodSelect
tree of the MethodInvocationTree
, and from there check if first it's a MemberSelectExpressionTree
,获取标识符,然后再次查看所选成员的 MethodInvocationTree
。通过循环直到你到达不是方法调用的东西,或者直接是标识符,你应该收集所有的方法调用。现在,问题是如何确定它是来自 java.util.stream.Stream
.
的方法
收集后,对于链的每个方法调用,您可以使用语义 API 访问 symbol()
corresponding to the invoked method. If the methods are correctly resolved by the semantic engine (bytecode is provided for analysis, type inference correctly computed by the engine, symbol not flagged as being unknown
),您应该能够验证 方法的所有者。对于所有这些方法,所有者应该是 java.util.stream.Stream
.
我正在尝试实现一个自定义的 SonarQube-Rule,它可以识别 Java 流 API 用法并检测违规情况,当在同一代码行中调用多个方法时,在 .stream
呼叫已完成。
示例:
// 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 助手 class,可以帮助我更深入地研究 AST,或者让我挑选出我需要的 AST 的确切部分,例如 PMD node.getFirstChildOfType(ASTTree.class)
?
非常感谢您的帮助!
为了回答你的最后一个问题,SonarJava API 没有提供任何方法来直接从 AST 中按树种过滤子项。必须在访问期间完成。
现在,可能有多种方法可以实现您想要做的事情,但您肯定需要同时使用语法和语义 API。请注意,此规则可能需要大量工作才能涵盖所有情况。
我建议您查看 methodSelect
tree of the MethodInvocationTree
, and from there check if first it's a MemberSelectExpressionTree
,获取标识符,然后再次查看所选成员的 MethodInvocationTree
。通过循环直到你到达不是方法调用的东西,或者直接是标识符,你应该收集所有的方法调用。现在,问题是如何确定它是来自 java.util.stream.Stream
.
收集后,对于链的每个方法调用,您可以使用语义 API 访问 symbol()
corresponding to the invoked method. If the methods are correctly resolved by the semantic engine (bytecode is provided for analysis, type inference correctly computed by the engine, symbol not flagged as being unknown
),您应该能够验证 方法的所有者。对于所有这些方法,所有者应该是 java.util.stream.Stream
.