我正在尝试为Java实现SonarQube自定义规则。我的要求是避免对某些类实例进行某些方法调用。我能够报告方法调用的问题,但无法检查调用该方法的引用(类的实例)。有人可以帮我吗? 。我使用的Sonarqube版本是5.6.6。这是我的规则代码但不起作用:
package org.sonar.samples.java.checks;
import com.google.common.collect.ImmutableList;
import java.util.List;
import org.sonar.check.Priority;
import org.sonar.check.Rule;
//import org.sonar.java.model.ExpressionUtils;
import org.sonar.samples.java.checks.utils.ExpressionUtils;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.semantic.Symbol;
import org.sonar.plugins.java.api.semantic.Type;
import org.sonar.plugins.java.api.tree.BaseTreeVisitor;
import org.sonar.plugins.java.api.tree.BlockTree;
import org.sonar.plugins.java.api.tree.ClassTree;
import org.sonar.plugins.java.api.tree.MethodInvocationTree;
import org.sonar.plugins.java.api.tree.MethodTree;
import org.sonar.plugins.java.api.tree.Tree;
import org.sonar.plugins.java.api.tree.Tree.Kind;
@Rule(key = "AvoidCloseMethod", name = "AvoidCloseMethod", description = "close() method of class com.test.MboSetRemote should be avoided. Instead of close(), cleanup() method should be called.", priority = Priority.BLOCKER, tags = {
"bug" })
public class AvoidCloseMethodCall extends IssuableSubscriptionVisitor {
private MethodVisitor methodVisitor = new MethodVisitor();
@Override
public List<Kind> nodesToVisit() {
return ImmutableList.of(Tree.Kind.METHOD);
}
@Override
public void visitNode(Tree tree) {
MethodTree methodTree = (MethodTree) tree;
if (!hasSemantic()) {
return;
}
if (methodTree.block() != null) {
methodVisitor.setHasNextOwner(methodTree.symbol().owner());
methodTree.block().accept(methodVisitor);
}
}
private static boolean ownerClassOfMethod(Symbol method) {
Type type = method.owner().type();
return type.is("com.test.MboSetRemote");
}
private class MethodVisitor extends BaseTreeVisitor {
private Symbol hasNextOwner;
@Override
public void visitMethodInvocation(MethodInvocationTree tree) {
Symbol method = tree.symbol();
if ("close".equals(method.name()) && tree.arguments().isEmpty() && ownerClassOfMethod(method)) {
reportIssue(ExpressionUtils.methodName(tree),
"close() method of class com.test.MboSetRemote should be avoided. Instead of close(), cleanup() method should be called.");
}
super.visitMethodInvocation(tree);
}
public void setHasNextOwner(Symbol hasNextOwner) {
this.hasNextOwner = hasNextOwner;
}
@Override
public void visitClass(ClassTree tree) {
// Don't visit nested classes
}
}
}