diff --git a/.idea/libraries/kotlinc_allopen_compiler_plugin.xml b/.idea/libraries/kotlinc_allopen_compiler_plugin.xml
index f2978b533bb6..d394011dc80f 100644
--- a/.idea/libraries/kotlinc_allopen_compiler_plugin.xml
+++ b/.idea/libraries/kotlinc_allopen_compiler_plugin.xml
@@ -1,18 +1,18 @@
-
+
-
- 887a2bbd8d8bb333520eedffdb10b9dfe98f8a6a0a009ef07ec85eb14faad14c
+
+ 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 cef6c89b9c1e..42a43a8f76ad 100644
--- a/.idea/libraries/kotlinc_analysis_api_providers.xml
+++ b/.idea/libraries/kotlinc_analysis_api_providers.xml
@@ -1,18 +1,18 @@
-
+
-
- 2aef188e9c37940e9704d2308e1f172fe789e1ae921c804d43da438dbc5d613f
+
+ 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 a991b130310e..1376495bb9ab 100644
--- a/.idea/libraries/kotlinc_analysis_project_structure.xml
+++ b/.idea/libraries/kotlinc_analysis_project_structure.xml
@@ -1,18 +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 5868f1571232..9f2a70ebf49c 100644
--- a/.idea/libraries/kotlinc_android_extensions_compiler_plugin.xml
+++ b/.idea/libraries/kotlinc_android_extensions_compiler_plugin.xml
@@ -1,18 +1,18 @@
-
+
-
- 1e0615aa54d80d98aa5a39d86f735418fa7ed6fb1cfae25af19e15500b52451f
+
+ 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 a12f3fe42af2..bc680f7a8e76 100644
--- a/.idea/libraries/kotlinc_assignment_compiler_plugin.xml
+++ b/.idea/libraries/kotlinc_assignment_compiler_plugin.xml
@@ -1,18 +1,18 @@
-
+
-
- 3eed42d90d9d5643137010025f47caf27bef8ec14d19458c0ab4333780307ad8
+
+ 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 644014a6d8c9..aacd0adacd9e 100644
--- a/.idea/libraries/kotlinc_high_level_api.xml
+++ b/.idea/libraries/kotlinc_high_level_api.xml
@@ -1,18 +1,18 @@
-
+
-
- 15ff30641208ff6949950e76fd0a41feade4fb6d8597e16f4fb5a9a9231c4f3b
+
+ 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 3531074c3726..fd09925bb76a 100644
--- a/.idea/libraries/kotlinc_high_level_api_fe10.xml
+++ b/.idea/libraries/kotlinc_high_level_api_fe10.xml
@@ -1,18 +1,18 @@
-
+
-
- ae61ffe8994a222c95c2ddcdaf1215c9d1502b81e588b3768a676b04e86cec52
+
+ 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 d92c179e3ef4..11d272a0780c 100644
--- a/.idea/libraries/kotlinc_high_level_api_fir.xml
+++ b/.idea/libraries/kotlinc_high_level_api_fir.xml
@@ -1,18 +1,18 @@
-
+
-
- e377ad4b7456629dda54771b005e629398c8bf166c0f77046907c5f490433365
+
+ 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 ceec7e369b3c..87b6e4d63a56 100644
--- a/.idea/libraries/kotlinc_high_level_api_fir_tests.xml
+++ b/.idea/libraries/kotlinc_high_level_api_fir_tests.xml
@@ -1,18 +1,18 @@
-
+
-
- 5d5fdde8b0816ce4b10a24fab4d727a8b8d2bb099d7a876293ce868f20c9bd08
+
+ 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 d05fe2874fc3..ab0af372c0f6 100644
--- a/.idea/libraries/kotlinc_high_level_api_impl_base.xml
+++ b/.idea/libraries/kotlinc_high_level_api_impl_base.xml
@@ -1,18 +1,18 @@
-
+
-
- fdf2f2ad50ed19159d6b760b1db96b85588d860c61ee6a07a531239390d73786
+
+ 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 341a51cd699b..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,18 +1,18 @@
-
+
-
- f9379ccf26f25458f0576f68fdfb2f4cabb890d19c0bbeee56282c5af6c42204
+
+ 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 90abdfb43594..05f09919d3fc 100644
--- a/.idea/libraries/kotlinc_incremental_compilation_impl_tests.xml
+++ b/.idea/libraries/kotlinc_incremental_compilation_impl_tests.xml
@@ -1,18 +1,18 @@
-
+
-
- a1c7b435662d3863f9cd69af64c247e4c9d65f8337458e11c48e6178f8cd3fb2
+
+ 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 83849dae4611..278690bd6081 100644
--- a/.idea/libraries/kotlinc_kotlin_build_common_tests.xml
+++ b/.idea/libraries/kotlinc_kotlin_build_common_tests.xml
@@ -1,18 +1,18 @@
-
+
-
- 8710de97b317e4c1155e31d5fb486aa5ed54ef14e6edf0f087e05560b277d415
+
+ 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 76a531045bf5..f31c3c282dc1 100644
--- a/.idea/libraries/kotlinc_kotlin_compiler_cli.xml
+++ b/.idea/libraries/kotlinc_kotlin_compiler_cli.xml
@@ -1,18 +1,18 @@
-
+
-
- 2b09eb033680fa7fca8b151de293103e172212222bb74fc8eb381d807e316a44
+
+ 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 c23a5ad0ae64..427a8d073413 100644
--- a/.idea/libraries/kotlinc_kotlin_compiler_common.xml
+++ b/.idea/libraries/kotlinc_kotlin_compiler_common.xml
@@ -1,18 +1,18 @@
-
+
-
- 102ac452ef6ab3f5f211f90c7104fb229828507409de190979417c5b86c957cd
+
+ 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 21b23c79e609..c463eea98d55 100644
--- a/.idea/libraries/kotlinc_kotlin_compiler_fe10.xml
+++ b/.idea/libraries/kotlinc_kotlin_compiler_fe10.xml
@@ -1,18 +1,18 @@
-
+
-
- cee18085f9397561fe585e0d6023a51accbd58e69f9cea44bc6624d477e46a9e
+
+ 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 526c53f5cdd5..6841990bec4a 100644
--- a/.idea/libraries/kotlinc_kotlin_compiler_fir.xml
+++ b/.idea/libraries/kotlinc_kotlin_compiler_fir.xml
@@ -1,18 +1,18 @@
-
+
-
- 0f086305c92b119c437aeeeeb2e2193f0f568d21d059a6152ccceb2df9e5f247
+
+ 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 7c49f1f23c1e..6fa32461f54a 100644
--- a/.idea/libraries/kotlinc_kotlin_compiler_ir.xml
+++ b/.idea/libraries/kotlinc_kotlin_compiler_ir.xml
@@ -1,18 +1,18 @@
-
+
-
- 504226c3982f3359976b0e1f1d1cf6ecfb15f661a88b6cc7977c2eb436a1d301
+
+ 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 0f8bf0d96c47..9f5a4271c5dc 100644
--- a/.idea/libraries/kotlinc_kotlin_compiler_tests.xml
+++ b/.idea/libraries/kotlinc_kotlin_compiler_tests.xml
@@ -1,18 +1,18 @@
-
+
-
- ce63b9f7a42766d1754843ba5945a52e9f9b1819aa7719f795b1d2976a04ced9
+
+ 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 85fa020557e6..c18f90069cf6 100644
--- a/.idea/libraries/kotlinc_kotlin_gradle_statistics.xml
+++ b/.idea/libraries/kotlinc_kotlin_gradle_statistics.xml
@@ -1,18 +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 c9618cc62547..af9522efae95 100644
--- a/.idea/libraries/kotlinc_kotlin_jps_common.xml
+++ b/.idea/libraries/kotlinc_kotlin_jps_common.xml
@@ -1,18 +1,18 @@
-
+
-
- 5e97712501e43dc7d26e491550f87298b92db3020785d8086f59cb363207e782
+
+ 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 d2f632a0bc25..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,18 +1,18 @@
-
+
-
- adbb75204da2b6cc3ec835324cfd27e9693860a7d3ca860ef0c686d0439c1ac0
+
+ 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 0dab25da3b1f..08ed026f776a 100644
--- a/.idea/libraries/kotlinc_kotlin_script_runtime.xml
+++ b/.idea/libraries/kotlinc_kotlin_script_runtime.xml
@@ -1,18 +1,18 @@
-
+
-
- cdf0892f2a1c68fcf6fcb2eef594fe8f75f5a190694f8cb3e7777c4f2e9057d7
+
+ 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 019bb8fa9a33..78bf47ac1473 100644
--- a/.idea/libraries/kotlinc_kotlin_scripting_common.xml
+++ b/.idea/libraries/kotlinc_kotlin_scripting_common.xml
@@ -1,18 +1,18 @@
-
+
-
- da9eef8af88aeef7f4bc7abefe5d61cb88d5331a0b557e18cc2e510319f07985
+
+ 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 3f5be1920a3f..b5d1187e48e6 100644
--- a/.idea/libraries/kotlinc_kotlin_scripting_compiler_impl.xml
+++ b/.idea/libraries/kotlinc_kotlin_scripting_compiler_impl.xml
@@ -1,18 +1,18 @@
-
+
-
- e23d966b84ce7a5138c04326815d1bca2ea3beba7302c4cc9b62090d0f71df6d
+
+ 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 890c8cd9f3f8..246ac9d1156e 100644
--- a/.idea/libraries/kotlinc_kotlin_scripting_jvm.xml
+++ b/.idea/libraries/kotlinc_kotlin_scripting_jvm.xml
@@ -1,18 +1,18 @@
-
+
-
- 10c5972e8270a7c87b9ec4f64e98473bdf82c8cd3e15682bd2040053b82a3d22
+
+ 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 6d68f2bff262..69d22834c2ab 100644
--- a/.idea/libraries/kotlinc_kotlinx_serialization_compiler_plugin.xml
+++ b/.idea/libraries/kotlinc_kotlinx_serialization_compiler_plugin.xml
@@ -1,18 +1,18 @@
-
+
-
- 8a8fc59eddf65643f2d7495de30664bad0495c1759b8784456f71a91481147a0
+
+ 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 e5ff23459856..658ed1615466 100644
--- a/.idea/libraries/kotlinc_lombok_compiler_plugin.xml
+++ b/.idea/libraries/kotlinc_lombok_compiler_plugin.xml
@@ -1,18 +1,18 @@
-
+
-
- 1f2b31a9a0d5565280743abcd703d49a03b12055011a6187d4bb4cffb5a9ed38
+
+ 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 75220b7936e6..0d3242c2d880 100644
--- a/.idea/libraries/kotlinc_low_level_api_fir.xml
+++ b/.idea/libraries/kotlinc_low_level_api_fir.xml
@@ -1,18 +1,18 @@
-
+
-
- 11460217230d2708a49f76ff1b743722a500c1e2cb8a92345769f58891e1af19
+
+ 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 e802d8e23d7f..6536a40b2104 100644
--- a/.idea/libraries/kotlinc_noarg_compiler_plugin.xml
+++ b/.idea/libraries/kotlinc_noarg_compiler_plugin.xml
@@ -1,18 +1,18 @@
-
+
-
- d40bdfb9e890ae8c0e6118072b06cc431cbfe9c9d646c42108204a9f64402940
+
+ 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 776fe71ca3e9..2bbf6a82df92 100644
--- a/.idea/libraries/kotlinc_parcelize_compiler_plugin.xml
+++ b/.idea/libraries/kotlinc_parcelize_compiler_plugin.xml
@@ -1,18 +1,18 @@
-
+
-
- 0b9c2a9b176a94ae341469eb4159d0d657c86727797902b2ca8c1468da70c7a2
+
+ 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 f28809f06c9d..5a8719cd2dc0 100644
--- a/.idea/libraries/kotlinc_sam_with_receiver_compiler_plugin.xml
+++ b/.idea/libraries/kotlinc_sam_with_receiver_compiler_plugin.xml
@@ -1,18 +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 78abf2600e57..68031adbc916 100644
--- a/.idea/libraries/kotlinc_scripting_compiler_plugin.xml
+++ b/.idea/libraries/kotlinc_scripting_compiler_plugin.xml
@@ -1,18 +1,18 @@
-
+
-
- 84b62b5cc5acb66bb3a9adf76210cd8566e657654f8a8c643cfbbc8408284767
+
+ 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 1c834b428d7d..8d865fa31937 100644
--- a/.idea/libraries/kotlinc_symbol_light_classes.xml
+++ b/.idea/libraries/kotlinc_symbol_light_classes.xml
@@ -1,18 +1,18 @@
-
+
-
- 031147e89f125081072584c70609d7810aba31e29862c30188e8872329b2c8a1
+
+ 31dda78dd29d692416b9ff8da002ffd1750ab6abeeb3a01e1f0a2c3ef877b6a9
-
+
-
+
\ No newline at end of file
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/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 302cf9a1d582..c678f1de4cdd 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
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.analysis.api.calls.KtImplicitReceiverValue
import org.jetbrains.kotlin.analysis.api.calls.KtReceiverValue
import org.jetbrains.kotlin.analysis.api.calls.KtSmartCastedReceiverValue
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
@@ -72,7 +73,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) {
@@ -99,7 +101,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/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/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))
}
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/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/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/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/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/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 {
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
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) {
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/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/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
+ }
+ }
}
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)?.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 }
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/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
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/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()
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
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/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
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");
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 5d8ae27a5d91..c81775255bf9 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,16 +12,14 @@ 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
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
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
@@ -54,6 +52,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
@@ -227,7 +226,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)
@@ -248,11 +247,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())
}
}
@@ -273,15 +272,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)
}
@@ -313,11 +321,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 }
)
}
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