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