- Instead of extending the API with `typeParameterNames`, this commit
creates a PSI-based Java type parameter symbol similarly to the
PSI-based Java class symbol. Because completion requires only the type
parameter name, this approach works fine, and without exposing an
optimization via the API.
- Instead of spreading `equals` and `hashCode` implementations over
`KtFirNamedClassOrObjectSymbol` and `KtFirPsiJavaClassSymbol`, this
commit introduces a shared base class.
- Some completion tests failed because the `hashCode` of
`KtFirNamedClassOrObjectSymbol` and `KtFirPsiJavaClassSymbol` was
different for symbols which should be equal. Both symbols now use the
`ClassId` hash code.
- `KtFirNamedClassOrObjectSymbol.equals` is now properly symmetric with
`KtFirPsiJavaClassSymbol`.
- `KtFirPsiJavaClassSymbol` now has a definite class ID, which
simplifies its implementation a little. `KtFirPsiJavaClassSymbol`
doesn't support local Java classes by design.
- Most Java classes aren't deprecated. To avoid building `firSymbol`
in such cases, this commit adds a simple heuristic which checks the
class's annotations for the presence of one of the deprecation
annotations recognized by the Kotlin compiler.
- Note that annotations are compared via simple names, so there is a
slight margin of error. However, comparing class IDs is more costly in
my tests, because getting an annotation's class ID is not as cheap as
getting its simple name.
- Completion accesses symbol type parameters to render their names.
Instead of building the whole list of type parameters, and
consequently the whole FIR class, completion can now access the type
parameter names directly.
- `KtFirVisibilityChecker` accessed `KtFirPsiJavaClassSymbol.firSymbol`
a significant number of times during completion, which led to many
instances of FIR class construction.
- This commit introduces a heuristic to `KtFirVisibilityChecker`
specifically for `KtFirPsiJavaClassSymbol` to bypass the compiler's
visibility checker. The fact that we're dealing with Java class
visibility from Kotlin makes this feasible without reimplementing the
full logic of `FirVisibilityChecker`.
- `FirJavaClass` gets all its annotations from the Java annotations, so
we can rely on `javaClass.annotations` to determine if any annotations
are present.
- Some completion performance tests (e.g. IntelliJ: "empty place typing
with library cache") spent a considerable amount of time in
`KtFirSymbolProviderByJavaPsi.getNamedClassSymbol`.
- This commit introduces `KtFirPsiJavaClassSymbol`, which implements
many `KtNamedClassOrObjectSymbol` properties with the `PsiClass`
instead of the FIR class. The `FirClassSymbol` is built only when
necessary. This improves performance when no "slow" properties need to
be computed for the symbol.
^KT-56617 fixed
Normally, compiled declaration searcher should look up declarations
only inside the session declarations. However, built-ins are treated
as a separate dependency, so '...WithoutDependencies()' functions
return only a part of declarations for the Kotlin standard library.
This commit effectively reverts changes in the previous change
(07fdbeca19).
This commit fixes the rest of failing compiletion tests:
- HighLevelJvmBasicCompletionTestGenerated
- HighLevelMultiFileJvmBasicCompletionTestGenerated
If an intersection override overrides members A.x, B.x and C.x and
B <: A, then A.x is subsumed by B.x, and we don't add it to the list of
overridden members. This fixes a false-positive MANY_IMPL_MEMBER_NOT_
IMPLEMENTED where an implementation is subsumed by an abstract override.
^KT-57092 Fixed
- The optimization reduces time spent in `LLFirProvider.SymbolProvider`
during my tests by 30-90% in some highlighted files. In other
performance tests, the optimization makes performance worse, so more
work is needed. In general, higher workload tests run faster with the
optimization, while lower workload tests run slower. This is expected
as the optimization trades short-term performance (for building
classifier/callable name sets) in favor of long-term speedup.
- The changes should also reduce the size of declaration caches like
`LLFirProviderHelper.classifierByClassId`.
- Building the name sets has a second use, as a similar optimization can
be implemented for dependent module providers, which may rely on the
sets computed here.
Note that there's no code that checks that
FirReceiverParameter's annotation's use-site target
is indeed `@receiver:`, because otherwise the
annotation wouldn't have made it into
the FirReceiverParameter.
In contrast, in K1 all such annotations are treated
as annotations on a KtTypeReference.
^KT-56769 Fixed
'JvmClassFileBasedSymbolProvider' works incorrectly for some cases,
such as built-in classes. Moreover, the whole declaration binding logic
looks over-complicated and redundant, as we get a 'ClassId'/'CallableId'
from a 'KtDeclaration', and look for it again in indices.
This commit fixes a bunch of failing completion tests:
- HighLevelJvmBasicCompletionTestGenerated
- HighLevelMultiFileJvmBasicCompletionTestGenerated
- FirKeywordCompletionHandlerTestGenerated
After 1cfd2ae7ff, all non-local
declarations became targets for on-air resolution. However, some of
them, including secondary constructors, are not supposed to be used
in that way. The commit restores the previous behavior.
This commits fixes failing tests in the following groups:
- FirIdeDependentAnalysisSourceModuleIsUsedAsExpressionTestGenerated
- FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated
- FirOnAirResolveTestGenerated
Library modules depend on all other project modules. Such a
simplification is useful for cross-library analysis. However, this
seems to be rather harmful for PSI->FIR binding as there might be
several versions of the same library in a project.
The implementation is rather limited. Advanced cases, such as
replacing a script with another one with different import directives,
won't work because of non-trivial relationship between 'FirFile' and
'FirScript'.