0

我有一个 IntelliJ 插件,它正在将 PsiReference 分辨率传送到“远程”类,并且遇到问题,因为resolve()当且仅当我在当前 IntelliJ 会话期间没有导航到编辑器中的远程文件时,该方法才返回 null。我怀疑需要促使 IntelliJ 在某种意义上解析文件(当您导航到文件时,您可以看到 IntelliJ 启动了某种解析运行,因为许多代码从最小突出显示到完全突出显示)但我不知道该怎么做。我查看了PsiManagerand PsiFile,在那里我找到了一些refresh()reloadFromDisk()方法,但我猜这些有很多我不想要的副作用,并且可能无论如何都不会启动解析运行。详情/说明如下。

代码看起来像这样:

文件 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,然后逻辑@AnnotationReferringToAnotherType在包含文件(文件 1)的顶部找到 ,并找到resolve()的定义File2。然后它会在其中查找一个用File2注释的方法@File3。由于@File3注释 onmustBeLookedUpToHandleAction没有指定它的值,插件现在必须查找定义@File3以确定默认值是什么。在新加载 IntelliJ 后,所有这些工作都非常顺利。失败的部分是resolve()从inPsiReferenceExpression SomeEnum.DEFAULT的实际定义。它始终如一地返回DEFAULTSomeEnumnull,直到我在编辑器中导航到文件 3,然后它每次都可以在会话的其余部分工作。似乎很明显,引用的解析正在被懒惰地解析,如果我能找到某种方法来开始解析一切应该没问题吗?

你可能会想“为什么这个逻辑这么复杂?”。大多数逻辑实际上都在我正在使用的库中 - 它是内部的,所以我可能能够进行一些更改,但我怀疑我是否能够针对这个问题做出根本性的改变,除非这个问题被证明是完全无法控制。

4

1 回答 1

0

Turns out this is a bug in IntelliJ: https://youtrack.jetbrains.com/issue/IDEA-133994

the workaround is to call getText() on one of the annotation definition's PsiElements before calling resolve() - e.g. once you have the PsiAnnotationMethod for File3.value call getText() on it before calling getDefaultValue().resolve()

deets:

The definition for File3 is "stubbed", so only the core components of its psi tree are actually available. Whenever information is requested from the stub that the stub doesn't have (e.g. by calling getText), the file containing the stubbed psi tree will be fully parsed and the stub replaced with a complete psi tree (see https://confluence.jetbrains.com/display/IDEADEV/Indexing+and+PSI+Stubs+in+IntelliJ+IDEA). The particular implementation of PsiAnnotationMethod.getDefaultValue will return a dummy PsiAnnotationMemberValue if the annotation is stubbed, and that dummy element is apparently not knowledgeable to honor the resolve().

于 2014-12-06T05:28:29.980 回答