FIR-tree for scripts is built either for KtScript or KtFile depending on
the file structure. The presence of import statements results in KtFile.
There are lazy trees (some nodes are stubs) that are not yet supported
for scripts. We build such ones for KtFile case.
This commit prevents lazy tree construction for scripts at references
shortening.
^KT-59801 fixed
Due to possible data races configuration discovery might fail. So far,
it happened silently and we used so-called default one. This
configuration is unaware of specific implicit imports, receivers, base
class, etc. Hence, broken highlighting and navigation.
This commit introduces the following changes:
1. Having default configuration for building `FirScript` is no longer an
option. Missing configuration means error reported via exception.
2. Every configuration usage is now logged in DEBUG mode.
Troubleshooting becomes easier.
^KT-60193 fixed
Base method `RawFirBuilder.Visitor.convertElement` has a parameter with
default value, its overridden one in `VisitorWithReplacement` is not
allowed to declare default. So far so good.
During its work the compiler throws an exception:
`java.lang.IllegalArgumentException: No argument for parameter`.
Prior to this commit code completion for .kts files was supported only
partially. Script has an implicit receiver - base class representing a
script itself, the point where its basic API resides. The knowledge of
this receiver was missing.
There are at least two context where this knowledge is crucial:
1. Code highlighting (worked fine)
2. Code completion (failed)
`FirScriptConfiguratorExtension` is responsible for filling
`FirScriptBuilder` with base script class (in addition to other
properties). See usages of [1] in its implementation.
The thing is that resolution during the completion works a bit
different. Instead of converting the entire `KtFile` it's interested
in `KtScript` only. See usages of [2].
`RawFirBuilder.Visitor.visitScript` is where implicit receivers were
missing.
Code completion and inspections applied to `.kts` files already have
`FirScript` and don't require its full reconstruction with expensive
`FirScriptConfiguratorExtension`. `RawFirBuilder.Visitor` was modified
to support sometimes already existing `FirElement`.
----------------------------------------------------------------
[1]: ScriptCompilationConfiguration.baseClass
[2]: RawFirBuilder.Visitor.convertScript
To be reported with [1] imports require source. It was missing for
implicit script imports.
`FirScriptConfiguratorExtensionImpl` was extended and now adds fake
source elements (users don't see imports in the source code).
Since diagnostics for implicit import statements are meaningless for
IDE, they are suppressed in `LLFirDiagnosticReporter`.
----------------------------------------------------------------------
[1]: DiagnosticReporter.reportOn()
The following two registrars were missing:
- FirScriptingCompilerExtensionIdeRegistrar
- FirScriptingSamWithReceiverExtensionRegistrar
`FirScriptingCompilerExtensionIdeRegistrar` was introduced as a copy of
`FirScriptingCompilerExtensionRegistrar` adapted for usage from IDE.
`FirRegisteredPluginAnnotations` and `FirJvmTypeMapper` are mandatory at
`FirExtensionService.registerExtensions` and reported as missing at
runtime.
Default imports coming from script configuration can be of "star" type.
Prior to this commit they were effectively ignored due to a bug at FQN
assembly.
Before: org.gradle.dsl.* => org.gradle.dsl.
After: org.gradle.dsl.* => org.gradle.dsl
The problem results in broken import quick fix and import optimizer on
the IDE side [1].
`AssignResolutionAltererExtension` introduced a possibility to override
resolution of assignment statements. The inconsistency though is
that `KtSimpleNameReference.getResolvesByNames` doesn't return a name
for the overridden `=`. Kotlin as a language doesn't support this [2].
This commit eliminates the drawback above:
1. It fixes the name `assign` the `=` can be resolved to [3].
This eliminates the need to search for the name, bypassing the
plugins.
2. `KtSimpleNameReference.getResolvesByNames` returns `assign` among
other names in case it deals with binary `=` and assignment is
resolved.
3. `KtCompilerPluginsProvider` was extended to check plugins' presence.
K1 implementation added.
----------------------------------------------------------------
[1]: https://youtrack.jetbrains.com/issue/KTIJ-24390
[2]: OperatorConventions.getNameForOperationSymbol
https://kotlinlang.org/docs/operator-overloading.html#augmented-assignments
[3]: OperatorConventions#ASSIGN_METHOD + AssignmentPluginNames
From now on we load script configurations for embedded Kotlin code
snippets. Potentially this might lead to an extra load during a file
analysis.
IDEA side test for the change is here:
`HighlightingTestGenerated.Uncategorized#testKotlinInJavaInjection`
^KT-56632 fixed
Case:
```
options.incrementalAfterFailure = false // assignment operator (a)
options.incrementalAfterFailure.set(false) // equivalent (without) (b)
// (a) works thanks to AssignResolutionAltererExtension
// 'incrementalAfterFailure' is a synthetic Java property
// i.e. getIncrementalAfterFailure()
// Navigation to 'incrementalAfterFailure' (a) doesn't work.
```
By navigation, we mean opening declaration sources. The reason of the
issue lied in sources absence (inability to find them).
In general, sources are available via declaration descriptor.
To find one for a property, one needs to understand expression
kind: read/write/both. Hence, the choice of a getter/setter/both.
Since `=` operator is interpreted as a write type expression, a setter
was searched. Missing one resulted in corrupted navigation.
As a fix we provide getter for the missing setter case.
^KT-56941 fixed
```
java.docsDir = file("src/docs")
```
is a `KtBinaryExpression`. Decision on the assignment validity involves
`AbstractAssignPluginResolutionAltererExtension.hasSpecialAnnotation()`.
The function requires a parent declaration, which in case of a script
is `KtScriptInitializer`.
^KT-56221 fixed
The following tests are outdated (JPS/Js is no longer supported):
- MultiplatformJpsTestWithGeneratedContentGenerated$Simple.testEditingPJsKotlin
- MultiplatformJpsTestWithGeneratedContentGenerated$SimpleNewMpp.testEditingPJsKotlin
GitOrigin-RevId: e4c4b5a75b39803bc5df966a3d957e5ab0f253b1
Original commit: https://github.com/JetBrains/intellij-community/commit/49542e2cce00b08f87c0c91093dff4e8c9df1032
The following tests are outdated (JPS/Native is no longer supported):
- MultiplatformJpsTestWithGeneratedContentGenerated$IgnoreAndWarnAboutNative.testEditingCKotlin
- MultiplatformJpsTestWithGeneratedContentGenerated$Simple.testEditingCKotlin
- MultiplatformJpsTestWithGeneratedContentGenerated$SimpleNewMpp.testEditingCKotlin
GitOrigin-RevId: 6e81a4a86a480563992b6fbde4ecbf47571bb49e
Original commit: https://github.com/JetBrains/intellij-community/commit/2a3a84bfa69853efd0be2eaca183cd615af03080
Receiver of a function call '<receiver>.foo()' (where receiver is a
class/object/alias name) might be specified incorrectly - corresponding
[companion] object might not be declared.
Before this commit '<receiver>' was considered to be undefined (null).
As a consequence, import suggestion included all 'foo()' functions from
the search scope.
Now as a value of '<receiver>' we set class/object/alias itself
resulting in an empty import suggestion list.
See org/jetbrains/kotlin/idea/util/CallType.kt:307
(#extractReceiverTypeFrom(descriptor: ClassDescriptor)).
After Kotlin-IDE-plugin is moved to intellij repository, this commit
updates contributing.md guide with corresponding references.
Other than that brief information on current repository is provided.
To provide similar behavior for both Gradle and JPS projects target and
source directories are now taken into account.
Prior to this commit AbstractMoveTest.kt contained a hack allowing not
to create empty target directories. It breaks updated logic of the move
check and therefore is removed.
To commit empty target directories under 'before' to git one needs to
put something in them (git ignores dirs otherwise). Hence .gitignore-s.
^KT-44841 Fixed
This commit resets mentioned file attribute from Kotlin binary files.
It finalizes the fix 929b6dd9 - users might have mistakenly set 'false'
value left on their file systems.
'List<WhenMissingCase>.hasUnknown' property was changed in 4222bb9a.
As a result quickfix's AddWhenRemainingBranchesFix.Companion.isAvailable
started responding 'no'.
This commit restores original property and provides a separate one for
compiler needs.
^KT-46063 Fixed
From now on sealed declarations get resolved with the help of
FirIdeSealedHierarchyProcessor. This change entails correct IDE side
check for sealed when exhaustiveness.
From now on sealed declarations get resolved with the help of
FirIdeSealedHierarchyProcessor. This change entails correct IDE side
check for sealed when exhaustiveness.
Compiler check for 'when' exhaustiveness requires that module
descriptors of a sealed class and its inheritors are the same (reference
identity matters). Prior to this commit and under some conditions they
were not. Details follow below.
Resolution related data structures (resolution facades) are organized
into trees (sdks, libs, and modules have their own nodes/facades,
module/class descriptors are stored inside). And the trees themselves
are put into a map associating so called PlatformAnalysisSettings and
GlobalFacades (plays a role of a root). PlatformAnalysisSettings is an
abstraction describing target platform and sdk of a module. The more
combinations exist for a project the more facades are used. Please, see
KotlinCacheService for more details.
So why a module can have multiple ModuleDescriptor-s?
Every tree mentioned above is an isolated resolution environment
containing its own instances of the outer world descriptors. Say, if a
project has modules X, Y, Z and we consider X then all three might have
their own vision of X, i.e. 3 descriptors exist at a time.
What descriptor instance does compiler get?
The path starts when the user opens a file in the editor and
highlighting pass starts (see usages of
ResolutionUtils#analyzeWithAllCompilerChecks). Module descriptor stored
in the resolution tree of the file's module gets injected into the
compiler's context. Starting from this moment compiler sees other
modules through the prism of a single resolution facade (tree).
Descriptors residing outside are alien.
This commit allows IdeSealedClassInheritorsProvider to figure out what
PlatformAnalysisSettings are associated with the resolution facade (read
ModuleDescriptor) seen by the compiler. Later on the same facade is used
to provide correct instances of sealed inheritors back to the compiler.
Module descriptor names in the form of 'stableName' depend on a build
system. See JvmCodegenUtil#getModuleName(). For JPS we get
<module-name.main> or <module-name.test> whereas for Gradle we get top
level <module-name>.
This commit changes approach: ModuleDescriptor-to-Module conversion is
no longer made by name. ModuleInfo is utilized instead.
^KT-45074 fixed
The idea behind this commit is that Move Refactoring should warn
developers in case their intention potentially breaks sealed
hierarchies (members must share the same module and package).
Provided algorithm has two goals:
- prevent destruction of correct hierarchies
- help in fixing broken ones
So far, quick-fix tests infrastructure neither supports the check
for multiple files (several .before/.after pairs) nor multi module
structure. Provided tests are quite limited yet allow to make sure that
the fix in question appears in expected context and get activated.
^KT-44043 fixed
This commit fixes test infrastructure issue.
Usage of "COMPILER_ARGUMENTS" test-data-instruction resulted in side
effect. Test cases following the one that used it got broken
LanguageVersionSetting - LanguageFeature.MultiPlatformProjects escaped,
languageVersion could be wrong.
Why it happened
KotlinProjectDescriptorWithFacet defines default values
of (language-version, isMultiplatform) settings for the test-case.
The values themselves are stored in KotlinFacetSettings and passed there
only once. After every test-case (if it uses "COMPILER_ARGUMENTS")
infrastructure calls
KotlinLightCodeInsightFixtureTestCaseKt#rollbackCompilerOptions which
resets mentioned values (among others) in KotlinFacetSettings.
Instances of KotlinProjectDescriptorWithFacet are reused hence facet
settings remained reset.
annotation, data, enum, inner, open - classes supplied with these
modifiers cannot be sealed.
Commit fixes code completion - "sealed" is no longer suggested in
the mentioned case.
Android gradle-project model differs from what we have for pure Java
and MPP. It's the reason why application classpath cannot be collected
correctly.
Until universal solution is provided delegation to gradle is put under
the registry flag. If disable platform runner is used as before.
Approach to take classpath from 'project.sourceSets' failed because it
was applied to extra modules - those without java like plugins
(extending project model with 'sourceSets').
This commit specifies criterion of gradle-project selection - the one to
create run task for.
^KT-42561 fixed
Due to the platform API limitation lambda related hints are treated
separately to all others. Hints removal on editing is not an exclusion
and is now supported as well.
Code editing changes inlay hints offset.
InlayModel.getAfterLineEndElementsInRange(int, int) call didn't return
previously existed hint by its "outdated" offset. From now on hints are
taken by logical line.
93a82060 introduced support of "delegate to Gradle" for Gradle-Kotlin.
This commit fixes an issue known as "Could not get unknown property
'sourceSets' for root project".
Before this commit "delegate to Gradle" option was not taken into
consideration. Was it MPP or SPP, KotlinRunConfiguration was always
executed by platform runner (as a default one). The reason behind this
was that there was no dedicated class (extension point) responsible for
Gradle-Kotlin pair. Now its KotlinGradleAppEnvProvider.
The reason of resource directory absence was that it couldn't be loaded
from the project configuration file. Just after the import it remained
in the memory and runner couldn' get it. KotlinOutputPathsDataService as
a pair to KotlinOutputPaths is what was missing. Details are provided
below.
------------------------------------------------------------------------
On a disk configuration represents a binary file containing serialized
graph of external project structure. It contains nodes belonging to both
IDEA and its plugins.
To deserialize a node IDEA tries to load its class using a chain of
class-loaders: its own and those provided by actual set of plugins.
The nuance is how to get plugins' ones. The approach is the following.
There is an association between a node's payload and a service which is
supposed to consume it see KotlinOutputPathsDataService#getTargetDataKey
and DataNode#getKey). Plugin services are guaranteed to be loaded by
plugin class loader.
No association - service - no plugin, node was just skipped.
------------------------------------------------------------------------
Lambda hints are placed at the end of a line in such a way that user
can't move the caret behind it. Unfortunately, hint provision
infrastructure doesn't take this detail into account.
As a workaround, KotlinLambdasHintsProvider now returns an empty result
(sink) to the outer infrastructure and accesses editor's inlay model
itself.
KotlinReferencesTypeHintsProvider which in now responsible for
type hints is not compatible with the existing
InlayTypeHintsTest. Because of that tests were migrated to the new
infrastructure.
KotlinSuspendingCallHintsProvider which in now responsible for
suspending call hints is not compatible with the existing
SuspendingCallHintsTest. Because of that tests were migrated to the new
infrastructure.
KotlinLambdasHintsProvider which in now responsible for lambda related
hints is not compatible with the existing LambdaReturnValueHintsTest.
Because of that tests were migrated to the new infrastructure.
Some time ago platform couldn't place hints at the end of a line.
This is how KotlinCodeHintsPass appeared. Class was responsible for
lambda related hints. Now that platform evolved functionality was moved
to KotlinLambdasHintsProvider.
Platform supports 2 interfaces for inlay hints providers:
- InlayParameterHintsProvider [1]
- InlayHintsProvider [2]
KotlinInlayParameterHintsProvider as an implementation of (1) and a
source of "Inlay Hints" menu has the following limitations:
- Platform treats component as a source of "Parameter hints" submenu
that cannot be split. Once can only add or remove its nested checkboxes.
- Only a single instance of (1) can be defined.
To have a separate menu items for "Inlay Hints" existing
KotlinInlayParameterHintsProvider was split. New providers
implementing (2) were extracted from it:
- KotlinReferencesTypeHintsProvider
- KotlinSuspendingCallHintsProvider
- KotlinLambdasHintsProvider
TODO: HintType move as a separate commit
This commit fixes an issue introduced in
AbstractKotlinCodeVisionProviderTest under a3c881da. Global Registry was
mistakenly used to manipulate the state of KotlinCodeVisionProvider. As
a result MultiFileHighlightingTestGenerated became unstable during the
parallel execution.
Feature received "experimental" status due to the low performance.
The root cause is slow find-usages functionality the feature is based
on. Once the later is improved Code-Vision should be revisited.
Previous commit of KT-38027 series contains production ready state.
To launch performance check again one needs to enable Code Vision in
AbstractPerformanceProjectsTest.setUp() with the following fun:
private fun enabledCodeVision() {
val codeVisionProvider = KotlinCodeVisionProvider()
val settings = codeVisionProvider.createSettings().apply {
showUsages = true
showInheritors = true
}
InlayHintsSettings.instance().storeSettings(codeVisionProvider.key,
KotlinLanguage.INSTANCE, settings)
}