instead of inside implementation configuration.
Whether a field is a child element is a core concept of the tree,
not a matter of particular implementation class.
It is especially visible in IR tree, where the base classes implement the
acceptChildren method. It will also be more relevant in the future.
This also aligns the config style between IR and FIR tree generators.
^KT-65773 In Progress
The notion of IR element class being 'semantically leaf' is rather hacky.
Instead, now we only distinguish whether an element has its
implementation class, which is what this notion was actually trying to
represent.
^KT-65773 In Progress
analogous to printFunctionDeclaration.
This decouples the printing logic from handling IR elements' fields,
and makes it easier to directly print arbitrary fields.
When those classes become auto-generated, the order of constructor
parameters will differ.
This commit ensures they will still be resolved correctly.
^KT-65773 In Progress
to replace custom logic that would throw in case of IrUninitialized.
This is to remove custom logic from those classes,
so that source generator will be able to generate
them in a straight-forward way.
Otherwise, it would need to be thought about those special cases, which
is better to be avoided.
There are two consequences:
- The error message will be more generic, and won't contain reference
to the element.
- It becomes possible to reassign returnType
property with IrUninitializedType
and read it afterward.
^KT-65773 In Progress
This is to remove custom logic from those classes,
so that source generator will be able to generate
them in a straight-forward way.
Otherwise, it would need to be thought about those special cases, which
is better to be avoided.
It is also a small step for future work,
which likely involves making parent property nullable.
Unfortunately, this change causes a loss of some details from exception
messages.
^KT-65773 In Progress
This commit removes the default parameter in constructor,
as well as custom logic in this class, which would
make it harder for its subsequent auto-generation.
^KT-65773 In Progress
The default value of those properties is a detail that should be handled
by implementation or builder layer.
This change will also simplify auto-generating and reasoning about
generated implementation classes, and allow for potential further
enhancements like intercepting all mutations.
^KT-65773 In Progress
It is required, so that IR tree generator will properly handle
the `annotations` property in subsequent commits,
e.g., to include them in implementation classes.
All subclasses of IrMutableAnnotationContainer
do already derive from IrElement.
^KT-65773 In Progress
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
In Native and JS, there is a special logic where the compiler saves
a copy of inlined function (see `InlineFunctionsSupport`). This copy
is used in the IR inliner. Because of that, we can't really compare
inlined function with other functions directly. We need to
get `originalFunction` first and save it.
- 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