Для целей более сложного анализа нам нужно собрать некоторую информацию в класс реализации 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());
}
}
}