原文链接:
http://www.jetbrains.org/intellij/sdk/docs/basics/architectural_overview/psi_files.html
PSI(程序结构接口)文件是将文件内容抽象为特定编程语言元素的层次结构的文件。
PsiFile类是所有PSI文件的基类,特定语言的PSI文件是其子类。例如,PsiJavaFile类代表Java文件,XmlFile类代表XML文件。
不像VirtualFile
和Document
的作用域为应用 (即使多个项目被打开,每个文件只被相同的VirtualFile
所代表),PSI的作用域为项目(如果一个文件属于多个同时打开项目,这个文件被多个PsiFile
实例所代表)。
我怎样得到一个PSI文件?
- 操作:
e.getData(LangDataKeys.PSI_FILE)
; - 虚拟文件:
PsiManager.getInstance(project).findFile()
; - 文档:
PsiDocumentManager.getInstance(project).getPsiFile()
; - 文件内的元素:
psiElement.getContainingFile()
; - 在项目的任何地方查找指定名字的文件,使用
FilenameIndex.getFilesByName(project, name, scope)
。
我能用它来做什么?
大多数修改操作都在单独的PSI元素上进行,而不是整个文件。
要遍历文件中的元素,使用psiFile.accept(new PsiRecursiveElementWalkingVisitor()...)
。
它从何而来?
由于PSI是依赖于语言的,PSI文件是通过Language对象使用LanguageParserDefinitions.INSTANCE.forLanguage(language).createFile(fileViewProvider)
方法创建的。
像文档一样,PSI文件也是被访问时按需创建的。
PSI文件可以持久化多长时间?
像文档一样,PSI文件也是相应的VirtualFile
实例的弱引用,如果没有任何引用就会被垃圾回收机制回收。
我怎样创建一个PSI文件?
PsiFileFactory
.getInstance(project).createFileFromText()
方法创建一个相应内容的内存PSI文件。
要保存PSI文件到磁盘,使用PsiDirectory
.add()
方法。
PSI文件改变时我怎样得到通知?
PsiManager.getInstance(project).addPsiTreeChangeListener()
允许你接受项目中PSI树所有更改的通知。
我怎样扩展PSI?
PSI可以通过自定义语言插件扩展支持其它语言 。更多关于开发自定义语言插件详情,参阅自定义语言支持。
使用PSI有什么规则?
所有对PSI文件内容的更改都会反映到文档上,所以使用文档时所有规则(读写操作、命令、只读处理) 都是有效的。