Q (tldr;):如何使用android-lint中的JavaScanner来检查以特定字符串作为参数的特定函数调用是否被JavaScanner/catch块包围。
详细信息:我已经完成了官方网站上的android-lint教程,并且已经浏览了现有lint-checks的源代码。然而,我似乎无法理解基于AST的JavaScanner解析的工作流程。我试图实现的是捕获一个设置特定属性的函数,并将其包围为try/catch块。例如:
MyPropertySettings.set("SOME_PROPERTY", "SOME_VAL"); 不应触发林特规则,但:
MyPropertySettings.set("SOME_SENSITIVE_PROPERTY", "SOME_VAL"); 应该这样做,因为它没有被带SetPropertyException的try/catch块包围。我不想将try/catch引入到函数本身,因为它只在非常罕见的情况下抛出异常(而且函数的内部部分基于某种反射模式)。
对于这个问题,即使是工作流/提示也可以。如果我能得到最初的几步,我也许能更好地掌握它。
更新:
经过进一步的研究,我发现我需要在set中设置上面的getApplicableMethodNames()函数,然后以某种方式读取该函数的属性,以确定检查是否适用。那部分应该很简单。
周围的尝试/捕捉将更加困难,我想我需要做一些“流分析”。现在的问题怎么样了。
发布于 2014-02-13 09:42:08
好的,除了getApplicableMethodNames()方法之外,您还需要重写visitMethod()函数。你会得到MethodInvocationNode的。只需使用node.astArguments()函数获取调用中传递的参数。这将返回可以使用StrictListAccessor迭代的参数列表。检查传递的参数,如果它符合您的条件,运行一个循环,并一直计算调用节点的父节点,直到找到一个try节点。如果它是一个try节点,那么您可以使用node.astCatches()获得一个捕获列表。扫描列表并找到适当的异常。如果找不到,那就报告。
发布于 2015-12-08 04:50:05
您可以编写如下代码:检查它是否被try/catch包围:
@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");
}}
在此之前,您必须通过重写来定义特定的方法:
@Override
public List<String> getApplicableMethodNames() {
return Collections.singletonList("set");
}https://stackoverflow.com/questions/16746888
复制相似问题