Пользовательское правило SonarQube OpenEdge для проверки & IF препроцессора с Proparse - PullRequest
2 голосов
/ 30 апреля 2020

Я пытаюсь создать пользовательский плагин на основе Riverside OpenEdge и его версии Proparse , чтобы создать правило, действительное для препроцессора & 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 , любая помощь приветствуется.

1 Ответ

0 голосов
/ 04 мая 2020

Во-первых, вы должны знать, что Proparse не дает доступа к каждой детали препроцессора. Тем не менее, метод unit.getMacroGraph() даст вам доступ к видимой части препроцессора, так что это хорошая отправная точка. Если вы ищете использование данной переменной препроцессора, вы можете искать экземпляры NamedMacroRef, указывающие на правильный объект MacroDef (с NamedMacroRef#getMacroDef()#getName()) и правильное значение.

В старом стиле для каждого l oop:

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()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...