如何强制IntelliJ插件解析文件的PsiReference分辨率?

时间:2014-12-05 01:39:56

标签: intellij-13 intellij-plugin psi

我有一个IntelliJ插件,它将PsiReference分辨率转移到"遥远的" class,并且遇到问题,因为当且仅当我在当前的IntelliJ会话期间没有导航到编辑器中的远程文件时,resolve()方法才返回null。我怀疑在某种意义上需要激励IntelliJ来解析文件(当你导航到文件时,你可以看到IntelliJ启动某种解析运行,因为很多代码从最小突出显示到完全突出显示)但我不知道该怎么做。我查看了PsiManagerPsiFile,在那里我发现了一些refresh()reloadFromDisk()方法,但我猜这些方法有很多副作用我不会# 39;无论如何都希望并且可能无法启动解析运行。详情/说明如下。

代码看起来像这样:

文件1,我在foo上调用插件操作:

@AnnotationReferringToAnotherType(File2.class)
class File1 {
  String foo;
}

文件2,插件必须查找才能对foo执行操作:

class File2 {
  @File3
  void mustBeLookedUpToHandleAction() {}
}

还必须查找文件3:

@interface File3 {
  public enum SomeEnum {
    DEFAULT,
    SOMETHING_ELSE
  }

  SomeEnum value() default SomeEnum.DEFAULT;
}

我在foo上执行操作,然后逻辑找到包含文件(文件1)顶部的@AnnotationReferringToAnotherTyperesolve()到{{1}的定义}}。然后,它会在File2中查找使用File2注释的方法。由于@File3上的@File3注释未指定其值,因此插件现在必须查找mustBeLookedUpToHandleAction的定义,以确定默认值。所有这些都在新加载IntelliJ后完全顺利。失败的部分是@File3 resolve()中的PsiReferenceExpressionSomeEnum.DEFAULTDEFAULT的实际定义。它始终返回SomeEnum,直到我在编辑器中导航到文件3,然后在每次会话的剩余时间内都有效。很明显,参考文献'分辨率正在懒散地解析,如果我能找到一些方法来启动解析一切应该没问题?

你可能在想"为什么这个逻辑如此复杂?"。大多数逻辑实际上是在我使用的库中 - 它是内部的,所以我可能会做出一些改变,但我怀疑我是否能够进行基本的改变。这个问题,除非这个问题完全无法解决。

1 个答案:

答案 0 :(得分:0)

原来这是IntelliJ中的一个错误:https://youtrack.jetbrains.com/issue/IDEA-133994

解决方法是在致电getText()之前在其中一个注释定义PsiElement上致电resolve() - 例如在调用PsiAnnotationMethod

之前,File3.value getText()调用getDefaultValue().resolve() File3之后

DEETS:

getText的定义是" stubbed",因此只有其psi树的核心组件实际可用。无论何时从存根中请求存根(例如通过调用PsiAnnotationMethod.getDefaultValue),都将完全解析包含存根psi树的文件,并用完整的psi树替换存根(请参阅{ {3}})。如果注释是存根的,PsiAnnotationMemberValue的特定实现将返回一个虚拟resolve(),并且该虚拟元素显然不了解{{1}}。