我有一个IntelliJ插件,它将PsiReference分辨率转移到"遥远的" class,并且遇到问题,因为当且仅当我在当前的IntelliJ会话期间没有导航到编辑器中的远程文件时,resolve()
方法才返回null。我怀疑在某种意义上需要激励IntelliJ来解析文件(当你导航到文件时,你可以看到IntelliJ启动某种解析运行,因为很多代码从最小突出显示到完全突出显示)但我不知道该怎么做。我查看了PsiManager
和PsiFile
,在那里我发现了一些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)顶部的@AnnotationReferringToAnotherType
和resolve()
到{{1}的定义}}。然后,它会在File2
中查找使用File2
注释的方法。由于@File3
上的@File3
注释未指定其值,因此插件现在必须查找mustBeLookedUpToHandleAction
的定义,以确定默认值。所有这些都在新加载IntelliJ后完全顺利。失败的部分是@File3
resolve()
中的PsiReferenceExpression
到SomeEnum.DEFAULT
中DEFAULT
的实际定义。它始终返回SomeEnum
,直到我在编辑器中导航到文件3,然后在每次会话的剩余时间内都有效。很明显,参考文献'分辨率正在懒散地解析,如果我能找到一些方法来启动解析一切应该没问题?
你可能在想"为什么这个逻辑如此复杂?"。大多数逻辑实际上是在我使用的库中 - 它是内部的,所以我可能会做出一些改变,但我怀疑我是否能够进行基本的改变。这个问题,除非这个问题完全无法解决。
答案 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}}。