原文鏈接:
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文件內容的更改都會反映到文檔上,所以使用文檔時所有規則(讀寫操作、命令、只讀處理) 都是有效的。