一键导入
intellij-psi-vfs-safety
PSI/VFS/Document thread-safety rules for IntelliJ plugin development. Use when reading/writing PSI trees, Documents, or VFS files.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
PSI/VFS/Document thread-safety rules for IntelliJ plugin development. Use when reading/writing PSI trees, Documents, or VFS files.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when writing, migrating, or reviewing IntelliJ Platform tests that use the JUnit 5 test framework fixtures, including project/module/source-root setup, fixture lifecycle, annotations, and common safe patterns.
AutoCleanKey usage guide for UserData lifecycle management in IntelliJ plugins. Use when working with UserDataHolder cleanup tied to Disposable or CoroutineScope.
Use in IntelliJ projects with `.idea/` when searching, editing, inspecting, formatting, or exploring workspace and library symbols/text/problems through the IDE.
IntelliJ plugin Disposable/CoroutineScope lifecycle patterns. Use when registering services, listeners, or UserData that must clean up on plugin unload.
| name | intellij-psi-vfs-safety |
| description | PSI/VFS/Document thread-safety rules for IntelliJ plugin development. Use when reading/writing PSI trees, Documents, or VFS files. |
所有 PSI 读取必须运行在 readAction/runReadAction 内,除非特定 PSI API 显式文档说明不同的安全访问合约。
// 正确
val text = readAction { psiFile.text }
// 错误 — 可能不在读锁中
val text = psiFile.text
需要与 PSI、committed offset、navigation/symbol resolution 保持一致的 Document 读取,必须使用 committed document 并在 read access 下进行。
val doc = PsiDocumentManager.getInstance(project).getLastCommittedDocument(psiFile)
val offset = readAction { doc?.getLineStartOffset(line) }
VFS 读写遵循具体 API 的锁注解(@RequiresReadLock、@RequiresWriteLock)和文档合同。当需要与 PSI/Document 状态保持一致性快照时,获取对应的 read/write access。
对于读取 PSI/Document 或需要 VFS access 约束的内部辅助函数,不假设调用者已持有正确的锁。在深层辅助函数中添加显式守卫:
fun readPsi(psiFile: PsiFile): String {
ApplicationManager.getApplication().assertReadAccessAllowed()
return psiFile.text
}
在 write action 中修改编辑器 Document 后,必须在返回前调用:
writeAction {
document.insertString(offset, text)
PsiDocumentManager.getInstance(project)
.doPostponedOperationsAndUnblockDocument(document)
PsiDocumentManager.getInstance(project).commitDocument(document)
}
val committedDoc = PsiDocumentManager.getInstance(project)
.getLastCommittedDocument(psiFile)
// 使用 committedDoc 进行 offset 计算和符号解析
如果 getLastCommittedDocument 返回 null,返回清晰的 retriable 错误消息,让调用方 commit/retry,而不是静默使用可能过期的未提交状态。