The platform interface is an interface which Standalone, IntelliJ, and any additional platforms need to implement for the Analysis API to work in their respective environment.
Note: The platform interface has not been stabilized together with the user-facing Analysis API surface. In fact, since both platform implementations are currently maintained by JetBrains, we will keep the platform interface in an experimental state for a while. Ultimately, it is our goal to stabilize the platform interface as well so that third-party developers can support their own environments.
analysis-api
module. A user typically invokes the analyze
entry point to work with symbols, types, calls, and other concepts. We explicitly differentiate users and platforms, especially in the context of user-facing vs. platform APIs. The platform interface is normally hidden from users, as they should not need to access nor be aware of the inner workings of the Analysis API.From the view of the Analysis API, a platform has the following responsibilities:
KaModule
s and related concepts.KaLifetimeToken
s. Even if modifications are not possible, the platform must provide a notion of “static” lifetime.A specific platform may have additional features, such as providing a DSL for project structure creation to users like Standalone, but this is up to the platform.
Additional responsibilities may be added in the future as the Analysis API (and especially LL FIR) evolves. Platforms need to be evolved with the rest of the Analysis API.
Some platforms like the IntelliJ Kotlin plugin are both an Analysis API user and a platform implementation. This is perfectly legal, but care should be taken to properly separate modules which use the Analysis API and modules which additionally provide implementations for platform components.
Platforms need to provide information about project and library content to the Analysis API engine, because the Analysis API itself has no direct way of knowing the content of all source files, and neither does it include an out-of-the-box indexing solution.
For example, if we're analyzing a class, and it references another class org.example.Foo
, the Analysis API will need to look up the declaration of org.example.Foo
. It is the responsibility of the platform to implement a KotlinDeclarationProvider
which returns a PSI declaration for that class, in any way which works for the platform.
Platforms are responsible for modification and lifetime because they control the location and content of their projects. It is not an Analysis API user's responsibility to define lifetime when they have no control over the content from inside an analyze
block.
Of course, when a platform implementation is also a user, the lines get blurred again. However, even if, for example, an IDE intention modifies the code, the code modification itself should still be published as a modification event via the platform interface, and hence the IDE acts in its capacity as a platform. Inside an analyze
block where content should be read-only, the IDE is purely an Analysis API user and exerts no control over modification.
The IntelliJ Kotlin plugin and the Standalone Analysis API are the two currently existing platforms, both maintained by JetBrains. There are no plans to support additional platforms, but third-party developers are welcome to incorporate the Analysis API into their own environments.
The platform interface is defined in this module, analysis-api-platform-interface
. It consists of two parts:
Platform components and engine services may occur in the same packages, but they can be distinguished by their prefixes: Platform components use the Kotlin
prefix (e.g. KotlinDeclarationProvider
), while engine services use the Ka
prefix (e.g. KaLifetimeTracker
).
To ease discovery, platform components extend the KotlinPlatformComponent
marker interface, while engine services extend KaEngineService
. This makes it easy to identify which components needs to be implemented, i.e. all KotlinPlatformComponent
s (with an exception for optional platform components, marked with KotlinOptionalPlatformComponent
).
In addition to these abstract interfaces, the platform interface also contains additional abstract concepts which aren't strictly platform components (e.g. KotlinDeclarationProvider
), as well as base implementations for a few platform components. All these declarations are usually placed in the same package as the related platform component.
The platform interface has the following important subpackages:
declarations
: Platform components which provide declarations or information about declarations, see “information about the code” above.lifetime
: Services for lifetime handling. Notably, there are already two standard implementations for lifetime tokens: KotlinAlwaysAccessibleLifetimeToken
for static code (used by Standalone) and KotlinReadActionConfinementLifetimeToken
for modifiable code (used by IntelliJ).modification
: Message topics and services for publishing modification events. See KotlinModificationTopics
.packages
: Platform components which provide information about packages, see “information about the code” above.permissions
: Services for permission handling. KaAnalysisPermissionChecker
can be used by lifetime tokens to implement isAccessible
, but is also used internally to check permissions when analyze
is called.projectStructure
: Platform components which provide information about the project‘s structure, such as KaModule
s which are the Analysis API’s conception of modules. The core component to implement is KotlinProjectStructureProvider
, but there are various other components which cover other important aspects of project information.In general, it is the responsibility of the platform to initialize the Analysis API. Even Standalone does the bulk of the initialization work itself, albeit triggered by the Analysis API user.
Initialization mostly takes the form of registration of internal and public services. The Analysis API has its own service registration mechanism via plugin XMLs. These XML files especially register internal engine services, which would be cumbersome for a platform to enumerate. Standalone currently implements its own handler for applying these plugin XMLs, and no such support is currently available via the platform interface out of the box.
You can track the following issue: KT-69385. Please leave a comment if it affects you.