PSI导航

走着路睡觉大约 2 分钟

PSI导航

PSI导航分为3种方式:

  • 从上向下:当你需要查询PSI文件或PSI元素的 子PSI元素 时(例如:查找它某个方法包含的变量)

  • 从下向上:当你需要查找某一个PSI元素的父PSI元素时(例如:查找某个变量所在的方法)

  • 引用:如果一个PSI元素是引用对象,可以导航到它的本体(声明该对象的地方),也可以从本体查找所有引用它的PSI元素。详情查看文档: PSI引用

从上向下导航

从上向下导航常用Visitoropen in new window

下面方法可以获取到某个PSI元素内包含的所有JAVA局部变量:

// 1. 新建一个 Visitor的实现类(一般使用匿名内部类。Visitor跟编程语言有关,例如:JAVA使用JavaRecursiveElementVisitor,xml使用XmlElementVisitor),重写它的方法,在方法中过滤你想要的PSI元素,并处理业务逻辑
// 2. 在 PsiElement.accept() 方法中传入 上一步的实现类
PsiElement.accept(new JavaRecursiveElementVisitor() {
  @Override
  public void visitLocalVariable(PsiLocalVariable variable) {
    super.visitLocalVariable(variable);
    System.out.println("Found a variable at offset " + variable.getTextRange().getStartOffset());
  }
});

大多数情况下,你也可以使用特定的API进行导航。例如:可以直接使用 PsiClass.getMethods() 来获取一个java class的所有方法

PsiTreeUtilopen in new window 提供了很多通用的,跟编程语言无关的方法,例如 findChildrenOfType()

从下向上导航

从下向上导航的时候,需要知道从哪个 PSI元素偏移量(offset) 开始。

如何你有偏移量(offset),可以直接使用 PsiFile.findElementAt() 方法获取到 PSI元素。这个方法返回的是具体的 PSI元素,如果你还需要访问它的前后关系,可以使用PSI树进行查找

大多数情况下,使用 PsiTreeUtil.getParentOfType() 方法进行自下而上的查找,这个方法从它自己开始访问它的所有父元素,直到找到对应的元素类型即返回。例如:可以使用 PsiTreeUtil.getParentOfType(element, PsiMethod.class) 查询PSI元素 所在的方法

有时候,也可以使用特定的查找方法,例如:PsiMethod.getContainingClass() 可以查找方法所在的类

下面的方法经常一起使用:

PsiFile psiFile = anActionEvent.getData(CommonDataKeys.PSI_FILE);
PsiElement element = psiFile.findElementAt(offset);
PsiMethod containingMethod = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
PsiClass containingClass = containingMethod.getContainingClass();

PSI导航代码示例: PsiNavigationDemoActionopen in new window

上次编辑于:
贡献者: zhaojingbo
Loading...