我正在尝试创建一个自定义插件,基于 Riverside OpenEdge插件 及其版本 俗语 来创建一个规则,对&IF预处理程序进行估值。
该规则需要验证应用程序是否使用了一个废弃的 &GLOBAL-DEFINE
像这样。
/* "A" is the deprecated value of "opts" so I want to create a new ISSUE here */
&IF "{&opts}" = "A" &THEN
MESSAGE "DEPRECATED CODE".
&ENDIF
&IF "{&opts}" > "A" &THEN
MESSAGE "OK CODE".
&ENDIF
对于我扩展的这个规则,我试着做了这样的事情。
if (unit.getMacroGraph().macroEventList.stream().noneMatch(macro -> macro instanceof NamedMacroRef
&& ((NamedMacroRef) macro).getMacroDef().getName().equalsIgnoreCase("opts"))) {
return;
}
TokenSource stream = unit.lex();
ProToken tok = (ProToken) stream.nextToken();
while (tok.getNodeType() != ABLNodeType.EOF_ANTLR4) {
if (tok.getNodeType() == ABLNodeType.AMPIF) {
// Verify node.
System.out.println(tok);
}
tok = (ProToken) stream.nextToken();
}
但我不知道这是否是最好的验证方式 (我根据其他来源的代码做的) 但它没有工作,因为下一个节点是空的 "QSSTRING". 我是一个非常新的 俗语 的世界,任何帮助都是感激的。
首先,你要知道,Proparse并不能提供对预处理程序的每一个细节的访问。也就是说,该方法 unit.getMacroGraph()
会让你访问预处理器的可见部分,所以这是一个很好的起点.如果你正在寻找给定的预处理器变量的用法,你可以搜索指向正确的MacroDef对象的NamedMacroRef实例(使用 NamedMacroRef#getMacroDef()#getName()
),以及正确的值。
在一个老式的for-each循环中。
for (MacroRef ref : unit.getMacroSourceArray()) {
if ((ref instanceof NamedMacroRef)) {
if ("opts".equalsIgnoreCase(((NamedMacroRef) ref).getMacroDef().getName())
&& "A".equalsIgnoreCase(((NamedMacroRef) ref).getMacroDef().getValue())) {
System.out.println("OPTS variable usage with value 'A' at file " + ref.getFileIndex() + ":" + ref.getLine());
}
}
}
在这个文件上,
&global-define opts a
&IF "{&opts}" = "A" &THEN
MESSAGE "DEPRECATED CODE".
&ENDIF
&undefine opts
&global-define opts b
&IF "{&opts}" > "A" &THEN
MESSAGE "OK CODE".
&ENDIF
就会得到:
OPTS variable usage with value 'A' at file 0:2
所以你无法访问表达式引擎 但我认为目前的API已经足够满足你的需求了。
然后,你可以用以下方式向SonarQube报告问题 OpenEdgeProparseCheck#reportIssue()