- `KtFirAnalysisSession` does not need to depend on project out-of-block
and project root modification trackers anymore, as its underlying
use-site session determines validity. To ensure that use-site sessions
are invalidated in SLC equality tests, modification events also need
to be published.
- We do not need `AtomicBoolean` here, because setting `_isValid` to a
constant `false` suffices.
- Also replace the public setter of `isValid` with `markInvalid` to
prohibit setting `isValid` to `true` again.
- Out-of-block modification of stable modules is meaningless, because
stable modules should not be affected by out-of-block modification.
Hence, only global *source* out-of-block modification makes sense and
global out-of-block modification events can be removed.
- Any time an anchor module's session is invalidated, we need to make
sure that all its dependents are also invalidated. Because those
dependents may include libraries, invalidation after global source
modification needs to invalidate such libraries, even if other stable
module sessions should remain untouched.
- `LLFirSessionCache.sourceCache` can contain library and library
sources sessions. However, global source modification events should
not remove such sessions from the cache, because they belong to
"stable" modules.
- The commit introduces the term "stable module" as a combined term for
binary and library source modules. Library sources are not binaries,
but nevertheless they cannot cause nor be affected by out-of-block
modification.
- The term "source modules" as used by global "source" modification is
slightly imprecise, as it does *not* include library sources, but for
the sake of conciseness, I don't plan to change that.
- The lambda passed to `invokeLater` in `LLFirSession.invalidate` might
survive beyond project disposal (especially in tests), so me must not
capture a hard reference to the session that can leak its `project`.
- Until the IDE module dependents provider has been implemented for
script dependents (see KTIJ-25620), we must assume that any script
modification may lead to any other script session being out of date.
Hence, script modification now leads to the removal of all script
sessions.
- Because the IDE module dependents provider doesn't provide script
dependents for libraries yet, library modification must also lead to
global script session invalidation.
- We don't need to invalidate dependent sessions when the root session
isn't in the session cache, or if the session is already marked as
invalid, because any dependent sessions that might exist won't be
referencing entities from the root session at that point.
- Because `KtModule`s and thereby sessions may depend on each other
cyclically, we must not create a session during the creation of
another session. Otherwise, let's say session A and B depend on each
other. Then we get the following nested creation: session A -> session
B -> session A -> session B, and so on.
- Dependency symbol providers are in part taken from dependency
sessions. Hence, we have to create dependency symbol providers lazily.
- For the creation of dependency symbol providers we only need to access
the non-dependency symbol providers of a session dependency, so we
don't need to access the dependency's dependency symbol providers.
Hence, the lazy construction won't run into issues with cycles later
on.
^KT-57743 fixed
- Kotlin modification events are published before or after the
modification, depending on the underlying cause. For example, PSI tree
change events in the IDE can occur both before and after the change,
so module and global out-of-block modification events must not make
timing guarantees. Similarly, module state modification events
published by the IDE can both happen before and after a module change,
with most events happening before the change.
- This commit replaces session modification trackers with event-based
session invalidation. The removal of modification trackers should
improve overall performance, because session invalidation events
happen less frequently than sessions are accessed. Getting rid of
modification trackers also allows sessions to refer to other sessions
lazily, which is essential when cyclic dependencies occur.
- The new `LLFirSession` validity tracker has constant complexity and
will not cause the same kind of performance issues as dependency
modification trackers. It is a bridge to support modification trackers
in certain parts of the code (e.g. for `CachedValue`s), while being
backed by event-based invalidation.
- `LLFirSessionInvalidationService` is the bridge between modification
events and `LLFirSessionCache`. It finds out which modules should be
invalidated and instructs the session cache to remove the associated
sessions.
- Session invalidation must always happen in a write action to preserve
consistency between sessions. Otherwise, while a session A is already
removed from the cache, it might still be referenced by a dependent
session B which is in the process of being invalidated. Such a session
must never be returned from `getSession`.
^KT-57515 fixed
- The IDE implementation of `KotlinModuleDependentsProvider` cannot
easily find all dependents for a builtins or SDK module. Instead,
builtins and SDK changes can be handled via global module state
modification events, because most modules will depend on builtins and
SDK modules.
- Event-based session invalidation requires knowledge about the
dependents of a `KtModule`. This is because, when the session for a
module is invalidated, all sessions for modules which depend on that
module, directly or indirectly, must also be invalidated.
- Note that the approach with modification trackers relied on module
dependencies. Events have an opposite flow of information compared to
modification trackers: Modification trackers request whether a change
occurred, while events publish that a change occurred. Thus, the
modules which need to be incorporated into the invalidation dynamic
are also flipped: dependents instead of dependencies.
- `KotlinModuleDependentsProvider` is designed to work generally. It can
be used for purposes beyond session invalidation.
- `registerServicesForProjectEnvironment` relied on lists of all modules
and source files, which the standalone project structure providers
would have already been able to provide with the right interface.
- In `StandaloneAnalysisAPISessionBuilder.build`, to get all modules and
source files, `projectStructureProvider` had to be hard-casted to
`KtModuleProviderImpl`.
- This commit introduces `KtStaticProjectStructureProvider`, a shared
interface for project structure providers with static module
structures that know about their modules and source files.
- `KtResolveExtension`s need to participate in active invalidation,
because LL FIR sessions depend on changes in resolve extension files.
- The resolve extension will simply be able to use the
`KotlinModificationSubscriptionService`, which is part of the Analysis
API surface for **API implementors**, to publish modification events.
- The commit refactors some modification trackers previously provided by
`KotlinModificationTrackerFactory` to a subscription-directed
mechanism implemented via `MessageBus` and `KotlinTopics`. The
following modification trackers are affected:
- Module out-of-block modification: The FE10 Analysis API doesn't use
these modification trackers, so the effect is limited to LL FIR.
- Module state: Likewise, FE10 doesn't use this modification tracker,
so again the effect is limited to LL FIR.
- Project and library modifications trackers remain, because many small
objects in e.g. light classes depend on these trackers (making
listener management unfeasible), and they are not relevant for
`LLFirSession` invalidation.
- This new API paves the way for a session invalidation service to
subscribe to out-of-block and module state changes as events. This
removes the need to iterate through modification trackers.
- Also note that the out-of-block modification provided by the new
subscription mechanism is intended to work for _any_ `KtModule`, as
long as it makes sense to have out-of-block modifications. For
example, the subscription should work for script modules. The OOB
modification tracker previously only supported `KtSourceModule`s,
which required separate single-file modification trackers for script
and not-under-content-root modules.
- `MessageBus` is a general utility provided by IntelliJ, but usually it
is retrieved from `project`. To keep these two concerns decoupled,
`project.messageBus` should not be used directly. Instead, the commit
adds a `KotlinMessageBusProvider`, which for now just provides the
project message bus with its standard implementation, but allows
swapping out the message bus implementation later.
- Global changes are also supported by the new subscription API. Such
global changes may for example occur during cache invalidation in
tests, on global PSI tree changes, or when an SDK is removed.
- Test-only invalidation has been moved from
`KotlinModificationTrackerFactory` to a new
`KotlinGlobalModificationService`. This creates one central service
for invalidation between tests, which is easier from an implementation
and a usage perspective than calling multiple scattered services and
providers.
Test source sets do not participate in the metadata compilations by
default, so the check misses them. This commit just encodes this
behavior into tests, without actually addressing it
KT-60724
- Exclude kotlin-stdlib and kotlin-test from reporting
- kotlin-stdlib wasn't reported, because it doesn't even have Gradle
modular metadata (so no o.j.k.platform.type attribute, and check doesn't
work). This commit explicitly excludes kotlin-stdlib, so that when it
starts publishing Gradle Modular Metadata, nothing would break
- kotlin-test was reported only when it is declared in commonMain,
because we're checking only metadata compilations, and commonTest
isn't compiled to metadata
- Depending on kotlin-test is an odd configuration, but it arises
sometimes (e.g. when people extract some test utilities in a separate
Gradle project)
^KT-58872
- Assert that all dependencies are resolved. Gradle won't fail the build
by default, which might lead to test running in a weird misconfigured
state and producing unreliable results (can be green even though there
are bugs)
- Fix several typos and misconfigurations that were revealed after
adding assertion described above
'KotlinSourceSet.LanguageSettings' is now acts as a wrapper for the
related Kotlin compilation task 'compilerOptions' object, similar to how
'kotlinOptions' is working now.
Source sets consistency check now will ignore shared source sets with no
linked compilation to avoid users need to configure them as well.
^KT-57292 In Progress
Atomicfu compiler plugin supported transformations for K/N:
* atomic properties are replaced with volatile properties and all the operations are delegated to native atomic intrinsics
* atomic arrays are replaced with kotlin.concurrent.Atomic*Arrays
* all other features available on JVM are covered as well (custom atomic extensions, delegated properties, debug tracing)
See (KT-58358, https://github.com/Kotlin/kotlinx-atomicfu/issues/261)
Merge-request: KT-MR-11253
Merged-by: Maria Sokolova <maria.sokolova@jetbrains.com>
Previous attempt was at 6807ed6642, but it was reverted in 7771e5914d
(see that commit for the explanation). Now it should be fine to remove
these version requirements.
No issue reported because it's mostly not a user-visible change. The
main effect is that it reduces differences in metadata between K1 and
K2, namely it fixes the ValueClass.kt kotlinp test.
K1 uses `Any?` in `transformSuspendFunctionToRuntimeFunctionType`, so
use `Any?` in K2 too.
This type is not used for anything, it's just an artifact of how suspend
types are represented in metadata. It's removed during deserialization
(see `TypeDeserializer.createSuspendFunctionType` or
`FirTypeDeserializer.createSuspendFunctionType`). So it's not a
user-visible change. The only effect is that it reduces differences in
metadata between K1 and K2, namely in the test
`libraries/tools/kotlinp/testData/ValueClass.kt`.
Language feature InlineClasses is enabled since 1.3. The current lowest
supported language version is 1.4, so any compiler that can read
binaries produced by the current compiler also supports inline classes,
which means that the version requirement is not needed anymore.
No issue reported because it's mostly not a user-visible change. The
main effect is that it reduces differences in metadata between K1 and
K2, because K2 never supported writing this version requirement properly
due to the TODO in `hasInlineClassTypesInSignature`.
KGP supports only Gradle since 6.8.3, and we run tests on
buildserver only since this version, so we shouldn't try to work if
gradle < 6.8.3.
And in general in MPP plugin we shouldn't support version that is not
supported in KGP
#KT-59278