From b25dc8808533e014faa08ef3178d52e61bbb2cef Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Wed, 24 Apr 2024 22:06:18 +0200 Subject: [PATCH 01/21] [kotlin] restore coop-dev configuration GitOrigin-RevId: fde8d6d27ce6c52d96b0f7d3c11d122ce08a0dfd --- .idea/libraries/kotlinc_allopen_compiler_plugin.xml | 13 +++---------- .idea/libraries/kotlinc_analysis_api_providers.xml | 13 +++---------- .../kotlinc_analysis_project_structure.xml | 13 +++---------- .../kotlinc_android_extensions_compiler_plugin.xml | 13 +++---------- .../kotlinc_assignment_compiler_plugin.xml | 13 +++---------- .idea/libraries/kotlinc_high_level_api.xml | 13 +++---------- .idea/libraries/kotlinc_high_level_api_fe10.xml | 13 +++---------- .idea/libraries/kotlinc_high_level_api_fir.xml | 13 +++---------- .../libraries/kotlinc_high_level_api_fir_tests.xml | 13 +++---------- .../libraries/kotlinc_high_level_api_impl_base.xml | 13 +++---------- .../kotlinc_high_level_api_impl_base_tests.xml | 13 +++---------- .../kotlinc_incremental_compilation_impl_tests.xml | 13 +++---------- .../libraries/kotlinc_kotlin_build_common_tests.xml | 13 +++---------- .idea/libraries/kotlinc_kotlin_compiler_cli.xml | 13 +++---------- .idea/libraries/kotlinc_kotlin_compiler_common.xml | 13 +++---------- .idea/libraries/kotlinc_kotlin_compiler_fe10.xml | 13 +++---------- .idea/libraries/kotlinc_kotlin_compiler_fir.xml | 13 +++---------- .idea/libraries/kotlinc_kotlin_compiler_ir.xml | 13 +++---------- .idea/libraries/kotlinc_kotlin_compiler_tests.xml | 13 +++---------- .../libraries/kotlinc_kotlin_gradle_statistics.xml | 13 +++---------- .idea/libraries/kotlinc_kotlin_jps_common.xml | 13 +++---------- ...lin_jps_plugin_classpath_bootstrap_for_tests.xml | 13 +++---------- .idea/libraries/kotlinc_kotlin_script_runtime.xml | 13 +++---------- .idea/libraries/kotlinc_kotlin_scripting_common.xml | 13 +++---------- .../kotlinc_kotlin_scripting_compiler_impl.xml | 13 +++---------- .idea/libraries/kotlinc_kotlin_scripting_jvm.xml | 13 +++---------- ...otlinc_kotlinx_serialization_compiler_plugin.xml | 13 +++---------- .idea/libraries/kotlinc_lombok_compiler_plugin.xml | 13 +++---------- .idea/libraries/kotlinc_low_level_api_fir.xml | 13 +++---------- .idea/libraries/kotlinc_noarg_compiler_plugin.xml | 13 +++---------- .../libraries/kotlinc_parcelize_compiler_plugin.xml | 13 +++---------- .../kotlinc_sam_with_receiver_compiler_plugin.xml | 13 +++---------- .../libraries/kotlinc_scripting_compiler_plugin.xml | 13 +++---------- .idea/libraries/kotlinc_symbol_light_classes.xml | 13 +++---------- .../resources/model.properties | 2 +- 35 files changed, 103 insertions(+), 341 deletions(-) diff --git a/.idea/libraries/kotlinc_allopen_compiler_plugin.xml b/.idea/libraries/kotlinc_allopen_compiler_plugin.xml index f2978b533bb6..4da80494a292 100644 --- a/.idea/libraries/kotlinc_allopen_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_allopen_compiler_plugin.xml @@ -1,18 +1,11 @@ - - - - - 887a2bbd8d8bb333520eedffdb10b9dfe98f8a6a0a009ef07ec85eb14faad14c - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_analysis_api_providers.xml b/.idea/libraries/kotlinc_analysis_api_providers.xml index cef6c89b9c1e..c65c2e7f5fef 100644 --- a/.idea/libraries/kotlinc_analysis_api_providers.xml +++ b/.idea/libraries/kotlinc_analysis_api_providers.xml @@ -1,18 +1,11 @@ - - - - - 2aef188e9c37940e9704d2308e1f172fe789e1ae921c804d43da438dbc5d613f - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_analysis_project_structure.xml b/.idea/libraries/kotlinc_analysis_project_structure.xml index a991b130310e..82f7979eb40e 100644 --- a/.idea/libraries/kotlinc_analysis_project_structure.xml +++ b/.idea/libraries/kotlinc_analysis_project_structure.xml @@ -1,18 +1,11 @@ - - - - - cee2ed7f9023a371850c84823cc38357885a3bae286c0d5b69b26d6bd3b49b4a - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_android_extensions_compiler_plugin.xml b/.idea/libraries/kotlinc_android_extensions_compiler_plugin.xml index 5868f1571232..0e5ac0304637 100644 --- a/.idea/libraries/kotlinc_android_extensions_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_android_extensions_compiler_plugin.xml @@ -1,18 +1,11 @@ - - - - - 1e0615aa54d80d98aa5a39d86f735418fa7ed6fb1cfae25af19e15500b52451f - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_assignment_compiler_plugin.xml b/.idea/libraries/kotlinc_assignment_compiler_plugin.xml index a12f3fe42af2..dea92e24e5ae 100644 --- a/.idea/libraries/kotlinc_assignment_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_assignment_compiler_plugin.xml @@ -1,18 +1,11 @@ - - - - - 3eed42d90d9d5643137010025f47caf27bef8ec14d19458c0ab4333780307ad8 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_high_level_api.xml b/.idea/libraries/kotlinc_high_level_api.xml index 644014a6d8c9..a114836a34e4 100644 --- a/.idea/libraries/kotlinc_high_level_api.xml +++ b/.idea/libraries/kotlinc_high_level_api.xml @@ -1,18 +1,11 @@ - - - - - 15ff30641208ff6949950e76fd0a41feade4fb6d8597e16f4fb5a9a9231c4f3b - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_high_level_api_fe10.xml b/.idea/libraries/kotlinc_high_level_api_fe10.xml index 3531074c3726..4b25d1e2ea91 100644 --- a/.idea/libraries/kotlinc_high_level_api_fe10.xml +++ b/.idea/libraries/kotlinc_high_level_api_fe10.xml @@ -1,18 +1,11 @@ - - - - - ae61ffe8994a222c95c2ddcdaf1215c9d1502b81e588b3768a676b04e86cec52 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_high_level_api_fir.xml b/.idea/libraries/kotlinc_high_level_api_fir.xml index d92c179e3ef4..3f79b279fd40 100644 --- a/.idea/libraries/kotlinc_high_level_api_fir.xml +++ b/.idea/libraries/kotlinc_high_level_api_fir.xml @@ -1,18 +1,11 @@ - - - - - e377ad4b7456629dda54771b005e629398c8bf166c0f77046907c5f490433365 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_high_level_api_fir_tests.xml b/.idea/libraries/kotlinc_high_level_api_fir_tests.xml index ceec7e369b3c..fa4ad57051d5 100644 --- a/.idea/libraries/kotlinc_high_level_api_fir_tests.xml +++ b/.idea/libraries/kotlinc_high_level_api_fir_tests.xml @@ -1,18 +1,11 @@ - - - - - 5d5fdde8b0816ce4b10a24fab4d727a8b8d2bb099d7a876293ce868f20c9bd08 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_high_level_api_impl_base.xml b/.idea/libraries/kotlinc_high_level_api_impl_base.xml index d05fe2874fc3..800ae5291f23 100644 --- a/.idea/libraries/kotlinc_high_level_api_impl_base.xml +++ b/.idea/libraries/kotlinc_high_level_api_impl_base.xml @@ -1,18 +1,11 @@ - - - - - fdf2f2ad50ed19159d6b760b1db96b85588d860c61ee6a07a531239390d73786 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_high_level_api_impl_base_tests.xml b/.idea/libraries/kotlinc_high_level_api_impl_base_tests.xml index 341a51cd699b..9ca44a62e22e 100644 --- a/.idea/libraries/kotlinc_high_level_api_impl_base_tests.xml +++ b/.idea/libraries/kotlinc_high_level_api_impl_base_tests.xml @@ -1,18 +1,11 @@ - - - - - f9379ccf26f25458f0576f68fdfb2f4cabb890d19c0bbeee56282c5af6c42204 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_incremental_compilation_impl_tests.xml b/.idea/libraries/kotlinc_incremental_compilation_impl_tests.xml index 90abdfb43594..8b4076cbb8cc 100644 --- a/.idea/libraries/kotlinc_incremental_compilation_impl_tests.xml +++ b/.idea/libraries/kotlinc_incremental_compilation_impl_tests.xml @@ -1,18 +1,11 @@ - - - - - a1c7b435662d3863f9cd69af64c247e4c9d65f8337458e11c48e6178f8cd3fb2 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_build_common_tests.xml b/.idea/libraries/kotlinc_kotlin_build_common_tests.xml index 83849dae4611..7fb08a733403 100644 --- a/.idea/libraries/kotlinc_kotlin_build_common_tests.xml +++ b/.idea/libraries/kotlinc_kotlin_build_common_tests.xml @@ -1,18 +1,11 @@ - - - - - 8710de97b317e4c1155e31d5fb486aa5ed54ef14e6edf0f087e05560b277d415 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_compiler_cli.xml b/.idea/libraries/kotlinc_kotlin_compiler_cli.xml index 76a531045bf5..a1835cb62419 100644 --- a/.idea/libraries/kotlinc_kotlin_compiler_cli.xml +++ b/.idea/libraries/kotlinc_kotlin_compiler_cli.xml @@ -1,18 +1,11 @@ - - - - - 2b09eb033680fa7fca8b151de293103e172212222bb74fc8eb381d807e316a44 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_compiler_common.xml b/.idea/libraries/kotlinc_kotlin_compiler_common.xml index c23a5ad0ae64..8295f79b980d 100644 --- a/.idea/libraries/kotlinc_kotlin_compiler_common.xml +++ b/.idea/libraries/kotlinc_kotlin_compiler_common.xml @@ -1,18 +1,11 @@ - - - - - 102ac452ef6ab3f5f211f90c7104fb229828507409de190979417c5b86c957cd - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_compiler_fe10.xml b/.idea/libraries/kotlinc_kotlin_compiler_fe10.xml index 21b23c79e609..c9233b56ce26 100644 --- a/.idea/libraries/kotlinc_kotlin_compiler_fe10.xml +++ b/.idea/libraries/kotlinc_kotlin_compiler_fe10.xml @@ -1,18 +1,11 @@ - - - - - cee18085f9397561fe585e0d6023a51accbd58e69f9cea44bc6624d477e46a9e - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_compiler_fir.xml b/.idea/libraries/kotlinc_kotlin_compiler_fir.xml index 526c53f5cdd5..c073d79e7e49 100644 --- a/.idea/libraries/kotlinc_kotlin_compiler_fir.xml +++ b/.idea/libraries/kotlinc_kotlin_compiler_fir.xml @@ -1,18 +1,11 @@ - - - - - 0f086305c92b119c437aeeeeb2e2193f0f568d21d059a6152ccceb2df9e5f247 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_compiler_ir.xml b/.idea/libraries/kotlinc_kotlin_compiler_ir.xml index 7c49f1f23c1e..fef122b3d84a 100644 --- a/.idea/libraries/kotlinc_kotlin_compiler_ir.xml +++ b/.idea/libraries/kotlinc_kotlin_compiler_ir.xml @@ -1,18 +1,11 @@ - - - - - 504226c3982f3359976b0e1f1d1cf6ecfb15f661a88b6cc7977c2eb436a1d301 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_compiler_tests.xml b/.idea/libraries/kotlinc_kotlin_compiler_tests.xml index 0f8bf0d96c47..e70786754336 100644 --- a/.idea/libraries/kotlinc_kotlin_compiler_tests.xml +++ b/.idea/libraries/kotlinc_kotlin_compiler_tests.xml @@ -1,18 +1,11 @@ - - - - - ce63b9f7a42766d1754843ba5945a52e9f9b1819aa7719f795b1d2976a04ced9 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_gradle_statistics.xml b/.idea/libraries/kotlinc_kotlin_gradle_statistics.xml index 85fa020557e6..4fbc26183694 100644 --- a/.idea/libraries/kotlinc_kotlin_gradle_statistics.xml +++ b/.idea/libraries/kotlinc_kotlin_gradle_statistics.xml @@ -1,18 +1,11 @@ - - - - - b85733a0ae14c035d391cae10cb7824aab122152d71f25ff5a3575e4f127d9d6 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_jps_common.xml b/.idea/libraries/kotlinc_kotlin_jps_common.xml index c9618cc62547..619a2f8596f3 100644 --- a/.idea/libraries/kotlinc_kotlin_jps_common.xml +++ b/.idea/libraries/kotlinc_kotlin_jps_common.xml @@ -1,18 +1,11 @@ - - - - - 5e97712501e43dc7d26e491550f87298b92db3020785d8086f59cb363207e782 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_jps_plugin_classpath_bootstrap_for_tests.xml b/.idea/libraries/kotlinc_kotlin_jps_plugin_classpath_bootstrap_for_tests.xml index d2f632a0bc25..f0352a7aa530 100644 --- a/.idea/libraries/kotlinc_kotlin_jps_plugin_classpath_bootstrap_for_tests.xml +++ b/.idea/libraries/kotlinc_kotlin_jps_plugin_classpath_bootstrap_for_tests.xml @@ -1,18 +1,11 @@ - - - - - adbb75204da2b6cc3ec835324cfd27e9693860a7d3ca860ef0c686d0439c1ac0 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_script_runtime.xml b/.idea/libraries/kotlinc_kotlin_script_runtime.xml index 0dab25da3b1f..770d7d5d6926 100644 --- a/.idea/libraries/kotlinc_kotlin_script_runtime.xml +++ b/.idea/libraries/kotlinc_kotlin_script_runtime.xml @@ -1,18 +1,11 @@ - - - - - cdf0892f2a1c68fcf6fcb2eef594fe8f75f5a190694f8cb3e7777c4f2e9057d7 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_scripting_common.xml b/.idea/libraries/kotlinc_kotlin_scripting_common.xml index 019bb8fa9a33..c7dd5770d74b 100644 --- a/.idea/libraries/kotlinc_kotlin_scripting_common.xml +++ b/.idea/libraries/kotlinc_kotlin_scripting_common.xml @@ -1,18 +1,11 @@ - - - - - da9eef8af88aeef7f4bc7abefe5d61cb88d5331a0b557e18cc2e510319f07985 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_scripting_compiler_impl.xml b/.idea/libraries/kotlinc_kotlin_scripting_compiler_impl.xml index 3f5be1920a3f..a6f76b90a4f5 100644 --- a/.idea/libraries/kotlinc_kotlin_scripting_compiler_impl.xml +++ b/.idea/libraries/kotlinc_kotlin_scripting_compiler_impl.xml @@ -1,18 +1,11 @@ - - - - - e23d966b84ce7a5138c04326815d1bca2ea3beba7302c4cc9b62090d0f71df6d - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_scripting_jvm.xml b/.idea/libraries/kotlinc_kotlin_scripting_jvm.xml index 890c8cd9f3f8..2557d96de87e 100644 --- a/.idea/libraries/kotlinc_kotlin_scripting_jvm.xml +++ b/.idea/libraries/kotlinc_kotlin_scripting_jvm.xml @@ -1,18 +1,11 @@ - - - - - 10c5972e8270a7c87b9ec4f64e98473bdf82c8cd3e15682bd2040053b82a3d22 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlinx_serialization_compiler_plugin.xml b/.idea/libraries/kotlinc_kotlinx_serialization_compiler_plugin.xml index 6d68f2bff262..3f4a8446caa1 100644 --- a/.idea/libraries/kotlinc_kotlinx_serialization_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_kotlinx_serialization_compiler_plugin.xml @@ -1,18 +1,11 @@ - - - - - 8a8fc59eddf65643f2d7495de30664bad0495c1759b8784456f71a91481147a0 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_lombok_compiler_plugin.xml b/.idea/libraries/kotlinc_lombok_compiler_plugin.xml index e5ff23459856..b4d334ad3eef 100644 --- a/.idea/libraries/kotlinc_lombok_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_lombok_compiler_plugin.xml @@ -1,18 +1,11 @@ - - - - - 1f2b31a9a0d5565280743abcd703d49a03b12055011a6187d4bb4cffb5a9ed38 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_low_level_api_fir.xml b/.idea/libraries/kotlinc_low_level_api_fir.xml index 75220b7936e6..9a6c0a9e430e 100644 --- a/.idea/libraries/kotlinc_low_level_api_fir.xml +++ b/.idea/libraries/kotlinc_low_level_api_fir.xml @@ -1,18 +1,11 @@ - - - - - 11460217230d2708a49f76ff1b743722a500c1e2cb8a92345769f58891e1af19 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_noarg_compiler_plugin.xml b/.idea/libraries/kotlinc_noarg_compiler_plugin.xml index e802d8e23d7f..b6fd153fe007 100644 --- a/.idea/libraries/kotlinc_noarg_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_noarg_compiler_plugin.xml @@ -1,18 +1,11 @@ - - - - - d40bdfb9e890ae8c0e6118072b06cc431cbfe9c9d646c42108204a9f64402940 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_parcelize_compiler_plugin.xml b/.idea/libraries/kotlinc_parcelize_compiler_plugin.xml index 776fe71ca3e9..fc7e17f3726b 100644 --- a/.idea/libraries/kotlinc_parcelize_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_parcelize_compiler_plugin.xml @@ -1,18 +1,11 @@ - - - - - 0b9c2a9b176a94ae341469eb4159d0d657c86727797902b2ca8c1468da70c7a2 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_sam_with_receiver_compiler_plugin.xml b/.idea/libraries/kotlinc_sam_with_receiver_compiler_plugin.xml index f28809f06c9d..413282e19ef7 100644 --- a/.idea/libraries/kotlinc_sam_with_receiver_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_sam_with_receiver_compiler_plugin.xml @@ -1,18 +1,11 @@ - - - - - a36baa1fed10aa978adfe12b6924884856a6daa09894e98182368a644d34e4d1 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_scripting_compiler_plugin.xml b/.idea/libraries/kotlinc_scripting_compiler_plugin.xml index 78abf2600e57..228429619a95 100644 --- a/.idea/libraries/kotlinc_scripting_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_scripting_compiler_plugin.xml @@ -1,18 +1,11 @@ - - - - - 84b62b5cc5acb66bb3a9adf76210cd8566e657654f8a8c643cfbbc8408284767 - - - + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_symbol_light_classes.xml b/.idea/libraries/kotlinc_symbol_light_classes.xml index 1c834b428d7d..5c994726b0ab 100644 --- a/.idea/libraries/kotlinc_symbol_light_classes.xml +++ b/.idea/libraries/kotlinc_symbol_light_classes.xml @@ -1,18 +1,11 @@ - - - - - 031147e89f125081072584c70609d7810aba31e29862c30188e8872329b2c8a1 - - - + - + - + \ No newline at end of file diff --git a/plugins/kotlin/util/project-model-updater/resources/model.properties b/plugins/kotlin/util/project-model-updater/resources/model.properties index 5aedc6632f27..87d9ce21f133 100644 --- a/plugins/kotlin/util/project-model-updater/resources/model.properties +++ b/plugins/kotlin/util/project-model-updater/resources/model.properties @@ -1,6 +1,6 @@ # Please do not touch this file. It is the responsibility of Kotlin/IntelliJ Kotlin team to advance kotlin compiler version kotlincVersion=2.0.20-dev-2192 -kotlincArtifactsMode=MAVEN +kotlincArtifactsMode=BOOTSTRAP jpsPluginVersion=1.9.23-release-779 jpsPluginArtifactsMode=MAVEN From 9e56bb35d6d89df02524747dcc223f8b3d201f4c Mon Sep 17 00:00:00 2001 From: Kirill Rakhman Date: Wed, 24 Apr 2024 09:39:44 +0200 Subject: [PATCH 02/21] [kotlin] Update test data KT-67512 GitOrigin-RevId: 9755e4a5d01f4a8867170a559ccb3abbb2001221 --- ...lifiedSuperTypeHasAnnotations.fir.kt.after | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 plugins/kotlin/idea/tests/testData/quickfix/specifySuperType/fullyQualifiedSuperTypeHasAnnotations.fir.kt.after diff --git a/plugins/kotlin/idea/tests/testData/quickfix/specifySuperType/fullyQualifiedSuperTypeHasAnnotations.fir.kt.after b/plugins/kotlin/idea/tests/testData/quickfix/specifySuperType/fullyQualifiedSuperTypeHasAnnotations.fir.kt.after new file mode 100644 index 000000000000..45c20f5d2128 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/specifySuperType/fullyQualifiedSuperTypeHasAnnotations.fir.kt.after @@ -0,0 +1,20 @@ +// "Specify supertype" "true" +// SHOULD_DIFFER_FROM_FE10 +package a.b.c + +interface Z { + fun foo() {} +} + +open class X { + open fun foo() {} +} + +class Test : (@Suppress("foo") a.b.c.X)(), Z { + override fun foo() { + super.foo() + } +} + +// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.SpecifySuperTypeFix +// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.k2.codeinsight.fixes.SpecifySuperTypeFixFactory$SpecifySuperTypeQuickFix \ No newline at end of file From 863a3631284d94b456ca362d5231f690fb1dc08c Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Wed, 17 Apr 2024 17:42:58 +0900 Subject: [PATCH 03/21] [kotlin] Adapt to changes in 'KtAnnotationValue' GitOrigin-RevId: 8fa84b102a944050ca0459c776d605d4e94d0d8c --- .../k2/codeinsight/fixes/OptInFixFactories.kt | 13 +++++-- .../WasExperimentalOptInsNecessityChecker.kt | 8 ++++- .../postfix/KotlinTryPostfixTemplate.kt | 14 ++++++-- .../idea/fir/fe10/BaseDescriptorsWrappers.kt | 35 +++++++++++++++---- .../ExtractionDataAnalyzer.kt | 28 +++++++++------ 5 files changed, 74 insertions(+), 24 deletions(-) diff --git a/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/OptInFixFactories.kt b/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/OptInFixFactories.kt index a4d019b10362..2c45aa720c60 100644 --- a/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/OptInFixFactories.kt +++ b/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/OptInFixFactories.kt @@ -6,10 +6,12 @@ import com.intellij.psi.util.findParentOfType import com.intellij.util.containers.addIfNotNull import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.analyze +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationWithArgumentsInfo import org.jetbrains.kotlin.analysis.api.annotations.KtKClassAnnotationValue import org.jetbrains.kotlin.analysis.api.annotations.annotationsByClassId import org.jetbrains.kotlin.analysis.api.fir.diagnostics.KtFirDiagnostic import org.jetbrains.kotlin.analysis.api.fir.utils.getActualAnnotationTargets +import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType import org.jetbrains.kotlin.idea.base.psi.KotlinPsiHeuristics import org.jetbrains.kotlin.idea.codeinsight.api.applicators.fixes.KotlinQuickFixFactory import org.jetbrains.kotlin.idea.quickfix.AddAnnotationFix @@ -98,10 +100,15 @@ private object OptInGeneralUtils : OptInGeneralUtilsBase() { val typeReference = it.typeReference val resolvedClass = typeReference?.getKtType()?.expandedClassSymbol ?: return false val classAnnotation = resolvedClass.annotationsByClassId(OptInNames.SUBCLASS_OPT_IN_REQUIRED_CLASS_ID).firstOrNull() - val annotationMarkerClass = classAnnotation?.arguments?.find { arg -> arg.name == OptInNames.OPT_IN_ANNOTATION_CLASS } - val apiClassId = (annotationMarkerClass?.expression as? KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue)?.classId - apiClassId?.asSingleFqName() == annotationFqName + classAnnotation != null && findMarkerClassId(classAnnotation)?.asSingleFqName() == annotationFqName } } } + + private fun findMarkerClassId(annotation: KtAnnotationApplicationWithArgumentsInfo): ClassId? { + val argument = annotation.arguments.find { arg -> arg.name == OptInNames.OPT_IN_ANNOTATION_CLASS } ?: return null + val value = argument.expression as? KtKClassAnnotationValue ?: return null + val type = value.type as? KtNonErrorClassType ?: return null + return type.classId.takeUnless { it.isLocal } + } } \ No newline at end of file diff --git a/plugins/kotlin/code-insight/impl-base/src/org/jetbrains/kotlin/idea/codeinsights/impl/base/inspection/WasExperimentalOptInsNecessityChecker.kt b/plugins/kotlin/code-insight/impl-base/src/org/jetbrains/kotlin/idea/codeinsights/impl/base/inspection/WasExperimentalOptInsNecessityChecker.kt index 0ccb1992040b..ae83ee14b004 100644 --- a/plugins/kotlin/code-insight/impl-base/src/org/jetbrains/kotlin/idea/codeinsights/impl/base/inspection/WasExperimentalOptInsNecessityChecker.kt +++ b/plugins/kotlin/code-insight/impl-base/src/org/jetbrains/kotlin/idea/codeinsights/impl/base/inspection/WasExperimentalOptInsNecessityChecker.kt @@ -4,6 +4,7 @@ package org.jetbrains.kotlin.idea.codeinsights.impl.base.inspection import com.intellij.util.asSafely import org.jetbrains.kotlin.analysis.api.annotations.* import org.jetbrains.kotlin.analysis.api.base.KtConstantValue +import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name @@ -40,10 +41,15 @@ internal object WasExperimentalOptInsNecessityChecker { return annotation.argumentByName(OptInNames.WAS_EXPERIMENTAL_ANNOTATION_CLASS) ?.asSafely() ?.values - ?.mapNotNull { (it as? KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue)?.classId } + ?.mapNotNull { computeAnnotationMarkerClassId(it) } ?: emptyList() } + private fun computeAnnotationMarkerClassId(value: KtAnnotationValue): ClassId? { + val type = (value as? KtKClassAnnotationValue)?.type as? KtNonErrorClassType ?: return null + return type.classId.takeIf { !it.isLocal } + } + private fun KtAnnotationsList.findAnnotation(classId: ClassId): KtAnnotationApplicationWithArgumentsInfo? = annotationsByClassId(classId).firstOrNull() diff --git a/plugins/kotlin/code-insight/postfix-templates/src/org/jetbrains/kotlin/idea/codeInsight/postfix/KotlinTryPostfixTemplate.kt b/plugins/kotlin/code-insight/postfix-templates/src/org/jetbrains/kotlin/idea/codeInsight/postfix/KotlinTryPostfixTemplate.kt index fb4c53336c84..9b91596e8a79 100644 --- a/plugins/kotlin/code-insight/postfix-templates/src/org/jetbrains/kotlin/idea/codeInsight/postfix/KotlinTryPostfixTemplate.kt +++ b/plugins/kotlin/code-insight/postfix-templates/src/org/jetbrains/kotlin/idea/codeInsight/postfix/KotlinTryPostfixTemplate.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.analysis.api.calls.* import org.jetbrains.kotlin.analysis.api.lifetime.allowAnalysisFromWriteAction import org.jetbrains.kotlin.analysis.api.lifetime.allowAnalysisOnEdt import org.jetbrains.kotlin.analysis.api.symbols.* +import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType import org.jetbrains.kotlin.idea.base.psi.classIdIfNonLocal import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.psi.* @@ -167,8 +168,17 @@ private class ExceptionClassCollector : KtTreeVisitor() { private fun processAnnotationValue(value: KtAnnotationValue) { when (value) { is KtArrayAnnotationValue -> value.values.forEach(::processAnnotationValue) - is KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue -> mutableExceptionClasses.add(value.classId) - is KtKClassAnnotationValue.KtLocalKClassAnnotationValue -> hasLocalClasses = true + is KtKClassAnnotationValue -> { + val type = value.type + if (type is KtNonErrorClassType) { + val classId = type.classId + if (classId.isLocal) { + hasLocalClasses = true + } else { + mutableExceptionClasses.add(classId) + } + } + } else -> {} } } diff --git a/plugins/kotlin/k2-fe10-bindings/src/org/jetbrains/kotlin/idea/fir/fe10/BaseDescriptorsWrappers.kt b/plugins/kotlin/k2-fe10-bindings/src/org/jetbrains/kotlin/idea/fir/fe10/BaseDescriptorsWrappers.kt index 7e2a821dc907..2cc32483b8b4 100644 --- a/plugins/kotlin/k2-fe10-bindings/src/org/jetbrains/kotlin/idea/fir/fe10/BaseDescriptorsWrappers.kt +++ b/plugins/kotlin/k2-fe10-bindings/src/org/jetbrains/kotlin/idea/fir/fe10/BaseDescriptorsWrappers.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin.* import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol import org.jetbrains.kotlin.analysis.api.symbols.markers.KtNamedSymbol import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithTypeParameters +import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor @@ -20,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.SpecialNames +import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.psi.KtPureElement import org.jetbrains.kotlin.resolve.constants.* import org.jetbrains.kotlin.resolve.scopes.MemberScope @@ -78,14 +80,33 @@ private fun KtSymbolOrigin.toCallableDescriptorKind(): CallableMemberDescriptor. else -> CallableMemberDescriptor.Kind.DECLARATION } -private fun KtAnnotationValue.toConstantValue(): ConstantValue<*> { +private fun KtAnnotationValue.toConstantValue(context: Fe10WrapperContext): ConstantValue<*> { return when (this) { - KtUnsupportedAnnotationValue -> ErrorValue.create("Unsupported annotation value") - is KtArrayAnnotationValue -> ArrayValue(values.map { it.toConstantValue() }) { TODO() } + is KtUnsupportedAnnotationValue -> ErrorValue.create("Unsupported annotation value") + is KtArrayAnnotationValue -> ArrayValue(values.map { it.toConstantValue(context) }) { TODO() } is KtAnnotationApplicationValue -> TODO() - is KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue -> KClassValue(classId, arrayDimensions = 0) - is KtKClassAnnotationValue.KtLocalKClassAnnotationValue -> TODO() - is KtKClassAnnotationValue.KtErrorClassAnnotationValue -> ErrorValue.create("Unresolved class") + is KtKClassAnnotationValue -> context.withAnalysisSession { + when (val type = type) { + is KtNonErrorClassType -> { + val classId = type.classId + if (classId.isLocal) { + KClassValue(KClassValue.Value.LocalClass(type.toKotlinType(context))) + } else { + var unwrappedType: KtNonErrorClassType = type + var arrayDimensions = 0 + while (unwrappedType.classId == StandardClassIds.Array) { + val elementType = unwrappedType.getArrayElementType()?.lowerBoundIfFlexible() as? KtNonErrorClassType ?: break + unwrappedType = elementType + arrayDimensions += 1 + } + KClassValue(unwrappedType.classId, arrayDimensions) + } + } + else -> { + ErrorValue.create("Unresolved class") + } + } + } is KtEnumEntryAnnotationValue -> { val callableId = callableId ?: return ErrorValue.create("Unresolved enum entry") val classId = callableId.classId ?: return ErrorValue.create("Unresolved enum entry") @@ -181,7 +202,7 @@ class KtSymbolBasedAnnotationDescriptor( get() = ktAnnotationCall.classId?.asSingleFqName() override val allValueArguments: Map> = - ktAnnotationCall.arguments.associate { it.name to it.expression.toConstantValue() } + ktAnnotationCall.arguments.associate { it.name to it.expression.toConstantValue(context) } override val source: SourceElement get() = ktAnnotationCall.psi.toSourceElement() diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/extractionEngine/ExtractionDataAnalyzer.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/extractionEngine/ExtractionDataAnalyzer.kt index 90d73c4de427..e5b90ef42227 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/extractionEngine/ExtractionDataAnalyzer.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/extractionEngine/ExtractionDataAnalyzer.kt @@ -12,10 +12,7 @@ import org.jetbrains.kotlin.analysis.api.KtAnalysisNonPublicApi import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.analyze import org.jetbrains.kotlin.analysis.api.analyzeCopy -import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationWithArgumentsInfo -import org.jetbrains.kotlin.analysis.api.annotations.KtArrayAnnotationValue -import org.jetbrains.kotlin.analysis.api.annotations.KtKClassAnnotationValue -import org.jetbrains.kotlin.analysis.api.annotations.annotations +import org.jetbrains.kotlin.analysis.api.annotations.* import org.jetbrains.kotlin.analysis.api.components.KtDataFlowExitPointSnapshot import org.jetbrains.kotlin.analysis.api.components.KtDiagnosticCheckerFilter import org.jetbrains.kotlin.analysis.api.fir.diagnostics.KtFirDiagnostic @@ -272,15 +269,24 @@ private fun IExtractionData.getExperimentalMarkers(): ExperimentalMarkers { val fqName = annotationEntry.classId?.asSingleFqName() ?: continue if (fqName in FqNames.OptInFqNames.OPT_IN_FQ_NAMES) { - for (argument in annotationEntry.arguments) { - val expression = argument.expression - if (expression is KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue) { - optInMarkerNames.add(expression.classId.asSingleFqName()) - } else if (expression is KtArrayAnnotationValue) { - expression.values.filterIsInstance() - .forEach { optInMarkerNames.add(it.classId.asSingleFqName()) } + fun processValue(value: KtAnnotationValue, isRecursive: Boolean) { + when (value) { + is KtKClassAnnotationValue -> { + val classId = (value.type as? KtNonErrorClassType)?.classId?.takeUnless { it.isLocal } + if (classId != null) { + optInMarkerNames.add(classId.asSingleFqName()) + } + } + is KtArrayAnnotationValue -> { + if (isRecursive) { + value.values.forEach { processValue(it, isRecursive = false) } + } + } + else -> {} } } + + annotationEntry.arguments.forEach { processValue(it.expression, isRecursive = true) } } else if (annotationEntry.isExperimentalMarker()) { propagatingMarkerDescriptors.add(annotationEntry) } From 2efd6062ab8b0c414addb3fe4b0d43262ddeae3e Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Wed, 24 Apr 2024 17:08:29 +0900 Subject: [PATCH 04/21] [kotlin] Do not store 'KtAnnotationApplication' outside the 'analyze()' block 'KtAnnotationApplication's became 'KtLifetimeOwner's, so now they cannot be stored for indefinite time. GitOrigin-RevId: d9c61cb54521b2e1f8d0bdfff93169b95fdf72b1 --- .../extractFunction/ExtractableCodeDescriptor.kt | 13 ++++--------- .../ui/KotlinFirExtractFunctionDialog.java | 2 +- .../extractionEngine/ExtractionDataAnalyzer.kt | 16 +++++++++------- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/extractFunction/ExtractableCodeDescriptor.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/extractFunction/ExtractableCodeDescriptor.kt index 70d184a0ca91..4a3fe8a74769 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/extractFunction/ExtractableCodeDescriptor.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/extractFunction/ExtractableCodeDescriptor.kt @@ -7,14 +7,10 @@ import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.analyze import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotated import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication -import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationWithArgumentsInfo -import org.jetbrains.kotlin.analysis.api.annotations.KtConstantAnnotationValue -import org.jetbrains.kotlin.analysis.api.base.KtConstantValue import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.KtRendererAnnotationsFilter import org.jetbrains.kotlin.analysis.api.renderer.declarations.impl.KtDeclarationRendererForSource import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter -import org.jetbrains.kotlin.analysis.utils.relfection.renderAsDataClassToString import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.ControlFlow import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.DuplicateInfo import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.ExtractableCodeDescriptorWithConflictsResult @@ -24,12 +20,12 @@ import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.IReplace import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.TypeParameter import org.jetbrains.kotlin.lexer.KtKeywordToken import org.jetbrains.kotlin.lexer.KtModifierKeywordToken +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtSimpleNameExpression import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType -import org.jetbrains.kotlin.utils.mapToSetOrEmpty data class ExtractableCodeDescriptor( val context: KtElement, @@ -44,7 +40,7 @@ data class ExtractableCodeDescriptor( override val returnType: KtType, override val modifiers: List = emptyList(), override val optInMarkers: List = emptyList(), - val annotations: List = emptyList() + val annotationClassIds: Set = emptySet() ) : IExtractableCodeDescriptor { override val name: String get() = suggestedNames.firstOrNull() ?: "" @@ -56,9 +52,8 @@ data class ExtractableCodeDescriptor( override val annotationsText: String get() { - if (annotations.isEmpty()) return "" + if (annotationClassIds.isEmpty()) return "" val container = extractionData.commonParent.getStrictParentOfType() ?: return "" - val classIds = annotations.mapNotNull { it.classId }.toSet() return analyze(container) { val filteredRenderer = KtDeclarationRendererForSource.WITH_QUALIFIED_NAMES.annotationRenderer.with { annotationFilter = annotationFilter.and(object : KtRendererAnnotationsFilter { @@ -67,7 +62,7 @@ data class ExtractableCodeDescriptor( annotation: KtAnnotationApplication, owner: KtAnnotated ): Boolean { - return annotation.classId in classIds + return annotation.classId in annotationClassIds } }) diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/extractFunction/ui/KotlinFirExtractFunctionDialog.java b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/extractFunction/ui/KotlinFirExtractFunctionDialog.java index 69c390c94766..49b21f6ea1d1 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/extractFunction/ui/KotlinFirExtractFunctionDialog.java +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/extractFunction/ui/KotlinFirExtractFunctionDialog.java @@ -303,6 +303,6 @@ public class KotlinFirExtractFunctionDialog extends DialogWrapper { returnType, originalDescriptor.getModifiers(), originalDescriptor.getOptInMarkers(), - originalDescriptor.getAnnotations()); + originalDescriptor.getAnnotationClassIds()); } } diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/extractionEngine/ExtractionDataAnalyzer.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/extractionEngine/ExtractionDataAnalyzer.kt index e5b90ef42227..811937867b57 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/extractionEngine/ExtractionDataAnalyzer.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/extractionEngine/ExtractionDataAnalyzer.kt @@ -50,6 +50,7 @@ import org.jetbrains.kotlin.idea.references.ReadWriteAccessChecker import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtBlockExpression import org.jetbrains.kotlin.psi.KtBreakExpression @@ -223,7 +224,7 @@ internal class ExtractionDataAnalyzer(private val extractionData: ExtractionData returnType = returnType, modifiers = if (hasSuspendReference(extractionData)) listOf(KtTokens.SUSPEND_KEYWORD) else emptyList(), optInMarkers = experimentalMarkers.optInMarkers, - annotations = experimentalMarkers.propagatingMarkerDescriptors + annotationClassIds = experimentalMarkers.propagatingMarkerClassIds ) for (analyser in ExtractFunctionDescriptorModifier.EP_NAME.extensionList) { descriptor = analyser.modifyDescriptor(descriptor) @@ -244,11 +245,11 @@ internal class ExtractionDataAnalyzer(private val extractionData: ExtractionData } private data class ExperimentalMarkers( - val propagatingMarkerDescriptors: List, + val propagatingMarkerClassIds: Set, val optInMarkers: List ) { companion object { - val empty = ExperimentalMarkers(emptyList(), emptyList()) + val empty = ExperimentalMarkers(emptySet(), emptyList()) } } @@ -311,11 +312,12 @@ private fun IExtractionData.getExperimentalMarkers(): ExperimentalMarkers { } } + val propagatingMarkerClassIds = propagatingMarkerDescriptors + .mapNotNull { it.classId } + .filterTo(LinkedHashSet()) { it.asSingleFqName() in requiredMarkers } + return ExperimentalMarkers( - propagatingMarkerDescriptors.filter { - val classId = it.classId - classId != null && classId.asSingleFqName() in requiredMarkers - }, + propagatingMarkerClassIds, optInMarkerNames.filter { it in requiredMarkers } ) } From c8050ebd569afd8608410960efee6e41d39aeb7c Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Thu, 25 Apr 2024 17:41:09 +0900 Subject: [PATCH 05/21] [kotlin] Adapt newly appeared code in 'KotlinIdeDeclarationRenderer' to changes in 'KtAnnotationValue' GitOrigin-RevId: 6d4a45aaa077c73419a74133a4021c8660f736cd --- .../quickDoc/KotlinIdeDeclarationRenderer.kt | 56 ++++++++++++++----- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/plugins/kotlin/code-insight/kotlin.code-insight.k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/quickDoc/KotlinIdeDeclarationRenderer.kt b/plugins/kotlin/code-insight/kotlin.code-insight.k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/quickDoc/KotlinIdeDeclarationRenderer.kt index e8822aad6d8c..2ec5ae6c567b 100644 --- a/plugins/kotlin/code-insight/kotlin.code-insight.k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/quickDoc/KotlinIdeDeclarationRenderer.kt +++ b/plugins/kotlin/code-insight/kotlin.code-insight.k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/quickDoc/KotlinIdeDeclarationRenderer.kt @@ -4,6 +4,8 @@ package org.jetbrains.kotlin.idea.k2.codeinsight.quickDoc import com.google.common.html.HtmlEscapers import com.intellij.codeInsight.documentation.DocumentationManagerUtil import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.KtStarTypeProjection +import org.jetbrains.kotlin.analysis.api.KtTypeArgumentWithVariance import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotated import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationValue @@ -64,13 +66,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtTypeParameterSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol import org.jetbrains.kotlin.analysis.api.symbols.markers.KtNamedSymbol import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility -import org.jetbrains.kotlin.analysis.api.types.KtClassType -import org.jetbrains.kotlin.analysis.api.types.KtFunctionalType -import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType -import org.jetbrains.kotlin.analysis.api.types.KtType -import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability -import org.jetbrains.kotlin.analysis.api.types.KtTypeParameterType -import org.jetbrains.kotlin.analysis.api.types.KtUsualClassType +import org.jetbrains.kotlin.analysis.api.types.* import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter import org.jetbrains.kotlin.analysis.utils.printer.prettyPrint import org.jetbrains.kotlin.builtins.StandardNames @@ -85,6 +81,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.renderer.render import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.renderer.render as renderName @@ -724,7 +721,7 @@ internal class KotlinIdeDeclarationRenderer( renderConstantAnnotationValue(value) } - KtUnsupportedAnnotationValue -> { + is KtUnsupportedAnnotationValue -> { append("error(\"non-annotation value\")") } @@ -735,13 +732,44 @@ internal class KotlinIdeDeclarationRenderer( } private fun PrettyPrinter.renderKClassAnnotationValue(value: KtKClassAnnotationValue) { - when (value) { - is KtKClassAnnotationValue.KtErrorClassAnnotationValue -> append("UNRESOLVED_CLASS") - is KtKClassAnnotationValue.KtLocalKClassAnnotationValue -> append(value.ktClass.nameAsName?.renderName()) - is KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue -> append(value.classId.asSingleFqName().renderName()) + renderType(value.type) + append("::class") + } + + private fun PrettyPrinter.renderType(type: KtType) { + if (type.annotations.isNotEmpty()) { + for (annotation in type.annotations) { + append('@') + renderAnnotationApplication(annotation) + append(' ') + } + } + + when (type) { + is KtUsualClassType -> { + val classId = type.classId + if (classId.isLocal) { + append(classId.shortClassName.render()) + } else { + append(classId.asSingleFqName().render()) + } + + if (type.ownTypeArguments.isNotEmpty()) { + printCollection(type.ownTypeArguments, ", ", prefix = "<", postfix = ">") { typeProjection -> + when (typeProjection) { + is KtStarTypeProjection -> append('*') + is KtTypeArgumentWithVariance -> renderType(typeProjection.type) + } + } + } + } + is KtClassErrorType -> { + append("UNRESOLVED_CLASS") + } + else -> { + append(type.asStringForDebugging()) + } } - append(highlight("::") { asColon }) - append(highlight("class") { asKeyword }) } private fun PrettyPrinter.renderConstantAnnotationValue(value: KtConstantAnnotationValue) { From f0186d68612df8b1134006664d7390f903ca5c26 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Thu, 25 Apr 2024 17:43:52 +0900 Subject: [PATCH 06/21] [kotlin] Adapt newly appeared code in 'ExtractionDataAnalyzer' to changes in 'KtAnnotationValue' GitOrigin-RevId: baaaad562a94b3c141cf09249c21e1634eba1b8f --- .../introduce/extractionEngine/ExtractionDataAnalyzer.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/extractionEngine/ExtractionDataAnalyzer.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/extractionEngine/ExtractionDataAnalyzer.kt index 811937867b57..37e08655e9d7 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/extractionEngine/ExtractionDataAnalyzer.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/extractionEngine/ExtractionDataAnalyzer.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.analysis.api.components.KtDiagnosticCheckerFilter import org.jetbrains.kotlin.analysis.api.fir.diagnostics.KtFirDiagnostic import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol +import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.project.structure.DanglingFileResolutionMode import org.jetbrains.kotlin.idea.base.resources.KotlinBundle From 81c5aa5509c58a2194f29a0439890bbe99436b29 Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Tue, 23 Apr 2024 19:15:27 +0200 Subject: [PATCH 07/21] [kotlin] update convention for KtLifetimeOwner implementation ^KT-67655 GitOrigin-RevId: 2c5a9fe607264f72fb84be782a3d82f00f5a2d5e --- .../kotlin/idea/base/codeInsight/KotlinCallProcessor.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/KotlinCallProcessor.kt b/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/KotlinCallProcessor.kt index bb4c5b86646b..93d21bdfca51 100644 --- a/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/KotlinCallProcessor.kt +++ b/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/KotlinCallProcessor.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.base.codeInsight import com.intellij.openapi.progress.ProgressManager @@ -168,7 +168,7 @@ object KotlinCallProcessor { is KtFunctionLikeSymbol -> { val signature = symbol.asSignature() val partiallyAppliedSymbol = KtPartiallyAppliedFunctionSymbol(signature, null, null) - val call = KtSimpleFunctionCall(partiallyAppliedSymbol, linkedMapOf(), mapOf(), _isImplicitInvoke = false) + val call = KtSimpleFunctionCall(partiallyAppliedSymbol, linkedMapOf(), mapOf(), isImplicitInvoke = false) processCallTarget(FunctionCallTarget(element, call, partiallyAppliedSymbol)) } From a1a3667efedb6c6531a9bc94163c11017111871f Mon Sep 17 00:00:00 2001 From: Marco Pennekamp Date: Wed, 24 Apr 2024 20:43:36 +0200 Subject: [PATCH 08/21] [kotlin] Rewrite infix usages of `KtType.isEqualTo` and `KtType.isSubTypeOf` ^KT-67750 GitOrigin-RevId: b535d4e6d4128541146b2658d1c62cbaf34c3c88 --- .../kotlin/idea/base/analysis/api/utils/typeUtils.kt | 2 +- .../idea/k2/codeinsight/fixes/CastExpressionFixFactories.kt | 2 +- .../idea/k2/codeinsight/fixes/SpecifySuperTypeFixFactory.kt | 2 +- .../kotlin/idea/k2/codeinsight/fixes/TypeMismatchFactories.kt | 2 +- .../k2/codeinsight/inspections/EqualsOrHashCodeInspection.kt | 2 +- .../expressions/ReplaceCallWithBinaryOperatorInspection.kt | 4 ++-- .../FirDeclarationFromUnresolvedNameContributor.kt | 4 ++-- .../impl/k2/contributors/helpers/CallableMetadataProvider.kt | 4 ++-- .../kotlin/idea/k2/refactoring/util/BranchedFoldingUtils.kt | 4 ++-- .../k2/refactoring/util/RedundantExplicitTypeArgumentsUtil.kt | 4 ++-- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/analysis/api/utils/typeUtils.kt b/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/analysis/api/utils/typeUtils.kt index bb9849d25a21..5696a83e8b82 100644 --- a/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/analysis/api/utils/typeUtils.kt +++ b/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/analysis/api/utils/typeUtils.kt @@ -26,7 +26,7 @@ infix fun KtType.isPossiblySubTypeOf(superType: KtType): Boolean { val superTypeWithReplacedTypeArguments = superType.expandedClassSymbol?.let { symbol -> buildClassTypeWithStarProjections(symbol, superType.nullability) } - return superTypeWithReplacedTypeArguments != null && this isSubTypeOf superTypeWithReplacedTypeArguments + return superTypeWithReplacedTypeArguments != null && isSubTypeOf(superTypeWithReplacedTypeArguments) } context(KtAnalysisSession) diff --git a/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/CastExpressionFixFactories.kt b/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/CastExpressionFixFactories.kt index 07c38fc13163..f33402c4e95a 100644 --- a/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/CastExpressionFixFactories.kt +++ b/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/CastExpressionFixFactories.kt @@ -115,7 +115,7 @@ object CastExpressionFixFactories { if (element is KtExpression) { val actualExpressionType = element.getKtType() - if (actualExpressionType != null && !(actualExpressionType isEqualTo actualType)) { + if (actualExpressionType != null && !actualExpressionType.isEqualTo(actualType)) { //don't suggest cast for nested generic argument incompatibilities return emptyList() } diff --git a/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/SpecifySuperTypeFixFactory.kt b/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/SpecifySuperTypeFixFactory.kt index 41e1a7e56975..d6b3e2b2edbe 100644 --- a/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/SpecifySuperTypeFixFactory.kt +++ b/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/SpecifySuperTypeFixFactory.kt @@ -89,7 +89,7 @@ object SpecifySuperTypeFixFactory { // the candidate would not contain those being removed here. candidates.removeAll { superType -> candidates.any { otherSuperType -> - !superType.isEqualTo(otherSuperType) && otherSuperType isSubTypeOf superType + !superType.isEqualTo(otherSuperType) && otherSuperType.isSubTypeOf(superType) } } if (candidates.isEmpty()) return@IntentionBased emptyList() diff --git a/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/TypeMismatchFactories.kt b/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/TypeMismatchFactories.kt index 6377eda0648e..f689ce19e240 100644 --- a/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/TypeMismatchFactories.kt +++ b/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/TypeMismatchFactories.kt @@ -56,7 +56,7 @@ object TypeMismatchFactories { return emptyList() } val nullableExpectedType = expectedType.withNullability(KtTypeNullability.NULLABLE) - if (actualType isSubTypeOf nullableExpectedType) { + if (actualType.isSubTypeOf(nullableExpectedType)) { return listOfNotNull(psi.asAddExclExclCallFix()) } } diff --git a/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/EqualsOrHashCodeInspection.kt b/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/EqualsOrHashCodeInspection.kt index 9dbd9397afe9..1c8fa58cf8d4 100644 --- a/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/EqualsOrHashCodeInspection.kt +++ b/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/EqualsOrHashCodeInspection.kt @@ -282,7 +282,7 @@ internal class EqualsOrHashCodeInspection : AbstractKotlinInspection() { val isNullable = type.isMarkedNullable var text = when { - type isEqualTo builtinTypes.BYTE || type isEqualTo builtinTypes.SHORT || type isEqualTo builtinTypes.INT -> ref + type.isEqualTo(builtinTypes.BYTE) || type.isEqualTo(builtinTypes.SHORT) || type.isEqualTo(builtinTypes.INT) -> ref type.isArrayOrPrimitiveArray() -> { val canUseArrayContentFunctions = targetClass.canUseArrayContentFunctions() diff --git a/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/expressions/ReplaceCallWithBinaryOperatorInspection.kt b/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/expressions/ReplaceCallWithBinaryOperatorInspection.kt index ec2660e3a6d1..598c42b52d58 100644 --- a/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/expressions/ReplaceCallWithBinaryOperatorInspection.kt +++ b/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/expressions/ReplaceCallWithBinaryOperatorInspection.kt @@ -221,13 +221,13 @@ context(KtAnalysisSession) private fun areRelatedBySubtyping(first: KtExpression, second: KtExpression): Boolean { val firstType = first.getKtType() ?: return false val secondType = second.getKtType() ?: return false - return firstType isSubTypeOf secondType || secondType isSubTypeOf firstType + return firstType.isSubTypeOf(secondType) || secondType.isSubTypeOf(firstType) } context(KtAnalysisSession) private fun KtExpression.hasDoubleOrFloatType(): Boolean { val type = getKtType() ?: return false - return type isSubTypeOf builtinTypes.DOUBLE || type isSubTypeOf builtinTypes.FLOAT + return type.isSubTypeOf(builtinTypes.DOUBLE) || type.isSubTypeOf(builtinTypes.FLOAT) } context(KtAnalysisSession) diff --git a/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/FirDeclarationFromUnresolvedNameContributor.kt b/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/FirDeclarationFromUnresolvedNameContributor.kt index 6fda4d78a93b..fac869f6e239 100644 --- a/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/FirDeclarationFromUnresolvedNameContributor.kt +++ b/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/FirDeclarationFromUnresolvedNameContributor.kt @@ -95,13 +95,13 @@ internal class FirDeclarationFromUnresolvedNameContributor( val expectedReceiverType = getReceiverType(symbol) ?: return false // FIXME: this check does not work with generic types (i.e. List and List) - actualReceiverType isSubTypeOf expectedReceiverType + actualReceiverType.isSubTypeOf(expectedReceiverType) } else -> { // If there is no explicit receiver at call-site, we check if any implicit receiver at call-site matches the extension // receiver type for the current declared symbol val extensionReceiverType = symbol.receiverType ?: return true - getImplicitReceiverTypesAtPosition(unresolvedRef).any { it isSubTypeOf extensionReceiverType } + getImplicitReceiverTypesAtPosition(unresolvedRef).any { it.isSubTypeOf(extensionReceiverType) } } } is KtClassOrObjectSymbol -> when { diff --git a/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/helpers/CallableMetadataProvider.kt b/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/helpers/CallableMetadataProvider.kt index bb3530e1ee9d..549094ccc26d 100644 --- a/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/helpers/CallableMetadataProvider.kt +++ b/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/helpers/CallableMetadataProvider.kt @@ -284,13 +284,13 @@ internal object CallableMetadataProvider { actualReceiverType: KtType, expectedReceiverType: KtType, ): CallableKind? = when { - actualReceiverType isEqualTo expectedReceiverType -> when { + actualReceiverType.isEqualTo(expectedReceiverType) -> when { isExtensionCallOnTypeParameterReceiver(symbol) -> CallableKind.TYPE_PARAMETER_EXTENSION symbol.isExtension -> CallableKind.THIS_TYPE_EXTENSION else -> CallableKind.THIS_CLASS_MEMBER } - actualReceiverType isSubTypeOf expectedReceiverType -> when { + actualReceiverType.isSubTypeOf(expectedReceiverType) -> when { symbol.isExtension -> CallableKind.BASE_TYPE_EXTENSION else -> CallableKind.BASE_CLASS_MEMBER } diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/util/BranchedFoldingUtils.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/util/BranchedFoldingUtils.kt index c53d7653501a..4a23a67f21af 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/util/BranchedFoldingUtils.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/util/BranchedFoldingUtils.kt @@ -221,8 +221,8 @@ object BranchedFoldingUtils { val rightTypeOfSecond = second.right?.getKtType() ?: return false if (!leftType.canBeNull && rightTypeOfSecond.canBeNull) return false val nonNullableRightTypeOfSecond = rightTypeOfSecond.withNullability(KtTypeNullability.NON_NULLABLE) - return nonNullableRightTypeOfFirst isEqualTo nonNullableRightTypeOfSecond || - (first.operationToken == KtTokens.EQ && nonNullableRightTypeOfSecond isSubTypeOf leftType) + return nonNullableRightTypeOfFirst.isEqualTo(nonNullableRightTypeOfSecond) || + (first.operationToken == KtTokens.EQ && nonNullableRightTypeOfSecond.isSubTypeOf(leftType)) } /** diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/util/RedundantExplicitTypeArgumentsUtil.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/util/RedundantExplicitTypeArgumentsUtil.kt index 7c2e7fcd2e0c..5cf98f541748 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/util/RedundantExplicitTypeArgumentsUtil.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/util/RedundantExplicitTypeArgumentsUtil.kt @@ -119,8 +119,8 @@ private fun buildType(type: KtType, typeArgumentsMapping: Map Date: Thu, 25 Apr 2024 22:39:17 +0200 Subject: [PATCH 09/21] [kotlin][k2] Rewrite additional infix usages of `KtType.isEqualTo` and `KtType.isSubTypeOf` ^KT-67750 GitOrigin-RevId: e3faf5248d188dbbb54d0b6a1605e8c1eeb94d48 --- .../org/jetbrains/kotlin/j2k/postProcessings/diagnosticBased.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/kotlin/j2k/k2/src/org/jetbrains/kotlin/j2k/postProcessings/diagnosticBased.kt b/plugins/kotlin/j2k/k2/src/org/jetbrains/kotlin/j2k/postProcessings/diagnosticBased.kt index 38f185804768..3df98f1f8611 100644 --- a/plugins/kotlin/j2k/k2/src/org/jetbrains/kotlin/j2k/postProcessings/diagnosticBased.kt +++ b/plugins/kotlin/j2k/k2/src/org/jetbrains/kotlin/j2k/postProcessings/diagnosticBased.kt @@ -28,7 +28,7 @@ private val smartcastImpossibleFactory = KotlinQuickFixFactory.IntentionBased { return@IntentionBased emptyList() } val nullableExpectedType = expectedType.withNullability(KtTypeNullability.NULLABLE) - if (actualType isSubTypeOf nullableExpectedType) { + if (actualType.isSubTypeOf(nullableExpectedType)) { return@IntentionBased listOf(AddExclExclCallFix(psi)) } return@IntentionBased emptyList() From 62564761187aa14913b3415a0e1ae78fa317cf72 Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Thu, 25 Apr 2024 19:58:03 +0200 Subject: [PATCH 10/21] [kotlin] KtCall: drop redundant implementation ^KT-66039 GitOrigin-RevId: 0776763ab4dc1801b750a7014737f0bcb476364b --- .../idea/fir/fe10/Fe10WrapperContext.kt | 8 +- .../binding/CallAndResolverCallWrappers.kt | 12 +-- .../Fe10BindingSpecialConstructions.kt | 93 ------------------- 3 files changed, 4 insertions(+), 109 deletions(-) delete mode 100644 plugins/kotlin/k2-fe10-bindings/src/org/jetbrains/kotlin/idea/fir/fe10/binding/Fe10BindingSpecialConstructions.kt diff --git a/plugins/kotlin/k2-fe10-bindings/src/org/jetbrains/kotlin/idea/fir/fe10/Fe10WrapperContext.kt b/plugins/kotlin/k2-fe10-bindings/src/org/jetbrains/kotlin/idea/fir/fe10/Fe10WrapperContext.kt index 8268478e0333..805c033ca9d3 100644 --- a/plugins/kotlin/k2-fe10-bindings/src/org/jetbrains/kotlin/idea/fir/fe10/Fe10WrapperContext.kt +++ b/plugins/kotlin/k2-fe10-bindings/src/org/jetbrains/kotlin/idea/fir/fe10/Fe10WrapperContext.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.fir.fe10 @@ -21,7 +21,6 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo import org.jetbrains.kotlin.idea.base.util.Frontend10ApiUsage -import org.jetbrains.kotlin.idea.fir.fe10.binding.Fe10BindingSpecialConstructionsWrappers import org.jetbrains.kotlin.idea.fir.fe10.binding.KtSymbolBasedBindingContext import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -34,7 +33,6 @@ interface Fe10WrapperContext { val moduleDescriptor: ModuleDescriptor val languageVersionSettings: LanguageVersionSettings val bindingContext: BindingContext - val fe10BindingSpecialConstructionFunctions: Fe10BindingSpecialConstructionsWrappers // This property used to disable some logic used locally for debug purposes val enableLogging: Boolean get() = false @@ -113,7 +111,7 @@ fun KtVariableLikeSymbol.toDeclarationDescriptor(context: Fe10WrapperContext): V fun KtTypeAliasSymbol.toDeclarationDescriptor(context: Fe10WrapperContext) = KtSymbolBasedTypeAliasDescriptor(this, context) class Fe10WrapperContextImpl( - private val project: Project, + project: Project, private val ktElement: KtElement ) : Fe10WrapperContext { private val module: KtModule = ProjectStructureProvider.getModule(project, ktElement, null) @@ -137,8 +135,6 @@ class Fe10WrapperContextImpl( override val bindingContext: BindingContext = KtSymbolBasedBindingContext(this) - override val fe10BindingSpecialConstructionFunctions = Fe10BindingSpecialConstructionsWrappers(this) - override fun noImplementation(additionalInfo: String): Nothing = error("This method should not be called for wrappers. $additionalInfo") diff --git a/plugins/kotlin/k2-fe10-bindings/src/org/jetbrains/kotlin/idea/fir/fe10/binding/CallAndResolverCallWrappers.kt b/plugins/kotlin/k2-fe10-bindings/src/org/jetbrains/kotlin/idea/fir/fe10/binding/CallAndResolverCallWrappers.kt index 56bb00a84e91..cc90496c4560 100644 --- a/plugins/kotlin/k2-fe10-bindings/src/org/jetbrains/kotlin/idea/fir/fe10/binding/CallAndResolverCallWrappers.kt +++ b/plugins/kotlin/k2-fe10-bindings/src/org/jetbrains/kotlin/idea/fir/fe10/binding/CallAndResolverCallWrappers.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.fir.fe10.binding @@ -128,18 +128,10 @@ class CallAndResolverCallWrappers(bindingContext: KtSymbolBasedBindingContext) { } return FunctionFe10WrapperResolvedCall(call, ktCall, diagnostic, context) } + is KtVariableAccessCall -> { return VariableFe10WrapperResolvedCall(call, ktCall, diagnostic, context) } - is KtCheckNotNullCall -> { - val kotlinType = context.withAnalysisSession { ktCall.baseExpression.getKtType() }?.toKotlinType(context) - return Fe10BindingSpecialConstructionResolvedCall( - call, - kotlinType, - context.fe10BindingSpecialConstructionFunctions.EXCL_EXCL, - context - ) - } else -> context.implementationPostponed(ktCall.javaClass.canonicalName) } diff --git a/plugins/kotlin/k2-fe10-bindings/src/org/jetbrains/kotlin/idea/fir/fe10/binding/Fe10BindingSpecialConstructions.kt b/plugins/kotlin/k2-fe10-bindings/src/org/jetbrains/kotlin/idea/fir/fe10/binding/Fe10BindingSpecialConstructions.kt deleted file mode 100644 index 8ec188f93908..000000000000 --- a/plugins/kotlin/k2-fe10-bindings/src/org/jetbrains/kotlin/idea/fir/fe10/binding/Fe10BindingSpecialConstructions.kt +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ -package org.jetbrains.kotlin.idea.fir.fe10.binding - -import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor -import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor -import org.jetbrains.kotlin.idea.fir.fe10.Fe10WrapperContext -import org.jetbrains.kotlin.psi.Call -import org.jetbrains.kotlin.psi.ValueArgument -import org.jetbrains.kotlin.resolve.calls.model.* -import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus -import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind -import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue -import org.jetbrains.kotlin.storage.LockBasedStorageManager -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.TypeSubstitutor -import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils -import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.createFunctionDescriptorForSpecialConstruction -import org.jetbrains.kotlin.types.typeUtil.asTypeProjection - -class Fe10BindingSpecialConstructionsWrappers(val context: Fe10WrapperContext) { - val EXCL_EXCL: FunctionDescriptor = run { - createFunctionDescriptorForSpecialConstruction( - ControlStructureTypingUtils.ResolveConstruct.EXCL_EXCL, - listOf("baseExpr"), - listOf(true), - context.moduleDescriptor, - LockBasedStorageManager.NO_LOCKS - ) - } -} - -// special calls have exactly one type parameter -class Fe10BindingSpecialConstructionResolvedCall( - private val psiCall: Call, - private val inferredTypeParameter: KotlinType?, - private val descriptor: FunctionDescriptor, - private val context: Fe10WrapperContext -) : ResolvedCall { - - init { - check(psiCall.valueArguments.size == descriptor.valueParameters.size) { - "${psiCall.valueArguments.size} != ${descriptor.valueParameters.size}" - } - } - - private val typeArgument get() = inferredTypeParameter ?: descriptor.typeParameters.single().defaultType - - private val _resultingDescriptor = run { - val substitutionMap = mapOf(descriptor.typeParameters.single().typeConstructor to typeArgument.asTypeProjection()) - descriptor.substitute(TypeSubstitutor.create(substitutionMap))!! - } - - - override fun getExtensionReceiver(): ReceiverValue? = null - override fun getDispatchReceiver(): ReceiverValue? = null - override fun getContextReceivers(): List = emptyList() - override fun getExplicitReceiverKind(): ExplicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER - - override fun getStatus(): ResolutionStatus = - if (inferredTypeParameter == null) ResolutionStatus.INCOMPLETE_TYPE_INFERENCE else ResolutionStatus.SUCCESS - - override fun getCall(): Call = psiCall - - override fun getCandidateDescriptor(): FunctionDescriptor = descriptor - - override fun getResultingDescriptor(): FunctionDescriptor = _resultingDescriptor - - - override fun getValueArguments(): Map = - linkedMapOf().apply { - for ((index, parameter) in resultingDescriptor.valueParameters.withIndex()) { - put(parameter, ExpressionValueArgument(psiCall.valueArguments[index])) - } - } - - override fun getValueArgumentsByIndex(): List = psiCall.valueArguments.map(::ExpressionValueArgument) - - override fun getArgumentMapping(valueArgument: ValueArgument): ArgumentMapping { - val index = psiCall.valueArguments.indexOf(valueArgument) - if (index == -1) return ArgumentUnmapped - return ArgumentMatchImpl(resultingDescriptor.valueParameters[index]) - } - - override fun getTypeArguments(): Map = - mapOf(descriptor.typeParameters.single() to typeArgument) - - override fun getDataFlowInfoForArguments(): DataFlowInfoForArguments = context.noImplementation() - override fun getSmartCastDispatchReceiverType(): KotlinType = context.noImplementation() -} \ No newline at end of file From c01444f90a000f533457708b5f2a3ad189707962 Mon Sep 17 00:00:00 2001 From: Marco Pennekamp Date: Tue, 16 Apr 2024 20:00:52 +0200 Subject: [PATCH 11/21] [kotlin][k2] Use semantic type equality in `ShadowedCallablesFilter` - With the changes in KT-62889, we get an awkward situation where we may have one type already expanded from a library (e.g. `java.lang.StringBuilder`), and another type from sources still unexpanded (e.g. `kotlin.text.StringBuilder`). - The completion test `HighLevelBasicCompletionHandlerTestGenerated$Basic$Kdoc.testFunctionFqName` ran into this exact situation, as it tries to compare two `buildString` functions with parameter types `java.lang/kotlin.text.StringBuilder.() -> Unit`. - Using semantic type equality solves the issue, as it expands types on its own. And in general, using semantic type equality here is better, since it's closer to overload checking. - Note that we cannot simply use `fullyExpandedType` and compare these expanded types structurally, as currently, type arguments are not expanded, so `kotlin.text.StringBuilder.() -> Unit` would not be expanded (`kotlin.text.StringBuilder` is a type argument of a function class type). ^KT-62889 ^KT-67439 GitOrigin-RevId: 3ef57fe10775a9d01f4466541449eecbe2d9ac08 --- .../helpers/ShadowedCallablesFilter.kt | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/helpers/ShadowedCallablesFilter.kt b/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/helpers/ShadowedCallablesFilter.kt index 1b427527166f..1b61b476211b 100644 --- a/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/helpers/ShadowedCallablesFilter.kt +++ b/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/helpers/ShadowedCallablesFilter.kt @@ -247,6 +247,7 @@ private sealed class SimplifiedSignature { requiredTypeArgumentsCount = if (typeArgumentsAreRequired) callableSignature.symbol.typeParameters.size else 0, lazy(LazyThreadSafetyMode.NONE) { callableSignature.valueParameters.map { it.returnType } }, callableSignature.valueParameters.mapIndexedNotNull { index, parameter -> index.takeIf { parameter.symbol.isVararg } }, + this@KtAnalysisSession, ) } } @@ -266,7 +267,8 @@ private sealed class SimplifiedSignature { val functionalType = signature.returnType as? KtFunctionalType ?: error("Unexpected ${signature.returnType::class}") functionalType.parameterTypes }, - varargValueParameterIndices = emptyList() + varargValueParameterIndices = emptyList(), + this@KtAnalysisSession, ) } @@ -303,6 +305,7 @@ private class FunctionLikeSimplifiedSignature( private val requiredTypeArgumentsCount: Int, private val valueParameterTypes: Lazy>, private val varargValueParameterIndices: List, + private val analysisSession: KtAnalysisSession, ) : SimplifiedSignature() { override fun hashCode(): Int { var result = name.hashCode() @@ -318,5 +321,21 @@ private class FunctionLikeSimplifiedSignature( other.containerFqName == containerFqName && other.requiredTypeArgumentsCount == requiredTypeArgumentsCount && other.varargValueParameterIndices == varargValueParameterIndices && - other.valueParameterTypes.value == valueParameterTypes.value + areValueParameterTypesEqualTo(other) + + /** + * We need to use semantic type equality instead of the default structural equality of [KtType] to check if two signatures overlap. + */ + private fun areValueParameterTypesEqualTo(other: FunctionLikeSimplifiedSignature): Boolean { + val types1 = other.valueParameterTypes.value + val types2 = valueParameterTypes.value + if (types1.size != types2.size) return false + + with(analysisSession) { + for (i in types1.indices) { + if (!types1[i].isEqualTo(types2[i])) return false + } + return true + } + } } From debc8b283ed2976c1366b4c041a54f1692ec40ca Mon Sep 17 00:00:00 2001 From: Marco Pennekamp Date: Wed, 17 Apr 2024 18:13:30 +0200 Subject: [PATCH 12/21] [kotlin][k2] `RemoveExplicitTypeIntention`: Add explicit support for removing error types - With the changes in KT-67514, the `removeUnresolvedType` test started to fail as the error type wasn't removed anymore. Previously, `isInitializerTypeContextIndependent` returned `true` for a `KtConstantExpression` initializer using a subtyping check `Int <: ERROR`. - While this worked for the integer constant in question, it's better to explicitly support removing error types. ^KT-67514 GitOrigin-RevId: 16348c9973ad06e474fed0f38bd2b0688490eef1 --- .../intentions/RemoveExplicitTypeIntention.kt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/RemoveExplicitTypeIntention.kt b/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/RemoveExplicitTypeIntention.kt index 2787cc17c4c4..07ac92c89a8d 100644 --- a/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/RemoveExplicitTypeIntention.kt +++ b/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/RemoveExplicitTypeIntention.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.analysis.api.components.KtConstantEvaluationMode import org.jetbrains.kotlin.analysis.api.components.buildClassType import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility import org.jetbrains.kotlin.analysis.api.symbols.receiverType +import org.jetbrains.kotlin.analysis.api.types.KtErrorType import org.jetbrains.kotlin.config.AnalysisFlags import org.jetbrains.kotlin.config.ExplicitApiMode import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings @@ -87,12 +88,19 @@ internal class RemoveExplicitTypeIntention : private fun KtDeclaration.isExplicitTypeReferenceNeededForTypeInferenceByAnalyze(): Boolean { val typeReference = typeReference ?: return false val initializer = getInitializerOrGetterInitializer() ?: return true + val explicitType = getReturnKtType() + + // The initializer may require an explicit type, but an error type is definitely not it. The intention makes a conscious decision to + // allow the user to quickly remove completely erroneous explicit types. + // + // The situation is more fuzzy with errors in type arguments. Here, it makes sense not to remove the type, but rather to fix it. And + // with a little bit of type information, the intention has a better chance of deciding whether the initializer needs that explicit + // type. So we don't check the `explicitType` for nested errors. + if (explicitType is KtErrorType) return false if (!isInitializerTypeContextIndependent(initializer, typeReference)) return true val initializerType = initializer.getKtType() ?: return true - val explicitType = getReturnKtType() - val typeCanBeRemoved = if (isVar) { initializerType.isEqualTo(explicitType) } else { From 68eb10c6669730a72ae44474adb6bc5ef5c0e5df Mon Sep 17 00:00:00 2001 From: Marco Pennekamp Date: Thu, 18 Apr 2024 21:33:52 +0200 Subject: [PATCH 13/21] [kotlin][k2] Update J2K test data after removing error type leniency in type equality - `parenthesized2`: `''` is not a valid character, so the property initializer had an error type "ERROR CLASS: Incorrect character: ''". ^KT-67514 ^KTIJ-29632 ^KTIJ-29640 GitOrigin-RevId: b8aea5e0290216c5a1621547c67aebefaa4be588 --- .../comments/fieldWithLineBreakCommentAndInitializer.java | 3 +++ .../newJ2k/comments/fieldWithLineBreakCommentAndInitializer.kt | 1 + .../labelStatement/complicatedExampleFromJavaTutorial.java | 1 - .../testData/newJ2k/newClassExpression/newInnerClass.java | 3 +++ .../tests/testData/newJ2k/newClassExpression/newInnerClass.kt | 1 + .../newJ2k/newClassExpression/newStaticInnerClass.java | 3 +++ .../testData/newJ2k/newClassExpression/newStaticInnerClass.kt | 1 + .../newJ2k/parenthesizedExpression/parenthesized2.java | 2 +- .../testData/newJ2k/parenthesizedExpression/parenthesized2.kt | 2 +- 9 files changed, 14 insertions(+), 3 deletions(-) diff --git a/plugins/kotlin/j2k/shared/tests/testData/newJ2k/comments/fieldWithLineBreakCommentAndInitializer.java b/plugins/kotlin/j2k/shared/tests/testData/newJ2k/comments/fieldWithLineBreakCommentAndInitializer.java index 8eb8496e1181..5000247bba70 100644 --- a/plugins/kotlin/j2k/shared/tests/testData/newJ2k/comments/fieldWithLineBreakCommentAndInitializer.java +++ b/plugins/kotlin/j2k/shared/tests/testData/newJ2k/comments/fieldWithLineBreakCommentAndInitializer.java @@ -1,3 +1,6 @@ +// IGNORE_K2 +// KTIJ-29640 + package some; public class Foo { diff --git a/plugins/kotlin/j2k/shared/tests/testData/newJ2k/comments/fieldWithLineBreakCommentAndInitializer.kt b/plugins/kotlin/j2k/shared/tests/testData/newJ2k/comments/fieldWithLineBreakCommentAndInitializer.kt index e38cc55a8ae4..7192bded4b21 100644 --- a/plugins/kotlin/j2k/shared/tests/testData/newJ2k/comments/fieldWithLineBreakCommentAndInitializer.kt +++ b/plugins/kotlin/j2k/shared/tests/testData/newJ2k/comments/fieldWithLineBreakCommentAndInitializer.kt @@ -1,3 +1,4 @@ +// KTIJ-29640 package some object Foo { diff --git a/plugins/kotlin/j2k/shared/tests/testData/newJ2k/labelStatement/complicatedExampleFromJavaTutorial.java b/plugins/kotlin/j2k/shared/tests/testData/newJ2k/labelStatement/complicatedExampleFromJavaTutorial.java index c59ad3dafbc8..0aa2b3dd0982 100644 --- a/plugins/kotlin/j2k/shared/tests/testData/newJ2k/labelStatement/complicatedExampleFromJavaTutorial.java +++ b/plugins/kotlin/j2k/shared/tests/testData/newJ2k/labelStatement/complicatedExampleFromJavaTutorial.java @@ -1,3 +1,2 @@ -// IGNORE_K2 //statement test: for (int i = 0; i <= max; i++) { int n = substring.length(); int j = i; int k = 0; while (n-- != 0) { if (searchMe.charAt(j++) != substring.charAt(k++)) { continue test; } } foundIt = true; break test; } System.out.println(foundIt ? "Found it" : "Didn't find it"); }} \ No newline at end of file diff --git a/plugins/kotlin/j2k/shared/tests/testData/newJ2k/newClassExpression/newInnerClass.java b/plugins/kotlin/j2k/shared/tests/testData/newJ2k/newClassExpression/newInnerClass.java index 1f4cdf9f5892..e0db08823333 100644 --- a/plugins/kotlin/j2k/shared/tests/testData/newJ2k/newClassExpression/newInnerClass.java +++ b/plugins/kotlin/j2k/shared/tests/testData/newJ2k/newClassExpression/newInnerClass.java @@ -1,3 +1,6 @@ +// IGNORE_K2 +// KTIJ-29632 + package org.test; class OuterClass { diff --git a/plugins/kotlin/j2k/shared/tests/testData/newJ2k/newClassExpression/newInnerClass.kt b/plugins/kotlin/j2k/shared/tests/testData/newJ2k/newClassExpression/newInnerClass.kt index 40373d51f344..24e778c0f010 100644 --- a/plugins/kotlin/j2k/shared/tests/testData/newJ2k/newClassExpression/newInnerClass.kt +++ b/plugins/kotlin/j2k/shared/tests/testData/newJ2k/newClassExpression/newInnerClass.kt @@ -1,3 +1,4 @@ +// KTIJ-29632 package org.test internal class OuterClass { diff --git a/plugins/kotlin/j2k/shared/tests/testData/newJ2k/newClassExpression/newStaticInnerClass.java b/plugins/kotlin/j2k/shared/tests/testData/newJ2k/newClassExpression/newStaticInnerClass.java index 0465c7498aa8..4184e868e3f5 100644 --- a/plugins/kotlin/j2k/shared/tests/testData/newJ2k/newClassExpression/newStaticInnerClass.java +++ b/plugins/kotlin/j2k/shared/tests/testData/newJ2k/newClassExpression/newStaticInnerClass.java @@ -1,3 +1,6 @@ +// IGNORE_K2 +// KTIJ-29632 + package demo; class Foo { diff --git a/plugins/kotlin/j2k/shared/tests/testData/newJ2k/newClassExpression/newStaticInnerClass.kt b/plugins/kotlin/j2k/shared/tests/testData/newJ2k/newClassExpression/newStaticInnerClass.kt index 5189a744c3ff..b163e863df6b 100644 --- a/plugins/kotlin/j2k/shared/tests/testData/newJ2k/newClassExpression/newStaticInnerClass.kt +++ b/plugins/kotlin/j2k/shared/tests/testData/newJ2k/newClassExpression/newStaticInnerClass.kt @@ -1,3 +1,4 @@ +// KTIJ-29632 package demo import demo.Foo.Bar diff --git a/plugins/kotlin/j2k/shared/tests/testData/newJ2k/parenthesizedExpression/parenthesized2.java b/plugins/kotlin/j2k/shared/tests/testData/newJ2k/parenthesizedExpression/parenthesized2.java index 3ed511322f74..7c0a118dcaa7 100644 --- a/plugins/kotlin/j2k/shared/tests/testData/newJ2k/parenthesizedExpression/parenthesized2.java +++ b/plugins/kotlin/j2k/shared/tests/testData/newJ2k/parenthesizedExpression/parenthesized2.java @@ -1,3 +1,3 @@ //statement -Character str = '' +Character str = 'a' (str.toString() + "abc").length() \ No newline at end of file diff --git a/plugins/kotlin/j2k/shared/tests/testData/newJ2k/parenthesizedExpression/parenthesized2.kt b/plugins/kotlin/j2k/shared/tests/testData/newJ2k/parenthesizedExpression/parenthesized2.kt index a3122fc93c46..ec32ea76347b 100644 --- a/plugins/kotlin/j2k/shared/tests/testData/newJ2k/parenthesizedExpression/parenthesized2.kt +++ b/plugins/kotlin/j2k/shared/tests/testData/newJ2k/parenthesizedExpression/parenthesized2.kt @@ -1,2 +1,2 @@ -val str = '' +val str = 'a' (str.toString() + "abc").length From 84b2a2b199e83bc21a234ef1522c64c55c2f12ec Mon Sep 17 00:00:00 2001 From: Marco Pennekamp Date: Tue, 23 Apr 2024 16:16:58 +0200 Subject: [PATCH 14/21] [kotlin][k2] Update semantic matcher test data after changes to error type leniency in K2 - KTIJ-29689: The `misc2.kt` test failed after removal of error type leniency. `MyClass` and `YourClass` are both unresolved, which leads to comparisons of types such as `ERROR CLASS: Symbol not found for MyClass?` with another instance of `ERROR CLASS: Symbol not found for MyClass?`. Without error type leniency, these types are not trivially equal anymore. - The new test `singleParamTypeError.kt` is an example where a match *should not* be found when there's a type error (as we cannot sufficiently prove that the third lambda is semantically equal to the first two). With error type leniency, `K2SemanticMatcher` finds the lambda with `UnresolvedType` as a match, while K1 does not. Disabling error type leniency fixes this test for K2. ^KT-67514 ^KTIJ-29689 GitOrigin-RevId: dacc724c97f34d820bfed22ab5493c89927646ab --- .../psi/patternMatching/K1PsiUnifierTestGenerated.java | 5 +++++ .../localCallables/lambdas/singleParamTypeError.kt | 8 ++++++++ .../localCallables/lambdas/singleParamTypeError.kt.match | 5 +++++ .../unifier/equivalence/expressions/misc/misc2.kt | 5 ++++- .../unifier/equivalence/expressions/misc/misc2.kt.match | 6 +++--- .../refactoring/introduce/K2PsiUnifierTestGenerated.java | 5 +++++ 6 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 plugins/kotlin/idea/tests/testData/unifier/equivalence/declarations/localCallables/lambdas/singleParamTypeError.kt create mode 100644 plugins/kotlin/idea/tests/testData/unifier/equivalence/declarations/localCallables/lambdas/singleParamTypeError.kt.match diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/psi/patternMatching/K1PsiUnifierTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/psi/patternMatching/K1PsiUnifierTestGenerated.java index 1bf0301417a0..62712c3da6c0 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/psi/patternMatching/K1PsiUnifierTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/psi/patternMatching/K1PsiUnifierTestGenerated.java @@ -203,6 +203,11 @@ public abstract class K1PsiUnifierTestGenerated extends AbstractK1PsiUnifierTest runTest("testData/unifier/equivalence/declarations/localCallables/lambdas/singleParam.kt"); } + @TestMetadata("singleParamTypeError.kt") + public void testSingleParamTypeError() throws Exception { + runTest("testData/unifier/equivalence/declarations/localCallables/lambdas/singleParamTypeError.kt"); + } + @TestMetadata("unitCoercion.kt") public void testUnitCoercion() throws Exception { runTest("testData/unifier/equivalence/declarations/localCallables/lambdas/unitCoercion.kt"); diff --git a/plugins/kotlin/idea/tests/testData/unifier/equivalence/declarations/localCallables/lambdas/singleParamTypeError.kt b/plugins/kotlin/idea/tests/testData/unifier/equivalence/declarations/localCallables/lambdas/singleParamTypeError.kt new file mode 100644 index 000000000000..3c0946feacf7 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/unifier/equivalence/declarations/localCallables/lambdas/singleParamTypeError.kt @@ -0,0 +1,8 @@ +// DISABLE-ERRORS +fun foo(x: (Int) -> Int) { } + +fun test() { + foo({ it }) + foo({ x -> x }) + foo({ x: UnresolvedType -> x }) +} diff --git a/plugins/kotlin/idea/tests/testData/unifier/equivalence/declarations/localCallables/lambdas/singleParamTypeError.kt.match b/plugins/kotlin/idea/tests/testData/unifier/equivalence/declarations/localCallables/lambdas/singleParamTypeError.kt.match new file mode 100644 index 000000000000..d6c7edd7a023 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/unifier/equivalence/declarations/localCallables/lambdas/singleParamTypeError.kt.match @@ -0,0 +1,5 @@ +(69,75) +{ it } + +(85,95) +{ x -> x } diff --git a/plugins/kotlin/idea/tests/testData/unifier/equivalence/expressions/misc/misc2.kt b/plugins/kotlin/idea/tests/testData/unifier/equivalence/expressions/misc/misc2.kt index bacb1571dca4..a72f1d78eaed 100644 --- a/plugins/kotlin/idea/tests/testData/unifier/equivalence/expressions/misc/misc2.kt +++ b/plugins/kotlin/idea/tests/testData/unifier/equivalence/expressions/misc/misc2.kt @@ -1,7 +1,10 @@ +// IGNORE_K2 +// KTIJ-29689 + // DISABLE-ERRORS fun foo() { (a.foo((n + 2)*(m - 1))[k[i]] is MyClass?) || (b.foo(n - 2)[i + 1] !is YourClass) a.foo((n + 2*m - 1))[k[i]] is MyClass? || b.foo[n - 2](i + 1) !is YourClass a.foo((n + 2)*(m - 1))[k[i]] is MyClass? || b.foo(n - 2)[i + 1] !is YourClass (a.foo((n + 2)*(m - 1))[k[i]] is MyClass?) || (b.foo(n - 2)[i + 1] !is YourClass) -} \ No newline at end of file +} diff --git a/plugins/kotlin/idea/tests/testData/unifier/equivalence/expressions/misc/misc2.kt.match b/plugins/kotlin/idea/tests/testData/unifier/equivalence/expressions/misc/misc2.kt.match index 2a42d3f434fb..6ff8c5050140 100644 --- a/plugins/kotlin/idea/tests/testData/unifier/equivalence/expressions/misc/misc2.kt.match +++ b/plugins/kotlin/idea/tests/testData/unifier/equivalence/expressions/misc/misc2.kt.match @@ -1,8 +1,8 @@ -(34,115) +(49,130) (a.foo((n + 2)*(m - 1))[k[i]] is MyClass?) || (b.foo(n - 2)[i + 1] !is YourClass) -(200,277) +(215,292) a.foo((n + 2)*(m - 1))[k[i]] is MyClass? || b.foo(n - 2)[i + 1] !is YourClass -(282,363) +(297,378) (a.foo((n + 2)*(m - 1))[k[i]] is MyClass?) || (b.foo(n - 2)[i + 1] !is YourClass) diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/introduce/K2PsiUnifierTestGenerated.java b/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/introduce/K2PsiUnifierTestGenerated.java index aae32a4d325f..86bfa9005953 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/introduce/K2PsiUnifierTestGenerated.java +++ b/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/introduce/K2PsiUnifierTestGenerated.java @@ -203,6 +203,11 @@ public abstract class K2PsiUnifierTestGenerated extends AbstractK2PsiUnifierTest runTest("../../idea/tests/testData/unifier/equivalence/declarations/localCallables/lambdas/singleParam.kt"); } + @TestMetadata("singleParamTypeError.kt") + public void testSingleParamTypeError() throws Exception { + runTest("../../idea/tests/testData/unifier/equivalence/declarations/localCallables/lambdas/singleParamTypeError.kt"); + } + @TestMetadata("unitCoercion.kt") public void testUnitCoercion() throws Exception { runTest("../../idea/tests/testData/unifier/equivalence/declarations/localCallables/lambdas/unitCoercion.kt"); From cecbf5188b39c91a5afa01b817f4dbcb774b5081 Mon Sep 17 00:00:00 2001 From: Marco Pennekamp Date: Tue, 23 Apr 2024 19:27:34 +0200 Subject: [PATCH 15/21] [kotlin][k2] Use error type leniency in parameter info receiver type checks - Finding candidates for parameter info relies on the resolution of a possibly partially specified call. For example, a call `listOf(1).foo<>` to `fun List.foo()` is missing type arguments, but we still want to provide type parameter info for `T` and `K`. - See: `SubstitutedTypeParamInReceiver.kt`. - The call candidate's receiver is checked against the type of the call's receiver to avoid suggesting functions with mismatched receivers. - The subtyping check for this implicitly relies on error type leniency to fill the holes caused by partial specification. For example, the call candidate's receiver for `fun List.foo()` is `List`, because `T` is not specified in `listOf(1).foo<>`. `filterCandidateByReceiverTypeAndVisibility` then checks if `List` (from `listOf(1)`) is a subtype of `List`. - The "structurally correct" solution would be to substitute `Any`/`Nothing`/the inferred type argument into the unspecified type arguments depending on covariance/contravariance/invariance of the type parameter. But this is unwieldy, and error type lenience is equivalent to that approach, as it "dynamically" treats the error type as `Any`/`Nothing`/the inferred type argument. ^KT-67514 GitOrigin-RevId: a0cd586fd2634fb322ca52ee7b5aec59a415cbe3 --- .../base/analysis/api/utils/resolveUtils.kt | 6 +++-- .../KotlinHighLevelTypeArgumentInfoHandler.kt | 22 ++++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/analysis/api/utils/resolveUtils.kt b/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/analysis/api/utils/resolveUtils.kt index 4e7bf5defa06..b844287284bc 100644 --- a/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/analysis/api/utils/resolveUtils.kt +++ b/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/analysis/api/utils/resolveUtils.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.analysis.api.base.KtConstantValue import org.jetbrains.kotlin.analysis.api.calls.KtCallCandidateInfo import org.jetbrains.kotlin.analysis.api.calls.KtFunctionCall import org.jetbrains.kotlin.analysis.api.calls.singleFunctionCallOrNull +import org.jetbrains.kotlin.analysis.api.components.KaSubtypingErrorTypePolicy import org.jetbrains.kotlin.analysis.api.components.buildClassType import org.jetbrains.kotlin.analysis.api.signatures.KtFunctionLikeSignature import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol @@ -68,7 +69,8 @@ fun filterCandidateByReceiverTypeAndVisibility( signature: KtFunctionLikeSignature, callElement: KtElement, fileSymbol: KtFileSymbol, - explicitReceiver: KtExpression? + explicitReceiver: KtExpression?, + subtypingErrorTypePolicy: KaSubtypingErrorTypePolicy = KaSubtypingErrorTypePolicy.STRICT, ): Boolean { val candidateSymbol = signature.symbol if (callElement is KtConstructorDelegationCall) { @@ -95,7 +97,7 @@ fun filterCandidateByReceiverTypeAndVisibility( val receiverTypes = collectReceiverTypesForElement(callElement, explicitReceiver) val candidateReceiverType = signature.receiverType - if (candidateReceiverType != null && receiverTypes.none { it.isSubTypeOf(candidateReceiverType) }) return false + if (candidateReceiverType != null && receiverTypes.none { it.isSubTypeOf(candidateReceiverType, subtypingErrorTypePolicy) }) return false // Filter out candidates not visible from call site if (candidateSymbol is KtSymbolWithVisibility && !isVisible(candidateSymbol, fileSymbol, explicitReceiver, callElement)) return false diff --git a/plugins/kotlin/fir/src/org/jetbrains/kotlin/idea/parameterInfo/KotlinHighLevelTypeArgumentInfoHandler.kt b/plugins/kotlin/fir/src/org/jetbrains/kotlin/idea/parameterInfo/KotlinHighLevelTypeArgumentInfoHandler.kt index 353ecefd9e1d..9f7e468ddcd1 100644 --- a/plugins/kotlin/fir/src/org/jetbrains/kotlin/idea/parameterInfo/KotlinHighLevelTypeArgumentInfoHandler.kt +++ b/plugins/kotlin/fir/src/org/jetbrains/kotlin/idea/parameterInfo/KotlinHighLevelTypeArgumentInfoHandler.kt @@ -5,6 +5,7 @@ import com.intellij.psi.util.parentOfType import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.analyze import org.jetbrains.kotlin.analysis.api.calls.KtCallableMemberCall +import org.jetbrains.kotlin.analysis.api.components.KaSubtypingErrorTypePolicy import org.jetbrains.kotlin.analysis.api.renderer.types.impl.KtTypeRendererForSource import org.jetbrains.kotlin.analysis.api.signatures.KtFunctionLikeSignature import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol @@ -62,7 +63,26 @@ class KotlinHighLevelFunctionTypeArgumentInfoHandler : KotlinHighLevelTypeArgume val symbols = callElement.collectCallCandidates() .mapNotNull { (it.candidate as? KtCallableMemberCall<*, *>)?.partiallyAppliedSymbol?.signature } .filterIsInstance>() - .filter { filterCandidateByReceiverTypeAndVisibility(it, callElement, fileSymbol, explicitReceiver) } + .filter { candidate -> + // We use the `LENIENT` error type policy to permit candidates even when there are partially specified type arguments (e.g., + // `foo<>` for `foo`), as the specified type arguments may directly affect a candidate's receiver type. + // + // ``` + // fun List.foo() {} + // + // listOf(1).foo<>() + // ``` + // + // In this example, the call candidate for `fun List.foo() {}` has the following receiver type: `List`, + // because `T` is not specified. But the call still fits `foo`. The user just hasn't written down the type argument yet. + filterCandidateByReceiverTypeAndVisibility( + candidate, + callElement, + fileSymbol, + explicitReceiver, + KaSubtypingErrorTypePolicy.LENIENT, + ) + } // Multiple overloads may have the same type parameters (see Overloads.kt test), so we select the distinct ones. return symbols.distinctBy { buildPresentation(fetchCandidateInfo(it.symbol), -1).first }.map { it.symbol } From 3c22f185443afe41d675d571d13cb9537960309c Mon Sep 17 00:00:00 2001 From: Marco Pennekamp Date: Wed, 24 Apr 2024 17:40:22 +0200 Subject: [PATCH 16/21] [kotlin][k2] Use error type leniency when checking for preceding type mismatches in parameter info - Let's say we have a call `m(unresolved, true)` and we want to get the parameter info at the caret. In general, we want to display parameter infos which don't fit the argument types (before the caret argument) as disabled. Here, `unresolved` has a type error, though, which technically doesn't fit the parameter type `Int`, but displaying `x: Int, y: Boolean` is still applicable and even helps the user fix the error. ^KT-67514 GitOrigin-RevId: 48054f4422b9e32787c14efbc96ca3aa650fdc5c --- .../base/analysis/api/utils/CallParameterInfoProvider.kt | 9 +++++++-- .../KotlinHighLevelFunctionParameterInfoHandler.kt | 7 ++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/analysis/api/utils/CallParameterInfoProvider.kt b/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/analysis/api/utils/CallParameterInfoProvider.kt index 965b75006a63..1034eb64710d 100644 --- a/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/analysis/api/utils/CallParameterInfoProvider.kt +++ b/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/analysis/api/utils/CallParameterInfoProvider.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.idea.base.analysis.api.utils import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.components.KaSubtypingErrorTypePolicy import org.jetbrains.kotlin.analysis.api.signatures.KtFunctionLikeSignature import org.jetbrains.kotlin.analysis.api.signatures.KtVariableLikeSignature import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin @@ -18,19 +19,23 @@ import org.jetbrains.kotlin.util.OperatorNameConventions object CallParameterInfoProvider { /** - * Returns true when there is an argument before current that is mapped to a parameter with different type. + * Returns `true` when there is an argument before the current one that is mapped to a parameter with a different type. + * + * If error types should be ignored when checking for type mismatches, please specify [KaSubtypingErrorTypePolicy.LENIENT] as the + * [subtypingErrorTypePolicy]. */ context(KtAnalysisSession) fun hasTypeMismatchBeforeCurrent( sourceElement: KtElement, argumentMapping: Map>, currentArgumentIndex: Int, + subtypingErrorTypePolicy: KaSubtypingErrorTypePolicy = KaSubtypingErrorTypePolicy.STRICT, ): Boolean { val argumentExpressionsBeforeCurrent = getArgumentOrIndexExpressions(sourceElement).take(currentArgumentIndex).filterNotNull() for (argumentExpression in argumentExpressionsBeforeCurrent) { val parameterForArgument = argumentMapping[argumentExpression] ?: continue val argumentType = argumentExpression.getKtType() ?: error("Argument should have a KtType") - if (argumentType.isNotSubTypeOf(parameterForArgument.returnType)) { + if (argumentType.isNotSubTypeOf(parameterForArgument.returnType, subtypingErrorTypePolicy)) { return true } } diff --git a/plugins/kotlin/fir/src/org/jetbrains/kotlin/idea/parameterInfo/KotlinHighLevelFunctionParameterInfoHandler.kt b/plugins/kotlin/fir/src/org/jetbrains/kotlin/idea/parameterInfo/KotlinHighLevelFunctionParameterInfoHandler.kt index c98e8baa7046..c236e4482fa8 100644 --- a/plugins/kotlin/fir/src/org/jetbrains/kotlin/idea/parameterInfo/KotlinHighLevelFunctionParameterInfoHandler.kt +++ b/plugins/kotlin/fir/src/org/jetbrains/kotlin/idea/parameterInfo/KotlinHighLevelFunctionParameterInfoHandler.kt @@ -13,6 +13,7 @@ import com.intellij.ui.JBColor import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.analyze import org.jetbrains.kotlin.analysis.api.annotations.annotations +import org.jetbrains.kotlin.analysis.api.components.KaSubtypingErrorTypePolicy import org.jetbrains.kotlin.analysis.api.renderer.types.impl.KtTypeRendererForSource import org.jetbrains.kotlin.analysis.api.signatures.KtVariableLikeSignature import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol @@ -202,7 +203,11 @@ abstract class KotlinHighLevelParameterInfoWithCallHandlerBase Date: Wed, 24 Apr 2024 18:20:21 +0200 Subject: [PATCH 17/21] [kotlin][k2] Avoid printing error types in call chain hints provider - With the changes in KT-67514, the `errorType.kt` test for `KtCallChainHintsProvider` started to fail because error types were now included in the type chain. Previously, an error type was implicitly filtered out by the `isEqualTo` check, where the expression's error type was trivially equal to the previous expression's type. - The test failure was caused by an assertion in `PresentationTreeBuilderImpl.complete` because the presentation added to the sink had no text elements, given that `printKtType` prints nothing for an error type. ^KT-67514 GitOrigin-RevId: 82d528a456c8fd5cc041e3bb41aae54df7c2a036 --- .../idea/k2/codeinsight/hints/KtCallChainHintsProvider.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/kotlin/code-insight/kotlin.code-insight.k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/hints/KtCallChainHintsProvider.kt b/plugins/kotlin/code-insight/kotlin.code-insight.k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/hints/KtCallChainHintsProvider.kt index b9f1e3f2a046..a6f88b5bca22 100644 --- a/plugins/kotlin/code-insight/kotlin.code-insight.k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/hints/KtCallChainHintsProvider.kt +++ b/plugins/kotlin/code-insight/kotlin.code-insight.k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/hints/KtCallChainHintsProvider.kt @@ -6,6 +6,7 @@ import com.intellij.codeInsight.hints.declarative.InlineInlayPosition import com.intellij.psi.PsiElement import com.intellij.psi.PsiWhiteSpace import org.jetbrains.kotlin.analysis.api.analyze +import org.jetbrains.kotlin.analysis.api.types.KtErrorType import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.psi.KtArrayAccessExpression import org.jetbrains.kotlin.psi.KtCallExpression @@ -49,6 +50,8 @@ class KtCallChainHintsProvider : AbstractKtInlayHintsProvider() { } } .map { it.first } + // Error types cannot be printed by `printKtType`, so we shouldn't include them in the chain. + .filter { it.type !is KtErrorType } .toList() if (someTypeIsUnknown) return //if (isChainUnacceptable(reversedChain)) return From 9955fd0494b02072580f0490df4a25193fa967ad Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 1 May 2024 00:04:29 +0200 Subject: [PATCH 18/21] [psi] pass originals for UpdateAddedFileProcessor In all existing `UpdateAddedFileProcessor` originalElement was unused, probably because it was always null. To update kotlin packages only when they were aligned initially, it's necessary to have this original information. ^IDEA-352804 fixed GitOrigin-RevId: 0e72fe47351605d1758daef5855742a81c18f65f --- .../refactoring/copy/CopyClassesHandler.java | 2 +- platform/core-impl/api-dump-unreviewed.txt | 2 +- .../psi/impl/file/PsiDirectoryImpl.java | 4 +- .../impl/file/UpdateAddedFileProcessor.java | 8 +++- platform/lang-impl/api-dump-unreviewed.txt | 1 + .../copy/CopyFilesOrDirectoriesHandler.java | 40 +++++++++++++------ 6 files changed, 38 insertions(+), 19 deletions(-) diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/copy/CopyClassesHandler.java b/java/java-impl-refactorings/src/com/intellij/refactoring/copy/CopyClassesHandler.java index cd11aaf787bc..66004fe7b943 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/copy/CopyClassesHandler.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/copy/CopyClassesHandler.java @@ -451,7 +451,7 @@ public final class CopyClassesHandler extends CopyHandlerDelegateBase implements }); dumbService.completeJustSubmittedTasks(); - CopyFilesOrDirectoriesHandler.updateAddedFiles(createdFiles); + CopyFilesOrDirectoriesHandler.updateAddedFiles(createdFiles, filesToProcess); runWriteAction(project, RefactoringBundle.message("copy.update.references"), progress -> { final Set rebindExpressions = new HashSet<>(); diff --git a/platform/core-impl/api-dump-unreviewed.txt b/platform/core-impl/api-dump-unreviewed.txt index 87acc094f049..6fa970822682 100644 --- a/platform/core-impl/api-dump-unreviewed.txt +++ b/platform/core-impl/api-dump-unreviewed.txt @@ -3158,7 +3158,7 @@ a:com.intellij.psi.impl.file.UpdateAddedFileProcessor - a:canProcessElement(com.intellij.psi.PsiFile):Z - s:forElement(com.intellij.psi.PsiFile):com.intellij.psi.impl.file.UpdateAddedFileProcessor - a:update(com.intellij.psi.PsiFile,com.intellij.psi.PsiFile):V -- s:updateAddedFiles(java.lang.Iterable):V +- s:updateAddedFiles(java.lang.Iterable,java.lang.Iterable):V com.intellij.psi.impl.file.impl.FileManager - a:cleanupForNextTest():V - a:createFileViewProvider(com.intellij.openapi.vfs.VirtualFile,Z):com.intellij.psi.FileViewProvider diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java index cf128969073b..d71490d92def 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java @@ -353,7 +353,7 @@ public class PsiDirectoryImpl extends PsiElementBase implements PsiDirectory, Qu if (UPDATE_ADDED_FILE_KEY.get(this, true)) { DumbService.getInstance(getProject()).completeJustSubmittedTasks(); PsiFile copyPsi = findCopy(copyVFile, vFile); - UpdateAddedFileProcessor.updateAddedFiles(Collections.singletonList(copyPsi)); + UpdateAddedFileProcessor.updateAddedFiles(Collections.singletonList(copyPsi), Collections.singletonList(originalFile)); return copyPsi; } return findCopy(copyVFile, vFile); @@ -432,7 +432,7 @@ public class PsiDirectoryImpl extends PsiElementBase implements PsiDirectory, Qu PsiFile newFile = myManager.findFile(newVFile); if (newFile == null) throw new IncorrectOperationException("Could not find file " + newVFile); - UpdateAddedFileProcessor.updateAddedFiles(Collections.singletonList(newFile)); + UpdateAddedFileProcessor.updateAddedFiles(Collections.singletonList(newFile), Collections.singletonList(originalFile)); return newFile; } catch (IOException e) { diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/UpdateAddedFileProcessor.java b/platform/core-impl/src/com/intellij/psi/impl/file/UpdateAddedFileProcessor.java index 89250bbd30d5..adb584c670ba 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/file/UpdateAddedFileProcessor.java +++ b/platform/core-impl/src/com/intellij/psi/impl/file/UpdateAddedFileProcessor.java @@ -11,6 +11,8 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Iterator; + /** * @author Maxim.Mossienko */ @@ -30,15 +32,17 @@ public abstract class UpdateAddedFileProcessor { return null; } - public static void updateAddedFiles(@NotNull Iterable copyPsis) throws IncorrectOperationException { + public static void updateAddedFiles(@NotNull Iterable copyPsis, @Nullable Iterable originals) throws IncorrectOperationException { + Iterator iterator = originals != null ? originals.iterator() : null; for (PsiFile copyPsi : copyPsis) { + PsiFile original = iterator != null ? (iterator.hasNext() ? iterator.next() : null) : null; UpdateAddedFileProcessor processor = forElement(copyPsi); if (processor != null) { TreeElement tree = (TreeElement)SourceTreeToPsiMap.psiElementToTree(copyPsi); if (tree != null) { ChangeUtil.encodeInformation(tree); } - processor.update(copyPsi, null); + processor.update(copyPsi, original); if (tree != null) { ChangeUtil.decodeInformation(tree); } diff --git a/platform/lang-impl/api-dump-unreviewed.txt b/platform/lang-impl/api-dump-unreviewed.txt index 64f381f6879e..3effcd372321 100644 --- a/platform/lang-impl/api-dump-unreviewed.txt +++ b/platform/lang-impl/api-dump-unreviewed.txt @@ -25917,6 +25917,7 @@ c:com.intellij.refactoring.copy.CopyFilesOrDirectoriesHandler - getActionName(com.intellij.psi.PsiElement[]):java.lang.String - s:resolveDirectory(com.intellij.psi.PsiDirectory):com.intellij.psi.PsiDirectory - s:updateAddedFiles(java.util.List):V +- s:updateAddedFiles(java.util.List,java.util.List):V f:com.intellij.refactoring.copy.CopyHandler - s:canClone(com.intellij.psi.PsiElement[]):Z - s:canCopy(com.intellij.psi.PsiElement[]):Z diff --git a/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesHandler.java b/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesHandler.java index 8c66a01bbaa3..37257749b013 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesHandler.java +++ b/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesHandler.java @@ -239,6 +239,7 @@ public class CopyFilesOrDirectoriesHandler extends CopyHandlerDelegateBase imple try { final int[] choice = files.length > 1 || files[0].isDirectory() ? new int[]{-1} : null; List added = new ArrayList<>(); + List originals = new ArrayList<>(); PsiManager manager = PsiManager.getInstance(project); List items = new ArrayList<>(files.length); for (VirtualFile file : files) { @@ -249,12 +250,12 @@ public class CopyFilesOrDirectoriesHandler extends CopyHandlerDelegateBase imple } items.add(item); } - copyToDirectory(items, newName, targetDirectory, choice, title, added); + copyToDirectory(items, newName, targetDirectory, choice, title, added, originals); if (!added.isEmpty()) { DumbService.getInstance(project).completeJustSubmittedTasks(); - updateAddedFiles(added); + updateAddedFiles(added, originals); if (openInEditor) { PsiFile firstFile = added.get(0); CopyHandler.updateSelectionInActiveProjectView(firstFile, project, doClone); @@ -269,16 +270,24 @@ public class CopyFilesOrDirectoriesHandler extends CopyHandlerDelegateBase imple } } + /** + * @deprecated it's better to call {@link CopyFilesOrDirectoriesHandler#updateAddedFiles(List, List)} to provide original elements + */ + @Deprecated public static void updateAddedFiles(List added) { + updateAddedFiles(added, null); + } + + public static void updateAddedFiles(List added, @Nullable List originals) { if (added.isEmpty()) return; Project project = added.get(0).getProject(); DumbService dumbService = DumbService.getInstance(project); if (Registry.is("run.refactorings.under.progress")) { ApplicationManagerEx.getApplicationEx().runWriteActionWithCancellableProgressInDispatchThread( - RefactoringBundle.message("progress.title.update.added.files"), project, null, pi -> dumbService.runWithAlternativeResolveEnabled(() -> UpdateAddedFileProcessor.updateAddedFiles(added))); + RefactoringBundle.message("progress.title.update.added.files"), project, null, pi -> dumbService.runWithAlternativeResolveEnabled(() -> UpdateAddedFileProcessor.updateAddedFiles(added, originals))); } else { - WriteAction.run(() -> dumbService.runWithAlternativeResolveEnabled(() -> UpdateAddedFileProcessor.updateAddedFiles(added))); + WriteAction.run(() -> dumbService.runWithAlternativeResolveEnabled(() -> UpdateAddedFileProcessor.updateAddedFiles(added, originals))); } } @@ -307,12 +316,13 @@ public class CopyFilesOrDirectoriesHandler extends CopyHandlerDelegateBase imple int @Nullable [] choice, @Nullable @NlsContexts.Command String title) throws IncorrectOperationException, IOException { ArrayList added = new ArrayList<>(); - copyToDirectory(Collections.singletonList(elementToCopy), newName, targetDirectory, choice, title, added); + ArrayList originals = new ArrayList<>(); + copyToDirectory(Collections.singletonList(elementToCopy), newName, targetDirectory, choice, title, added, originals); if (added.isEmpty()) { return null; } DumbService.getInstance(elementToCopy.getProject()).completeJustSubmittedTasks(); - updateAddedFiles(added); + updateAddedFiles(added, originals); return added.get(0); } @@ -321,7 +331,8 @@ public class CopyFilesOrDirectoriesHandler extends CopyHandlerDelegateBase imple @NotNull PsiDirectory targetDirectory, int @Nullable [] choice, @Nullable @NlsContexts.Command String title, - @NotNull List added) throws IncorrectOperationException, IOException { + @NotNull List added, + @NotNull List originals) throws IncorrectOperationException, IOException { MultiMap existingFiles = new MultiMap<>(); ApplicationEx app = ApplicationManagerEx.getApplicationEx(); if (Registry.is("run.refactorings.under.progress")) { @@ -329,7 +340,7 @@ public class CopyFilesOrDirectoriesHandler extends CopyHandlerDelegateBase imple Consumer copyAction = pi -> { try { for (PsiFileSystemItem elementToCopy : elementsToCopy) { - copyToDirectoryUnderProgress(elementToCopy, newName, targetDirectory, added, existingFiles, pi); + copyToDirectoryUnderProgress(elementToCopy, newName, targetDirectory, added, originals, existingFiles, pi); } } catch (Throwable e) { @@ -349,7 +360,7 @@ public class CopyFilesOrDirectoriesHandler extends CopyHandlerDelegateBase imple .withName(title) .run(() -> { for (PsiFileSystemItem elementToCopy : elementsToCopy) { - copyToDirectoryUnderProgress(elementToCopy, newName, targetDirectory, added, existingFiles, null); + copyToDirectoryUnderProgress(elementToCopy, newName, targetDirectory, added, originals, existingFiles, null); } }); } @@ -446,15 +457,17 @@ public class CopyFilesOrDirectoriesHandler extends CopyHandlerDelegateBase imple /** * @param elementToCopy PsiFile or PsiDirectory - * @param newName can be not null only if elements.length == 1 - * @param added a collection of files to be updated + * @param newName can be not null only if elements.length == 1 + * @param added a collection of files to be updated + * @param originals a collection of files which were updated * @param existingFiles a collection of files which already exist in the target - * @param pi progress indicator if any + * @param pi progress indicator if any */ private static void copyToDirectoryUnderProgress(PsiFileSystemItem elementToCopy, @Nullable String newName, @NotNull PsiDirectory targetDirectory, @NotNull List added, + List originals, MultiMap existingFiles, @Nullable ProgressIndicator pi) throws IncorrectOperationException, IOException { if (pi != null) { @@ -469,6 +482,7 @@ public class CopyFilesOrDirectoriesHandler extends CopyHandlerDelegateBase imple existingFiles.putValue(targetDirectory, file); return; } + originals.add(file); ((PsiDirectoryImpl)targetDirectory).executeWithUpdatingAddedFilesDisabled(() -> ContainerUtil.addIfNotNull(added, targetDirectory.copyFileFrom(name, file))); } else if (elementToCopy instanceof PsiDirectory directory) { @@ -496,7 +510,7 @@ public class CopyFilesOrDirectoriesHandler extends CopyHandlerDelegateBase imple LOG.info("invalid file: " + file.getExtension()); continue; } - copyToDirectoryUnderProgress(item, null, subdirectory, added, existingFiles, pi); + copyToDirectoryUnderProgress(item, null, subdirectory, added, originals, existingFiles, pi); } } else { From b81473222713fe1fe1d2812b0df877a0dc4e19f1 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 1 May 2024 00:30:41 +0200 Subject: [PATCH 19/21] [kotlin] k2: bindToElement should keep infix/operator expressions untouched ^KTIJ-29781 fixed GitOrigin-RevId: 72c7f8aa48842827729b2c5319bed6311d1d2720 --- .../refactoring/bindToFqn/functionCall/Operator.kt | 10 ++++++++++ .../bindToFqn/functionCall/Operator.kt.after | 10 ++++++++++ .../idea/k2/refactoring/K2ReferenceMutateService.kt | 9 +++++---- .../bindToElement/AbstractK2BindToElementTest.kt | 2 ++ .../bindToElement/K2BindToElementTestGenerated.java | 13 +++++++++++++ .../bindToElement/K2BindToFqnTestGenerated.java | 13 +++++++++++++ 6 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 plugins/kotlin/idea/tests/testData/refactoring/bindToFqn/functionCall/Operator.kt create mode 100644 plugins/kotlin/idea/tests/testData/refactoring/bindToFqn/functionCall/Operator.kt.after diff --git a/plugins/kotlin/idea/tests/testData/refactoring/bindToFqn/functionCall/Operator.kt b/plugins/kotlin/idea/tests/testData/refactoring/bindToFqn/functionCall/Operator.kt new file mode 100644 index 000000000000..1cb58650c4a9 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/bindToFqn/functionCall/Operator.kt @@ -0,0 +1,10 @@ +// BIND_TO test.B.plus +package test + +class B { + operator fun plus(b: B) { } + + fun m() { + val v = this + this + } +} diff --git a/plugins/kotlin/idea/tests/testData/refactoring/bindToFqn/functionCall/Operator.kt.after b/plugins/kotlin/idea/tests/testData/refactoring/bindToFqn/functionCall/Operator.kt.after new file mode 100644 index 000000000000..1cb58650c4a9 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/bindToFqn/functionCall/Operator.kt.after @@ -0,0 +1,10 @@ +// BIND_TO test.B.plus +package test + +class B { + operator fun plus(b: B) { } + + fun m() { + val v = this + this + } +} diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/K2ReferenceMutateService.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/K2ReferenceMutateService.kt index 0f77f62ab181..71e0ed40dc88 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/K2ReferenceMutateService.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/K2ReferenceMutateService.kt @@ -203,13 +203,14 @@ internal class K2ReferenceMutateService : KtReferenceMutateServiceBase() { return ReplaceResult(newNameExpr.replaceWithQualified(fqName, newNameExpr), false) } - private fun KtSimpleNameExpression.replaceShortName(fqName: FqName, targetElement: PsiElement?): ReplaceResult { + private fun KtSimpleNameExpression.replaceShortName(fqName: FqName, targetElement: PsiElement? ): ReplaceResult { val psiFactory = KtPsiFactory(project) val shortName = fqName.shortName().asString() - val isInfixFun = targetElement is KtNamedFunction && targetElement.modifierList?.hasModifier(KtTokens.INFIX_KEYWORD) == true - val newNameExpression = if (isInfixFun) psiFactory.createOperationName(shortName) else psiFactory.createSimpleName(shortName) + val isOperator = targetElement is KtNamedFunction && targetElement.hasModifier(KtTokens.OPERATOR_KEYWORD) + val isInfixFun = targetElement is KtNamedFunction && targetElement.hasModifier(KtTokens.INFIX_KEYWORD) == true + val newNameExpression = if (isInfixFun || isOperator) psiFactory.createOperationName(shortName) else psiFactory.createSimpleName(shortName) val newSimpleName = replaced(newNameExpression) - val isUnQualifiable = targetElement?.isCallableAsExtensionFunction() == true + val isUnQualifiable = targetElement?.isCallableAsExtensionFunction() == true || isOperator || isInfixFun return if (isUnQualifiable || fqName.parent() == FqName.ROOT) { newSimpleName.containingKtFile.addImport(fqName) ReplaceResult(newSimpleName, isUnQualifiable) diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/bindToElement/AbstractK2BindToElementTest.kt b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/bindToElement/AbstractK2BindToElementTest.kt index 2aa40c1e0259..68e1c2fa82c0 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/bindToElement/AbstractK2BindToElementTest.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/bindToElement/AbstractK2BindToElementTest.kt @@ -4,6 +4,7 @@ package org.jetbrains.kotlin.idea.k2.refactoring.bindToElement import com.intellij.psi.JavaPsiFacade import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile +import com.intellij.psi.PsiMethod import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.util.parentOfType import org.jetbrains.kotlin.analysis.api.KtAllowAnalysisOnEdt @@ -37,5 +38,6 @@ abstract class AbstractK2BindToElementTest : AbstractK2BindToTest() { return JavaPsiFacade.getInstance(myFixture.project).findClass(nameToBind, projectScope) ?: KotlinTopLevelFunctionFqnNameIndex[nameToBind, myFixture.project, projectScope].firstOrNull() ?: KotlinTopLevelPropertyFqnNameIndex[nameToBind, myFixture.project, projectScope].firstOrNull() + ?: JavaPsiFacade.getInstance(myFixture.project).findClass(nameToBind.substringBeforeLast("."), projectScope)?.findMethodsByName(nameToBind.substringAfterLast("."))?.get(0) as PsiMethod } } \ No newline at end of file diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/bindToElement/K2BindToElementTestGenerated.java b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/bindToElement/K2BindToElementTestGenerated.java index 6e406a14ae02..5a5e19903184 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/bindToElement/K2BindToElementTestGenerated.java +++ b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/bindToElement/K2BindToElementTestGenerated.java @@ -179,6 +179,19 @@ public abstract class K2BindToElementTestGenerated extends AbstractK2BindToEleme } } + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../../idea/tests/testData/refactoring/bindToFqn/functionCall") + public static class FunctionCall extends AbstractK2BindToElementTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("Operator.kt") + public void testOperator() throws Exception { + runTest("../../idea/tests/testData/refactoring/bindToFqn/functionCall/Operator.kt"); + } + } + @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("../../idea/tests/testData/refactoring/bindToFqn/importReference") public static class ImportReference extends AbstractK2BindToElementTest { diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/bindToElement/K2BindToFqnTestGenerated.java b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/bindToElement/K2BindToFqnTestGenerated.java index 1b7b674eac39..1d5631e5c7d9 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/bindToElement/K2BindToFqnTestGenerated.java +++ b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/bindToElement/K2BindToFqnTestGenerated.java @@ -177,6 +177,19 @@ public abstract class K2BindToFqnTestGenerated extends AbstractK2BindToFqnTest { } } + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../../idea/tests/testData/refactoring/bindToFqn/functionCall") + public static class FunctionCall extends AbstractK2BindToFqnTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("Operator.kt") + public void testOperator() throws Exception { + runTest("../../idea/tests/testData/refactoring/bindToFqn/functionCall/Operator.kt"); + } + } + @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("../../idea/tests/testData/refactoring/bindToFqn/importReference") public static class ImportReference extends AbstractK2BindToFqnTest { From 2ff3c63ecba13a068deb17efd92177b90dd4661c Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 1 May 2024 00:39:05 +0200 Subject: [PATCH 20/21] [kotlin] k2: implement copy refactoring - implement `KotlinUpdateAddedFileProcessor` to update package statements - reuse move refactoring: to do so and keep the v2 plugin model, it was necessary to invert dependencies (and make them consistent with other refactorings modules) ^KTIJ-28018 fixed GitOrigin-RevId: b71a7ea9cae5c1f2a42771674ee065ee0460d0c1 --- .../kotlin/idea/core/packageUtils.kt | 3 +- .../copy/CopyKotlinDeclarationsHandler.kt | 121 +------ .../idea/refactoring/kotlinRefactoringUtil.kt | 8 - .../idea/refactoring/copy/AbstractCopyTest.kt | 5 +- .../copy/AbstractMultiModuleCopyTest.kt | 2 + .../copyClassCaretInside/before/foo/test.kt | 2 +- .../copyClassToSamePackageWithRename.test | 3 +- .../after/bar/test2.k2.kt | 5 + .../refactoring/copy/kt18149/kt18149.test | 3 +- .../conflicts.k2.txt | 1 + .../AbstractCopyKotlinDeclarationsHandler.kt | 143 +++++++++ .../copy/CopyKotlinDeclarationDialog.kt | 7 +- .../kotlinCommonRefactoringUtil.kt | 5 + .../kotlin.refactorings.introduce.k2.xml | 3 - .../kotlin.refactorings.k2.iml | 1 + .../resources/kotlin.refactorings.k2.xml | 9 + .../copy/CopyKotlinDeclarationsHandler.kt | 294 ++++++++++++++++++ .../copy/KotlinUpdateAddedFileProcessor.kt | 23 ++ .../kotlin/idea/k2/refactoring/utils.kt | 21 -- .../kotlin.refactorings.move.k2.iml | 1 - .../resources/kotlin.refactorings.move.k2.xml | 3 - .../move/descriptor/K2MoveTargetDescriptor.kt | 2 +- .../move/processor/K2MoveRenameUsageInfo.kt | 32 +- .../move/processor/moveConflictUtil.kt | 6 +- .../k2/refactoring/move/processor/moveUtil.kt | 26 +- .../kotlin.refactorings.tests.k2.iml | 2 + .../k2/refactoring/copy/AbstractK2CopyTest.kt | 34 ++ .../refactoring/copy/K2CopyTestGenerated.java | 230 ++++++++++++++ .../copy/K2MultiModuleCopyTestGenerated.java | 40 +++ .../GenerateK2RefactoringsTests.kt | 12 + 30 files changed, 866 insertions(+), 181 deletions(-) create mode 100644 plugins/kotlin/idea/tests/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/bar/test2.k2.kt create mode 100644 plugins/kotlin/idea/tests/testData/refactoring/copyMultiModule/internalReferencesToAnotherModule2/conflicts.k2.txt create mode 100644 plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/copy/AbstractCopyKotlinDeclarationsHandler.kt rename plugins/kotlin/{idea => refactorings/kotlin.refactorings.common}/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationDialog.kt (96%) create mode 100644 plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/copy/CopyKotlinDeclarationsHandler.kt create mode 100644 plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/copy/KotlinUpdateAddedFileProcessor.kt create mode 100644 plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/copy/AbstractK2CopyTest.kt create mode 100644 plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/copy/K2CopyTestGenerated.java create mode 100644 plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/copy/K2MultiModuleCopyTestGenerated.java diff --git a/plugins/kotlin/frontend-independent/src/org/jetbrains/kotlin/idea/core/packageUtils.kt b/plugins/kotlin/frontend-independent/src/org/jetbrains/kotlin/idea/core/packageUtils.kt index bf3fdfbfa8fa..70b5dbb77884 100644 --- a/plugins/kotlin/frontend-independent/src/org/jetbrains/kotlin/idea/core/packageUtils.kt +++ b/plugins/kotlin/frontend-independent/src/org/jetbrains/kotlin/idea/core/packageUtils.kt @@ -55,7 +55,8 @@ private fun PsiDirectory.getNonRootFqNameOrNull(): FqName? = getPackage()?.quali fun PsiFile.getFqNameByDirectory(): FqName { val singleFileSourcesTracker = SingleFileSourcesTracker.getInstance(project) - val singleFileSourcePackageName = singleFileSourcesTracker.getPackageNameForSingleFileSource(virtualFile) + val vFile = virtualFile ?: return FqName.ROOT + val singleFileSourcePackageName = singleFileSourcesTracker.getPackageNameForSingleFileSource(vFile) singleFileSourcePackageName?.let { return FqName(it) } return parent?.getNonRootFqNameOrNull() ?: FqName.ROOT } diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt index b3a746cc691e..73e58559ff41 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt @@ -7,7 +7,6 @@ import com.intellij.openapi.application.runReadAction import com.intellij.openapi.application.runWriteAction import com.intellij.openapi.project.Project import com.intellij.openapi.ui.Messages -import com.intellij.openapi.util.Key import com.intellij.openapi.vfs.* import com.intellij.psi.* import com.intellij.psi.search.LocalSearchScope @@ -15,14 +14,10 @@ import com.intellij.psi.search.searches.ReferencesSearch import com.intellij.refactoring.BaseRefactoringProcessor import com.intellij.refactoring.RefactoringBundle import com.intellij.refactoring.copy.CopyFilesOrDirectoriesDialog -import com.intellij.refactoring.copy.CopyFilesOrDirectoriesHandler -import com.intellij.refactoring.copy.CopyHandlerDelegateBase import com.intellij.refactoring.util.MoveRenameUsageInfo import com.intellij.usageView.UsageInfo import com.intellij.util.IncorrectOperationException import com.intellij.util.containers.MultiMap -import org.jetbrains.annotations.TestOnly -import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.base.util.quoteIfNeeded import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedRefactoringRequests import org.jetbrains.kotlin.idea.core.getFqNameWithImplicitPrefix @@ -38,122 +33,14 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtNamedDeclaration -import org.jetbrains.kotlin.psi.UserDataProperty import org.jetbrains.kotlin.psi.psiUtil.isAncestor -import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf -import org.jetbrains.kotlin.utils.ifEmpty -class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { - companion object { - - private val commandName get() = RefactoringBundle.message("copy.handler.copy.files.directories") - - @set:TestOnly - var Project.newName: String? by UserDataProperty(Key.create("NEW_NAME")) - - private fun PsiElement.getCopyableElement() = - parentsWithSelf.firstOrNull { it is KtFile || (it is KtNamedDeclaration && it.parent is KtFile) } as? KtElement - - private fun PsiElement.getDeclarationsToCopy(): List = when (val declarationOrFile = getCopyableElement()) { - is KtFile -> declarationOrFile.declarations.filterIsInstance().ifEmpty { listOf(declarationOrFile) } - is KtNamedDeclaration -> listOf(declarationOrFile) - else -> emptyList() - } - } - - private val copyFilesHandler by lazy { CopyFilesOrDirectoriesHandler() } - - private fun getSourceFiles(elements: Array): Array? { - return elements - .map { it.containingFile ?: it as? PsiFileSystemItem ?: return null } - .toTypedArray() - } - - private fun canCopyFiles(elements: Array, fromUpdate: Boolean): Boolean { - val sourceFiles = getSourceFiles(elements) ?: return false - if (!sourceFiles.any { it is KtFile }) return false - return copyFilesHandler.canCopy(sourceFiles, fromUpdate) - } - - private fun canCopyDeclarations(elements: Array): Boolean { - val containingFile = - elements - .flatMap { it.getDeclarationsToCopy().ifEmpty { return false } } - .distinctBy { it.containingFile } - .singleOrNull() - ?.containingFile ?: return false - return containingFile.sourceRoot != null - } - - override fun canCopy(elements: Array, fromUpdate: Boolean): Boolean { - return canCopyDeclarations(elements) || canCopyFiles(elements, fromUpdate) - } - - enum class ExistingFilePolicy { - APPEND, OVERWRITE, SKIP - } - - private fun getOrCreateTargetFile( - originalFile: KtFile, - targetDirectory: PsiDirectory, - targetFileName: String - ): KtFile? { - val existingFile = targetDirectory.findFile(targetFileName) - if (existingFile == originalFile) return null - if (existingFile != null) when (getFilePolicy(existingFile, targetFileName, targetDirectory)) { - ExistingFilePolicy.APPEND -> { - } - ExistingFilePolicy.OVERWRITE -> runWriteAction { existingFile.delete() } - ExistingFilePolicy.SKIP -> return null - } - return runWriteAction { - if (existingFile != null && existingFile.isValid) { - existingFile as KtFile - } else { - createKotlinFile(targetFileName, targetDirectory) - } - } - } - - private fun getFilePolicy( - existingFile: PsiFile?, +class CopyKotlinDeclarationsHandler : AbstractCopyKotlinDeclarationsHandler() { + override fun createFile( targetFileName: String, targetDirectory: PsiDirectory - ): ExistingFilePolicy { - val message = KotlinBundle.message( - "text.file.0.already.exists.in.1", - targetFileName, - targetDirectory.virtualFile.path - ) - - return if (existingFile !is KtFile) { - if (isUnitTestMode()) return ExistingFilePolicy.OVERWRITE - - val answer = Messages.showOkCancelDialog( - message, - commandName, - KotlinBundle.message("action.text.overwrite"), - KotlinBundle.message("action.text.cancel"), - Messages.getQuestionIcon() - ) - if (answer == Messages.OK) ExistingFilePolicy.OVERWRITE else ExistingFilePolicy.SKIP - } else { - if (isUnitTestMode()) return ExistingFilePolicy.APPEND - - val answer = Messages.showYesNoCancelDialog( - message, - commandName, - KotlinBundle.message("action.text.append"), - KotlinBundle.message("action.text.overwrite"), - KotlinBundle.message("action.text.cancel"), - Messages.getQuestionIcon() - ) - when (answer) { - Messages.YES -> ExistingFilePolicy.APPEND - Messages.NO -> ExistingFilePolicy.OVERWRITE - else -> ExistingFilePolicy.SKIP - } - } + ): KtFile { + return createKotlinFile(targetFileName, targetDirectory) } private data class TargetData( diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt index b524a6d7e7a4..b36621b3e183 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt @@ -20,11 +20,9 @@ import com.intellij.openapi.util.NlsContexts import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.* import com.intellij.psi.util.PsiTreeUtil -import com.intellij.refactoring.BaseRefactoringProcessor.ConflictsInTestsException import com.intellij.refactoring.changeSignature.ChangeSignatureUtil import com.intellij.refactoring.listeners.RefactoringEventData import com.intellij.refactoring.listeners.RefactoringEventListener -import com.intellij.refactoring.ui.ConflictsDialog import com.intellij.refactoring.util.ConflictsUtil import com.intellij.refactoring.util.RefactoringUIUtil import com.intellij.util.VisibilityUtil @@ -53,11 +51,9 @@ import org.jetbrains.kotlin.idea.refactoring.memberInfo.KtPsiClassWrapper import org.jetbrains.kotlin.idea.refactoring.rename.canonicalRender import org.jetbrains.kotlin.idea.roots.isOutsideKotlinAwareSourceRoot import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers -import org.jetbrains.kotlin.idea.util.application.isUnitTestMode import org.jetbrains.kotlin.idea.util.liftToExpected import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.renderer.DescriptorRenderer @@ -403,10 +399,6 @@ fun invokeOnceOnCommandFinish(action: () -> Unit) { }) } -fun FqNameUnsafe.hasIdentifiersOnly(): Boolean = pathSegments().all { it.asString().quoteIfNeeded().isIdentifier() } - -fun FqName.hasIdentifiersOnly(): Boolean = pathSegments().all { it.asString().quoteIfNeeded().isIdentifier() } - fun PsiNamedElement.isInterfaceClass(): Boolean = when (this) { is KtClass -> isInterface() is PsiClass -> isInterface diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/refactoring/copy/AbstractCopyTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/refactoring/copy/AbstractCopyTest.kt index 830bcb25c98f..536d8636a26b 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/refactoring/copy/AbstractCopyTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/refactoring/copy/AbstractCopyTest.kt @@ -6,18 +6,19 @@ import com.google.gson.JsonObject import com.intellij.openapi.application.runWriteAction import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.isFile import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile import com.intellij.psi.util.PsiTreeUtil import com.intellij.refactoring.PackageWrapper import com.intellij.refactoring.copy.CopyHandler import com.intellij.refactoring.move.moveClassesOrPackages.MultipleRootsMoveDestination +import org.jetbrains.kotlin.idea.base.util.getString import org.jetbrains.kotlin.idea.core.util.toPsiDirectory import org.jetbrains.kotlin.idea.core.util.toPsiFile import org.jetbrains.kotlin.idea.jsonUtils.getNullableString -import org.jetbrains.kotlin.idea.base.util.getString import org.jetbrains.kotlin.idea.refactoring.AbstractMultifileRefactoringTest -import org.jetbrains.kotlin.idea.refactoring.copy.CopyKotlinDeclarationsHandler.Companion.newName +import org.jetbrains.kotlin.idea.refactoring.copy.AbstractCopyKotlinDeclarationsHandler.Companion.newName import org.jetbrains.kotlin.idea.refactoring.runRefactoringTest import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.utils.ifEmpty diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/refactoring/copy/AbstractMultiModuleCopyTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/refactoring/copy/AbstractMultiModuleCopyTest.kt index 94700f8e6879..6447073a2d21 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/refactoring/copy/AbstractMultiModuleCopyTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/refactoring/copy/AbstractMultiModuleCopyTest.kt @@ -12,6 +12,8 @@ abstract class AbstractMultiModuleCopyTest : KotlinMultiFileTestCase() { override fun getTestDataDirectory() = IDEA_TEST_DATA_DIR + //protected open fun isFirPlugin(): Boolean = false + fun doTest(path: String) { val config = loadTestConfiguration(File(path)) diff --git a/plugins/kotlin/idea/tests/testData/refactoring/copy/copyClassCaretInside/before/foo/test.kt b/plugins/kotlin/idea/tests/testData/refactoring/copy/copyClassCaretInside/before/foo/test.kt index 0698c3acf975..d8784bdccb76 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/copy/copyClassCaretInside/before/foo/test.kt +++ b/plugins/kotlin/idea/tests/testData/refactoring/copy/copyClassCaretInside/before/foo/test.kt @@ -1,7 +1,7 @@ package foo class A { - val a: A = A() + val a: A = A() val b: B = B() } diff --git a/plugins/kotlin/idea/tests/testData/refactoring/copy/copyClassToSamePackageWithRename/copyClassToSamePackageWithRename.test b/plugins/kotlin/idea/tests/testData/refactoring/copy/copyClassToSamePackageWithRename/copyClassToSamePackageWithRename.test index 925cde84532d..7d3c6236e31a 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/copy/copyClassToSamePackageWithRename/copyClassToSamePackageWithRename.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/copy/copyClassToSamePackageWithRename/copyClassToSamePackageWithRename.test @@ -1,5 +1,6 @@ { "mainFile": "foo/test.kt", "targetPackage": "foo", - "newName": "X" + "newName": "X", + "enabledInK2": "false" } diff --git a/plugins/kotlin/idea/tests/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/bar/test2.k2.kt b/plugins/kotlin/idea/tests/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/bar/test2.k2.kt new file mode 100644 index 000000000000..a301d069c0db --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/bar/test2.k2.kt @@ -0,0 +1,5 @@ +package boo + +class B { + val b: B = B() +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/copy/kt18149/kt18149.test b/plugins/kotlin/idea/tests/testData/refactoring/copy/kt18149/kt18149.test index 148e0a34c3da..abe6e14604a3 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/copy/kt18149/kt18149.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/copy/kt18149/kt18149.test @@ -1,5 +1,6 @@ { "mainFile": "refactor/copy/test.kt", "targetPackage": "refactor.copy2", - "withRuntime": "true" + "withRuntime": "true", + "enabledInK2": "false"//KTIJ-29780 } diff --git a/plugins/kotlin/idea/tests/testData/refactoring/copyMultiModule/internalReferencesToAnotherModule2/conflicts.k2.txt b/plugins/kotlin/idea/tests/testData/refactoring/copyMultiModule/internalReferencesToAnotherModule2/conflicts.k2.txt new file mode 100644 index 000000000000..4f166b7a2896 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/copyMultiModule/internalReferencesToAnotherModule2/conflicts.k2.txt @@ -0,0 +1 @@ +Property b uses class B which will be inaccessible after move diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/copy/AbstractCopyKotlinDeclarationsHandler.kt b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/copy/AbstractCopyKotlinDeclarationsHandler.kt new file mode 100644 index 000000000000..296b03bb44b7 --- /dev/null +++ b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/copy/AbstractCopyKotlinDeclarationsHandler.kt @@ -0,0 +1,143 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.refactoring.copy + +import com.intellij.openapi.application.runWriteAction +import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.Messages +import com.intellij.openapi.util.Key +import com.intellij.psi.PsiDirectory +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import com.intellij.psi.PsiFileSystemItem +import com.intellij.refactoring.RefactoringBundle +import com.intellij.refactoring.copy.CopyFilesOrDirectoriesHandler +import com.intellij.refactoring.copy.CopyHandlerDelegateBase +import org.jetbrains.annotations.TestOnly +import org.jetbrains.kotlin.idea.base.resources.KotlinBundle +import org.jetbrains.kotlin.idea.util.application.isUnitTestMode +import org.jetbrains.kotlin.idea.util.sourceRoot +import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtNamedDeclaration +import org.jetbrains.kotlin.psi.UserDataProperty +import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf + +abstract class AbstractCopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { + companion object { + + val commandName get() = RefactoringBundle.message("copy.handler.copy.files.directories") + + @set:TestOnly + var Project.newName: String? by UserDataProperty(Key.create("NEW_NAME")) + + fun PsiElement.getCopyableElement() = + parentsWithSelf.firstOrNull { it is KtFile || (it is KtNamedDeclaration && it.parent is KtFile) } as? KtElement + + private fun PsiElement.getDeclarationsToCopy(): List = when (val declarationOrFile = getCopyableElement()) { + is KtFile -> declarationOrFile.declarations.filterIsInstance().ifEmpty { listOf(declarationOrFile) } + is KtNamedDeclaration -> listOf(declarationOrFile) + else -> emptyList() + } + } + + protected val copyFilesHandler by lazy { CopyFilesOrDirectoriesHandler() } + + protected fun getSourceFiles(elements: Array): Array? { + return elements + .map { it.containingFile ?: it as? PsiFileSystemItem ?: return null } + .toTypedArray() + } + + private fun canCopyFiles(elements: Array, fromUpdate: Boolean): Boolean { + val sourceFiles = getSourceFiles(elements) ?: return false + if (!sourceFiles.any { it is KtFile }) return false + return copyFilesHandler.canCopy(sourceFiles, fromUpdate) + } + + protected fun canCopyDeclarations(elements: Array): Boolean { + val containingFile = + elements + .flatMap { it.getDeclarationsToCopy().ifEmpty { return false } } + .distinctBy { it.containingFile } + .singleOrNull() + ?.containingFile ?: return false + return containingFile.sourceRoot != null + } + + override fun canCopy(elements: Array, fromUpdate: Boolean): Boolean { + return canCopyDeclarations(elements) || canCopyFiles(elements, fromUpdate) + } + + enum class ExistingFilePolicy { + APPEND, OVERWRITE, SKIP + } + + protected fun getOrCreateTargetFile( + originalFile: KtFile, + targetDirectory: PsiDirectory, + targetFileName: String + ): KtFile? { + val existingFile = targetDirectory.findFile(targetFileName) + if (existingFile == originalFile) return null + if (existingFile != null) when (getFilePolicy(existingFile, targetFileName, targetDirectory)) { + ExistingFilePolicy.APPEND -> { + } + + ExistingFilePolicy.OVERWRITE -> runWriteAction { existingFile.delete() } + ExistingFilePolicy.SKIP -> return null + } + return runWriteAction { + if (existingFile != null && existingFile.isValid) { + existingFile as KtFile + } else { + createFile(targetFileName, targetDirectory) + } + } + } + + abstract fun createFile( + targetFileName: String, + targetDirectory: PsiDirectory + ): KtFile + + private fun getFilePolicy( + existingFile: PsiFile?, + targetFileName: String, + targetDirectory: PsiDirectory + ): ExistingFilePolicy { + val message = KotlinBundle.message( + "text.file.0.already.exists.in.1", + targetFileName, + targetDirectory.virtualFile.path + ) + + return if (existingFile !is KtFile) { + if (isUnitTestMode()) return ExistingFilePolicy.OVERWRITE + + val answer = Messages.showOkCancelDialog( + message, + commandName, + KotlinBundle.message("action.text.overwrite"), + KotlinBundle.message("action.text.cancel"), + Messages.getQuestionIcon() + ) + if (answer == Messages.OK) ExistingFilePolicy.OVERWRITE else ExistingFilePolicy.SKIP + } else { + if (isUnitTestMode()) return ExistingFilePolicy.APPEND + + val answer = Messages.showYesNoCancelDialog( + message, + commandName, + KotlinBundle.message("action.text.append"), + KotlinBundle.message("action.text.overwrite"), + KotlinBundle.message("action.text.cancel"), + Messages.getQuestionIcon() + ) + when (answer) { + Messages.YES -> ExistingFilePolicy.APPEND + Messages.NO -> ExistingFilePolicy.OVERWRITE + else -> ExistingFilePolicy.SKIP + } + } + } +} \ No newline at end of file diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationDialog.kt b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationDialog.kt similarity index 96% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationDialog.kt rename to plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationDialog.kt index 0326577bb225..5e583030d501 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationDialog.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationDialog.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.refactoring.copy import com.intellij.ide.util.DirectoryChooser @@ -9,6 +9,7 @@ import com.intellij.openapi.ui.Messages import com.intellij.openapi.util.NlsContexts import com.intellij.openapi.util.Pass import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.JavaDirectoryService import com.intellij.psi.PsiDirectory import com.intellij.psi.PsiManager import com.intellij.refactoring.HelpID @@ -27,7 +28,6 @@ import com.intellij.util.ui.UIUtil import org.jetbrains.annotations.Nls import org.jetbrains.annotations.NonNls import org.jetbrains.kotlin.idea.base.resources.KotlinBundle -import org.jetbrains.kotlin.idea.core.getPackage import org.jetbrains.kotlin.idea.refactoring.hasIdentifiersOnly import org.jetbrains.kotlin.idea.refactoring.ui.KotlinDestinationFolderComboBox import org.jetbrains.kotlin.idea.roots.getSuitableDestinationSourceRoots @@ -116,7 +116,7 @@ class CopyKotlinDeclarationDialog( } private val qualifiedName: String - get() = defaultTargetDirectory?.getPackage()?.qualifiedName ?: "" + get() = defaultTargetDirectory?.let { JavaDirectoryService.getInstance()!!.getPackage(it) } ?.qualifiedName ?: "" val newName: String get() = classNameField.text @@ -181,3 +181,4 @@ class CopyKotlinDeclarationDialog( private val RECENTS_KEY = "CopyKotlinDeclarationDialog.RECENTS_KEY" } } + diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/kotlinCommonRefactoringUtil.kt b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/kotlinCommonRefactoringUtil.kt index e51587d11525..feb9eee8791c 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/kotlinCommonRefactoringUtil.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/kotlinCommonRefactoringUtil.kt @@ -24,6 +24,8 @@ import org.jetbrains.kotlin.idea.base.projectStructure.matches import org.jetbrains.kotlin.idea.refactoring.memberInfo.KtPsiClassWrapper import org.jetbrains.kotlin.idea.util.application.isUnitTestMode import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* import java.util.* @@ -323,3 +325,6 @@ fun Project.checkConflictsInteractively( onAccept() } + +fun FqNameUnsafe.hasIdentifiersOnly(): Boolean = pathSegments().all { it.asString().quoteIfNeeded().isIdentifier() } +fun FqName.hasIdentifiersOnly(): Boolean = pathSegments().all { it.asString().quoteIfNeeded().isIdentifier() } \ No newline at end of file diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/resources/kotlin.refactorings.introduce.k2.xml b/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/resources/kotlin.refactorings.introduce.k2.xml index 866ced300e40..3c420a4ff8cf 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/resources/kotlin.refactorings.introduce.k2.xml +++ b/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/resources/kotlin.refactorings.introduce.k2.xml @@ -1,7 +1,4 @@ - - - + \ No newline at end of file diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/resources/kotlin.refactorings.k2.xml b/plugins/kotlin/refactorings/kotlin.refactorings.k2/resources/kotlin.refactorings.k2.xml index dc5ff6cad631..2e032c725c54 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/resources/kotlin.refactorings.k2.xml +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/resources/kotlin.refactorings.k2.xml @@ -2,6 +2,8 @@ messages.KotlinBundle + + @@ -25,6 +27,13 @@ + + + + diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/copy/CopyKotlinDeclarationsHandler.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/copy/CopyKotlinDeclarationsHandler.kt new file mode 100644 index 000000000000..f0ebde0725f3 --- /dev/null +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/copy/CopyKotlinDeclarationsHandler.kt @@ -0,0 +1,294 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. + +package org.jetbrains.kotlin.idea.k2.refactoring.copy + +import com.intellij.ide.util.EditorHelper +import com.intellij.openapi.application.runWriteAction +import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.Messages +import com.intellij.openapi.vfs.* +import com.intellij.psi.* +import com.intellij.psi.search.LocalSearchScope +import com.intellij.psi.search.searches.ReferencesSearch +import com.intellij.refactoring.BaseRefactoringProcessor +import com.intellij.refactoring.MoveDestination +import com.intellij.refactoring.RefactoringBundle +import com.intellij.refactoring.copy.CopyFilesOrDirectoriesDialog +import com.intellij.usageView.UsageInfo +import com.intellij.util.IncorrectOperationException +import com.intellij.util.containers.MultiMap +import org.jetbrains.kotlin.analysis.api.KtAllowAnalysisOnEdt +import org.jetbrains.kotlin.analysis.api.lifetime.allowAnalysisOnEdt +import org.jetbrains.kotlin.idea.base.analysis.api.utils.analyzeInModalWindow +import org.jetbrains.kotlin.idea.base.util.quoteIfNeeded +import org.jetbrains.kotlin.idea.core.getFqNameWithImplicitPrefix +import org.jetbrains.kotlin.idea.core.getFqNameWithImplicitPrefixOrRoot +import org.jetbrains.kotlin.idea.core.packageMatchesDirectoryOrImplicit +import org.jetbrains.kotlin.idea.k2.refactoring.move.descriptor.K2MoveTargetDescriptor +import org.jetbrains.kotlin.idea.k2.refactoring.move.descriptor.K2MoveTargetDescriptor.SourceDirectory +import org.jetbrains.kotlin.idea.k2.refactoring.move.processor.K2MoveRenameUsageInfo.Companion.markInternalUsages +import org.jetbrains.kotlin.idea.k2.refactoring.move.processor.K2MoveRenameUsageInfo.Companion.retargetInternalUsages +import org.jetbrains.kotlin.idea.k2.refactoring.move.processor.K2MoveRenameUsageInfo.Companion.unMarkNonUpdatableUsages +import org.jetbrains.kotlin.idea.k2.refactoring.move.processor.checkModuleDependencyConflictsForInternalUsages +import org.jetbrains.kotlin.idea.k2.refactoring.move.processor.checkVisibilityConflictsForInternalUsages +import org.jetbrains.kotlin.idea.k2.refactoring.move.processor.createCopyTarget +import org.jetbrains.kotlin.idea.k2.refactoring.move.processor.createKotlinFile +import org.jetbrains.kotlin.idea.refactoring.checkConflictsInteractively +import org.jetbrains.kotlin.idea.refactoring.copy.AbstractCopyKotlinDeclarationsHandler +import org.jetbrains.kotlin.idea.refactoring.copy.CopyKotlinDeclarationDialog +import org.jetbrains.kotlin.idea.util.application.executeCommand +import org.jetbrains.kotlin.idea.util.application.isUnitTestMode +import org.jetbrains.kotlin.idea.util.sourceRoot +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtNamedDeclaration + +class CopyKotlinDeclarationsHandler : AbstractCopyKotlinDeclarationsHandler() { + override fun createFile( + targetFileName: String, targetDirectory: PsiDirectory + ): KtFile = createKotlinFile(targetFileName, targetDirectory) + + private data class TargetData( + val openInEditor: Boolean, val newName: String, val targetDirWrapper: K2MoveTargetDescriptor, val targetSourceRoot: VirtualFile? + ) + + private data class SourceData( + val project: Project, + val singleElementToCopy: KtElement?, + val elementsToCopy: List, + val originalFile: KtFile, + val initialTargetDirectory: PsiDirectory + ) + + private fun getTargetData(sourceData: SourceData): TargetData? { + if (isUnitTestMode()) { + val targetSourceRoot: VirtualFile = sourceData.initialTargetDirectory.sourceRoot ?: return null + val newName: String = sourceData.project.newName ?: sourceData.singleElementToCopy?.name ?: sourceData.originalFile.name + if (sourceData.singleElementToCopy != null && newName.isEmpty()) return null + return TargetData( + openInEditor = false, + newName = newName, + targetDirWrapper = sourceData.initialTargetDirectory.toSourceDirectory(), + targetSourceRoot = targetSourceRoot + ) + + } + + val openInEditor: Boolean + val newName: String? + val targetDirWrapper: K2MoveTargetDescriptor? + val targetSourceRoot: VirtualFile? + + val singleNamedSourceElement = sourceData.singleElementToCopy as? KtNamedDeclaration + + if (singleNamedSourceElement !== null) { + val dialog = CopyKotlinDeclarationDialog(singleNamedSourceElement, sourceData.initialTargetDirectory, sourceData.project) + dialog.title = commandName + if (!dialog.showAndGet()) return null + + openInEditor = dialog.openInEditor + newName = dialog.newName + targetDirWrapper = dialog.targetDirectory?.toSourceDirectory(sourceData) + targetSourceRoot = dialog.targetSourceRoot + } else { + val dialog = CopyFilesOrDirectoriesDialog( + arrayOf(sourceData.originalFile), sourceData.initialTargetDirectory, sourceData.project,/*doClone = */false + ) + if (!dialog.showAndGet()) return null + openInEditor = dialog.openInEditor() + newName = dialog.newName + targetDirWrapper = dialog.targetDirectory?.toSourceDirectory() + targetSourceRoot = dialog.targetDirectory?.sourceRoot + } + + if (targetDirWrapper == null || newName == null) return null + + if (sourceData.singleElementToCopy != null && newName.isEmpty()) return null + + return TargetData( + openInEditor = openInEditor, newName = newName, targetDirWrapper = targetDirWrapper, targetSourceRoot = targetSourceRoot + ) + } + + private fun MoveDestination.toSourceDirectory( + sourceData: SourceData + ): SourceDirectory = SourceDirectory(FqName(targetPackage.qualifiedName), getTargetDirectory(sourceData.initialTargetDirectory)) + + private fun PsiDirectory.toSourceDirectory( + ): SourceDirectory = SourceDirectory(getFqNameWithImplicitPrefixOrRoot(), this) + + private fun doCopyFiles(filesToCopy: Array, initialTargetDirectory: PsiDirectory?) { + if (filesToCopy.isEmpty()) return + filesToCopy.first().project.executeCommand(commandName) { + if (copyFilesHandler.canCopy(filesToCopy)) { + copyFilesHandler.doCopy(filesToCopy, initialTargetDirectory) + } + } + } + + @OptIn(KtAllowAnalysisOnEdt::class) + override fun doCopy(elements: Array, defaultTargetDirectory: PsiDirectory?) { + + if (elements.isEmpty()) return + + if (!canCopyDeclarations(elements)) { + val sourceFiles = getSourceFiles(elements) ?: return + return doCopyFiles(sourceFiles, defaultTargetDirectory) + } + + val elementsToCopy = elements.mapNotNull { it.getCopyableElement() } + if (elementsToCopy.isEmpty()) return + + val singleElementToCopy = elementsToCopy.singleOrNull() + + val originalFile = elementsToCopy.first().containingFile as KtFile + val initialTargetDirectory = defaultTargetDirectory ?: originalFile.containingDirectory ?: return + + val project = initialTargetDirectory.project + + val sourceData = SourceData( + project = project, + singleElementToCopy = singleElementToCopy, + elementsToCopy = elementsToCopy.filterIsInstance(), + originalFile = originalFile, + initialTargetDirectory = initialTargetDirectory + ) + + val targetData = getTargetData(sourceData) ?: return + + for (element in elementsToCopy) { + markInternalUsages(element) + } + + val conflicts: MultiMap = + analyzeInModalWindow(elementsToCopy.first(), RefactoringBundle.message("detecting.possible.conflicts")) { + collectConflicts(sourceData, targetData) + } + + project.checkConflictsInteractively(conflicts) { + try { + project.executeCommand(commandName) { + doRefactor(sourceData, targetData) + } + } finally { + allowAnalysisOnEdt { + unMarkNonUpdatableUsages(elements.asIterable()) + } + } + } + } + + private data class RefactoringResult( + val targetFile: PsiFile, val copiedDeclaration: KtNamedDeclaration?, val restoredInternalUsages: List? = null + ) + + private fun doRefactor(sourceData: SourceData, targetData: TargetData) { + + try { + val targetDirectory = runWriteAction { + targetData.targetDirWrapper.getOrCreateTarget() as PsiDirectory + } + + val targetFileName = + if (targetData.newName.contains(".")) targetData.newName else targetData.newName + "." + sourceData.originalFile.virtualFile.extension + + val isSingleDeclarationInFile = + sourceData.singleElementToCopy is KtNamedDeclaration && sourceData.originalFile.declarations.singleOrNull() == sourceData.singleElementToCopy + + val fileToCopy = when { + sourceData.singleElementToCopy is KtFile -> sourceData.singleElementToCopy + isSingleDeclarationInFile -> sourceData.originalFile + else -> null + } + + var refactoringResult = if (fileToCopy !== null) { + doRefactoringOnFile(fileToCopy, targetDirectory, targetFileName, isSingleDeclarationInFile) + } else { + val targetFile = getOrCreateTargetFile(sourceData.originalFile, targetDirectory, targetFileName) + ?: throw IncorrectOperationException("Could not create target file.") + doRefactoringOnElement(sourceData, targetFile) + } + + refactoringResult.copiedDeclaration?.let { newDeclaration -> + if (targetData.newName == newDeclaration.name) return@let + val selfReferences = ReferencesSearch.search(newDeclaration, LocalSearchScope(newDeclaration)).findAll() + runWriteAction { + selfReferences.forEach { it.handleElementRename(targetData.newName) } + newDeclaration.setName(targetData.newName) + } + } + + if (targetData.openInEditor) { + EditorHelper.openInEditor(refactoringResult.targetFile) + } + } catch (e: IncorrectOperationException) { + Messages.showMessageDialog(sourceData.project, e.message, RefactoringBundle.message("error.title"), Messages.getErrorIcon()) + } + } + + + private fun doRefactoringOnFile( + fileToCopy: KtFile, + targetDirectory: PsiDirectory, + targetFileName: String, + isSingleDeclarationInFile: Boolean + ): RefactoringResult { + val targetFile = runWriteAction { // implicit package prefix may change after copy + val targetDirectoryFqName = targetDirectory.getFqNameWithImplicitPrefix() + val copiedFile = targetDirectory.copyFileFrom(targetFileName, fileToCopy) + if (copiedFile is KtFile && fileToCopy.packageMatchesDirectoryOrImplicit()) { + targetDirectoryFqName?.quoteIfNeeded()?.let { copiedFile.packageFqName = it } + } + + copiedFile + } + + val copiedDeclaration = if (isSingleDeclarationInFile && targetFile is KtFile) { + targetFile.declarations.singleOrNull() as? KtNamedDeclaration + } else null + + return RefactoringResult(targetFile, copiedDeclaration) + } + + private fun doRefactoringOnElement( + sourceData: SourceData, targetFile: KtFile + ): RefactoringResult { + val restoredInternalUsages = ArrayList() + val oldToNewElementsMapping = HashMap() + + runWriteAction { + val newElements = sourceData.elementsToCopy.map { targetFile.add(it.copy()) as KtNamedDeclaration } + sourceData.elementsToCopy.zip(newElements).toMap(oldToNewElementsMapping) + retargetInternalUsages(oldToNewElementsMapping, fromCopy = true) + } + + val copiedDeclaration = oldToNewElementsMapping.values.singleOrNull() + + return RefactoringResult(targetFile, copiedDeclaration, restoredInternalUsages) + } + + private fun collectConflicts( + sourceData: SourceData, + targetData: TargetData, + ): MultiMap { + + if (isUnitTestMode() && BaseRefactoringProcessor.ConflictsInTestsException.isTestIgnore()) return MultiMap.empty() + + if (sourceData.project != sourceData.originalFile.project) return MultiMap.empty() + + val elements = mutableSetOf() + elements.addAll(sourceData.elementsToCopy) + (sourceData.singleElementToCopy as? KtFile)?.declarations?.filterIsInstance()?.forEach(elements::add) + val (fakeTarget, _) = createCopyTarget( + elements, targetData.targetDirWrapper.baseDirectory, targetData.targetDirWrapper.pkgName, targetData.newName + ) + + return MultiMap().apply { + putAllValues(checkVisibilityConflictsForInternalUsages(elements, fakeTarget)) + putAllValues(checkModuleDependencyConflictsForInternalUsages(elements, fakeTarget)) + } + } + + override fun doClone(element: PsiElement) {} +} diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/copy/KotlinUpdateAddedFileProcessor.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/copy/KotlinUpdateAddedFileProcessor.kt new file mode 100644 index 000000000000..9d3598376cd3 --- /dev/null +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/copy/KotlinUpdateAddedFileProcessor.kt @@ -0,0 +1,23 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.k2.refactoring.copy + +import com.intellij.psi.PsiFile +import com.intellij.psi.impl.file.UpdateAddedFileProcessor +import org.jetbrains.kotlin.idea.base.util.quoteIfNeeded +import org.jetbrains.kotlin.idea.core.getFqNameWithImplicitPrefix +import org.jetbrains.kotlin.idea.core.packageMatchesDirectoryOrImplicit +import org.jetbrains.kotlin.psi.KtFile + +class KotlinUpdateAddedFileProcessor : UpdateAddedFileProcessor() { + override fun canProcessElement(element: PsiFile): Boolean = element is KtFile + + override fun update(element: PsiFile, originalElement: PsiFile?) { + val targetFile = element as? KtFile ?: return + if ((originalElement == null || originalElement is KtFile && originalElement.packageMatchesDirectoryOrImplicit()) && + targetFile.packageMatchesDirectoryOrImplicit() != true) { + targetFile.containingDirectory?.getFqNameWithImplicitPrefix()?.quoteIfNeeded()?.let { targetDirectoryFqName -> + targetFile.packageFqName = targetDirectoryFqName + } + } + } +} \ No newline at end of file diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/utils.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/utils.kt index d537a8f59d67..276527568b93 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/utils.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/utils.kt @@ -51,27 +51,6 @@ fun modifyPsiWithOptimizedImports(file: KtFile, block: () -> T): T { return result } -@JvmOverloads -fun getOrCreateKotlinFile( - fileName: String, - targetDir: PsiDirectory, - packageName: String? = targetDir.getFqNameWithImplicitPrefix()?.asString() -): KtFile = - (targetDir.findFile(fileName) ?: createKotlinFile(fileName, targetDir, packageName)) as KtFile - -fun createKotlinFile( - fileName: String, - targetDir: PsiDirectory, - packageName: String? = targetDir.getFqNameWithImplicitPrefix()?.asString() -): KtFile { - targetDir.checkCreateFile(fileName) - val packageFqName = packageName?.let(::FqName) ?: FqName.ROOT - val file = PsiFileFactory.getInstance(targetDir.project).createFileFromText( - fileName, KotlinFileType.INSTANCE, if (!packageFqName.isRoot) "package ${packageFqName.quoteIfNeeded()} \n\n" else "" - ) - return targetDir.add(file) as KtFile -} - fun PsiElement?.canDeleteElement(): Boolean { if (this is KtObjectDeclaration && isObjectLiteral()) return false diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/kotlin.refactorings.move.k2.iml b/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/kotlin.refactorings.move.k2.iml index 81c28de17134..4b6e00e64a03 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/kotlin.refactorings.move.k2.iml +++ b/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/kotlin.refactorings.move.k2.iml @@ -39,7 +39,6 @@ - diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/resources/kotlin.refactorings.move.k2.xml b/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/resources/kotlin.refactorings.move.k2.xml index ac096dbec743..0f89b25c6dda 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/resources/kotlin.refactorings.move.k2.xml +++ b/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/resources/kotlin.refactorings.move.k2.xml @@ -1,7 +1,4 @@ - - - diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/descriptor/K2MoveTargetDescriptor.kt b/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/descriptor/K2MoveTargetDescriptor.kt index e6e8f13545aa..364341c089ac 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/descriptor/K2MoveTargetDescriptor.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/descriptor/K2MoveTargetDescriptor.kt @@ -7,7 +7,7 @@ import com.intellij.psi.PsiFileSystemItem import com.intellij.util.concurrency.annotations.RequiresWriteLock import org.jetbrains.kotlin.idea.core.getFqNameWithImplicitPrefixOrRoot import org.jetbrains.kotlin.idea.core.util.toPsiDirectory -import org.jetbrains.kotlin.idea.k2.refactoring.getOrCreateKotlinFile +import org.jetbrains.kotlin.idea.k2.refactoring.move.processor.getOrCreateKotlinFile import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtFile diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/processor/K2MoveRenameUsageInfo.kt b/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/processor/K2MoveRenameUsageInfo.kt index 4903b780e0d9..d474c8394c90 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/processor/K2MoveRenameUsageInfo.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/processor/K2MoveRenameUsageInfo.kt @@ -3,6 +3,7 @@ package org.jetbrains.kotlin.idea.k2.refactoring.move.processor import com.intellij.openapi.util.Key import com.intellij.psi.* +import com.intellij.psi.PsiElement import com.intellij.psi.search.searches.ReferencesSearch import com.intellij.psi.util.isAncestor import com.intellij.psi.util.parentOfType @@ -13,6 +14,7 @@ import com.intellij.refactoring.move.moveMembers.MoveMembersProcessor import com.intellij.refactoring.util.MoveRenameUsageInfo import com.intellij.usageView.UsageInfo import org.jetbrains.kotlin.analysis.api.KtAllowAnalysisFromWriteAction +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.analyze import org.jetbrains.kotlin.analysis.api.lifetime.allowAnalysisFromWriteAction import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol @@ -156,16 +158,14 @@ sealed class K2MoveRenameUsageInfo( * Finds any usage inside [containing]. We need these usages because when moving [containing] to a different package references * that where previously imported by default might now require an explicit import. */ - @OptIn(KtAllowAnalysisFromWriteAction::class) - private fun markInternalUsages(containing: KtElement) = allowAnalysisFromWriteAction { - containing.forEachDescendantOfType { refExpr -> - val resolved = analyze(refExpr) { refExpr.mainReference.resolve() } as? PsiNamedElement ?: return@forEachDescendantOfType - val usageInfo = Source(refExpr, refExpr.mainReference, resolved, true) - refExpr.internalUsageInfo = usageInfo - } - } + fun markInternalUsages(containing: KtElement) = + containing.forEachDescendantOfType { refExpr -> + val resolved = refExpr.mainReference.resolve() as? PsiNamedElement ?: return@forEachDescendantOfType + val usageInfo = Source(refExpr, refExpr.mainReference, resolved, true) + refExpr.internalUsageInfo = usageInfo + } - internal fun unMarkNonUpdatableUsages(containing: Set) = containing.forEach { + fun unMarkNonUpdatableUsages(containing: Iterable) = containing.forEach { unMarkNonUpdatableUsages(it) } @@ -175,7 +175,7 @@ sealed class K2MoveRenameUsageInfo( * Like, for example, instance methods. */ @OptIn(KtAllowAnalysisFromWriteAction::class) - internal fun unMarkNonUpdatableUsages(containing: KtElement) = allowAnalysisFromWriteAction { + fun unMarkNonUpdatableUsages(containing: PsiElement) = allowAnalysisFromWriteAction { containing.forEachDescendantOfType { refExpr -> if (!refExpr.isImportable()) refExpr.internalUsageInfo = null } @@ -250,10 +250,14 @@ sealed class K2MoveRenameUsageInfo( * After moving, internal usages might have become invalid, this method restores these usage infos. * @see internalUsageInfo */ - private fun restoreInternalUsages(containingDecl: KtNamedDeclaration, oldToNewMap: Map): List { + private fun restoreInternalUsages( + containingDecl: KtNamedDeclaration, + oldToNewMap: Map, + fromCopy: Boolean + ): List { return containingDecl.collectDescendantsOfType().mapNotNull { refExpr -> val usageInfo = refExpr.internalUsageInfo - if (usageInfo?.element != null) return@mapNotNull usageInfo + if (!fromCopy && usageInfo?.element != null) return@mapNotNull usageInfo val referencedElement = (usageInfo as? Source)?.referencedElement ?: return@mapNotNull null val newReferencedElement = oldToNewMap[referencedElement] ?: referencedElement if (!newReferencedElement.isValid || newReferencedElement !is PsiNamedElement) return@mapNotNull null @@ -261,10 +265,10 @@ sealed class K2MoveRenameUsageInfo( } } - private fun retargetInternalUsages(oldToNewMap: Map) { + fun retargetInternalUsages(oldToNewMap: Map, fromCopy: Boolean = false) { val newDeclarations = oldToNewMap.values.toList() val internalUsages = newDeclarations - .flatMap { decl -> restoreInternalUsages(decl, oldToNewMap) } + .flatMap { decl -> restoreInternalUsages(decl, oldToNewMap, fromCopy) } .filterIsInstance() .sortedByFile() shortenUsages(retargetMoveUsages(internalUsages, oldToNewMap)) diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/processor/moveConflictUtil.kt b/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/processor/moveConflictUtil.kt index 92e849e213ce..f72a086ceac2 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/processor/moveConflictUtil.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/processor/moveConflictUtil.kt @@ -99,7 +99,7 @@ internal fun findAllMoveConflicts( * Creates a non-physical file that contains the moved elements with all references retargeted. * This non-physical file can be used to analyze for conflicts without modifying the file on the disk. */ -private fun createCopyTarget( +fun createCopyTarget( declarationsToMove: Set, targetDir: PsiDirectory, targetPkg: FqName, @@ -221,7 +221,7 @@ private fun checkVisibilityConflictForNonMovedUsages( /** * Check whether the moved internal usages are still visible towards their physical declaration. */ -private fun checkVisibilityConflictsForInternalUsages( +fun checkVisibilityConflictsForInternalUsages( allDeclarationsToMove: Set, fakeTarget: KtFile ): MultiMap { @@ -287,7 +287,7 @@ private fun checkModuleDependencyConflictsForNonMovedUsages( }.toMultiMap() } -private fun checkModuleDependencyConflictsForInternalUsages( +fun checkModuleDependencyConflictsForInternalUsages( allDeclarationsToMove: Set, fakeTarget: KtFile ): MultiMap { diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/processor/moveUtil.kt b/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/processor/moveUtil.kt index 7e29cdce79b5..bbf8288418cd 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/processor/moveUtil.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.move.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/move/processor/moveUtil.kt @@ -4,9 +4,12 @@ package org.jetbrains.kotlin.idea.k2.refactoring.move.processor import com.intellij.java.analysis.JavaAnalysisBundle import com.intellij.psi.JavaDirectoryService import com.intellij.psi.PsiDirectory +import com.intellij.psi.PsiFileFactory import com.intellij.refactoring.move.MoveMultipleElementsViewDescriptor +import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.base.psi.kotlinFqName import org.jetbrains.kotlin.idea.base.util.quoteIfNeeded +import org.jetbrains.kotlin.idea.core.getFqNameWithImplicitPrefix import org.jetbrains.kotlin.idea.k2.refactoring.move.descriptor.K2ChangePackageDescriptor import org.jetbrains.kotlin.idea.k2.refactoring.move.descriptor.K2MoveDescriptor import org.jetbrains.kotlin.name.FqName @@ -42,4 +45,25 @@ internal fun KtFile.updatePackageDirective(pkgName: FqName) { internal fun KtFile.updatePackageDirective(destination: PsiDirectory) { val newPackageName = JavaDirectoryService.getInstance().getPackage(destination)?.kotlinFqName ?: return updatePackageDirective(newPackageName) -} \ No newline at end of file +} + +@JvmOverloads +fun getOrCreateKotlinFile( + fileName: String, + targetDir: PsiDirectory, + packageName: String? = targetDir.getFqNameWithImplicitPrefix()?.asString() +): KtFile = + (targetDir.findFile(fileName) ?: createKotlinFile(fileName, targetDir, packageName)) as KtFile + +fun createKotlinFile( + fileName: String, + targetDir: PsiDirectory, + packageName: String? = targetDir.getFqNameWithImplicitPrefix()?.asString() +): KtFile { + targetDir.checkCreateFile(fileName) + val packageFqName = packageName?.let(::FqName) ?: FqName.ROOT + val file = PsiFileFactory.getInstance(targetDir.project).createFileFromText( + fileName, KotlinFileType.INSTANCE, if (!packageFqName.isRoot) "package ${packageFqName.quoteIfNeeded()} \n\n" else "" + ) + return targetDir.add(file) as KtFile +} diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/kotlin.refactorings.tests.k2.iml b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/kotlin.refactorings.tests.k2.iml index e299409bd3b5..e7d7b0bb2351 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/kotlin.refactorings.tests.k2.iml +++ b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/kotlin.refactorings.tests.k2.iml @@ -26,5 +26,7 @@ + + \ No newline at end of file diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/copy/AbstractK2CopyTest.kt b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/copy/AbstractK2CopyTest.kt new file mode 100644 index 000000000000..36f4ba43ec0f --- /dev/null +++ b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/copy/AbstractK2CopyTest.kt @@ -0,0 +1,34 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.k2.refactoring.copy + +import com.google.gson.JsonObject +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.isFile +import com.intellij.testFramework.LightProjectDescriptor +import org.jetbrains.kotlin.idea.refactoring.copy.AbstractCopyTest +import org.jetbrains.kotlin.idea.refactoring.copy.AbstractMultiModuleCopyTest +import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor + +abstract class AbstractK2CopyTest: AbstractCopyTest() { + override fun isFirPlugin(): Boolean = true + + override fun getProjectDescriptor(): LightProjectDescriptor { + return KotlinWithJdkAndRuntimeLightProjectDescriptor.getInstance() + } + + override fun isEnabled(config: JsonObject): Boolean = config.get("enabledInK2")?.asBoolean != false + + override fun fileFilter(file: VirtualFile): Boolean { + if (file.isFile && file.extension == "kt") { + if (file.name.endsWith(".k2.kt")) return true + val k2CounterPart = file.parent.findChild("${file.nameWithoutExtension}.k2.kt") + if (k2CounterPart?.isFile == true) return false + } + return super.fileFilter(file) + } + + override fun fileNameMapper(file: VirtualFile): String = + file.name.replace(".k2.kt", ".kt") +} + +abstract class AbstractK2MultiModuleCopyTest: AbstractMultiModuleCopyTest() \ No newline at end of file diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/copy/K2CopyTestGenerated.java b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/copy/K2CopyTestGenerated.java new file mode 100644 index 000000000000..bbcde8f098b6 --- /dev/null +++ b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/copy/K2CopyTestGenerated.java @@ -0,0 +1,230 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. + +package org.jetbrains.kotlin.idea.k2.refactoring.copy; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.idea.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.idea.test.KotlinTestUtils; +import org.jetbrains.kotlin.test.TestMetadata; +import org.jetbrains.kotlin.idea.base.test.TestRoot; +import org.junit.runner.RunWith; + +/** + * This class is generated by {@link org.jetbrains.kotlin.testGenerator.generator.TestGenerator}. + * DO NOT MODIFY MANUALLY. + */ +@SuppressWarnings("all") +@TestRoot("refactorings/kotlin.refactorings.tests.k2") +@TestDataPath("$CONTENT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +@TestMetadata("../../idea/tests/testData/refactoring/copy") +public class K2CopyTestGenerated extends AbstractK2CopyTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("copyClassCaretInside/copyClassCaretInside.test") + public void testCopyClassCaretInside_CopyClassCaretInside() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyClassCaretInside/copyClassCaretInside.test"); + } + + @TestMetadata("copyClassToExistingFile/copyClassToExistingFile.test") + public void testCopyClassToExistingFile_CopyClassToExistingFile() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyClassToExistingFile/copyClassToExistingFile.test"); + } + + @TestMetadata("copyClassToNewFile/copyClassToNewFile.test") + public void testCopyClassToNewFile_CopyClassToNewFile() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyClassToNewFile/copyClassToNewFile.test"); + } + + @TestMetadata("copyClassToSamePackageWithRename/copyClassToSamePackageWithRename.test") + public void testCopyClassToSamePackageWithRename_CopyClassToSamePackageWithRename() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyClassToSamePackageWithRename/copyClassToSamePackageWithRename.test"); + } + + @TestMetadata("copyClassWithCompanionRefs/copyClassWithCompanionRefs.test") + public void testCopyClassWithCompanionRefs_CopyClassWithCompanionRefs() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyClassWithCompanionRefs/copyClassWithCompanionRefs.test"); + } + + @TestMetadata("copyClassWithRename/copyClassWithRename.test") + public void testCopyClassWithRename_CopyClassWithRename() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyClassWithRename/copyClassWithRename.test"); + } + + @TestMetadata("copyFIleFromDefaultPackage/copyFIleFromDefaultPackage.test") + public void testCopyFIleFromDefaultPackage_CopyFIleFromDefaultPackage() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyFIleFromDefaultPackage/copyFIleFromDefaultPackage.test"); + } + + @TestMetadata("copyFIleRetainContent/copyFIleRetainContent.test") + public void testCopyFIleRetainContent_CopyFIleRetainContent() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyFIleRetainContent/copyFIleRetainContent.test"); + } + + @TestMetadata("copyFIleToDefaultPackage/copyFIleToDefaultPackage.test") + public void testCopyFIleToDefaultPackage_CopyFIleToDefaultPackage() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyFIleToDefaultPackage/copyFIleToDefaultPackage.test"); + } + + @TestMetadata("copyFIleWithPackageAndDirUnmatched/copyFIleWithPackageAndDirUnmatched.test") + public void testCopyFIleWithPackageAndDirUnmatched_CopyFIleWithPackageAndDirUnmatched() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyFIleWithPackageAndDirUnmatched/copyFIleWithPackageAndDirUnmatched.test"); + } + + @TestMetadata("copyFileFromDefaultPackageToDefaultPackage/copyFileFromDefaultPackageToDefaultPackage.test") + public void testCopyFileFromDefaultPackageToDefaultPackage_CopyFileFromDefaultPackageToDefaultPackage() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyFileFromDefaultPackageToDefaultPackage/copyFileFromDefaultPackageToDefaultPackage.test"); + } + + @TestMetadata("copyFileFromDefaultPackageWithImpicitPrefix/copyFileFromDefaultPackageWithImpicitPrefix.test") + public void testCopyFileFromDefaultPackageWithImpicitPrefix_CopyFileFromDefaultPackageWithImpicitPrefix() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyFileFromDefaultPackageWithImpicitPrefix/copyFileFromDefaultPackageWithImpicitPrefix.test"); + } + + @TestMetadata("copyFileToRoot/copyFileToRoot.test") + public void testCopyFileToRoot_CopyFileToRoot() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyFileToRoot/copyFileToRoot.test"); + } + + @TestMetadata("copyFunCallQualificationWithParentheses/copyFunCallQualificationWithParentheses.test") + public void testCopyFunCallQualificationWithParentheses_CopyFunCallQualificationWithParentheses() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyFunCallQualificationWithParentheses/copyFunCallQualificationWithParentheses.test"); + } + + @TestMetadata("copyKtFileToTextFile/copyKtFileToTextFile.test") + public void testCopyKtFileToTextFile_CopyKtFileToTextFile() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyKtFileToTextFile/copyKtFileToTextFile.test"); + } + + @TestMetadata("copyLocalClass/copyLocalClass.test") + public void testCopyLocalClass_CopyLocalClass() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyLocalClass/copyLocalClass.test"); + } + + @TestMetadata("copyLocalFunction/copyLocalFunction.test") + public void testCopyLocalFunction_CopyLocalFunction() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyLocalFunction/copyLocalFunction.test"); + } + + @TestMetadata("copyLocalVariable/copyLocalVariable.test") + public void testCopyLocalVariable_CopyLocalVariable() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyLocalVariable/copyLocalVariable.test"); + } + + @TestMetadata("copyMemberFunction/copyMemberFunction.test") + public void testCopyMemberFunction_CopyMemberFunction() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyMemberFunction/copyMemberFunction.test"); + } + + @TestMetadata("copyMemberProperty/copyMemberProperty.test") + public void testCopyMemberProperty_CopyMemberProperty() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyMemberProperty/copyMemberProperty.test"); + } + + @TestMetadata("copyMultiClassFile/copyMultiClassFile.test") + public void testCopyMultiClassFile_CopyMultiClassFile() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyMultiClassFile/copyMultiClassFile.test"); + } + + @TestMetadata("copyMultipleClassesToExistingFile/copyMultipleClassesToExistingFile.test") + public void testCopyMultipleClassesToExistingFile_CopyMultipleClassesToExistingFile() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyMultipleClassesToExistingFile/copyMultipleClassesToExistingFile.test"); + } + + @TestMetadata("copyMultipleClassesToNewFile/copyMultipleClassesToNewFile.test") + public void testCopyMultipleClassesToNewFile_CopyMultipleClassesToNewFile() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyMultipleClassesToNewFile/copyMultipleClassesToNewFile.test"); + } + + @TestMetadata("copyMultipleDeclarations/copyMultipleDeclarations.test") + public void testCopyMultipleDeclarations_CopyMultipleDeclarations() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyMultipleDeclarations/copyMultipleDeclarations.test"); + } + + @TestMetadata("copyMultipleFilesDifferentDirectoriesToNewDirectory/copyMultipleFilesDifferentDirectoriesToNewDirectory.test") + public void testCopyMultipleFilesDifferentDirectoriesToNewDirectory_CopyMultipleFilesDifferentDirectoriesToNewDirectory() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyMultipleFilesDifferentDirectoriesToNewDirectory/copyMultipleFilesDifferentDirectoriesToNewDirectory.test"); + } + + @TestMetadata("copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject.test") + public void testCopyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject_CopyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject.test"); + } + + @TestMetadata("copyMultipleFilesToNewDirectory/copyMultipleFilesToNewDirectory.test") + public void testCopyMultipleFilesToNewDirectory_CopyMultipleFilesToNewDirectory() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyMultipleFilesToNewDirectory/copyMultipleFilesToNewDirectory.test"); + } + + @TestMetadata("copyNestedClass/copyNestedClass.test") + public void testCopyNestedClass_CopyNestedClass() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyNestedClass/copyNestedClass.test"); + } + + @TestMetadata("copyObject/copyObject.test") + public void testCopyObject_CopyObject() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyObject/copyObject.test"); + } + + @TestMetadata("copySingleClassFile/copySingleClassFile.test") + public void testCopySingleClassFile_CopySingleClassFile() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copySingleClassFile/copySingleClassFile.test"); + } + + @TestMetadata("copySingleClassWithRename/copySingleClassWithRename.test") + public void testCopySingleClassWithRename_CopySingleClassWithRename() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copySingleClassWithRename/copySingleClassWithRename.test"); + } + + @TestMetadata("copySingleClass/copySingleClass.test") + public void testCopySingleClass_CopySingleClass() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copySingleClass/copySingleClass.test"); + } + + @TestMetadata("copyTopLevelFunctionWithRename/copyTopLevelFunctionWithRename.test") + public void testCopyTopLevelFunctionWithRename_CopyTopLevelFunctionWithRename() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyTopLevelFunctionWithRename/copyTopLevelFunctionWithRename.test"); + } + + @TestMetadata("copyTopLevelFunction/copyTopLevelFunction.test") + public void testCopyTopLevelFunction_CopyTopLevelFunction() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyTopLevelFunction/copyTopLevelFunction.test"); + } + + @TestMetadata("copyTopLevelPropertyWithRename/copyTopLevelPropertyWithRename.test") + public void testCopyTopLevelPropertyWithRename_CopyTopLevelPropertyWithRename() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyTopLevelPropertyWithRename/copyTopLevelPropertyWithRename.test"); + } + + @TestMetadata("copyTopLevelProperty/copyTopLevelProperty.test") + public void testCopyTopLevelProperty_CopyTopLevelProperty() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyTopLevelProperty/copyTopLevelProperty.test"); + } + + @TestMetadata("copyWithImportInsertion/copyWithImportInsertion.test") + public void testCopyWithImportInsertion_CopyWithImportInsertion() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/copyWithImportInsertion/copyWithImportInsertion.test"); + } + + @TestMetadata("kt18149/kt18149.test") + public void testKt18149_Kt18149() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/kt18149/kt18149.test"); + } + + @TestMetadata("protectedConstructorRefInSuperListEntry/protectedConstructorRefInSuperListEntry.test") + public void testProtectedConstructorRefInSuperListEntry_ProtectedConstructorRefInSuperListEntry() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/protectedConstructorRefInSuperListEntry/protectedConstructorRefInSuperListEntry.test"); + } + + @TestMetadata("refToImportJavaStaticField/refToImportJavaStaticField.test") + public void testRefToImportJavaStaticField_RefToImportJavaStaticField() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/refToImportJavaStaticField/refToImportJavaStaticField.test"); + } + + @TestMetadata("refToImportJavaStaticMethod/refToImportJavaStaticMethod.test") + public void testRefToImportJavaStaticMethod_RefToImportJavaStaticMethod() throws Exception { + runTest("../../idea/tests/testData/refactoring/copy/refToImportJavaStaticMethod/refToImportJavaStaticMethod.test"); + } +} diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/copy/K2MultiModuleCopyTestGenerated.java b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/copy/K2MultiModuleCopyTestGenerated.java new file mode 100644 index 000000000000..0fac4f27e708 --- /dev/null +++ b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/copy/K2MultiModuleCopyTestGenerated.java @@ -0,0 +1,40 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. + +package org.jetbrains.kotlin.idea.k2.refactoring.copy; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.idea.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.idea.test.KotlinTestUtils; +import org.jetbrains.kotlin.test.TestMetadata; +import org.jetbrains.kotlin.idea.base.test.TestRoot; +import org.junit.runner.RunWith; + +/** + * This class is generated by {@link org.jetbrains.kotlin.testGenerator.generator.TestGenerator}. + * DO NOT MODIFY MANUALLY. + */ +@SuppressWarnings("all") +@TestRoot("refactorings/kotlin.refactorings.tests.k2") +@TestDataPath("$CONTENT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +@TestMetadata("../../idea/tests/testData/refactoring/copyMultiModule") +public class K2MultiModuleCopyTestGenerated extends AbstractK2MultiModuleCopyTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("fileNotUnderSourceRoot/fileNotUnderSourceRoot.test") + public void testFileNotUnderSourceRoot_FileNotUnderSourceRoot() throws Exception { + runTest("../../idea/tests/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/fileNotUnderSourceRoot.test"); + } + + @TestMetadata("internalReferencesToAnotherModule2/internalReferencesToAnotherModule.test") + public void testInternalReferencesToAnotherModule2_InternalReferencesToAnotherModule() throws Exception { + runTest("../../idea/tests/testData/refactoring/copyMultiModule/internalReferencesToAnotherModule2/internalReferencesToAnotherModule.test"); + } + + @TestMetadata("referencesToUnrelatedModule/referencesToUnrelatedModule.test") + public void testReferencesToUnrelatedModule_ReferencesToUnrelatedModule() throws Exception { + runTest("../../idea/tests/testData/refactoring/copyMultiModule/referencesToUnrelatedModule/referencesToUnrelatedModule.test"); + } +} diff --git a/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/GenerateK2RefactoringsTests.kt b/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/GenerateK2RefactoringsTests.kt index 0e56637e08b6..7ec427c48c28 100644 --- a/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/GenerateK2RefactoringsTests.kt +++ b/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/GenerateK2RefactoringsTests.kt @@ -3,6 +3,8 @@ package org.jetbrains.kotlin.fir.testGenerator import org.jetbrains.kotlin.idea.k2.refactoring.bindToElement.AbstractK2BindToElementTest import org.jetbrains.kotlin.idea.k2.refactoring.bindToElement.AbstractK2BindToFqnTest +import org.jetbrains.kotlin.idea.k2.refactoring.copy.AbstractK2CopyTest +import org.jetbrains.kotlin.idea.k2.refactoring.copy.AbstractK2MultiModuleCopyTest import org.jetbrains.kotlin.idea.k2.refactoring.inline.AbstractKotlinFirInlineTest import org.jetbrains.kotlin.idea.k2.refactoring.introduce.AbstractK2PsiUnifierTest import org.jetbrains.kotlin.idea.k2.refactoring.introduce.introduceVariable.AbstractK2IntroduceVariableTest @@ -91,6 +93,16 @@ internal fun MutableTWorkspace.generateK2RefactoringsTests() { } } + testGroup("refactorings/kotlin.refactorings.tests.k2", category = REFACTORING, testDataPath = "../../idea/tests/testData") { + testClass< AbstractK2CopyTest> { + model("refactoring/copy", pattern = TEST, flatten = true) + } + + testClass { + model("refactoring/copyMultiModule", pattern = TEST, flatten = true) + } + } + testGroup("refactorings/kotlin.refactorings.move.k2", category = MOVE_REFACTORING, testDataPath = "../../idea/tests/testData") { testClass { model("refactoring/changePackage", pattern = TEST, flatten = true) From a9c9b4d7ea41f254c11abd3f304d04daa92e5d0f Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 2 May 2024 10:33:54 +0200 Subject: [PATCH 21/21] [kotlin] Advance kotlinc version for analyzer to 2.0.20-dev-2794 GitOrigin-RevId: 48e0941228a70d02e552813237ea3a91ab2fb0b2 --- .idea/libraries/kotlinc_allopen_compiler_plugin.xml | 13 ++++++++++--- .idea/libraries/kotlinc_analysis_api_providers.xml | 13 ++++++++++--- .../kotlinc_analysis_project_structure.xml | 13 ++++++++++--- .../kotlinc_android_extensions_compiler_plugin.xml | 13 ++++++++++--- .../kotlinc_assignment_compiler_plugin.xml | 13 ++++++++++--- .idea/libraries/kotlinc_high_level_api.xml | 13 ++++++++++--- .idea/libraries/kotlinc_high_level_api_fe10.xml | 13 ++++++++++--- .idea/libraries/kotlinc_high_level_api_fir.xml | 13 ++++++++++--- .../libraries/kotlinc_high_level_api_fir_tests.xml | 13 ++++++++++--- .../libraries/kotlinc_high_level_api_impl_base.xml | 13 ++++++++++--- .../kotlinc_high_level_api_impl_base_tests.xml | 13 ++++++++++--- .../kotlinc_incremental_compilation_impl_tests.xml | 13 ++++++++++--- .../libraries/kotlinc_kotlin_build_common_tests.xml | 13 ++++++++++--- .idea/libraries/kotlinc_kotlin_compiler_cli.xml | 13 ++++++++++--- .idea/libraries/kotlinc_kotlin_compiler_common.xml | 13 ++++++++++--- .idea/libraries/kotlinc_kotlin_compiler_fe10.xml | 13 ++++++++++--- .idea/libraries/kotlinc_kotlin_compiler_fir.xml | 13 ++++++++++--- .idea/libraries/kotlinc_kotlin_compiler_ir.xml | 13 ++++++++++--- .idea/libraries/kotlinc_kotlin_compiler_tests.xml | 13 ++++++++++--- .../libraries/kotlinc_kotlin_gradle_statistics.xml | 13 ++++++++++--- .idea/libraries/kotlinc_kotlin_jps_common.xml | 13 ++++++++++--- ...lin_jps_plugin_classpath_bootstrap_for_tests.xml | 13 ++++++++++--- .idea/libraries/kotlinc_kotlin_script_runtime.xml | 13 ++++++++++--- .idea/libraries/kotlinc_kotlin_scripting_common.xml | 13 ++++++++++--- .../kotlinc_kotlin_scripting_compiler_impl.xml | 13 ++++++++++--- .idea/libraries/kotlinc_kotlin_scripting_jvm.xml | 13 ++++++++++--- ...otlinc_kotlinx_serialization_compiler_plugin.xml | 13 ++++++++++--- .idea/libraries/kotlinc_lombok_compiler_plugin.xml | 13 ++++++++++--- .idea/libraries/kotlinc_low_level_api_fir.xml | 13 ++++++++++--- .idea/libraries/kotlinc_noarg_compiler_plugin.xml | 13 ++++++++++--- .../libraries/kotlinc_parcelize_compiler_plugin.xml | 13 ++++++++++--- .../kotlinc_sam_with_receiver_compiler_plugin.xml | 13 ++++++++++--- .../libraries/kotlinc_scripting_compiler_plugin.xml | 13 ++++++++++--- .idea/libraries/kotlinc_symbol_light_classes.xml | 13 ++++++++++--- .../resources/model.properties | 4 ++-- 35 files changed, 342 insertions(+), 104 deletions(-) diff --git a/.idea/libraries/kotlinc_allopen_compiler_plugin.xml b/.idea/libraries/kotlinc_allopen_compiler_plugin.xml index 4da80494a292..d394011dc80f 100644 --- a/.idea/libraries/kotlinc_allopen_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_allopen_compiler_plugin.xml @@ -1,11 +1,18 @@ - + + + + + 4b6f71c4c5a7a48e086e743a9d4ca54dd90e630060bcf87dbd6819758c036520 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_analysis_api_providers.xml b/.idea/libraries/kotlinc_analysis_api_providers.xml index c65c2e7f5fef..42a43a8f76ad 100644 --- a/.idea/libraries/kotlinc_analysis_api_providers.xml +++ b/.idea/libraries/kotlinc_analysis_api_providers.xml @@ -1,11 +1,18 @@ - + + + + + af7be4f3bddcfd36113601b7ab312e5fab657186373e125a3954d4fe9b2dedd4 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_analysis_project_structure.xml b/.idea/libraries/kotlinc_analysis_project_structure.xml index 82f7979eb40e..1376495bb9ab 100644 --- a/.idea/libraries/kotlinc_analysis_project_structure.xml +++ b/.idea/libraries/kotlinc_analysis_project_structure.xml @@ -1,11 +1,18 @@ - + + + + + cee2ed7f9023a371850c84823cc38357885a3bae286c0d5b69b26d6bd3b49b4a + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_android_extensions_compiler_plugin.xml b/.idea/libraries/kotlinc_android_extensions_compiler_plugin.xml index 0e5ac0304637..9f2a70ebf49c 100644 --- a/.idea/libraries/kotlinc_android_extensions_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_android_extensions_compiler_plugin.xml @@ -1,11 +1,18 @@ - + + + + + 7075f7976e6e9778e33c04b4cdf4eb453e385dca08f6d5ed4b59ef7969911024 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_assignment_compiler_plugin.xml b/.idea/libraries/kotlinc_assignment_compiler_plugin.xml index dea92e24e5ae..bc680f7a8e76 100644 --- a/.idea/libraries/kotlinc_assignment_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_assignment_compiler_plugin.xml @@ -1,11 +1,18 @@ - + + + + + dcb82b05707abb41bf95dc3bb2a0d1f203e293d3cc693494763820f4ce38fcc6 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_high_level_api.xml b/.idea/libraries/kotlinc_high_level_api.xml index a114836a34e4..aacd0adacd9e 100644 --- a/.idea/libraries/kotlinc_high_level_api.xml +++ b/.idea/libraries/kotlinc_high_level_api.xml @@ -1,11 +1,18 @@ - + + + + + bfcfa5886e90b7b09bdf4daedff0fa381b8ef11ab6cf65116db8dc078911ad9b + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_high_level_api_fe10.xml b/.idea/libraries/kotlinc_high_level_api_fe10.xml index 4b25d1e2ea91..fd09925bb76a 100644 --- a/.idea/libraries/kotlinc_high_level_api_fe10.xml +++ b/.idea/libraries/kotlinc_high_level_api_fe10.xml @@ -1,11 +1,18 @@ - + + + + + 5231fa4cba7050f5f7585c6a6989bc3d6c628210ed3124c8c2c12df91d42b96b + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_high_level_api_fir.xml b/.idea/libraries/kotlinc_high_level_api_fir.xml index 3f79b279fd40..11d272a0780c 100644 --- a/.idea/libraries/kotlinc_high_level_api_fir.xml +++ b/.idea/libraries/kotlinc_high_level_api_fir.xml @@ -1,11 +1,18 @@ - + + + + + 7a57bc41c87e0809e1ff8a514d90ee337d9dac270ce971769d81458f7436a9a1 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_high_level_api_fir_tests.xml b/.idea/libraries/kotlinc_high_level_api_fir_tests.xml index fa4ad57051d5..87b6e4d63a56 100644 --- a/.idea/libraries/kotlinc_high_level_api_fir_tests.xml +++ b/.idea/libraries/kotlinc_high_level_api_fir_tests.xml @@ -1,11 +1,18 @@ - + + + + + 5557165fc0c270000843a1720c525b42118f870f19d26646d5d1244e6371bfbb + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_high_level_api_impl_base.xml b/.idea/libraries/kotlinc_high_level_api_impl_base.xml index 800ae5291f23..ab0af372c0f6 100644 --- a/.idea/libraries/kotlinc_high_level_api_impl_base.xml +++ b/.idea/libraries/kotlinc_high_level_api_impl_base.xml @@ -1,11 +1,18 @@ - + + + + + d9ad61106023c956b0740db65e8d5742a03d9fac884fa95a00f76bba62f888cc + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_high_level_api_impl_base_tests.xml b/.idea/libraries/kotlinc_high_level_api_impl_base_tests.xml index 9ca44a62e22e..76d1dc5dc4ad 100644 --- a/.idea/libraries/kotlinc_high_level_api_impl_base_tests.xml +++ b/.idea/libraries/kotlinc_high_level_api_impl_base_tests.xml @@ -1,11 +1,18 @@ - + + + + + a327cbbb2fa2b8dd2377d3bc9649fe7a4f892055674282ee2393ad489583193c + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_incremental_compilation_impl_tests.xml b/.idea/libraries/kotlinc_incremental_compilation_impl_tests.xml index 8b4076cbb8cc..05f09919d3fc 100644 --- a/.idea/libraries/kotlinc_incremental_compilation_impl_tests.xml +++ b/.idea/libraries/kotlinc_incremental_compilation_impl_tests.xml @@ -1,11 +1,18 @@ - + + + + + 39ef63fa8c4dd786c0b89045ca5be6f871076068d8ebbbcfbb3d12ac1ebc4e19 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_build_common_tests.xml b/.idea/libraries/kotlinc_kotlin_build_common_tests.xml index 7fb08a733403..278690bd6081 100644 --- a/.idea/libraries/kotlinc_kotlin_build_common_tests.xml +++ b/.idea/libraries/kotlinc_kotlin_build_common_tests.xml @@ -1,11 +1,18 @@ - + + + + + e1686c994d521d32b0f2995964feacae8ccc1fe11843bfc65f0ad59eb122387b + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_compiler_cli.xml b/.idea/libraries/kotlinc_kotlin_compiler_cli.xml index a1835cb62419..f31c3c282dc1 100644 --- a/.idea/libraries/kotlinc_kotlin_compiler_cli.xml +++ b/.idea/libraries/kotlinc_kotlin_compiler_cli.xml @@ -1,11 +1,18 @@ - + + + + + af7008e8fc5a44f91454bb1b266723036aaf131ffc8e7853f277b62f858f34d0 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_compiler_common.xml b/.idea/libraries/kotlinc_kotlin_compiler_common.xml index 8295f79b980d..427a8d073413 100644 --- a/.idea/libraries/kotlinc_kotlin_compiler_common.xml +++ b/.idea/libraries/kotlinc_kotlin_compiler_common.xml @@ -1,11 +1,18 @@ - + + + + + 9fa76943a3a8780d14e17756fb28f70596edac0f1a3552fc42734b1caa90c0c6 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_compiler_fe10.xml b/.idea/libraries/kotlinc_kotlin_compiler_fe10.xml index c9233b56ce26..c463eea98d55 100644 --- a/.idea/libraries/kotlinc_kotlin_compiler_fe10.xml +++ b/.idea/libraries/kotlinc_kotlin_compiler_fe10.xml @@ -1,11 +1,18 @@ - + + + + + 8b53eab335255c3fdde9f8176d792d334b10849f6282381dbdc3c7c11f8cd59a + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_compiler_fir.xml b/.idea/libraries/kotlinc_kotlin_compiler_fir.xml index c073d79e7e49..6841990bec4a 100644 --- a/.idea/libraries/kotlinc_kotlin_compiler_fir.xml +++ b/.idea/libraries/kotlinc_kotlin_compiler_fir.xml @@ -1,11 +1,18 @@ - + + + + + 101f6624bc97fbb05d9bc7a350e9f1fb225ca43d1acbf878e132164e85d08457 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_compiler_ir.xml b/.idea/libraries/kotlinc_kotlin_compiler_ir.xml index fef122b3d84a..6fa32461f54a 100644 --- a/.idea/libraries/kotlinc_kotlin_compiler_ir.xml +++ b/.idea/libraries/kotlinc_kotlin_compiler_ir.xml @@ -1,11 +1,18 @@ - + + + + + c9bc4388754382ba31657d1297fa3a1984956c874283d61b32229e32dd755412 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_compiler_tests.xml b/.idea/libraries/kotlinc_kotlin_compiler_tests.xml index e70786754336..9f5a4271c5dc 100644 --- a/.idea/libraries/kotlinc_kotlin_compiler_tests.xml +++ b/.idea/libraries/kotlinc_kotlin_compiler_tests.xml @@ -1,11 +1,18 @@ - + + + + + 1d91fcf0eee713001de75dc50efdfbfe0cc242532cf768fd61af492fd6eb20a3 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_gradle_statistics.xml b/.idea/libraries/kotlinc_kotlin_gradle_statistics.xml index 4fbc26183694..c18f90069cf6 100644 --- a/.idea/libraries/kotlinc_kotlin_gradle_statistics.xml +++ b/.idea/libraries/kotlinc_kotlin_gradle_statistics.xml @@ -1,11 +1,18 @@ - + + + + + b85733a0ae14c035d391cae10cb7824aab122152d71f25ff5a3575e4f127d9d6 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_jps_common.xml b/.idea/libraries/kotlinc_kotlin_jps_common.xml index 619a2f8596f3..af9522efae95 100644 --- a/.idea/libraries/kotlinc_kotlin_jps_common.xml +++ b/.idea/libraries/kotlinc_kotlin_jps_common.xml @@ -1,11 +1,18 @@ - + + + + + 8af31d936c2f7a09b44c90af1dd2d480166ed1aa0ce1ddc71af34b12fcbab9d6 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_jps_plugin_classpath_bootstrap_for_tests.xml b/.idea/libraries/kotlinc_kotlin_jps_plugin_classpath_bootstrap_for_tests.xml index f0352a7aa530..e4bd60a58d4a 100644 --- a/.idea/libraries/kotlinc_kotlin_jps_plugin_classpath_bootstrap_for_tests.xml +++ b/.idea/libraries/kotlinc_kotlin_jps_plugin_classpath_bootstrap_for_tests.xml @@ -1,11 +1,18 @@ - + + + + + 20a706fa8d85ab4f954060ad496a8596a43da2dfaa35fa906ad977aac8ced741 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_script_runtime.xml b/.idea/libraries/kotlinc_kotlin_script_runtime.xml index 770d7d5d6926..08ed026f776a 100644 --- a/.idea/libraries/kotlinc_kotlin_script_runtime.xml +++ b/.idea/libraries/kotlinc_kotlin_script_runtime.xml @@ -1,11 +1,18 @@ - + + + + + 2ea5103795759f607c29f21d760efbe1828a5f11d0117e0ee7b81e1396555536 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_scripting_common.xml b/.idea/libraries/kotlinc_kotlin_scripting_common.xml index c7dd5770d74b..78bf47ac1473 100644 --- a/.idea/libraries/kotlinc_kotlin_scripting_common.xml +++ b/.idea/libraries/kotlinc_kotlin_scripting_common.xml @@ -1,11 +1,18 @@ - + + + + + aa5ae1093b1bbb4c05e87c8f021526a854368d36cd94dcf92d24fc007d939797 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_scripting_compiler_impl.xml b/.idea/libraries/kotlinc_kotlin_scripting_compiler_impl.xml index a6f76b90a4f5..b5d1187e48e6 100644 --- a/.idea/libraries/kotlinc_kotlin_scripting_compiler_impl.xml +++ b/.idea/libraries/kotlinc_kotlin_scripting_compiler_impl.xml @@ -1,11 +1,18 @@ - + + + + + 4ab53123f6267ff1be5e714c2b9dcfa2f231f0b2b4bbcb47a22a476adbf22ca9 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_scripting_jvm.xml b/.idea/libraries/kotlinc_kotlin_scripting_jvm.xml index 2557d96de87e..246ac9d1156e 100644 --- a/.idea/libraries/kotlinc_kotlin_scripting_jvm.xml +++ b/.idea/libraries/kotlinc_kotlin_scripting_jvm.xml @@ -1,11 +1,18 @@ - + + + + + 7a9839a277baf2e23005a18e1d739acd97575ddfe36e40b1ae2918d1f325fa4f + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlinx_serialization_compiler_plugin.xml b/.idea/libraries/kotlinc_kotlinx_serialization_compiler_plugin.xml index 3f4a8446caa1..69d22834c2ab 100644 --- a/.idea/libraries/kotlinc_kotlinx_serialization_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_kotlinx_serialization_compiler_plugin.xml @@ -1,11 +1,18 @@ - + + + + + cd083c139ddad8543ceba0192d70103ec7c443c3ad0e70b1aa8d1a95b7ab8c2f + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_lombok_compiler_plugin.xml b/.idea/libraries/kotlinc_lombok_compiler_plugin.xml index b4d334ad3eef..658ed1615466 100644 --- a/.idea/libraries/kotlinc_lombok_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_lombok_compiler_plugin.xml @@ -1,11 +1,18 @@ - + + + + + eb317a6e78cb8017a7ced75dbe12d87beba7eefafb9bf1631c545e892462a355 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_low_level_api_fir.xml b/.idea/libraries/kotlinc_low_level_api_fir.xml index 9a6c0a9e430e..0d3242c2d880 100644 --- a/.idea/libraries/kotlinc_low_level_api_fir.xml +++ b/.idea/libraries/kotlinc_low_level_api_fir.xml @@ -1,11 +1,18 @@ - + + + + + 60ca633509b11e8b765c215bd0bbcbdabcdcf7eb0964c2fc16ba6a8da09069ca + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_noarg_compiler_plugin.xml b/.idea/libraries/kotlinc_noarg_compiler_plugin.xml index b6fd153fe007..6536a40b2104 100644 --- a/.idea/libraries/kotlinc_noarg_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_noarg_compiler_plugin.xml @@ -1,11 +1,18 @@ - + + + + + 52c398c0afe6ad6ad1a9c1ed5e44081346f63be13d8164f2eff1c892955a2150 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_parcelize_compiler_plugin.xml b/.idea/libraries/kotlinc_parcelize_compiler_plugin.xml index fc7e17f3726b..2bbf6a82df92 100644 --- a/.idea/libraries/kotlinc_parcelize_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_parcelize_compiler_plugin.xml @@ -1,11 +1,18 @@ - + + + + + 63bde35a4b30426403a04514a500f8c6ed72eb7a8fc1567564b136d13fb94565 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_sam_with_receiver_compiler_plugin.xml b/.idea/libraries/kotlinc_sam_with_receiver_compiler_plugin.xml index 413282e19ef7..5a8719cd2dc0 100644 --- a/.idea/libraries/kotlinc_sam_with_receiver_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_sam_with_receiver_compiler_plugin.xml @@ -1,11 +1,18 @@ - + + + + + a36baa1fed10aa978adfe12b6924884856a6daa09894e98182368a644d34e4d1 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_scripting_compiler_plugin.xml b/.idea/libraries/kotlinc_scripting_compiler_plugin.xml index 228429619a95..68031adbc916 100644 --- a/.idea/libraries/kotlinc_scripting_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_scripting_compiler_plugin.xml @@ -1,11 +1,18 @@ - + + + + + 1c9623b97dbc2b2318a27c42526e636d64083bb2aa06bd2613f6154bea04fe22 + + + - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_symbol_light_classes.xml b/.idea/libraries/kotlinc_symbol_light_classes.xml index 5c994726b0ab..8d865fa31937 100644 --- a/.idea/libraries/kotlinc_symbol_light_classes.xml +++ b/.idea/libraries/kotlinc_symbol_light_classes.xml @@ -1,11 +1,18 @@ - + + + + + 31dda78dd29d692416b9ff8da002ffd1750ab6abeeb3a01e1f0a2c3ef877b6a9 + + + - + - + \ No newline at end of file diff --git a/plugins/kotlin/util/project-model-updater/resources/model.properties b/plugins/kotlin/util/project-model-updater/resources/model.properties index 87d9ce21f133..12931f0c1f6f 100644 --- a/plugins/kotlin/util/project-model-updater/resources/model.properties +++ b/plugins/kotlin/util/project-model-updater/resources/model.properties @@ -1,6 +1,6 @@ # Please do not touch this file. It is the responsibility of Kotlin/IntelliJ Kotlin team to advance kotlin compiler version -kotlincVersion=2.0.20-dev-2192 -kotlincArtifactsMode=BOOTSTRAP +kotlincVersion=2.0.20-dev-2794 +kotlincArtifactsMode=MAVEN jpsPluginVersion=1.9.23-release-779 jpsPluginArtifactsMode=MAVEN