A bit of theory about projects and VFS. The previous part is here .
Project structure
In IntelliJ IDEA, the project encapsulates all source codes, libraries, build scripts in a single organizational unit. Absolutely all actions in IDEA occur in the context of the project. A project may contain collections of modules and libraries. Depending on the logical or functional requirements, you can create a single-module or multi-module project.
Modules
A module is a separate entity of functionality that can be launched, tested, and debugged independently.
Modules include such things as source codes, build scripts, unit tests, etc. Each module in the project can use a specific SDK, or inherit the project SDK. Modules may depend on other modules in the project.
Libraries
A library is a compiled code in an archive (for example, a JAR file) on which modules depend.
IntelliJ IDEA Community Edition supports three types of libraries:
- module library - visible only in this module, information about it is saved to * .iml file;
- project library - visible within the entire project, information about it is saved in the * .ipr file;
- global library - information about it is stored in the applicationLibraries.xml file, which visibility applies to all projects.
Sdk
Each project uses the Software Development Kit (SDK). For Java projects there is a special type of SDK called the JDK (Java Development Kit). The SDK determines which API is used when building the project. In a multi-module project, by default, the SDK is inherited by all modules, but it is also possible to define separate SDKs for the respective modules.
')
Facet
Facet is a functionality associated with a module that tells how to interact with the contents of the module. A module can have multiple faces.
In IntelliJ IDEA Ultimate Edition, there is a setting in the project settings that allows you to assign Facets, unlike Community Edition, where the Facet destination is available only from the API.
Project structure
From the perspective of the plugin developer, the project structure is as shown in the figure below.
The project contains one or more modules. Each module includes the source code of the plugin and calls an ordered set of entities related to the SDK and libraries. A module may have a set of faces.

Work with project files, modules, libraries
IntelliJ IDEA saves configuration data to XML files. The list of these files depends on the format of the project.
For a file-based project format, the information is stored in the project file “plugin-name.ipr”. Information about the modules is stored in the files "module-name.iml", which are created for each module.
For a project format based on a directory, project settings are saved in several XML files in the “.idea” sub-directory. Each file is responsible for its own set of settings and has a corresponding name: projectCodeStyle.xml, encodings.xml, vcs.xml, and so on. Module data is stored in * .iml files.
In order to work with projects and project files, there are several interfaces and classes:
- Project interface;
- abstract class ProjectRootManager;
- abstract class ProjectManager;
- interface ProjectFileIndex.
IntelliJ IDEA provides the following classes for working with modules:
- abstract class ModuleManager;
- Module interface;
- abstract class ModuleRootManager;
- interface ModuleRootModel;
- class ModuleUtil;
- interface ModifiableModuleModel;
- interface ModifiableRootModel.
To get the list of libraries, you can list all the entities of the module and select instances of the LibraryOrderEntry interface. To obtain the classes contained in the library, you can use the Library.ModifiableModel.getUrls method.
To work with facet, there are classes DefaultFacetsProvider and Facet.
IntelliJ IDEA Virtual File System
Virtual File System (VFS) is a component of IntelliJ IDEA that encapsulates most file functions. Serves for the following purposes:
- providing a universal API for working with files regardless of their physical location (on disk, in the archive, on an FTP server, etc.);
- tracking changes in files and providing both the old and new versions of their contents;
- Providing the ability to specify additional information for a file inside a VFS.
In order to provide the last two functions, VFS creates snapshots (snapshots) of the contents on the hard disk. Only those files that have been requested at least once through the VFS software interface get into snapshot and update them asynchronously in accordance with changes occurring on the disk.
Snapshots work at the application level, so even with multiple links from different projects, the data is stored in a single copy.
All access operations go through snapshot, if the requested information is not available, then it is loaded from disk. The contents of the files and the list of files in the directory are saved only if specific information is requested, otherwise only the meta information (name, size, etc.) is saved.
All write operations are synchronous, i.e. data is written to disk immediately.
IntelliJ IDEA performs an asynchronous full content update operation on startup. Also, by default, the update occurs when switching from another application, but this behavior can be configured on the tab "Settings | Synchronize files.
The synchronization operation is based on time stamps, if the modification date has not changed, then IDEA does not update the file contents. Whenever possible, IntelliJ IDEA uses file watchers built into the operating system (inotify, epoll, etc.).
Virtual file system events
All changes that occur to the virtual file system, as a result of performing an update operation or due to user actions, are called virtual file system events.
The most efficient way to monitor VFS events is to implement the BulkFileListener interface and subscribe to VirtualFileManager.VFS_CHANGES. This API provides a list of all changes that occurred during the update operation, which allows for batch processing. An alternative way is to implement the VirtualFileListener interface and register it with VirtualFileManager.addFileListener (). This option allows you to process changes one by one.
Do not forget that handlers work at the application level, therefore, receive events from all projects opened by the user. Therefore, the first step is to filter only the relevant events of the active project.
When updating, events are created only for files uploaded to snapshot. Therefore, if a single file was uploaded via VirtualFile.findChild (), then the changes that occur with it will be tracked, but with the neighbors in the directory - no.
In the
following part: lexical, syntactic analysis, PSI, Stub index.
All articles of the cycle: 1 , 2 , 3 , 4 , 5 , 6 , 7 .