对于更复杂的分析pupros,我们需要收集一些信息到传感器实现类和下一个行号绑定。
在哪里可以找到树元素的行号?
java.plugin.version:3.13.1 sonar.plugin.api.version: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);
}
}
然后我们来到analyze()的传感器接口实现 - 哎呀,这里没有关于为类名注册问题的代码行的信息,例如在类声明的行,没有再次解析文件。
/**
* 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());
}
}
}
答案 0 :(得分:4)
回答问题的多种方式。
首先让我重新说一下:如何从树的节点访问线路信息。
回答这个问题的最佳方法:升级到最新版本(4.2)并使用树的每个节点上可用的firstSyntaxToken().line()
方法。
但更好的是你根本不需要这个,你应该使用issuableSubscriptionVisitor(addIssue或reportIssue)中的可用方法来报告问题,而不是在传感器内引发问题。