SonarQube OpenEdge自定义规则,用Proparse验证&IF预处理器。

问题描述 投票:1回答:1

我正在尝试创建一个自定义插件,基于 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". 我是一个非常新的 俗语 的世界,任何帮助都是感激的。

sonarqube openedge
1个回答
0
投票

首先,你要知道,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()

© www.soinside.com 2019 - 2024. All rights reserved.