在代码检查中如何获取PsiCallExpression所在的方法以跳过特定场景
获取PsiCallExpression所在方法的完全限定名
要实现跳过测试类或特定方法的代码检查,你不需要用getUseScope,而是通过向上遍历Psi语法树找到当前调用所在的PsiMethod,再结合所属类的信息生成完全限定名,具体步骤如下:
1. 向上遍历找到所在的PsiMethod
从PsiCallExpression出发,不断获取父节点,直到找到PsiMethod类型的元素(如果调用不在方法内,比如静态代码块或顶级语句,可根据需求处理):
private PsiMethod getEnclosingMethod(PsiCallExpression callExpr) { PsiElement current = callExpr; while (current != null && !(current instanceof PsiMethod)) { current = current.getParent(); } return (PsiMethod) current; }
2. 生成方法的完全限定名
拿到PsiMethod后,先获取它所属的PsiClass,再结合类的完全限定名和方法名(若需区分重载,可额外拼接参数签名,仅做跳过判断的话类名+方法名通常足够):
private String getMethodFullyQualifiedName(PsiMethod method) { if (method == null) { return null; } PsiClass containingClass = method.getContainingClass(); if (containingClass == null) { return method.getName(); } String classFqn = containingClass.getQualifiedName(); return classFqn + "." + method.getName(); }
3. 跳过检查的逻辑示例
在visitCallExpression中使用上述方法,判断是否需要跳过:
@Override public void visitCallExpression(PsiCallExpression expression) { super.visitCallExpression(expression); PsiMethod enclosingMethod = getEnclosingMethod(expression); String methodFqn = getMethodFullyQualifiedName(enclosingMethod); // 跳过测试类中的方法(示例:类在test包下或类名含Test) if (methodFqn != null && (methodFqn.startsWith("com.example.test.") || methodFqn.contains(".Test."))) { return; } // 跳过特定方法,比如名为"skipCheckMethod"的方法 if (methodFqn != null && methodFqn.endsWith(".skipCheckMethod")) { return; } // 执行你的代码检查逻辑 checkTargetMethodCall(expression); }
补充说明
getUseScope返回的是该调用表达式的使用范围(比如类、包等),不是它所在的方法,所以不适合用来定位当前方法。- 如果调用在构造方法、静态初始化块或匿名内部类中,可在遍历父节点时额外判断
PsiConstructor、PsiStaticInitializer等类型,根据需求决定是否跳过。
内容的提问来源于stack exchange,提问作者Eugen
相关产品推荐
相关产品推荐

