There is a thing that `CandidateCollector` adds error candidate to the
list of resulting candidates only if its applicability at least the
same as current applicability of the collector
Also there is a problem, that deserialized symbol provider in CLI compiler
and stub-based symbol provider in AA may return the same declarations
in different order. This provokes the difference in the resulting set
of candidates between the two modes:
```
val x by unresolved
```
During the resolution of this code compiler tries to find function `getValue`,
and there are 6 of them in the stdlib. From them we are interseted in
specific three:
1. `fun <K, V> Map<K, V>.getValue(key: R|K|): R|V|`
2. `inline operator fun <V, V1 : V> Map<in String, @Exact V>.getValue(thisRef: Any?, property: KProperty<*>): V1`
3. `inline operator fun <V, V1 : V> MutableMap<in String, out @Exact V>.getValue(thisRef: Any?, property: KProperty<*>): V1`
- (1) is inapplicable with `INAPPLICABLE_ARGUMENTS_MAPPING_ERROR`
- (2) and (3) are inapplicable with `INAPPLICABLE_WRONG_RECEIVER`
- `INAPPLICABLE_ARGUMENTS_MAPPING_ERROR` is more specific applicability than `INAPPLICABLE_WRONG_RECEIVER`
- CLI compiler always sees those functions in order 1 -> 2 -> 3
- AA providers sometimes returns them in order 2 -> 3 -> 1
So in CLI compilation candidates (2) and (3) are not added to the resulting
set, as they are "less applicable" than (1), but in AA compilation they
can be added to the set before (1), which causes sporadic change in
FIR dump of `unsafeAssignmentExtra.kt`
To workaround this problem it was decided to treat `INAPPLICABLE_ARGUMENTS_MAPPING_ERROR`
and `INAPPLICABLE_WRONG_RECEIVER` applicabilities as "equally specific"
^KT-65218 Fixed
In 9b5a9ccb `throws Exception` was removed from java test sources and
all checked exceptions were wrapped with `RuntimeException`
But it was forgotten that there is a `rethrow` utility, which doesn't
wrap exception but makes the javac happy at the same time
Originally it was an application-level component, which caused non-trivial
logic and cognitive load to carefully handle those extensions to avoid
memory leaks.
6740a596 introduced a way to easily register `DiagnosticSuppressor` to
project, and this commit continues this work, making it a proper
project-level extension
A lot of changes caused by the fact, that this extension is needed to be
obtained from `BindingContext` (see `BindingContextSuppressCache` and
its usages), so almost all changes are introducing `Project` to
`BindingContext`
^KT-66449 Fixed
`DiagnosticSuppressor` didn't contain `ProjectExtensionDescriptor`, which
prevented usages of this extension point with API provided by
`CompilerPluginRegistrar`
See discussion in KT-60952
Return type computation of getter for synthetic property, which is
incompatible anyway (e.g. because there is no java in the hierarchy)
may cause excess dependency between return types of declarations, which
may lead to recursive problems in resolution
^KT-66313 Fixed
```kotlin
// FILE: AB.kt
interface A {
val x: Int = 1
}
interface B : A {
// f/o val x: Int
// overrides: A.x
}
// FILE: C.java
public interface C extends B {
// f/o val x: Int
// overrides: (B, A.x)
}
// FILE: D.java
public interface D extends C {
// f/o val x: Int
// overrides: (C, A.x)
}
// FILE: usage.kt
fun test(d: D) {
d.x
}
```
In such test backend will ask for overriddens of lazy property C.x only
after property lowering, which removes property `B.x` and replaces it
with getter `B.<get-x>`. That fact that there is no property anymore
really confuses `SpecialFakeOverrideSymbolsResolver` during computation
of overriddens of `C.x`.
So, to prevent this situation, we can process all source kotlin classes
beforehand, so when any lazy function/property will start computation
of its overriddens, there won't be the need to calculate mapping of
f/o for classes
This problem was found during work on KT-66341, after total signature
computation removal from fir2ir. Previously those fake-overrides just
matched by signature in symbol table
FIR instances of generated toString/hashCode/equals are session dependant,
so we need some cache, which operates only session-independent stuff.
Pair of `FirClass` and `Name` was chosen here
Previously SymbolTable played the role of this cache (with signatures as
keys). But it should be replaced in scope of KT-66341 and KT-64990
`@Suppress` annotation has `VALUE_PARAMETER` target, so when a property
in the primary constructor is annotated with `@Suppress` it sticks
to the parameter. But the suppression should work for all diagnostics
reported on the parameter **and** the property
^KT-66258 Fixed
There were two lazy properties in `KtPsiSourceElement`, which were
rarely computed, which led to the fact that source element retained
a lot of memory for those lazy delegates
^KT-66172 Fixed
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
Usually we create synthetic property in java class if there is a property
from the base kotlin class and getter/setter with a corresponding name
in the declared scope or one of supertype scopes. But there is a case,
where the same supertype contains both property and getter:
```
// FILE: Base.kt
open class Base {
open val b = "O"
@JvmName("getBJava")
fun getB() : String = "K"
}
// FILE: Derived.java
public class Derived extends Base {}
```
In this case we shouldn't create synthetic property, because `getB()`
function is invisible for `Derived` class
^KT-66020 Fixed
`IrProvider`s are used to bind unbound symbols which are left after IR
construction. fir2ir doesn't leave any unbound symbols in the tree,
so there is actually no need in FirIrProvider at all
Previously @EnhancedNullability for IR type was added if only there wasn't
an @FlexibleNullability annotation, which is inconsistent with K1
behavior
^KT-65302 Fixed
In some cases we transform flexible type into non-flexible during
enhancement, but don't add `@EnhancedNullability` attribute to them,
which breaks consistency with K1 on IR level
This commit fixes it
^KT-65302
This is needed for cases like dump handlers to register corresponding
checkers, which compares identity of dumps for different configurations,
like `IrTextDumpHandler` and `FirIrDumpIdenticalChecker`
This is needed to reduce the size of generated test files, which started
to exceed default IDE limit
Also update some (mostly old) test utilities to remove exceptions from
java signatures
Previously we forced computation only for java and precompiled classes,
assuming, that binary class can not extend source class, but it's not
true in two cases:
1. Classpath substitution: class with same name declared in library and
the source (more rare case)
2. Metadata compilation: depends-on dependcies are passed in binary
format, so `expect class` may be a binary one and corresponding
`actual class` may be a source. So if some class in `common` module
extend this expect class, actual class will be substituted instead of it
^KT-65669 Fixed
PendingDiagnosticsCollectorWithSuppress is a special diagnostic collector,
which aggregates diagnostics reported during checking of some specific
element before actually reporting them, so its workflow looks like this:
- start checking some element;
- all reported diagnostics go to `pendingDiagnosticsByFilePath` map;
- all checkers done their jobs;
- diagnostics from `pendingDiagnosticsByFilePath` go to the resulting map
of all diagnostics (not all, only ones which lay inside the checked
according to PSI);
- processed diagnostics removed from `pendingDiagnosticsByFilePath`
This approach works fine, but there was one problem with it:
`pendingDiagnosticsByFilePath` is not just a list of diagnostic, but
map of lists, grouped by the containing file. And only those lists
actually get cleared. But if some list was completely emptied, it still
remained in the original `pendingDiagnosticsByFilePath` map
This led to the performance problem in case, where there are no actual
diagnostics in the `pendingDiagnosticsByFilePath`, but the map itself
is not empty but full of empty lists. So collector iterated over this
map on each visiting of each element
And after KT-58881 this problem was uncovered, as number of visits of
elements was twiced (because now we iterate over the whole tree twice,
with Common and Platform checkers)
The fix is quite trivial -- if some list in `pendingDiagnosticsByFilePath`
becomes empty, remove it from the map
^KT-65579 Fixed
`FirDeserializedEnumAccessExpression` requires session to build proper
reference, so it's important to have it in all utilities, which may
pass this element as input
^KT-64975
This is needed to gain access to providers functionality in those
utilities, which is important for support of FirDeserializedEnumAccessExpression
node (see later commits)
^KT-64975
One of the previous commits moved calculation of diagnostics from
FirAnalyzerFacadeinto the separate test service, so it should be altered
in AA tests too
There are two ways of test service registration:
- manual call to `useAdditionalServices` in abstract test runner
- using of `additionalServices` property in one of test entity (e.g. in handler)
Services are registered in the same order (manual first, automatic second)
This led to the situation that if there was registered more specific
implementation of the service in the test configuration, it will be
overridden with regular implementation from handler, which is fixed
by this commit
There are some cases when we want to run some platform checker not from
platform session but from common session. All such cases appear when
we check some `expect` class
```kotlin
// MODULE: common
expect interface A
expect class B : A
class C : A
// MODULE: platform()()(common)
actual interface A {
fun foo()
}
actual class B : A {
override fun foo() {}
}
```
In this example we want to report "abstract foo not implemented" on
class `C`, but we don't want to report it on `expect class B` (as
its supertype is always `expect A`, never `actual A`)
So to cover such cases some platform checkers were split into two parts:
- `Regular`, which is platform checkers and runs for everything except
expect declaration
- `ForExpectClass`, which is common checkers and runs only for expect
declarations
^KT-58881 Fixed
^KT-58881 Fixed
^KT-64187 Fixed
This commit introduces MppChecker kind, which represents the new property
of checkers
- `MppCheckerKind.Common` means that this checker should run from the same
session to which corresponding declaration belongs
- `MppCheckerKind.Platform` means that in case of MPP compilation this
checker should run with session of leaf platform module for sources
of all modules
An example of a platform checker is a checker that checks class scopes
and reports ABSTRACT_NOT_IMPLEMENTED and similar diagnostics. If some
regular class in the common module contains expect supertypes, the
checker should consider the actualization of those supertypes to get
a complete type scope
^KT-58881
In the following commits, there will be a need to retrieve the scope of
the same class from different sessions, so we need to consider the
session as part of the key along with class symbol
3aa84906 changed native metadata serialization to use proper platform
session, but it caused a new bug: FirKLibSerializerExtension uses
FirProvider from the passed session to get a containing file of
serialized declaration to put some extension into the metadata. And
platform session doesn't contain information about any declarations
except platform ones
So it's needed to use the proper FirProvider in it, which can be
extracted from Fir2IrComponents. This provider contains providers from
all sessions that are being compiled plus providers for top-level
declarations generated by compiler plugins
^KT-65024 Fixed
K2 in MPP compilation expects that it receives module structure
with exactly one platform leaf module. This invariant may be broken
during grouping tests, so MPP tests should be run in standalone mode
```
abstract class Base
var x: Int
private set
}
class Derived : Base()
```
Without this change, FIR2IR created a symbol for setter of f/o Derived.x,
but IR f/o generator doesn't create a setter in f/o, as this setter is
invisible in Derived
^KT-64742