Q(tldr;):如何使用JavaScanner
中的android-lint
来检查特定字符串作为参数的特定函数调用是否已被包围一个try / catch块。
详细信息:我已经在官方网站上完成了android-lint教程,并且已经浏览了现有lint-checks
的来源。但是,我似乎无法掌握这种基于AST的JavaScanner解析的工作流程。我想要实现的是捕获一个设置特定属性并用try / catch块包围它的函数。例如:
MyPropertySettings.set("SOME_PROPERTY", "SOME_VAL");
不应该触发lint规则,但是:
MyPropertySettings.set("SOME_SENSITIVE_PROPERTY", "SOME_VAL");
应该因为它没有被SetPropertyException
的try / catch块包围。我不想将try / catch引入函数本身,因为它只在非常罕见的情况下抛出异常(并且函数的内部基于一些反射mojo)。
对于这个问题,即使工作流程/提示也没问题。如果我能够完成前几个步骤,我可能会更好地掌握它。
更新:
经过一些研究后,我发现我需要在set
中设置上面的getApplicableMethodNames()
函数,然后以某种方式读取该函数的属性以决定是否应用该检查。那部分应该很容易。
周围的尝试/捕获将更加困难,我收集我需要做一些“流量分析”。现在问题是怎么回事。
答案 0 :(得分:2)
嗯,与getApplicableMethodNames()
方法一起,您需要覆盖visitMethod()
函数。您将获得MethodInvocationNode
。只需使用node.astArguments()
函数获取调用中传递的参数。这将返回一个参数列表,您可以使用StrictListAccessor
进行迭代。检查传递的参数以及是否符合您的条件,运行循环并继续计算调用节点的父节点,直到找到try
节点。如果它是try节点,那么您可以使用node.astCatches()
获取捕获列表。扫描列表并找到相应的例外。如果没有找到,请报告。
答案 1 :(得分:1)
你可以像这样编码: 检查它是否被try / catch包围:
Player.new
}
在此之前,您必须通过覆盖来定义特定方法:
@Override
public void visitMethod(JavaContext context, AstVisitor visitor, MethodInvocation node) {
// check the specified class that invoke the method
JavaParser.ResolvedMethod method = (JavaParser.ResolvedMethod) context.resolve(node);
JavaParser.ResolvedClass clzz = method.getContainingClass();
boolean isSubClass = false;
// sSupportSuperType = {"class name"};
for (int i = 0; i < sSupportSuperType.length; i++) {
if (clzz.isSubclassOf(sSupportSuperType[i], false)) {
isSubClass = true;
break;
}
}
if (!isSubClass) return;
// check if surrounded by try/catch
Node parent = node;
while (true) {
Try tryCatch = context.getParentOfType(parent, Try.class);
if (tryCatch == null) {
break;
} else {
for (Catch aCatch : tryCatch.astCatches()) {
TypeReference catchType = aCatch.astExceptionDeclaration().astTypeReference();
}
parent = tryCatch;
}
}
// get the arguments string
String str = node.astArguments().first().toString();
if (!str.startsWith("\"SOME_PROPERTY\"")) {
context.report(ISSUE, node, context.getLocation(node), "message");
}