Как получить номер строки у посетителя узла при построении дерева в плагине sonarqube

Для целей более сложного анализа нам нужно собрать некоторую информацию в класс реализации Sensor и привязку номера следующей строки.

Где я могу найти номер строки элемента дерева?

java.plugin.версия: 3.13.1 сонар.plugin.api.версия: 5.2

Может быть, новые версии более функциональны?

Наша цель - проверить, что имя пакета и имя класса, содержащие некоторые детали соглашений об именах, не должны импортировать некоторые пакеты.

Из посетителя узла мы не можем видеть все узлы дерева, это очевидно. Но здесь мы можем зарегистрировать проблему для конкретного места кода узла с помощью внутреннего механизма addIssue().

/**
* First step implementation of node visitor for complex multinode check
*/
@Rule(key = "ImportClassCheck",
  name = "Import classes should not contain web or form", 
  description = "Import classes should not contain web or form", 
  priority = Priority.CRITICAL, 
  tags = {"bug" })

public class ImportClassCheck extends IssuableSubscriptionVisitor {

@Override
public List<Kind> nodesToVisit() {
    return ImmutableList.of(Tree.Kind.IMPORT, Tree.Kind.PACKAGE, Tree.Kind.CLASS);
}

@Override
public void visitNode(Tree tree) {
    if (JavaCodeSensor.packages.get(context.getFileKey()) == null) {
        JavaCodeSensor.packages.put(context.getFileKey(), new ImportClassCheckState());
        JavaCodeSensor.packages.get(context.getFileKey()).file = context.getFile();
    }

    if (tree.is(Kind.PACKAGE))
        JavaCodeSensor.packages.get(context.getFileKey()).packageTree = (PackageDeclarationTree) tree;

    if (tree.is(Kind.CLASS))
            JavaCodeSensor.packages.get(context.getFileKey()).classTree.add((ClassTree) tree);

    if (tree.is(Kind.IMPORT))
        JavaCodeSensor.packages.get(context.getFileKey()).importTree.add((ImportTree) tree);
}
}

Затем мы приходим к реализации интерфейса Sensor для анализа () - К сожалению, здесь нет информации о строке кода для регистрации проблемы для имени класса, например, в строке объявления класса, без повторного разбора файла.

/** 
* First step to register an Issue
*/
@Override
public void analyse(Project project, SensorContext sensorContext) {
    for (Entry<String, ImportClassCheckState> entry : packages.entrySet()) {
        if (entry.getValue().isRuleFails()) {
            NewIssue newIssue = sensorContext.newIssue().forRule(
                                RuleKey.of("java-custom-rules-template", "ImportClassCheck"));
            newIssue.at(newIssue.newLocation()
                    .on(filesystem
                            .inputFile(filesystem.predicates().is(entry.getValue().file)))
/* Here is a problem to identify code of line, but needed tree nodes are exists in 
ImportClassCheckState members*/
                            .at(new DefaultTextRange(new DefaultTextPointer(1, 0), 
                        new DefaultTextPointer(1, 0))));
            newIssue.save();

            logger.info("Issue registered for file " + entry.getValue().file.getName());
        }
    }
}

person Alexander Mitenko    schedule 20.09.2016    source источник
comment
В этом вопросе отсутствует слишком много информации: о каком плагине SonarQube вы говорите? какая версия этого плагина SQ? Не могли бы вы уточнить вариант использования, который вы хотели бы охватить? Спасибо   -  person Freddy - SonarSource Team    schedule 21.09.2016
comment
Добавлена ​​цель вопроса   -  person Alexander Mitenko    schedule 21.09.2016


Ответы (1)


Несколько способов ответить на ваш вопрос.

Позвольте мне сначала перефразировать: как получить доступ к информации о строке из узла дерева.

Лучший способ ответить только на этот вопрос: обновиться до последней версии (4.2) и использовать методы firstSyntaxToken().line(), доступные на каждом узле дерева.

Но что лучше, так это то, что вам это вообще не нужно, вы должны использовать методы, доступные в issuableSubscriptionVisitor (либо addIssue, либо reportIssue), чтобы сообщить о проблеме, а не поднимать проблему в датчике.

person benzonico    schedule 22.09.2016
comment
Спасибо! Я постараюсь использовать последние функции. - person Alexander Mitenko; 26.09.2016
comment
Способ, названный вами лучше, нам не подходит, т.к. заказчик выставил требования в зависимости от порядка узлов. - person Alexander Mitenko; 26.09.2016