This extension point allows changing the return type of call
from a declared type to its subtype.
With an idea that such a plugin needs the ability to
control available (extension) properties for this type.
A set of properties should be decided based on the resolved function,
provided arguments, types, and resolved lambdas.
It is not a goal to enable plugins to affect resolution in any way.
Types are not intended to have any structured capabilities
In other words.
The goal was to come up with a way to enable a limited form
of an "extensible records" mechanism through plugins.
- It should give enough value for a practical use.
(more info in the ticket).
- It should have minimal effect on the compilation process
This appears to be an extension point that solves this problem.
^KT-65859 Fixed
This element has been introduced to simplify resolution logic in LL FIR,
but now this element is redundant and only complicates the code as after
KT-56683 `FirFile` has real phases
^KT-65876 Fixed
- This was missed during the refactoring made by 46d5d512, which removed
`registerDefaultComponents` calls from platform-specific session
factories (including binary library session creation).
- Unfortunately, this doesn't fix KT-65563, which has also appeared
recently and I thought might be related.
^KT-66173 fixed
The commit "K2 scripting: treat default import similarly to K1"
introduced the new extension that provides default imports for scripts,
instead of the previous approach of explicit `FirImport` elements
creation. But registering it for the IDE case was forgotten. This
commit adds missing registration.
#KTIJ-28960 fixed
When we have parameters of annotation like
```
// FILE: Anno.kt
package p3
@Target(AnnotationTarget.FUNCTION)
annotation class Anno(vararg val x: String)
// FILE: main.kt
import p3.Anno
@Anno("A", "B")
fun foo(): Int = 10
```
the K2 CodeGen causes an exception reporting the unresolved type
reference. A lazy resolution call fixes the issue.
In addition, FIR for the value parameter to IR conversion fails because
`Fir2IrLazyProperty` for the value parameter tries to resolve the
initializer before creating the `IrParameterSymbol`. When it checks the
`localStorage`, it reports an error for the missing `IrParameterSymbol`.
This commit adds `IrParameterSymbol` before resolving the initializer.
^KT-65099 Fixed
- This commit moves all session invalidation tests from the IDE which
are non-cyclic to the Analysis API. Cyclic session invalidation tests
cannot be moved because the Kotlin test infrastructure doesn't support
cyclic module dependencies.
- In fact, these new tests cover more cases, because the IDE tests only
covered global module state and module out-of-block modification
events. Crucially, global source modification events are now
supported, which require libraries to be left alone.
- Module out-of-block modification for libraries is technically
undefined, but the test still checks this behavior. The current
session invalidation implementation behaves the same for any kind of
module-level modification event, so it is possible to publish a module
OOBM event for libraries. If this changes in the future, we can
disable those tests. But for now, it's good that these tests run,
because they will alert us to (accidental) changes to this behavior.
^KT-56288 fixed
^KT-65265 fixed
- Rewrite `TestModule.publishModificationEventByDirective`: we can get
the `KtModule` to publish an event for via the test module. The
directive can now be made optional, which is necessary when we want to
specify it in potentially multiple modules.
- Introduce the `WILDCARD_MODIFICATION_EVENT` directive, which allows
specifying THAT some modification event should be raised for a module,
but not WHICH one. This allows generating multiple tests which raise
different modification events over the same test data.
- Add various convenience functions for publishing wildcard modification
events. `publishWildcardModificationEventsByDirective` for the test
module structure is quite opinionated, but takes a lot of work from
test implementations.
- Because `ModificationEventDirectives` are part of the analysis test
framework, we register them as a general Analysis API test directive.
^KT-56288
Instead of always looking up smart casts on `lastNode` and separately
tracking the receiver state, simply track which flow the smart casts
belong to right now. This tracked flow is auto-advanced when new
`lastNode`s are created, but can be manually rolled back for things like
KT-63709.
- Unified and optimized visitor instead of transformer with many
redundant operations.
- `LLFirAnnotationArgumentsTargetResolver` now has the correct state
keeper for nested declarations – e.g., property accessors or value
parameters.
- `FirAllLazyAnnotationCalculatorVisitor` in tests now almost the same
as in the production as now it uses the same visitor without recursive
visiting
^KT-63606 Fixed
^KT-64000 Fixed
^KT-64579 Fixed
We don't have to resolve `FirFileAnnotationsContainer` before each
declaration.
This became possible after KT-65345 as now `FirDesignation` has `FirFile`
in its path so, `PersistenceContextCollector#collectContext` resolves
it as well as we don't have problems with unresolved annotations
during diagnostics processing
^KT-65876
Checker for conflicting declarations will now check for the following
scenarios too
- two expect declarations in different modules
- actual and non-expect declarations in different modules
^KT-63826 Fixed
If there is an expression receiver, we should process constructors only
of inner classes. Constructors of nested classes can be called only
on classifier
^KT-65333 Fixed
If actual declaration is broken (missing explicit `actual` keyword),
expect declaration still makes sense.
This way, we allow refactorings on broken code
^KT-65191 fixed
- The cache guarantees deterministic cleanup on removal, so if the
reference has already been removed from the cache, there is no need to
clean it up again.
- Still, I don't want to guarantee that `SoftValueCleaner` is only
invoked once (see its documentation), as soft reference semantics
cannot be tested properly in our current test infrastructure.
^KT-61222
- Now it's checked that cleanup behaves as expected in a concurrent
setting for `put` and `remove`. Note that Lincheck never checks that a
value is actually cleaned up. Instead, it compares the result with the
single-threaded execution of a scenario. Hence, the non-concurrent
`CleanableSoftValueCacheTest` is crucial, as it separately ensures
correct deterministic cleanup in a single-threaded environment.
- We cannot test that operations returning a new value (such as `get`)
always return values which haven't been cleaned up yet, because the
value might be cleaned up by another thread between the return point
of the operation and cleanup checking.
^KT-62136
- This new version fixes problems with concurrent hash maps in model
checking tests and allows us to remove the correctness guarantee for
them.
^KT-62136
- The non-concurrent `CleanableSoftValueCacheTest` ensures that
deterministic cleanup behaves correctly. A Lincheck test can only
discover differences between the single-threaded and concurrent
executions of a test scenario, so it cannot find correctness issues
with deterministic cleanup on its own.
^KT-61222
- If we have some value `X` in the cache, and we put `X` a second time
into the same location, `X` shouldn't be cleaned up because it wasn't
actually removed from the cache.
- With this feature, it's necessary to implement `put` in terms of
`backingMap.compute`, because we need to compare the old and the new
value atomically, and based on that, decide whether to create a new
soft reference.
^KT-61222
- Lincheck tests the linearizability of a concurrent data structure,
which helps us verify that `CleanableSoftValueCache` works in
concurrent scenarios.
^KT-62136 fixed
- The previous implementation of `putIfAbsent` made two calls to the
`backingMap`: `putIfAbsent` and `replace`. This breaks atomicity at
least in theory. Implementing the major compute operations in terms of
`backingMap.compute` allows us to restrict the critical section to
this single atomic `ConcurrentHashMap` operation, which is easier to
reason about.
- Using `backingMap.compute` also improves the guarantees we can make in
respect to `computeIfAbsent`'s computation function `f`. We can now
guarantee that the function is called exactly once iff the `key` is
absent, because it is only ever invoked inside `backingMap.compute`,
which makes this guarantee itself.
- Remove `putIfAbsent`, which isn't currently used by
`LLFirSessionCache`. It can easily be implemented using
`computeIfAbsent` in the future.
^KT-61222
- These tests simply ensure that a resolve extension is disposed after
any kind of modification event is raised. It's not meant to test
complex scenarios, but rather to detect when resolve extension
disposal isn't invoked *at all*.
- I tried implementing a similar test for resolve extension disposal
after soft reference garbage collection, but the only way to force the
GC to collect soft references is to allocate memory until an
out-of-memory error occurs. That is bad for the test infrastructure,
because it might allocate A LOT of memory (depending on the max heap),
which is problematic for running tests locally. Also, our Kotlin tests
stop on an OOM error altogether (so additional configuration would be
required) and the heap is dumped into a 20GB file (on my machine),
which is again problematic for local test runs.
^KT-61222
- This allows tests to specify which modification event they want to
publish.
- The modification event won't be published automatically. Tests need to
invoke `publishModificationEventByDirective` at the right time.
^KT-56288
- This commit adds the `Disposable` interface to `KtResolveExtension`.
Resolve extensions are disposed after their associated session has
been invalidated, or reclaimed by the GC.
- Example use case: Opening a message bus connection with the lifetime
of the resolve extension.
^KT-61222 fixed
- This commit adds a `Disposable` to `LLFirSession` which lives as long
as the session. For example, session components can now open a message
bus connection that is automatically disposed after the session has
been invalidated or reclaimed.
- Because `LLFirSession`s should still benefit from soft reference-based
automatic reclamation by the GC, we have to use a soft value map with
cleanup in `LLFirSessionCache`. It ensures that the child disposables
are properly disposed even when the session is collected as a soft
value.
- The session cannot be the `Disposable` itself because a valid
disposable reference is needed to call `Disposer.dispose`. When a soft
reference is added to a reference queue (such as the reference queue
employed by the soft value map), its referent is already cleared.
Hence, it's not possible to watch a softly referenced `Disposable`
with a reference queue and also pass it to `Disposer.dispose`. This is
why the `LLFirSessionCleaner` contains a strong reference to the
`disposable`, because that will not keep the `LLFirSession` from being
reclaimed, while keeping the `disposable` alive slightly longer than
the session.
^KT-61222