We do not need running IMPLICIT_TYPES_BODY_RESOLVE to check candidate applicability.
Additional resolve to IMPLICIT_TYPES_BODY_RESOLVE takes about 5% of completion time
^KTIJ-24640
For some synthetic methods from compiled Kotlin classes, it is
not possible to find the PsiElement, when navigating to declaration
in the IDE.
For other methods it works like this:
1. There is a SourceElement with a psi inside
2. Or for K1, the element is searched in the decompiled text
(see ByDescriptorIndexer),
3. Or for K2, the element is searched by Stub taken from metadata
(see FirDeserializedDeclarationSourceProvider)
However, these approaches do not apply to synthetic methods which have
no SourceElement and are not written into decompiled text and metadata.
These are methods values, valueOf, entries from enum and
copy, equals, hashCode, toString from data classes.
Therefore, it was decided to handle their cases separately
at the resolve stage.
Tests (in idea repository):
- org.jetbrains.kotlin.idea.resolve.ReferenceResolveWithLibTestGenerated#testDataClassSyntheticMethods
- org.jetbrains.kotlin.idea.resolve.ReferenceResolveWithLibTestGenerated#testEnumSyntheticMethods
- org.jetbrains.kotlin.idea.fir.resolve.FirReferenceResolveWithLibTestGenerated#testDataClassSyntheticMethods
- org.jetbrains.kotlin.idea.fir.resolve.FirReferenceResolveWithLibTestGenerated#testEnumSyntheticMethods
^KTIJ-24413 Fixed
Support FirStringConcatenationCall in FirCompileTimeConstantEvaluator.
This allows string templates ("foo${bar}") to be evaluated as constants,
assuming the interpolated expressions are themselves constant.
In addition, fixes some handling bugs with KtConstantEvaluationMode,
where some expressions that are not valid in a `const val` declaration
were being supported for `CONSTANT_EXPRESSION_EVALUATION`, including
non-static final Java fields in FIR, and composite expressions of
non-const properties in FE1.0.
This flag is true by default but is set to false for
- Java methods and constructors
- interface delegation methods that delegate to Java
The NAMED_ARGUMENTS_NOT_ALLOWED logic is mostly refactored to use the
new flag though some custom logic remains for determining the correct
message and to work around a corner case with fake overrides.
The flag is (de)serialized from/to metadata. For backward compatibility
with K1, delegated methods to Java types are deserialized as stable.
^KT-40480 Fixed
- KTIJ-24574 occurred because a local destructuring declaration was
erroneously returned as the non-local containing declaration of an
element by `getNonLocalContainingOrThisDeclaration`. This occurred in
`init` blocks.
KTIJ-24574 fixed
Before we resolved all declarations to body resolve.
It was rarely needed and badly affects performance.
If the resolution will still be needed, it will be lazily performed by KtSymbol
Use expanded ConeTypes to get correct parameters and return types
Also, fix the order of rendering modifiers in `KtFunctionalTypeRenderer`
^KTIJ-24527 Fixed
Example:
```stacktrace
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 32 out of bounds for length 17
at com.intellij.util.containers.RefHashMap$MyMap.rehash(RefHashMap.java:85)
at it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap.insert(Object2ObjectOpenHashMap.java:251)
at it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap.put(Object2ObjectOpenHashMap.java:259)
at com.intellij.util.containers.RefHashMap.putKey(RefHashMap.java:160)
at com.intellij.util.containers.RefKeyRefValueHashMap.put(RefKeyRefValueHashMap.java:55)
at org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder$FunctionLikeSymbolBuilder.buildFunctionSymbol(KtSymbolByFirBuilder.kt:727)
at org.jetbrains.kotlin.analysis.api.fir.scopes.FirScopeUtilsKt$getCallableSymbols$1$1$1$1.invoke(firScopeUtils.kt:25)
at org.jetbrains.kotlin.analysis.api.fir.scopes.FirScopeUtilsKt$getCallableSymbols$1$1$1$1.invoke(firScopeUtils.kt:24)
at org.jetbrains.kotlin.fir.scopes.impl.FirClassDeclaredMemberScopeImpl.processFunctionsByName(FirClassDeclaredMemberScope.kt:103)
```
^KTIJ-22749
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
FirReferenceResolveHelper internally checks whether the referenced class
id matches the qualifed access or not. If they do not match, it reports
an error. When the companion object has the same name as the class,
resolving a qualified expression access to a member of the companion
object causes an error because of the mismatch e.g.,
```
package my.sample
class Test {
fun a() {
my.sample.<caret>Test.say()
}
companion object Test {
fun say() {}
}
}
```
This commit fixes the issue.
TODO: When the companion object has a name difference from class, it
does not report an error but the resolution result is wrong in FIR. See
KT-56167.
---
Commentary from rebaser: the issue mentioned in this code is
fixed in 71a368e06e, so the actual
fix is omitted, and only test data is preserved
Now KtFirScopeProvider do not contain caches, so it can be reused between the threads. The only thread-local thing it had, was a ScopeSession. Now it's not stored in the KtFirScopeProvider
Remove psi caching for local declarations as it's fast to get the psi for those.
Local declarations cannot be from the library, so we do not need to search for deserialized psi for those.
^KTIJ-22749
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
This is needed to provide an ability to extend different kinds of
functional types
Also, cleanup and rename utilities related to functional types to avoid
possible confusions