Commit Graph

81 Commits

Author SHA1 Message Date
Marco Pennekamp 4fa0f1316d [AA Standalone] Refactoring: Rename testKtFiles to sourceKtFiles 2024-03-18 21:14:36 +00:00
Marco Pennekamp a9d7b0c595 [AA Standalone] Consider type aliases in direct inheritors search
A type alias may still be inherited from. For example:

```
sealed class MyClass

typealias T = MyClass

class Inheritor : T() // `Inheritor` is a direct inheritor of `MyClass`.
```

The index is a simplified version of the IDE's
`KotlinTypeAliasByExpansionShortNameIndex`, but it should be sufficient
for virtually all cases.

^KT-66013
2024-03-18 21:14:36 +00:00
Marco Pennekamp 1374bc8e2d [LL] Implement a common LLSealedInheritorsProvider
- The new `LLSealedInheritorsProvider` is based on the previous
  sealed inheritors provider implementation in the IDE. It uses the
  new direct inheritors provider and the module dependents provider to
  implement the same functionality that was previously confined to the
  IDE. With this design we avoid duplication of complex logic such as
  the KMP handling in `searchInheritors`.
- The implementation is designed to work in the production Standalone
  mode and the aforementioned services have already been implemented for
  Standalone in prior commits. Now we can get rid of the problematic
  `SealedClassInheritorsProviderForTests` and tests should more closely
  match production behavior.
- In IDE mode tests, `LLSealedInheritorsProvider` is used with
  Standalone Analysis API provider implementations. This is in line with
  the rest of the test infrastructure, where Standalone AA providers are
  generally used, as IDE providers aren't available.
- `KotlinSealedInheritorsProvider` is made obsolete by the common sealed
  inheritors provider.

^KT-66013 fixed
^KT-64505 fixed
2024-03-18 21:14:36 +00:00
Marco Pennekamp b2639a469b [AA Standalone] Implement KotlinDirectInheritorsProvider
- We are relying on static indexing to find candidates for sealed
  inheritors, hence the extension to the index.
- The direct usage of `KotlinStaticDeclarationProviderFactory` in
  `KotlinStandaloneDirectInheritorsProvider` is not pretty, but a proper
  design requires making the static index available as a service and
  moving "static" services to the Standalone API (from AA providers).

^KT-66013
2024-03-18 21:14:35 +00:00
Marco Pennekamp 31a65871f2 [AA] Add KotlinDirectInheritorsProvider
- Direct inheritors are needed to calculate sealed inheritors. The new
  `KotlinDirectInheritorsProvider` can be used to implement a common
  sealed inheritors provider in LL FIR.

^KT-66013
2024-03-18 21:14:35 +00:00
Marco Pennekamp e62038f5f3 [AA] Tests: Rewrite sealed class inheritors collection to use the declaration provider
- Now that binary libraries are decompiled to stubs instead of PSI
  files, we cannot collect sealed inheritors from `KtFile`s anymore.
  Since all `KtFile`s and binary library stubs are both indexed by the
  declaration provider, we can collect inheritors from its index
  instead.
- Invalidating all sessions at the end of `prepareSealedClassInheritors`
  fixes some improper resolve phases in lazy resolution test data. While
  the previous implementation requested an uncached resolve session, it
  didn't account for sessions of dependencies still being cached.

^KT-65960
2024-02-26 21:57:23 +00:00
Marco Pennekamp 47afd37596 [AA] IDE mode tests: Build and index stubs for binary libraries
- Instead of indexing binary library declarations from decompiled PSI,
  the static declaration provider now builds and indexes stubs. As noted
  in KT-65960, this brings IDE mode tests much more in line with
  decompiled stubs indexing in the IDE. It should allow us to catch
  issues with the stub-based deserialized symbol provider outside of IDE
  tests.
- In the Standalone mode, we can skip stub-indexing completely, as we
  provide FIR symbols via class-based deserialization. This also extends
  to shared binary roots.

^KT-65960 fixed
2024-02-26 21:57:23 +00:00
Jinseong Jeon 6f6496d78a AA: remove redundant code
computeIfAbsent right below will do the same thing
2024-02-19 21:54:22 +00:00
Jinseong Jeon 7911207734 AA: remove unused jar file system from KotlinStaticDeclarationProviderFactory 2024-02-19 21:54:21 +00:00
Marco Pennekamp 9a4bf0601e [AA] Add KtClass-based KotlinSealedInheritorsProvider
- The compiler's `SealedClassInheritorsProvider` should not be exposed
  outside LL FIR, as it is an internal compiler component and also
  exposes `FirRegularClass`. `KotlinSealedInheritorsProvider` is an
  Analysis API provider for sealed inheritors that accepts a `KtClass`
  instead.

^KT-64718 fixed
2024-01-30 11:48:09 +00:00
Jinseong Jeon 0dfaa91970 K2 UAST: simplify PSI declaration provider
In addition to class lookup (done at cec299ac), we can use
JavaFileManager to search classes in a certain package too.
2024-01-23 09:09:37 +00:00
Denis.Zharkov 2bdadeb0c8 Fix instability of declaration order of KotlinStaticDeclarationProvider
It affects how some rendering-related tests behave

^KT-64771 Fixed
2024-01-10 14:56:31 +00:00
Yan Zhulanow 7944602066 [Analysis API] Rework in-block modifications for dandling file modules
Before the change, all code fragment sessions were invalidated on any
PSI change. It was a simple solution, though not very effective.
Fragments were invalidated not only on a physical module change, but
also on change in another, unrelated code fragment.

As code fragment sessions were reworked to support also ordinary '.kt'
files, the old logic started to have even less sense, because ordinary
dangling files do not have a context element (they only have a context
module).

Currently, code fragment sessions are invalidated on any change in a
physical (non-dangling) module, and are also invalidated on any change
in their contextual dangling module, if any. With some work, this can be
improved further, so code fragments will be invalidated only on changes
in modules they depend on.

Relevant tests can be found in the IntelliJ project
(DanglingFileModuleInvalidationTest).
2024-01-05 16:04:14 +00:00
Dmitrii Gridin c14c12479c [SLC] fix multifile-classes in multiplatform case
Multifile-class can contain not only files from the same
module, but also files from the common part.
This commit also fixes KotlinByModulesResolutionScopeProvider as
it should provide all transitive dependencies

^KT-64714 Fixed
2024-01-05 15:07:55 +00:00
Marco Pennekamp 6474ff88fa [FIR] FirSymbolNamesProvider: Implement classifier package name sets
- Previously, only callable package name sets were implemented, because
  the compiler cannot economically compute classifier package sets for
  libraries. This has not changed. However, the K2 IntelliJ plugin and
  standalone Analysis API can very easily compute classifier package
  sets. Hence, this commit adds support to `FirSymbolNamesProvider` for
  such sets.
- Similar to callable package sets, classifier package sets (1) improve
  the memory usage of symbol names providers and (2) improve the
  performance of `mayHaveTopLevelClassifier`, which is a significant
  bottleneck in the IDE.
- In many cases, the package sets for callables and classifiers are the
  same. For example, the IDE Kotlin declaration provider computes the
  set of packages that contain any classifier and/or callable, for the
  following reasons: (1) indexing package names without filtering for
  declarations is much faster, (2) computing separate sets is not free
  both in time and memory, and (3) the performance impact of having a
  more narrow set for callables is expected to be negligible. For this
  reason, `FirSymbolNamesProvider.getPackageNames` exists to provide a
  shared package set.
- The `hasSpecific*PackageNamesComputation` properties are required to
  avoid caching the same package set in cached symbol names providers
  twice. Because these properties are constant, they can be checked very
  quickly, and no time has to be wasted trying a specific package set
  computation to find out whether it's supported.

### IDE Performance Results

Package set construction performance improved in the IDE in multiple
benchmarks. This improves the performance of symbol providers overall,
which has a direct impact on completion, code analysis, and Find Usages.

In a local manual run of the `intellij_commit/setUp` Find Usages
performance test, the total time spent in `getClassLikeSymbolByClassId`
improved from ~18.7s to ~11.2s. Due to parallel resolve, this does not
translate to a wall clock improvement of 7 seconds, but rather of a few
seconds.

Some performance tests improved markedly in warmup, with for example
`toolbox_enterprise/genUuid` Find Usages having an improvement in
`StubBasedFirDeserializedSymbolProvider.getClassLikeSymbolByClassId`
from 2.4s to 0.2s. This has a direct impact on the first-run performance
of the tested Find Usages command.

So far, classifier package sets in the IDE are only implemented for
libraries, and library sessions are cached after the first warmup.
Because the biggest impact of classifier package sets is avoiding
computation of "class names in package" sets, the impact of this
optimization is not accurately reflected in the timings reported by our
performance tests. `toolbox_enterprise/genUuid` above is a good example,
as the warmup timings are great, but after warmup,
`StubBasedFirDeserializedSymbolProvider.getClassLikeSymbolByClassId`
improved only from 150ms to 70ms.

`toolbox_enterprise/genUuid` is another example, as we can confidently
say that the first-run Find Usages performance has improved (which makes
a difference for the user), but it is unclear by how much, as warmup is
not measured in performance tests.

The same optimization for source sessions will be easier to measure, as
source sessions are invalidated after each performance test run. This
commit lays the groundwork for that as well, because source session
support only requires the requisite package set computation in the
IDE declaration provider to be implemented.

^KT-62553 fixed
2023-12-13 14:40:10 +00:00
Ilya Kirillov 5f5daa0e06 [Decompiler] rename :analysis:decompiled:native -> :analysis:decompiled:decompiler-native
to avoid possible name clashes between different
Gradle subprojects with the same name.

see https://github.com/gradle/gradle/issues/16986
2023-11-10 06:41:03 +00:00
Ilya Kirillov 7c6870f8d2 [Analysis API Standalone] index .knm files in KotlinStaticDeclarationProvider
so `FirSymbolNamesProvider` can know about them

^KT-62910
2023-11-10 06:41:03 +00:00
Ilya Kirillov 9c85857b68 [Analysis API Standalone] refactoring, extract stub create to a separate function 2023-11-10 06:41:03 +00:00
Roman Golyshev 2f50267d3f KT-63096 [LL] Make KotlinStaticAnnotationsResolver more correct
By using `KotlinDeclarationProvider`, it can now check that the
annotation is actually present in the scope
2023-11-09 23:39:32 +00:00
Marco Pennekamp 576d8d1c10 [AA] Allow declaration provider package set computation to return null
- This is in line with the API of `FirSymbolNamesProvider`. It only
  makes sense to compute package sets for source and library modules.
  Also, source module package set computation in the IDE is currently
  broken, so it's good to be able to return `null` in the meantime.
- This also allows the removal of the workaround for source modules in
  `LLFirProviderHelper`, as the IDE declaration provider can now return
  `null` itself in this case.

^KTIJ-27411
2023-10-26 21:07:28 +00:00
Marco Pennekamp 485a4cebb2 [AA] createDeclarationProvider: Document usages of the contextual module
^KTIJ-27411
2023-10-26 21:07:28 +00:00
Marco Pennekamp 2ec77822e2 [AA] createDeclarationProvider: Rename module to contextualModule
^KTIJ-27411
2023-10-26 21:07:28 +00:00
Marco Pennekamp a62ac940c4 [AA] Add abstraction for composable Kotlin providers
This further improves the `KotlinCompositeProvider` abstraction:

- Pulling the abstraction's interfaces outside the `impl` package allows
  us to write consolidated documentation on composable Kotlin providers.
- The addition of `KotlinComposableProvider` allows more specific bounds
  for the type parameters of `KotlinCompositeProvider` and
  `KotlinCompositeProviderFactory`. It also clarifies to Analysis API
  implementors which providers can be composed at all, as providers like
  `KotlinDeclarationProvider` extend this interface.
- `KotlinComposableProviderMerger` provides a unified interface for
  provider mergers.

^KT-61791
2023-10-12 16:10:32 +00:00
Marco Pennekamp b9e3d848a6 [AA] Add KotlinPackageProviderMerger
- In parallel to Kotlin declaration provider merging, we need a proper
  merging strategy for package providers as well, because resolve
  extensions may define additional package providers.
- Additionally, other non-scope-based package providers may be added in
  the future, and the merger preserves these out of the box.

^KT-61791
2023-10-12 16:10:32 +00:00
Marco Pennekamp c63dde4f7e [AA] Add abstraction for composite provider creation and merging
- Composite declaration providers and declaration provider mergers are
  extremely similar to the composite package providers and (newly to be
  implemented) package provider mergers. This commit extracts the common
  parts into a `KotlinCompositeProviderFactory`.

^KT-61791
2023-10-12 16:10:32 +00:00
Ilya Kirillov e8db349f24 [decompiler] extract builtin VirtualFile creation to a separate service for further reuse
^KTIJ-26760
2023-08-30 14:45:14 +00:00
Pavel Kirpichenkov 14eef4c7fe Minor: move lost comment 2023-08-17 12:03:09 +00:00
Pavel Kirpichenkov 6de54ef762 Minor: workaround false positive IDE error KTIJ-21172 2023-08-17 12:03:09 +00:00
Pavel Kirpichenkov ef6375f627 [LL] Use package provider to check for existing package
KT-59793
2023-08-17 12:03:08 +00:00
Yan Zhulanow 8a5cab6831 [LL API] Support '_DebugLabel's in code fragments 2023-08-07 16:22:01 +00:00
Marco Pennekamp 03c8654fe3 [AA] KT-58257 Improve modification event API and documentation
- Module state modification events now have a modification kind, which
  allows adding additional kinds of modification in the future (e.g.
  separating module property and content root updates, if the workspace
  model ever supports it).
  - Splitting off modification kinds was also a good opportunity to
    better document when module state modification occurs.
- Changed the documentation of modification events to be (1) less
  reliant on the IDE implementation and (2) more detailed in the
  intended effect of each event.
- Removed the notion of "stable" modules again and replaced it with
  "libraries". Even though an SDK is technically not a library, the
  term "library modules" should be more friendly to API consumers.
2023-07-31 15:58:01 +00:00
Marco Pennekamp d2b05b8f4f [AA] KT-58257 Restore timing guarantees of module state modification events
- Specifically for non-global module state modification, we can
  guarantee that the event is published before the module is modified.
  This allows subscribers to use the provided `KtModule` without needing
  to fear that the module has already been disposed (in case of
  removal).
2023-07-31 15:58:01 +00:00
Marco Pennekamp 62a71b1559 [AA] KT-58257 Remove global out-of-block modification events
- Out-of-block modification of stable modules is meaningless, because
  stable modules should not be affected by out-of-block modification.
  Hence, only global *source* out-of-block modification makes sense and
  global out-of-block modification events can be removed.
2023-07-31 15:58:01 +00:00
Marco Pennekamp 42c879a53c [LL FIR] KT-58257 Invalidate library sessions depending on anchor modules on global source modification
- Any time an anchor module's session is invalidated, we need to make
  sure that all its dependents are also invalidated. Because those
  dependents may include libraries, invalidation after global source
  modification needs to invalidate such libraries, even if other stable
  module sessions should remain untouched.
2023-07-31 15:58:01 +00:00
Marco Pennekamp 24045067bf [LL FIR] KT-58257 Keep library (source) sessions on global source invalidation
- `LLFirSessionCache.sourceCache` can contain library and library
  sources sessions. However, global source modification events should
  not remove such sessions from the cache, because they belong to
  "stable" modules.
- The commit introduces the term "stable module" as a combined term for
  binary and library source modules. Library sources are not binaries,
  but nevertheless they cannot cause nor be affected by out-of-block
  modification.
- The term "source modules" as used by global "source" modification is
  slightly imprecise, as it does *not* include library sources, but for
  the sake of conciseness, I don't plan to change that.
2023-07-31 15:58:01 +00:00
Marco Pennekamp 2d279c5f25 [AA] KT-58257 Remove timing guarantees of Kotlin modification events
- Kotlin modification events are published before or after the
  modification, depending on the underlying cause. For example, PSI tree
  change events in the IDE can occur both before and after the change,
  so module and global out-of-block modification events must not make
  timing guarantees. Similarly, module state modification events
  published by the IDE can both happen before and after a module change,
  with most events happening before the change.
2023-07-31 15:58:00 +00:00
Marco Pennekamp 0c94a3131c [AA] KT-58257 Add API for subscription-directed invalidation
- The commit refactors some modification trackers previously provided by
  `KotlinModificationTrackerFactory` to a subscription-directed
  mechanism implemented via `MessageBus` and `KotlinTopics`. The
  following modification trackers are affected:
  - Module out-of-block modification: The FE10 Analysis API doesn't use
    these modification trackers, so the effect is limited to LL FIR.
  - Module state: Likewise, FE10 doesn't use this modification tracker,
    so again the effect is limited to LL FIR.
- Project and library modifications trackers remain, because many small
  objects in e.g. light classes depend on these trackers (making
  listener management unfeasible), and they are not relevant for
  `LLFirSession` invalidation.
- This new API paves the way for a session invalidation service to
  subscribe to out-of-block and module state changes as events. This
  removes the need to iterate through modification trackers.
  - Also note that the out-of-block modification provided by the new
    subscription mechanism is intended to work for _any_ `KtModule`, as
    long as it makes sense to have out-of-block modifications. For
    example, the subscription should work for script modules. The OOB
    modification tracker previously only supported `KtSourceModule`s,
    which required separate single-file modification trackers for script
    and not-under-content-root modules.
- `MessageBus` is a general utility provided by IntelliJ, but usually it
  is retrieved from `project`. To keep these two concerns decoupled,
  `project.messageBus` should not be used directly. Instead, the commit
  adds a `KotlinMessageBusProvider`, which for now just provides the
  project message bus with its standard implementation, but allows
  swapping out the message bus implementation later.
- Global changes are also supported by the new subscription API. Such
  global changes may for example occur during cache invalidation in
  tests, on global PSI tree changes, or when an SDK is removed.
- Test-only invalidation has been moved from
  `KotlinModificationTrackerFactory` to a new
  `KotlinGlobalModificationService`. This creates one central service
  for invalidation between tests, which is easier from an implementation
  and a usage perspective than calling multiple scattered services and
  providers.
2023-07-31 15:58:00 +00:00
Pavel Kirpichenkov b316aa7d1d [AA] stub-based library symbol providers for non-JVM platforms
Use existing stub-based JVM library symbol provider for .knm and
.kotlin_metadata files. The only real difference is the scope filtering
by file types

KT-58769
2023-07-25 09:15:29 +00:00
Jinseong Jeon 6fc02c3408 SLC: ROOT package exists no matter what
^KT-59843 Fixed
2023-07-11 11:47:23 +02:00
Egor Kulikov 27f4b53570 [FIR] Do not expect builtin imports to be always resolved
Merge-request: KT-MR-10886
Merged-by: Egor Kulikov <Egor.Kulikov@jetbrains.com>
2023-07-05 14:02:50 +00:00
Anna Kozlova f96b5bae48 [LL] anchor module provider for navigation in monorepo
Use information from IDE about anchor module,
to include everything from that module and dependencies into library session
^ KTIJ-24683
2023-07-03 17:10:51 +00:00
Anna Kozlova 86bed92a46 [AA] ensure psi files from stdlib do not leak 2023-06-07 21:00:26 +00:00
Marco Pennekamp 915c412929 [AA] KT-58580 Add KotlinDeclarationProviderMerger
- A proper merging strategy for declaration providers is required for
  cases where the main declaration provider created by
  `createDeclarationProvider` can't provide all declarations that the
  original declaration providers can provide. Then, only a sublist of
  the declaration providers should be merged, while keeping the
  unmergeable declaration providers intact.

^KT-58580 fixed
2023-05-31 18:34:42 +00:00
Marco Pennekamp fba0648005 [AA] Move impl declaration providers to subpackage 2023-05-31 18:34:42 +00:00
Marco Pennekamp 52f025f39b [AA] Extract SublistMerger to analysis-api-providers utils
- This utility is useful for other places where sublists need to be
  merged.
2023-05-31 18:34:42 +00:00
Ilya Kirillov c646008438 [Analysis API] refactoring, extract forEachNonKotlinPsiElementFinder to a separate file 2023-05-19 11:53:16 +00:00
Yan Zhulanow bb37a959d4 [LL API] Move composite declaration provider to be used in IntelliJ 2023-05-16 08:42:57 +00:00
Yan Zhulanow d3cb41cbab [LL API] Pass contextual modules to 'KotlinDeclarationProvider' factory
^KT-57559 Fixed
2023-05-16 08:42:57 +00:00
Yan Zhulanow 5e04c0d4f7 [LL API] Move 'FileBasedKotlinDeclarationProvider' to be used in IDE 2023-05-16 08:42:57 +00:00
Anna Kozlova 5ca052f87b [LL] [cls] use stubBased symbol provider for builtins
this gives the following benefits:
1. no protobuf in memory, all data is already present in stubs
2. given that symbol provider for libraries is already stub based,
we can get rid of complicated code to find source psi by deserialized fir
3. it's also possible to reduce number of index access,
when fir is requested for given ktElement
2023-05-09 07:36:09 +00:00