For the following example, when we run the reference shortener, it
drops `a.b.c` qualifier, because it matches "FOURTH".
```
package a.b.c
fun <T, E, D> foo(a: T, b: E, c: D) = a.hashCode() + b.hashCode() + c.hashCode() // FIRST
fun <E> E.foo() = hashCode() // SECOND
object Receiver {
fun <T, E, D> foo(a: T, b: E, c: D) = a.hashCode() + b.hashCode() + c.hashCode() // THIRD
fun foo(a: Int, b: Boolean, c: String) = a.hashCode() + b.hashCode() + c.hashCode() // FOURTH
fun test(): Int {
fun foo(a: Int, b: Boolean, c: Int) = a + b.hashCode() + c // FIFTH
return <expr>a.b.c.foo(1, false, "bar")</expr>
}
}
```
As shown in the above example, when SHORTEN_IF_ALEADY_IMPORTED option is
given from a user, the reference shortener has to check whether it can
drop the qualifier without changing the referenced symbol and if it is
possible to do that without adding a new import directive, it deletes
the qualifier.
It needs two steps:
1. Collect all candidate symbols matching the signature e.g., function
arguments / type arguments
2. Determine whether the referenced symbol has the highest reference
priority when we drops the qualifier depending on scopes
This commit uses `AllCandidatesResolver(shorteningContext.analysisSession.useSiteSession).
getAllCandidates( .. fake FIR call/property-access ..)` for step1.
For step2, we use a heuristic based on scopes of candidates. If a
candidate symbol is under the same scope with the target expression, it
has a `FirLocalScope` which has the high priority. So when we have a
candidate under a `FirLocalScope` and the actual referenced symbol is
different from the candidate, we must avoid dropping its qualifier
because the shortening will change its semantics i.e., reference.
The order of scopes depending on their scope types is:
1. FirLocalScope
2. FirClassUseSiteMemberScope / FirNestedClassifierScope
3. FirExplicitSimpleImportingScope
4. FirPackageMemberScope
5. others
Note that for "others" the above rule can be wrong. Please update it if
you find other scopes that have a priority higher than the specified
scopes.
One of non-trivial parts is the priority among multiple
FirClassUseSiteMemberScope and FirNestedClassifierScope. They are
basically scopes for class declarations. We decide their priorities
based on the distance of class declaration from the target expression.
Note that we take a strict approach to reject all false positive. For
example, when we are not sure, we don't shorten it to avoid changing its
semantics.
TODO: One corner case is handling receivers. We have to update
```
private fun shortenIfAlreadyImported(
firQualifiedAccess: FirQualifiedAccess,
calledSymbol: FirCallableSymbol<*>,
expressionInScope: KtExpression,
): Boolean
```
The current implementation cannot handle the following example:
```
package foo
class Foo {
fun test() {
// It references FIRST. Removing `foo` lets it reference SECOND.
<caret>foo.myRun {
42
}
}
}
inline fun <R> myRun(block: () -> R): R = block() // FIRST
inline fun <T, R> T.myRun(block: T.() -> R): R = block() // SECOND
```
Tests related to TODO:
- analysis/analysis-api/testData/components/referenceShortener/referenceShortener/receiver2.kt
- analysis/analysis-api/testData/components/referenceShortener/referenceShortener/receiver3.kt
FunctionalTypeKind can be used in FE 1.0 too, so there is no need to
keep both classes. Also, removal of FunctionClassKind simplifies work
with FunctionalTypeKind in common code, like Analysis Api
and assert that symbol is not a substitution/intersection override
in the `compute` method otherwise.
Because `fakeOverrideSubstitution` should be calculated for all real
implicit types, no call to this method should actually happen.
Otherwise, it can be problematic to create a session
which would contain the full designation path:
`provider.getFirCallableContainerFile(symbol)`
returns `firFile` of a super class which might be from module `a`,
when declaration and its outer classes are from module `b`.
^KTIJ-24105
As 'initialiseVirtualFileFinderServices()' that is run during
test initialization collects transitive dependencies, all of them
must be ready. However, 'KtNotUnderContentRootModuleForTest' has a
built-in dependency provided by 'LLFirBuiltinsSessionFactory'.
Adds implementation and tests for the new
KtClassOrObjectSymbol.annotationApplicableTargets property on
KtSymbolInfoProvider. This implementation delegates to the canonical
implementation in AnnotationChecker for FE1.0, and to the implementation
in FirAnnotationHelpers for FIR.
This change also includes direct tests for annotationApplicableTargets,
and a fix for FirClassLikeSymbol.getAllowedAnnotationTargets in
FirAnnotationHelpers.
Fe10:
* supported default setter
* support default getter
* support parameter from default setter
Fir:
* support java synthetic properties
* support parameter from default setter
^KT-54051