About

A PSI (Program Structure Interface) file is the root of a structure representing the contents of a file as a hierarchy of elements in a particular programming language.

It represents a hierarchy of PSI elements (so-called PSI tree CST ? ).

A single PSI file may include several PSI trees in a particular programming language. A file may have multiple PSI file (if many language). A File View Providers manages this case ??

Management

Interface / Creation

The PsiFile class is the common base class for all PSI files, while files in a specific language are usually represented by its subclasses.

For example:

As PSI is language-dependent, PSI files are created through the Language object, by using the LanguageParserDefinitions.INSTANCE.forLanguage(language).createFile(fileViewProvider) method.

Like documents, PSI files are created on demand when the PSI is accessed for a particular file.

The PsiFileFactory.getInstance(project).createFileFromText() method creates an in-memory PSI file with the specified contents.

To save the PSI file to disk, use the PsiDirectory.add() method.

Scope

Scope: PSI has project scope (the same file is represented by multiple PsiFile instances if the file belongs to multiple projects open at the same time).

Get

View

In bin/idea.properties (from Viewing Psi Structure)

idea.is.internal=true

Then Tool > help/idea/2016.2/psi-viewer.html

Find

To find files with a specific name anywhere in the project, use FilenameIndex.getFilesByName(project, name, scope)

Operations

Most interesting modification operations are performed on the level of individual PSI elements, not files as a whole.

  • To iterate over the elements in a file, use psiFile.accept(new PsiRecursiveElementWalkingVisitor()…);

Any changes done to the content of PSI files are reflected in documents, so all rules for working with documents (read/write actions, commands, read-only status handling) are in effect.

Persistence

Like documents, PSI files are weakly referenced from the corresponding VirtualFile instances and can be garbage-collected if not referenced by anyone.

Watcher / Notification

PsiManager.getInstance(project).addPsiTreeChangeListener() allows you to receive notifications about all changes to the PSI tree of a project.

How do I extend PSI to support additional languages

PSI can be extended to support additional languages through custom language plugins: IDEA Plugin Dev - Custom Language Plugin

Documentation / Reference