Skip to content

KaResolveExtension

abstract class KaResolveExtension : Disposable

A resolve extension provides additional Kotlin files containing generated declarations, which will be included in the resolution as if they were regular source files in the module.

Each resolve extension is defined for a specific KaModule, which is determined by the KaResolveExtensionProvider which creates the resolve extension.

All member implementations should:

  • Consider caching the results for subsequent invocations.

  • Be lightweight and avoid building the whole file structure eagerly.

  • Avoid using Kotlin resolution, as these functions are called during session initialization, so Analysis API access is forbidden.

Lifecycle Management

A resolve extension is tied to the lifetime of its module's analysis session. It is created by KaResolveExtensionProvider during creation of an analysis session, and disposed after the analysis session has been invalidated.

KaResolveExtension implements the Disposable interface. The resolve extension can then act as a parent disposable, e.g. for a message bus connection.

You must not implement resolve extensions as module-level services, due to the following reasons:

  1. The IntelliJ platform SDK discourages the use of module-level services due to memory consumption. In particular, resolve extensions implemented as module-level services live longer than their corresponding analysis session, so the resolve extension would not be garbage collected after its corresponding analysis session has been invalidated.

  2. The module-level service living longer than the analysis session increases the risk of caching invalidated entities in a resolve extension.

  3. Because the resolve extension is a Disposable, if implemented as a module-level service, the service would be disposed too early during invalidation of the corresponding analysis session.

See also

Constructors

KaResolveExtension

constructor()

Functions

dispose

open override fun dispose()

getContainedPackages

abstract fun getContainedPackages(): Set<FqName>

Returns the set of packages that are contained in the files provided by getKtFiles. It should be an exact set of all file packages.

getKtFiles

Returns the list of files that should be generated for the module. The files should contain valid Kotlin code.

Modification and Invalidation

If the content of these files becomes invalid (e.g., because the source declarations they were based on changed), the resolve extension must publish an out-of-block modification event via the Analysis API message bus: KotlinModificationTopics.MODULE_OUT_OF_BLOCK_MODIFICATION.

To react to changes in Kotlin sources, the resolve extension may subscribe to Analysis API modification topics: KotlinModificationTopics. If the resolve extension both subscribes to and publishes modification events, care needs to be taken that no cycles are introduced. In general, the resolve extension should never publish an event for a module A in a listener for the same module A.

An out-of-block modification event for the resolve extension's associated module does not need to be published in response to an out-of-block modification event for the same module, because the original event suffices for invalidation.

See also

getShadowedScope

open fun getShadowedScope(): GlobalSearchScope

Returns the scope of files that should be shadowed by the files provided by getKtFiles.

Any files in the module that are included in this scope will be removed from analysis results. This allows the files provided by getKtFiles to cleanly replace those files from the module.

Resolve extensions may be used to generate declarations that would normally be provided by sources generated by an external build task, such as a resource compiler or annotation processor. In such a case, the resolve extension should provide a shadowed scope that covers those externally generated sources. This will prevent collisions between the definitions provided by getKtFiles and those provided by the (potentially stale) externally generated sources.