diff --git a/.idea/libraries/kotlinc_allopen_compiler_plugin.xml b/.idea/libraries/kotlinc_allopen_compiler_plugin.xml index 23dbeabd4f2e..b4d467c01e29 100644 --- a/.idea/libraries/kotlinc_allopen_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_allopen_compiler_plugin.xml @@ -1,18 +1,18 @@ - + - + ddf72df178668a0deab4460fcfd64642f823b9834b8a88102a7bf4145eca0efe - + - + \ 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 770637ab1be4..d24045ebc6ed 100644 --- a/.idea/libraries/kotlinc_analysis_api_providers.xml +++ b/.idea/libraries/kotlinc_analysis_api_providers.xml @@ -1,18 +1,18 @@ - + - - 89fdf915639b991a00e24209669f8eabf2127bd6ee02247adc81e328df5632fb + + c748938a365d687d79d8692fdc4db8477a053b195344765ae0d8fbd548bd7c7e - + - + \ 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 d3d24f51563e..b7e07ee1295a 100644 --- a/.idea/libraries/kotlinc_analysis_project_structure.xml +++ b/.idea/libraries/kotlinc_analysis_project_structure.xml @@ -1,18 +1,18 @@ - + - - ec3a35f2cb718777d77265c84165b562a8f666526ea5c9073b65f0df8f3a0b94 + + 8f96f27656f1fb78b40a9cefb7a987af0e8672ff4d9324c6bc5cea3fcde40b9b - + - + \ 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 9fbe8eac953e..6564d969f675 100644 --- a/.idea/libraries/kotlinc_android_extensions_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_android_extensions_compiler_plugin.xml @@ -1,18 +1,18 @@ - + - - a7007b8bbef5f9f019e0153eb78b1ddb5cf4e59cb69f66297e9fddb9edac0a66 + + 893d752521e9103097db28bb362f2aa54702d3b50c40ea42960305525374e590 - + - + \ 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 420ad79cf061..f7062c2e7372 100644 --- a/.idea/libraries/kotlinc_assignment_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_assignment_compiler_plugin.xml @@ -1,18 +1,18 @@ - + - - 7d68c0df49e2a70e5629f790cd0b339cbfc5341a2e5bf6d2bbfda16abf7d4285 + + 5fbe701b504ad9f6880942c20f5966b1134d0c4ca82e99463854d1a0ad6bb3b3 - + - + \ 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 f2a14c747c9a..b54bbe730dd2 100644 --- a/.idea/libraries/kotlinc_high_level_api.xml +++ b/.idea/libraries/kotlinc_high_level_api.xml @@ -1,18 +1,18 @@ - + - - bf44c46253233cf22b1cb51d817799ae22b1a9d24067a9cbbd731e5ab6caded4 + + 3515fb87590708a6205ec8e6f64fb9175824f5fc7c323a1763dc5144bcd45dfe - + - + \ 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 b0a2311bd71d..c510f8140e4e 100644 --- a/.idea/libraries/kotlinc_high_level_api_fe10.xml +++ b/.idea/libraries/kotlinc_high_level_api_fe10.xml @@ -1,18 +1,18 @@ - + - - 790c9d1ef0da1f56904a3233150ff8b70a6e8d86839e4e5bfa47e6c8a7897154 + + 538fd570d5f09e9116e44546d3206cff703b333c5211ef6e9f02817a265a1473 - + - + \ 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 bf0451acd960..65d7111bb80d 100644 --- a/.idea/libraries/kotlinc_high_level_api_fir.xml +++ b/.idea/libraries/kotlinc_high_level_api_fir.xml @@ -1,18 +1,18 @@ - + - - 4861094faece32eec7fbab70599af86123ef27a5c40b908b32e56255657a4d39 + + f5b4fc8d05b9eb687958b4ceea43ed79e7d3c61df68ffef67a38e01493ec0003 - + - + \ 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 0e4cbeaf9a5b..6a8635575c9c 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 @@ - + - - eae32f4e907720e000ee9c0e89a8c2ae846c3b09c70484cf1fb99c198833078e + + e8dbf32719346abe35ccc2b06549ae0743693bcfa4af7cfe118a110aa2ebf2b3 - + - + \ 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 b227e47b4cb3..63661107ff98 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 @@ - + - - d809596ffec9bb278947ec1fe3c20b18ac36d93e0beb8bd4918011ebe34e8a4c + + c29bc388417b5044e026369109af24ec119662c61d5dfbcde4bb41b63ffa351d - + - + \ 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 cbc8f0caa669..db7dac1c956c 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 @@ - + - - a3f332e6a539b64db0c3786183f72a4894901f0504e56d3cf24a98773b6e9818 + + dfdcc48a0902ce3066948864e94099daa9e7c6261f8f193f38a304a3072c82b3 - + - + \ 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 5e3b0c8306d9..a80859ba689d 100644 --- a/.idea/libraries/kotlinc_incremental_compilation_impl_tests.xml +++ b/.idea/libraries/kotlinc_incremental_compilation_impl_tests.xml @@ -1,18 +1,18 @@ - + - - 2dbf046fc51ad2ab2a3e4ab1668a76a17039ab6d211748bded2d32dc80f598b0 + + 97b7766c0fb7b2abe8ac61e826b7ca86c6524cfdb2550e41f568e33a26675b8f - + - + \ 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 0570ff42a050..a55894857b31 100644 --- a/.idea/libraries/kotlinc_kotlin_build_common_tests.xml +++ b/.idea/libraries/kotlinc_kotlin_build_common_tests.xml @@ -1,18 +1,18 @@ - + - - fd32673e172771aa481748ed3b5ae7c41d3bf57858a243d45a78ad9b9e317413 + + 8bc3cf8da11bcc47127c7037e05fca441932fb073eb55b175b48f637bac457a0 - + - + \ 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 ad8e0eb2c649..d173835adab8 100644 --- a/.idea/libraries/kotlinc_kotlin_compiler_cli.xml +++ b/.idea/libraries/kotlinc_kotlin_compiler_cli.xml @@ -1,18 +1,18 @@ - + - - 8e9b234e635346b81c55784563829d3feb14ece392eba0d748921b33e77889c8 + + 5256676ec55e96ab5ae8c69155bfed2b5aabe3be688acb352fee49382ffb7996 - + - + \ 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 85d9bd938a84..680393419699 100644 --- a/.idea/libraries/kotlinc_kotlin_compiler_common.xml +++ b/.idea/libraries/kotlinc_kotlin_compiler_common.xml @@ -1,18 +1,18 @@ - + - - 2d25341dddb8ba0e0c39a1499955315f2f44106833de8917f5009050a80edd45 + + d14ec9f5a6b76a184d077ae39609302855818b007df2c23f4238b26ab2c37385 - + - + \ 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 7c8ff55da80a..60acd3ad3c77 100644 --- a/.idea/libraries/kotlinc_kotlin_compiler_fe10.xml +++ b/.idea/libraries/kotlinc_kotlin_compiler_fe10.xml @@ -1,18 +1,18 @@ - + - - ab90822d2c5c5971c4bf38c0be4f12ba58753293ab995ba13652d0446c345e2c + + cd1da119d3819c6d5a7731a49ae9f0517e9e11d3943c2631b9e78be4d6269fb2 - + - + \ 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 c2d9e20e02fe..f48d42771cfa 100644 --- a/.idea/libraries/kotlinc_kotlin_compiler_fir.xml +++ b/.idea/libraries/kotlinc_kotlin_compiler_fir.xml @@ -1,18 +1,18 @@ - + - - 6a5e30e7d2117f4cf318c6534a524259cedcc04b0747d5d8d934375b4c91a537 + + 948e68ef2fe646907a29bc51bf8bf51e4331a528e605dcff06e01fd6fa0e7086 - + - + \ 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 597b6311104e..2eb7aa2c0744 100644 --- a/.idea/libraries/kotlinc_kotlin_compiler_ir.xml +++ b/.idea/libraries/kotlinc_kotlin_compiler_ir.xml @@ -1,18 +1,18 @@ - + - - d7ca67c2016096cc8188406f403187fac067caa3e751c97775dd6ccbbe42bb52 + + 4f332ba31fb80dfdb714350fc6c2d248a4f395ad79d95a6c414eca0cb5f3e790 - + - + \ 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 bf9194b9eedf..be430222a278 100644 --- a/.idea/libraries/kotlinc_kotlin_compiler_tests.xml +++ b/.idea/libraries/kotlinc_kotlin_compiler_tests.xml @@ -1,18 +1,18 @@ - + - - 4690fd58984f14ade528fd4b9871120275c57af5ece530ec1c46b0fc0a5ea568 + + e58124ba3b3e54a075af11fbadf935ca6a588fd0047a21b70df9540a30f9fd7e - + - + \ 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 2319ffe9620f..4470f669b4f5 100644 --- a/.idea/libraries/kotlinc_kotlin_gradle_statistics.xml +++ b/.idea/libraries/kotlinc_kotlin_gradle_statistics.xml @@ -1,18 +1,18 @@ - + - - ef0252705e16616de7416052b549a3751776a4afd612f2dfd2aa8b5013c9a75d + + 6b7c85675af645d04329526c3b2a892950d6709d6068627a7c6b6e9e565d24a4 - + - + \ 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 bb9ffaf8ab46..180048ca7322 100644 --- a/.idea/libraries/kotlinc_kotlin_jps_common.xml +++ b/.idea/libraries/kotlinc_kotlin_jps_common.xml @@ -1,18 +1,18 @@ - + - - 704a1119fb9d230dd1df129adeb81ddf549e48fbd33ff1c417636a218050b2de + + 3096663591312558cdda2780da243b8fd1115ddb60d4901496344af024b22424 - + - + \ 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 52707ddc1a2d..3fd251fbd385 100644 --- a/.idea/libraries/kotlinc_kotlin_script_runtime.xml +++ b/.idea/libraries/kotlinc_kotlin_script_runtime.xml @@ -1,18 +1,18 @@ - + - - 00965fa842543f930c8cbef0648b48b444c8571e1b30a8c3d3c6ceb5bec99701 + + c8c0551c3a58b6a508452cd998ec643c54616c7b263eee93b2309c377cc88011 - + - + \ 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 796f7d8f1598..5b027cbc2469 100644 --- a/.idea/libraries/kotlinc_kotlin_scripting_common.xml +++ b/.idea/libraries/kotlinc_kotlin_scripting_common.xml @@ -1,18 +1,18 @@ - + - - e1e6d7c7c0d08c37d6940327d289f72b226910722855c4e12644891e15601f5f + + fb23eeab32ff3b668488bcd6364ccc8c184856708f80f93790cbdad10ae6a2df - + - + \ 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 c9fa627cbae3..6ee82e98b544 100644 --- a/.idea/libraries/kotlinc_kotlin_scripting_compiler_impl.xml +++ b/.idea/libraries/kotlinc_kotlin_scripting_compiler_impl.xml @@ -1,18 +1,18 @@ - + - - fbba3ed8915bc536f6d8033363f2b27652f16604df87c1a292dd1d14a88b73a3 + + a2dfb7446c62d612e6779fd7c7d711f4a2ef9df078135750c2946fb1c3a342c9 - + - + \ 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 33108cac8fcd..ee6cd5f6c254 100644 --- a/.idea/libraries/kotlinc_kotlin_scripting_jvm.xml +++ b/.idea/libraries/kotlinc_kotlin_scripting_jvm.xml @@ -1,18 +1,18 @@ - + - - 4292efd8dfd2ee0c22edf048f5d2420d21d3dfb563dc9bce26ade225ade7273c + + 18f229e607d32cd92828ca4b9883d03530c0a5976993c26a9d60a81fb202565a - + - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_stdlib.xml b/.idea/libraries/kotlinc_kotlin_stdlib.xml index 390f05a5339f..b81c6e496a3c 100644 --- a/.idea/libraries/kotlinc_kotlin_stdlib.xml +++ b/.idea/libraries/kotlinc_kotlin_stdlib.xml @@ -1,18 +1,9 @@ - + - - 1f71be99add6fb58560f6f588b7d7ef28b7dcc6f84a3d8a5d490ea6ca61f3a29 - - - 465b9a646b1a79fea62ab55f09058873ce2a283764bb0d727611c2a03b610657 - - - 0571192be26fb22f7b63d40351ffb5d9f7e6a4150df55f9e8bebe2623c400bb9 - - - 02bd856fe93d67afd252e9903f95ebd78e8a34507f211477e44a1a580f070584 + + 045cc62b8df96cc13e466dce507d9ccb0b3a6950d91726ffb49d13ea0cf0264f @@ -23,17 +14,11 @@ - - - - + - - - - + \ No newline at end of file diff --git a/.idea/libraries/kotlinc_kotlin_stdlib_minimal_for_test.xml b/.idea/libraries/kotlinc_kotlin_stdlib_minimal_for_test.xml index b70b1e0ab337..c0f4a16df576 100644 --- a/.idea/libraries/kotlinc_kotlin_stdlib_minimal_for_test.xml +++ b/.idea/libraries/kotlinc_kotlin_stdlib_minimal_for_test.xml @@ -1,18 +1,18 @@ - + - - 6c4df6978ac2dd6313c737583e58300148442add91932a008dcbcfb063704639 + + 15a6e80e211fb0e917439a6df18e37fcd6a9c1ae9fc97ec9ab893674e7cce13e - + - + \ 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 d51dc870521a..01c498bd6ed6 100644 --- a/.idea/libraries/kotlinc_kotlinx_serialization_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_kotlinx_serialization_compiler_plugin.xml @@ -1,18 +1,18 @@ - + - - 511745d5976bfb0bce4a993f0f848e5e4f15558ac63e90f8b354d86d8e535aae + + f86d1be3a063b73ed92c056fa6ad93535a13997694cc8c8d39334bf70047655e - + - + \ 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 937e5744bff4..cfc267df7ac2 100644 --- a/.idea/libraries/kotlinc_lombok_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_lombok_compiler_plugin.xml @@ -1,18 +1,18 @@ - + - - 994e0de733fe43b3c2c594ec8c5ac8106e2372e14bcf0a60942c6ae23fe682b3 + + 2b95f437731ee0f52a202e456fbdc68f4efa06d319e1db72d7fde2a21cf2db88 - + - + \ 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 eb76eb5a7e00..35c649f566ac 100644 --- a/.idea/libraries/kotlinc_low_level_api_fir.xml +++ b/.idea/libraries/kotlinc_low_level_api_fir.xml @@ -1,18 +1,18 @@ - + - - eb69492c21b257aaaccff158a4db8822efd77e9b61a06941fbcddc73cedd0fbe + + 8de74e90fb94d0d886a488450923421d0dba6edd19fd8c69b02d014ad0da565a - + - + \ 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 cab07cdcefaa..d5242584395e 100644 --- a/.idea/libraries/kotlinc_noarg_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_noarg_compiler_plugin.xml @@ -1,18 +1,18 @@ - + - + efb8097b25caed72eb220f0836959a6ed3d264a94f6a21233cb4c57a09c38b42 - + - + \ 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 d036ed0764f9..3f7904c6bd8a 100644 --- a/.idea/libraries/kotlinc_parcelize_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_parcelize_compiler_plugin.xml @@ -1,18 +1,18 @@ - + - - e1cae6d063de2c43011204e3fdb8ea9b209a68742b6856d2b67d140f04074836 + + 1ed1f85971b554df7c82caecdbec585a5333d494b72fd01d479bf60b72a0a000 - + - + \ 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 e5b811207900..b43631f9ea39 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 @@ - + - - 59a4f1fae9b7a4d8c3ea3739f728c6ea6973612554aea0f210eb1543499227f1 + + 15e4e444653c60b47612e8125950cf97375c573fd8f441e4b0ab0f79e69b5b46 - + - + \ 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 3b3406090ad4..ea4b5da6c627 100644 --- a/.idea/libraries/kotlinc_scripting_compiler_plugin.xml +++ b/.idea/libraries/kotlinc_scripting_compiler_plugin.xml @@ -1,18 +1,18 @@ - + - - e6babe8a19873e036c635f8219280bf8c67f1570eea9a2dcdbf5932fee2ed0d3 + + 2997253b6b0b78e238b9a20d3777b27c620415c7cbd17ddd4252d7ecbad4ed30 - + - + \ 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 34b8b750062f..9b68a5f904c6 100644 --- a/.idea/libraries/kotlinc_symbol_light_classes.xml +++ b/.idea/libraries/kotlinc_symbol_light_classes.xml @@ -1,18 +1,18 @@ - + - - 6d093b58dc94e04727988716535b59240cefd326832f31036b8b13c54f3f47fa + + 61417bfd690fb05403b541b485b6668e108a7e161cec28e2275cd0b833b8d2a4 - + - + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index 831d4c73c556..f0a7bf2e4941 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -1149,10 +1149,11 @@ + + - @@ -1242,6 +1243,7 @@ + @@ -1266,7 +1268,9 @@ - + + + diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaUtilImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaUtilImpl.java index 4fd89edcaec0..704cb34752f6 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaUtilImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaUtilImpl.java @@ -248,6 +248,10 @@ public class RefJavaUtilImpl extends RefJavaUtil { @Override public boolean visitCallableReferenceExpression(@NotNull UCallableReferenceExpression methodRef) { + UExpression qualifierExpression = methodRef.getQualifierExpression(); + if (qualifierExpression != null) { + qualifierExpression.accept(this); + } RefElement refMethod = refManager.getReference(methodRef.getSourcePsi()); if (refFrom == refMethod) { visitReferenceExpression(methodRef); @@ -641,18 +645,17 @@ public class RefJavaUtilImpl extends RefJavaUtil { return Integer.compare(getAccessNumber(a1), getAccessNumber(a2)); } - @SuppressWarnings("StringEquality") private static int getAccessNumber(String a) { - if (a == PsiModifier.PRIVATE) { + if (PsiModifier.PRIVATE.equals(a)) { return 0; } - if (a == PsiModifier.PACKAGE_LOCAL) { + if (PsiModifier.PACKAGE_LOCAL.equals(a)) { return 1; } - if (a == PsiModifier.PROTECTED) { + if (PsiModifier.PROTECTED.equals(a)) { return 2; } - if (a == PsiModifier.PUBLIC) return 3; + if (PsiModifier.PUBLIC.equals(a)) return 3; return -1; } diff --git a/java/java-tests/testData/inspection/jvm/deadCode/usagesInCallableReceiver/expected.xml b/java/java-tests/testData/inspection/jvm/deadCode/usagesInCallableReceiver/expected.xml new file mode 100644 index 000000000000..72a38af0352a --- /dev/null +++ b/java/java-tests/testData/inspection/jvm/deadCode/usagesInCallableReceiver/expected.xml @@ -0,0 +1,8 @@ + + + + TC.kt + 6 + Parameter <code>s</code> is not used + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/jvm/deadCode/usagesInCallableReceiver/src/TC.kt b/java/java-tests/testData/inspection/jvm/deadCode/usagesInCallableReceiver/src/TC.kt new file mode 100644 index 000000000000..3f801b4efa2a --- /dev/null +++ b/java/java-tests/testData/inspection/jvm/deadCode/usagesInCallableReceiver/src/TC.kt @@ -0,0 +1,10 @@ +fun main() { + foo(1, "") +} + +fun foo(i: Int, + s: String //todo wrongly marked as unused, because simple references in callables are treated as class references +) { + println("Foo $i"::toString) + println(s::toString) +} \ No newline at end of file diff --git a/jvm/jvm-analysis-kotlin-tests/testSrc/com/intellij/codeInspection/tests/kotlin/KotlinJavaApiUsageInspectionTest.kt b/jvm/jvm-analysis-kotlin-tests/testSrc/com/intellij/codeInspection/tests/kotlin/KotlinJavaApiUsageInspectionTest.kt index 35c67824b6f5..30fb892c0d85 100644 --- a/jvm/jvm-analysis-kotlin-tests/testSrc/com/intellij/codeInspection/tests/kotlin/KotlinJavaApiUsageInspectionTest.kt +++ b/jvm/jvm-analysis-kotlin-tests/testSrc/com/intellij/codeInspection/tests/kotlin/KotlinJavaApiUsageInspectionTest.kt @@ -44,6 +44,19 @@ class KotlinJavaApiUsageInspectionTest : JavaApiUsageInspectionTestBase() { """.trimIndent()) } + fun `test reference in callable reference`() { + myFixture.setLanguageLevel(LanguageLevel.JDK_1_6) + val withErrorMessage = "\"default charset \${StandardCharsets.UTF_8}\"::toString" + myFixture.testHighlighting(JvmLanguage.KOTLIN, """ + import java.nio.charset.StandardCharsets + + fun main() { + ${withErrorMessage} + } + """.trimIndent()) + ""::toString + } + fun `test annotation`() { myFixture.setLanguageLevel(LanguageLevel.JDK_1_6) myFixture.testHighlighting(JvmLanguage.KOTLIN, """ diff --git a/jvm/jvm-analysis-kotlin-tests/testSrc/com/intellij/codeInspection/tests/kotlin/UnusedDeclarationKtTest20.java b/jvm/jvm-analysis-kotlin-tests/testSrc/com/intellij/codeInspection/tests/kotlin/UnusedDeclarationKtTest20.java index 8cf7a0840547..e5b4fae44a89 100644 --- a/jvm/jvm-analysis-kotlin-tests/testSrc/com/intellij/codeInspection/tests/kotlin/UnusedDeclarationKtTest20.java +++ b/jvm/jvm-analysis-kotlin-tests/testSrc/com/intellij/codeInspection/tests/kotlin/UnusedDeclarationKtTest20.java @@ -74,6 +74,11 @@ public class UnusedDeclarationKtTest20 extends AbstractUnusedDeclarationTest { doTest("deadCode/" + getTestName(true), myToolWrapper); } + public void testUsagesInCallableReceiver() { + myTool.getSharedLocalInspectionTool().PARAMETER = true; + doTest("deadCode/" + getTestName(true), myToolWrapper); + } + public void testMainParameter() { myTool.getSharedLocalInspectionTool().PARAMETER = true; myTool.getSharedLocalInspectionTool().LOCAL_VARIABLE = false; diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/kotlin/KotlinPluginBuilder.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/kotlin/KotlinPluginBuilder.kt index 1b7029fae40e..1f1fc527ca3b 100644 --- a/platform/build-scripts/src/org/jetbrains/intellij/build/kotlin/KotlinPluginBuilder.kt +++ b/platform/build-scripts/src/org/jetbrains/intellij/build/kotlin/KotlinPluginBuilder.kt @@ -47,7 +47,6 @@ object KotlinPluginBuilder { "kotlin.base.scripting", "kotlin.base.analysis-api-providers", "kotlin.base.analysis", - "kotlin.base.highlighting", "kotlin.base.code-insight", "kotlin.base.jps", "kotlin.base.analysis-api.utils", @@ -62,6 +61,7 @@ object KotlinPluginBuilder { "kotlin.base.fe10.highlighting", "kotlin.base.fe10.code-insight", "kotlin.base.fe10.obsolete-compat", + "kotlin.base.fe10.project-structure", "kotlin.core", "kotlin.idea", "kotlin.fir.frontend-independent", @@ -156,6 +156,7 @@ object KotlinPluginBuilder { "kotlin.features-trainer", "kotlin.base.fir.analysis-api-providers", "kotlin.base.fir.code-insight", + "kotlin.base.fir.project-structure", "kotlin.code-insight.api", "kotlin.code-insight.utils", "kotlin.code-insight.intentions-shared", @@ -181,7 +182,9 @@ object KotlinPluginBuilder { "kotlin.fir", "kotlin.searching.k2", "kotlin.searching.base", - "kotlin.highlighting", + "kotlin.highlighting.shared", + "kotlin.highlighting.k1", + "kotlin.highlighting.k2", "kotlin.uast.uast-kotlin-fir", "kotlin.uast.uast-kotlin-idea-fir", "kotlin.fir.fir-low-level-api-ide-impl", diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/EditInspectionToolsSettingsInSuppressedPlaceIntention.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/EditInspectionToolsSettingsInSuppressedPlaceIntention.java index ad9daa584ce8..de18439737be 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/EditInspectionToolsSettingsInSuppressedPlaceIntention.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/EditInspectionToolsSettingsInSuppressedPlaceIntention.java @@ -17,7 +17,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class EditInspectionToolsSettingsInSuppressedPlaceIntention implements IntentionAction { - private String myId; private String myDisplayName; @Override @@ -61,25 +60,26 @@ public class EditInspectionToolsSettingsInSuppressedPlaceIntention implements In @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - myId = getSuppressedId(editor, file); - if (myId != null) { - InspectionToolWrapper toolWrapper = getTool(project, file); + String suppressedId = getSuppressedId(editor, file); + if (suppressedId != null) { + InspectionToolWrapper toolWrapper = getTool(project, file, suppressedId); if (toolWrapper == null) return false; myDisplayName = toolWrapper.getDisplayName(); } - return myId != null; + return suppressedId != null; } @Nullable - private InspectionToolWrapper getTool(final Project project, final PsiFile file) { + private static InspectionToolWrapper getTool(final Project project, final PsiFile file, final String suppressId) { + if (suppressId == null) return null; final InspectionProjectProfileManager projectProfileManager = InspectionProjectProfileManager.getInstance(project); final InspectionProfileImpl inspectionProfile = projectProfileManager.getCurrentProfile(); - return inspectionProfile.getToolById(myId, file); + return inspectionProfile.getToolById(suppressId, file); } @Override public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - InspectionToolWrapper toolWrapper = getTool(project, file); + InspectionToolWrapper toolWrapper = getTool(project, file, getSuppressedId(editor, file)); if (toolWrapper == null) return; final InspectionProjectProfileManager projectProfileManager = InspectionProjectProfileManager.getInstance(project); final InspectionProfileImpl inspectionProfile = projectProfileManager.getCurrentProfile(); diff --git a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessorBase.java b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessorBase.java index be75a82bc89f..fb6cbccb39b4 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessorBase.java +++ b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessorBase.java @@ -12,6 +12,8 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiManager; +import com.intellij.psi.SmartPointerManager; +import com.intellij.psi.SmartPsiElementPointer; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.listeners.RefactoringElementListener; @@ -156,14 +158,19 @@ public abstract class ChangeSignatureProcessorBase extends BaseRefactoringProces protected void performRefactoring(UsageInfo @NotNull [] usages) { RefactoringTransaction transaction = getTransaction(); final ChangeInfo changeInfo = myChangeInfo; - final RefactoringElementListener elementListener = transaction == null ? null : transaction.getElementListener(changeInfo.getMethod()); - final String fqn = CopyReferenceAction.elementToFqn(changeInfo.getMethod()); + PsiElement method = changeInfo.getMethod(); + final RefactoringElementListener elementListener = transaction == null ? null : transaction.getElementListener(method); + final String fqn = CopyReferenceAction.elementToFqn(method); if (fqn != null) { + SmartPsiElementPointer pointer = SmartPointerManager.createPointer(method); UndoableAction action = new BasicUndoableAction() { @Override public void undo() { if (elementListener instanceof UndoRefactoringElementListener) { - ((UndoRefactoringElementListener)elementListener).undoElementMovedOrRenamed(changeInfo.getMethod(), fqn); + PsiElement element = pointer.getElement(); + if (element != null) { + ((UndoRefactoringElementListener)elementListener).undoElementMovedOrRenamed(element, fqn); + } } } @@ -175,7 +182,6 @@ public abstract class ChangeSignatureProcessorBase extends BaseRefactoringProces } try { doChangeSignature(changeInfo, usages); - final PsiElement method = changeInfo.getMethod(); LOG.assertTrue(method.isValid()); if (elementListener != null && changeInfo.isNameChanged()) { elementListener.elementRenamed(method); diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/createObjectAndMoveProhibitedDeclarationsFix/MoveProhibitedDeclarations.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/createObjectAndMoveProhibitedDeclarationsFix/MoveProhibitedDeclarations.kt index 769fd16892fd..45c16e679718 100644 --- a/plugins/devkit/devkit-kotlin-tests/testData/inspections/createObjectAndMoveProhibitedDeclarationsFix/MoveProhibitedDeclarations.kt +++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/createObjectAndMoveProhibitedDeclarationsFix/MoveProhibitedDeclarations.kt @@ -1,6 +1,7 @@ import com.intellij.openapi.diagnostic.Logger class MyExtensionImpl : MyExtension { + object Util companion object { // loggers are allowed diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/createObjectAndMoveProhibitedDeclarationsFix/MoveProhibitedDeclarations_after.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/createObjectAndMoveProhibitedDeclarationsFix/MoveProhibitedDeclarations_after.kt index 8d417aa0731b..e9daa69692cc 100644 --- a/plugins/devkit/devkit-kotlin-tests/testData/inspections/createObjectAndMoveProhibitedDeclarationsFix/MoveProhibitedDeclarations_after.kt +++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/createObjectAndMoveProhibitedDeclarationsFix/MoveProhibitedDeclarations_after.kt @@ -1,8 +1,9 @@ import com.intellij.openapi.diagnostic.Logger class MyExtensionImpl : MyExtension { + object Util - object Util { + object Util1 { // test properties' moving val s get() = "" @@ -38,6 +39,6 @@ class MyExtensionImpl : MyExtension { fun main() { // test references - MyExtensionImpl.Util.foo() - MyExtensionImpl.Util.a + MyExtensionImpl.Util1.foo() + MyExtensionImpl.Util1.a } \ No newline at end of file diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/createObjectAndMoveProhibitedDeclarationsFix/MoveProhibitedDeclarations_references_after.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/createObjectAndMoveProhibitedDeclarationsFix/MoveProhibitedDeclarations_references_after.kt index a031e4e66e14..cd49a186acaf 100644 --- a/plugins/devkit/devkit-kotlin-tests/testData/inspections/createObjectAndMoveProhibitedDeclarationsFix/MoveProhibitedDeclarations_references_after.kt +++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/createObjectAndMoveProhibitedDeclarationsFix/MoveProhibitedDeclarations_references_after.kt @@ -1,5 +1,5 @@ // test outside references fun main() { - MyExtensionImpl.Util.foo() - MyExtensionImpl.Util.a + MyExtensionImpl.Util1.foo() + MyExtensionImpl.Util1.a } \ No newline at end of file diff --git a/plugins/devkit/intellij.kotlin.devkit/src/inspections/CompanionObjectInExtensionInspection.kt b/plugins/devkit/intellij.kotlin.devkit/src/inspections/CompanionObjectInExtensionInspection.kt index da721abd5585..6e9d88b0726e 100644 --- a/plugins/devkit/intellij.kotlin.devkit/src/inspections/CompanionObjectInExtensionInspection.kt +++ b/plugins/devkit/intellij.kotlin.devkit/src/inspections/CompanionObjectInExtensionInspection.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.analysis.api.analyze import org.jetbrains.kotlin.analysis.api.lifetime.allowAnalysisOnEdt import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability import org.jetbrains.kotlin.asJava.toLightClass +import org.jetbrains.kotlin.idea.base.codeInsight.KotlinDeclarationNameValidator import org.jetbrains.kotlin.idea.base.codeInsight.KotlinNameSuggester import org.jetbrains.kotlin.idea.base.codeInsight.KotlinNameSuggestionProvider import org.jetbrains.kotlin.idea.base.fe10.codeInsight.newDeclaration.Fe10KotlinNewDeclarationNameValidator @@ -192,10 +193,12 @@ private class CreateObjectAndMoveProhibitedDeclarationsQuickFix( private fun suggestNameForObjectInstance(companionObject: KtObjectDeclaration): String { val containingClass = companionObject.containingClass()!! - return KotlinNameSuggester.suggestNameByName( - DEFAULT_OBJECT_NAME, - Fe10KotlinNewDeclarationNameValidator(containingClass, null, KotlinNameSuggestionProvider.ValidatorTarget.CLASS) - ) + analyze(containingClass) { + return KotlinNameSuggester.suggestNameByName( + DEFAULT_OBJECT_NAME, + Fe10KotlinNewDeclarationNameValidator(containingClass, null, KotlinNameSuggestionProvider.ValidatorTarget.CLASS) + ) + } } private fun invokeRenameFix(project: Project, file: PsiFile, editor: Editor?, createdObject: KtObjectDeclaration) { diff --git a/plugins/kotlin/all-tests-fir/kotlin.fir-all-tests.iml b/plugins/kotlin/all-tests-fir/kotlin.fir-all-tests.iml index 2561c1e5ebc9..c5ada6e25db5 100644 --- a/plugins/kotlin/all-tests-fir/kotlin.fir-all-tests.iml +++ b/plugins/kotlin/all-tests-fir/kotlin.fir-all-tests.iml @@ -39,7 +39,7 @@ - + @@ -49,5 +49,6 @@ + \ No newline at end of file diff --git a/plugins/kotlin/base/analysis-api-providers/kotlin.base.analysis-api-providers.iml b/plugins/kotlin/base/analysis-api-providers/kotlin.base.analysis-api-providers.iml index 970709a0b33d..7b3192c7328a 100644 --- a/plugins/kotlin/base/analysis-api-providers/kotlin.base.analysis-api-providers.iml +++ b/plugins/kotlin/base/analysis-api-providers/kotlin.base.analysis-api-providers.iml @@ -25,5 +25,7 @@ + + \ No newline at end of file diff --git a/plugins/kotlin/base/analysis-api-providers/resources/kotlin.base.analysis-api-providers.xml b/plugins/kotlin/base/analysis-api-providers/resources/kotlin.base.analysis-api-providers.xml index 5a7a3bed56a3..0b39310a2e6e 100644 --- a/plugins/kotlin/base/analysis-api-providers/resources/kotlin.base.analysis-api-providers.xml +++ b/plugins/kotlin/base/analysis-api-providers/resources/kotlin.base.analysis-api-providers.xml @@ -15,6 +15,9 @@ + diff --git a/plugins/kotlin/base/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/analysisApiProviders/IdeKotlinAnchorModuleProvider.kt b/plugins/kotlin/base/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/analysisApiProviders/IdeKotlinAnchorModuleProvider.kt index 83a07488749a..0f6d269b47c0 100644 --- a/plugins/kotlin/base/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/analysisApiProviders/IdeKotlinAnchorModuleProvider.kt +++ b/plugins/kotlin/base/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/analysisApiProviders/IdeKotlinAnchorModuleProvider.kt @@ -5,7 +5,7 @@ import com.intellij.openapi.project.Project import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule import org.jetbrains.kotlin.analysis.providers.KotlinAnchorModuleProvider -import org.jetbrains.kotlin.idea.base.projectStructure.libraryToSourceAnalysis.ResolutionAnchorCacheService.Companion.getInstance +import org.jetbrains.kotlin.idea.base.projectStructure.libraryToSourceAnalysis.ResolutionAnchorCacheService import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.LibraryInfo import org.jetbrains.kotlin.idea.base.projectStructure.toKtModule @@ -15,6 +15,11 @@ class IdeKotlinAnchorModuleProvider(val project: Project) : KotlinAnchorModulePr override fun getAnchorModule(libraryModule: KtLibraryModule): KtSourceModule? { @OptIn(Frontend10ApiUsage::class) val libraryInfo = libraryModule.moduleInfo as? LibraryInfo ?: return null - return getInstance(project).resolutionAnchorsForLibraries[libraryInfo]?.toKtModule() as? KtSourceModule + return ResolutionAnchorCacheService.getInstance(project).resolutionAnchorsForLibraries[libraryInfo]?.toKtModule() as? KtSourceModule } -} \ No newline at end of file + + override fun getAllAnchorModules(): Collection = + ResolutionAnchorCacheService.getInstance(project) + .librariesForResolutionAnchors.keys + .mapNotNull { it.toKtModule() as? KtSourceModule } +} diff --git a/plugins/kotlin/base/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/analysisApiProviders/KotlinModuleStateModificationService.kt b/plugins/kotlin/base/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/analysisApiProviders/KotlinModuleStateModificationService.kt new file mode 100644 index 000000000000..1bbb18cea83c --- /dev/null +++ b/plugins/kotlin/base/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/analysisApiProviders/KotlinModuleStateModificationService.kt @@ -0,0 +1,324 @@ +// Copyright 2000-2022 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.analysisApiProviders + +import com.intellij.ide.plugins.DynamicPluginListener +import com.intellij.ide.plugins.IdeaPluginDescriptor +import com.intellij.java.workspace.entities.JavaSourceRootPropertiesEntity +import com.intellij.openapi.Disposable +import com.intellij.openapi.fileEditor.FileDocumentManagerListener +import com.intellij.openapi.module.Module +import com.intellij.openapi.project.Project +import com.intellij.openapi.projectRoots.ProjectJdkTable +import com.intellij.openapi.projectRoots.Sdk +import com.intellij.openapi.roots.LibraryOrderEntry +import com.intellij.openapi.roots.ModuleRootEvent +import com.intellij.openapi.roots.ModuleRootListener +import com.intellij.openapi.roots.ProjectFileIndex +import com.intellij.openapi.roots.ProjectRootManager +import com.intellij.openapi.roots.libraries.Library +import com.intellij.openapi.vfs.StandardFileSystems +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.newvfs.BulkFileListener +import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent +import com.intellij.openapi.vfs.newvfs.events.VFileDeleteEvent +import com.intellij.openapi.vfs.newvfs.events.VFileEvent +import com.intellij.openapi.vfs.newvfs.events.VFileMoveEvent +import com.intellij.platform.workspace.jps.entities.ContentRootEntity +import com.intellij.platform.workspace.jps.entities.FacetEntity +import com.intellij.platform.workspace.jps.entities.LibraryEntity +import com.intellij.platform.workspace.jps.entities.ModuleEntity +import com.intellij.platform.workspace.jps.entities.SourceRootEntity +import com.intellij.platform.workspace.storage.EntityChange +import com.intellij.platform.workspace.storage.EntityStorage +import com.intellij.platform.workspace.storage.VersionedStorageChange +import com.intellij.platform.workspace.storage.WorkspaceEntity +import com.intellij.util.io.URLUtil +import com.intellij.workspaceModel.ide.impl.legacyBridge.library.findLibraryBridge +import com.intellij.workspaceModel.ide.impl.legacyBridge.module.findModule +import org.jetbrains.annotations.ApiStatus +import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.analysis.providers.KotlinGlobalModificationService +import org.jetbrains.kotlin.analysis.providers.analysisMessageBus +import org.jetbrains.kotlin.analysis.providers.topics.KotlinModuleStateModificationKind +import org.jetbrains.kotlin.analysis.providers.topics.KotlinTopics +import org.jetbrains.kotlin.idea.base.projectStructure.getBinaryAndSourceModuleInfos +import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.IdeaModuleInfo +import org.jetbrains.kotlin.idea.base.projectStructure.toKtModule +import org.jetbrains.kotlin.idea.util.AbstractSingleFileModuleBeforeFileEventListener +import org.jetbrains.kotlin.idea.util.toKtModulesForModificationEvents +import org.jetbrains.kotlin.idea.facet.isKotlinFacet +import org.jetbrains.kotlin.utils.alwaysTrue + +open class KotlinModuleStateModificationService(val project: Project) : Disposable { + protected open fun mayBuiltinsHaveChanged(events: List): Boolean { return false } + + private fun invalidateSourceModule( + module: Module, + modificationKind: KotlinModuleStateModificationKind = KotlinModuleStateModificationKind.UPDATE, + ) { + module.toKtModulesForModificationEvents().forEach { ktModule -> + project.publishModuleStateModification(ktModule, modificationKind) + } + } + + private fun invalidateLibraryModule( + library: Library, + modificationKind: KotlinModuleStateModificationKind = KotlinModuleStateModificationKind.UPDATE, + ) { + invalidateByModuleInfos(library.getBinaryAndSourceModuleInfos(project), modificationKind) + } + + private fun invalidateByModuleInfos(moduleInfos: Iterable, modificationKind: KotlinModuleStateModificationKind) { + moduleInfos.forEach { moduleInfo -> + project.publishModuleStateModification(moduleInfo.toKtModule(), modificationKind) + } + } + + /** + * Publishes a module state modification event for a script or not-under-content-root [KtModule] whose file is being moved or deleted. + * + * This listener processes events *before* the file is moved/deleted due to the following reasons: + * + * 1. Move: The file may be moved outside the project's content root. The listener cannot react to such files. + * 2. Deletion: Getting a PSI file (and in turn the PSI file's [KtModule]) for a virtual file which has been deleted is not feasible. + * + * A global out-of-block modification event will be published by `FirIdeOutOfBlockPsiTreeChangePreprocessor` when a Kotlin file is + * moved, but we still need this listener to publish a module state modification event specifically. + */ + internal class SingleFileModuleModificationListener(private val project: Project) : AbstractSingleFileModuleBeforeFileEventListener(project) { + override fun isRelevantEvent(event: VFileEvent, file: VirtualFile): Boolean = event is VFileMoveEvent || event is VFileDeleteEvent + + override fun processEvent(event: VFileEvent, module: KtModule) { + val modificationKind = when (event) { + is VFileDeleteEvent -> KotlinModuleStateModificationKind.REMOVAL + else -> KotlinModuleStateModificationKind.UPDATE + } + project.publishModuleStateModification(module, modificationKind) + } + } + + internal class LibraryUpdatesListener(private val project: Project) : BulkFileListener { + val index = ProjectRootManager.getInstance(project).fileIndex + + private val moduleStateModificationService: KotlinModuleStateModificationService get() = getInstance(project) + + override fun before(events: List) { + if (moduleStateModificationService.mayBuiltinsHaveChanged(events)) { + KotlinGlobalModificationService.getInstance(project).publishGlobalModuleStateModification() + return + } + + events.mapNotNull { event -> + val file = when (event) { + //for all other events workspace model should do the job + is VFileContentChangeEvent -> event.file + else -> return@mapNotNull null + } + if (!file.extension.equals("jar", ignoreCase = true)) return@mapNotNull null //react only on jars + val jarRoot = StandardFileSystems.jar().findFileByPath(file.path + URLUtil.JAR_SEPARATOR) ?: return@mapNotNull null + (index.getOrderEntriesForFile(jarRoot).firstOrNull { it is LibraryOrderEntry } as? LibraryOrderEntry)?.library + }.distinct().forEach { moduleStateModificationService.invalidateLibraryModule(it) } + } + } + + internal class JdkListener(private val project: Project) : ProjectJdkTable.Listener { + override fun jdkRemoved(jdk: Sdk) { + // Most modules will depend on an SDK, so its removal constitutes global module state modification. We cannot be more + // fine-grained here because `KtSdkModules`s aren't supported by `IdeKotlinModuleDependentsProvider`, so invalidation based on + // a module-level modification event may not work as expected with a `KtSdkModule`. + KotlinGlobalModificationService.getInstance(project).publishGlobalModuleStateModification() + } + } + + internal class NonWorkspaceModuleRootListener(private val project: Project) : ModuleRootListener { + override fun beforeRootsChange(event: ModuleRootEvent) { + if (event.isCausedByWorkspaceModelChangesOnly) return + + // The cases described in `isCausedByWorkspaceModelChangesOnly` are rare enough to publish global module state modification + // events for simplicity. `NonWorkspaceModuleRootListener` can eventually be removed once the APIs described in + // `isCausedByWorkspaceModelChangesOnly` are removed. + KotlinGlobalModificationService.getInstance(project).publishGlobalModuleStateModification() + } + } + + internal class FileDocumentListener(private val project: Project) : FileDocumentManagerListener { + override fun fileWithNoDocumentChanged(file: VirtualFile) { + // `FileDocumentManagerListener` may receive events from other projects via `FileDocumentManagerImpl`'s `AsyncFileListener`. + if (!ProjectFileIndex.getInstance(project).isInContent(file)) { + return + } + + // Workspace model changes are already handled by `KotlinModuleStateModificationService`, so we shouldn't publish a module state + // modification event when the `workspace.xml` is changed by the IDE. + if (file == project.workspaceFile) { + return + } + + // "No document" means no pomModel change. If the file's PSI was not loaded, then a modification event would be published via + // the `PsiTreeChangeEvent.PROP_UNLOADED_PSI` event. If the PSI was loaded, then `FileManagerImpl.reloadPsiAfterTextChange` is + // fired which doesn't provide any explicit changes, so we need to publish a global modification event because the file's + // content may have been changed externally. + KotlinGlobalModificationService.getInstance(project).publishGlobalModuleStateModification() + } + } + + internal class MyDynamicPluginListener(private val project: Project) : DynamicPluginListener { + override fun beforePluginUnload(pluginDescriptor: IdeaPluginDescriptor, isUpdate: Boolean) { + KotlinGlobalModificationService.getInstance(project).publishGlobalModuleStateModification() + } + + override fun pluginLoaded(pluginDescriptor: IdeaPluginDescriptor) { + KotlinGlobalModificationService.getInstance(project).publishGlobalModuleStateModification() + } + } + + @ApiStatus.Internal + fun beforeWorkspaceModelChanged(event: VersionedStorageChange) { + handleLibraryChanges(event) + + /** + * We keep track of the already invalidated modules because we don't need [handleChangesInsideModule] to publish another + * module state modification event for the same module. + */ + val alreadyInvalidatedModules = handleModuleChanges(event) + handleChangesInsideModule(event, alreadyInvalidatedModules) + } + + /** + * Handel changes inside a module structure. + * All such changes are treated as [UPDATE][KotlinModuleStateModificationKind.UPDATE] + * + * Some examples: changes in content roots, or in the module facet. + */ + private fun handleChangesInsideModule(event: VersionedStorageChange, alreadyInvalidatedModules: Set) { + for (changedModule in event.getChangesInsideModules()) { + if (changedModule in alreadyInvalidatedModules) continue + invalidateSourceModule(changedModule) + } + } + + private fun VersionedStorageChange.getChangesInsideModules(): Set = buildSet { + contentRootChanges(this) + facetChanges(this) + } + + private fun VersionedStorageChange.contentRootChanges(modules: MutableSet) { + getChanges(ContentRootEntity::class.java).mapNotNullTo(modules) { + getChangedModule(it.oldEntity, it.newEntity) + } + + getChanges(SourceRootEntity::class.java).mapNotNullTo(modules) { + getChangedModule(it.oldEntity?.contentRoot, it.newEntity?.contentRoot) + } + + getChanges(JavaSourceRootPropertiesEntity::class.java).mapNotNullTo(modules) { + getChangedModule(it.oldEntity?.sourceRoot?.contentRoot, it.newEntity?.sourceRoot?.contentRoot) + } + } + + private fun VersionedStorageChange.getChangedModule( + contentRootBefore: ContentRootEntity?, + contentRootAfter: ContentRootEntity? + ): Module? = getChangedModule( + contentRootBefore, + contentRootAfter, + moduleSelector = ContentRootEntity::module, + ) + + private fun VersionedStorageChange.facetChanges(modules: MutableSet) { + getChanges(FacetEntity::class.java).mapNotNullTo(modules) { + getChangedModule( + oldEntity = it.oldEntity, + newEntity = it.newEntity, + entityFilter = FacetEntity::isKotlinFacet, + moduleSelector = FacetEntity::module, + ) + } + } + + private fun VersionedStorageChange.getChangedModule( + oldEntity: T?, + newEntity: T?, + entityFilter: (T) -> Boolean = alwaysTrue(), + moduleSelector: (T) -> ModuleEntity?, + ): Module? { + val oldModule = oldEntity?.takeIf(entityFilter)?.let(moduleSelector)?.findModule(storageBefore) + val newModule = newEntity?.takeIf(entityFilter)?.let(moduleSelector)?.findModule(storageAfter) + if (newModule != null && oldModule != null) { + check(oldModule == newModule) { + "$oldModule should be equal to $newModule for ${EntityChange.Replaced::class.java}" + } + } + + return oldModule ?: newModule + } + + private fun handleLibraryChanges(event: VersionedStorageChange) { + val libraryEntities = event.getChanges(LibraryEntity::class.java).ifEmpty { return } + for (change in libraryEntities) { + when (change) { + is EntityChange.Added -> {} + is EntityChange.Removed -> { + change.oldEntity + .findLibraryBridge(event.storageBefore) + ?.let { invalidateLibraryModule(it, KotlinModuleStateModificationKind.REMOVAL) } + } + + is EntityChange.Replaced -> { + val changedLibrary = change.getReplacedEntity(event, LibraryEntity::findLibraryBridge) ?: continue + invalidateLibraryModule(changedLibrary) + } + } + } + } + + /** + * Invalidates removed and replaced [Module]s and returns the set of these invalidated modules. + */ + private fun handleModuleChanges(event: VersionedStorageChange): Set { + val moduleEntities = event.getChanges(ModuleEntity::class.java).ifEmpty { return emptySet() } + + return buildSet { + for (change in moduleEntities) { + when (change) { + is EntityChange.Added -> {} + is EntityChange.Removed -> { + change.oldEntity.findModule(event.storageBefore)?.let { module -> + invalidateSourceModule(module, KotlinModuleStateModificationKind.REMOVAL) + add(module) + } + } + + is EntityChange.Replaced -> { + val changedModule = change.getReplacedEntity(event, ModuleEntity::findModule) ?: continue + invalidateSourceModule(changedModule) + add(changedModule) + } + } + } + } + } + + override fun dispose() {} + + companion object { + fun getInstance(project: Project): KotlinModuleStateModificationService = + project.getService(KotlinModuleStateModificationService::class.java) + } +} + +private fun EntityChange.Replaced.getReplacedEntity( + event: VersionedStorageChange, + get: (C, EntityStorage) -> E +): E { + val old = get(oldEntity, event.storageBefore) + val new = get(newEntity, event.storageAfter) + check(old == new) { + "$old should be equal to $new for ${EntityChange.Replaced::class.java}" + } + return new +} + +private fun Project.publishModuleStateModification(module: KtModule, modificationKind: KotlinModuleStateModificationKind) { + analysisMessageBus.syncPublisher(KotlinTopics.MODULE_STATE_MODIFICATION).onModification(module, modificationKind) +} diff --git a/plugins/kotlin/base/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/analysisApiProviders/KotlinModuleStateTrackerProvider.kt b/plugins/kotlin/base/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/analysisApiProviders/KotlinModuleStateTrackerProvider.kt deleted file mode 100644 index 61f5b83d818f..000000000000 --- a/plugins/kotlin/base/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/analysisApiProviders/KotlinModuleStateTrackerProvider.kt +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright 2000-2022 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.analysisApiProviders - -import com.intellij.java.workspace.entities.JavaSourceRootPropertiesEntity -import com.intellij.openapi.Disposable -import com.intellij.openapi.module.Module -import com.intellij.openapi.project.Project -import com.intellij.openapi.projectRoots.ProjectJdkTable -import com.intellij.openapi.projectRoots.Sdk -import com.intellij.openapi.roots.LibraryOrderEntry -import com.intellij.openapi.roots.ProjectRootManager -import com.intellij.openapi.roots.libraries.Library -import com.intellij.openapi.vfs.StandardFileSystems -import com.intellij.openapi.vfs.VirtualFile -import com.intellij.openapi.vfs.VirtualFileManager -import com.intellij.openapi.vfs.newvfs.BulkFileListener -import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent -import com.intellij.openapi.vfs.newvfs.events.VFileDeleteEvent -import com.intellij.openapi.vfs.newvfs.events.VFileEvent -import com.intellij.openapi.vfs.newvfs.events.VFileMoveEvent -import com.intellij.platform.workspace.jps.entities.ContentRootEntity -import com.intellij.platform.workspace.jps.entities.LibraryEntity -import com.intellij.platform.workspace.jps.entities.ModuleEntity -import com.intellij.platform.workspace.jps.entities.SourceRootEntity -import com.intellij.util.io.URLUtil -import com.intellij.platform.backend.workspace.WorkspaceModelChangeListener -import com.intellij.platform.backend.workspace.WorkspaceModelTopics -import com.intellij.workspaceModel.ide.impl.legacyBridge.library.findLibraryBridge -import com.intellij.workspaceModel.ide.impl.legacyBridge.module.findModule -import com.intellij.platform.workspace.storage.EntityChange -import com.intellij.platform.workspace.storage.EntityStorage -import com.intellij.platform.workspace.storage.VersionedStorageChange -import com.intellij.platform.workspace.storage.WorkspaceEntity -import org.jetbrains.annotations.TestOnly -import org.jetbrains.kotlin.analysis.project.structure.* -import org.jetbrains.kotlin.analysis.providers.KtModuleStateTracker -import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo -import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.LibraryInfo -import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.ModuleSourceInfo -import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.SdkInfo -import org.jetbrains.kotlin.idea.base.util.Frontend10ApiUsage -import org.jetbrains.kotlin.parsing.KotlinParserDefinition -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.atomic.AtomicLong - -@OptIn(Frontend10ApiUsage::class) -open class KotlinModuleStateTrackerProvider(val project: Project) : Disposable { - init { - val busConnection = project.messageBus.connect(this) - busConnection.subscribe(WorkspaceModelTopics.CHANGED, ModelChangeListener()) - busConnection.subscribe(ProjectJdkTable.JDK_TABLE_TOPIC, JdkListener()) - busConnection.subscribe(VirtualFileManager.VFS_CHANGES, ScriptFileListener()) - busConnection.subscribe(VirtualFileManager.VFS_CHANGES, LibraryUpdatesListener()) - } - - private val builtinTracker = ModuleStateTrackerImpl() - private val libraryCache = ConcurrentHashMap() - private val sourceModuleCache = ConcurrentHashMap() - private val sdkCache = ConcurrentHashMap() - private val scriptCache = ConcurrentHashMap() - - protected open fun shouldInvalidateBuiltinSession(events: List): Boolean { return false } - - fun getModuleStateTrackerFor(module: KtModule): KtModuleStateTracker { - return when (module) { - is KtScriptDependencyModule -> ModuleStateTrackerImpl() - - is KtLibraryModule -> { - val libraryInfo = module.moduleInfo as LibraryInfo - libraryInfo.checkValidity() - return libraryCache.computeIfAbsent(libraryInfo.library) { ModuleStateTrackerImpl() } - } - - is KtSdkModule -> { - val sdkInfo = module.moduleInfo as SdkInfo - sdkInfo.checkValidity() - val sdk = sdkInfo.sdk - return sdkCache.computeIfAbsent(sdk) { ModuleStateTrackerImpl() } - } - - is KtSourceModule -> { - val sourceModule = module.moduleInfo as ModuleSourceInfo - sourceModule.checkValidity() - return sourceModuleCache.computeIfAbsent(sourceModule.module) { ModuleStateTrackerImpl() } - } - - is KtLibrarySourceModule -> getModuleStateTrackerFor(module.binaryLibrary) - - is KtBuiltinsModule -> builtinTracker - - is KtScriptModule -> { - val virtualFile = module.file.virtualFile ?: error("Script ${module.file} does not have a backing 'VirtualFile'") - scriptCache.computeIfAbsent(virtualFile) { ModuleStateTrackerImpl() } - } - - is KtNotUnderContentRootModule -> ModuleStateTrackerImpl() // TODO need proper cache? - } - } - - private inner class ScriptFileListener : BulkFileListener { - override fun after(events: List) { - for (event in events) { - val file = when (event) { - is VFileDeleteEvent -> event.file - is VFileMoveEvent -> event.file - else -> continue - } - - if (file.extension == KotlinParserDefinition.STD_SCRIPT_SUFFIX) { - scriptCache.remove(file)?.invalidate() - } - } - } - } - - private inner class LibraryUpdatesListener : BulkFileListener { - val index = ProjectRootManager.getInstance(project).fileIndex - override fun after(events: List) { - if (shouldInvalidateBuiltinSession(events)) { - builtinTracker.incModificationCount() - libraryCache.values.forEach { it.incModificationCount() } - sourceModuleCache.values.forEach { it.incModificationCount() } - sdkCache.values.forEach { it.incModificationCount() } - scriptCache.values.forEach { it.incModificationCount() } - return - } - events.mapNotNull { event -> - val file = when (event) { - //for all other events workspace model should do the job - is VFileContentChangeEvent -> event.file - else -> return@mapNotNull null - } - if (file.extension != "jar") return@mapNotNull null //react only on jars - val jarRoot = StandardFileSystems.jar().findFileByPath(file.path + URLUtil.JAR_SEPARATOR) ?: return@mapNotNull null - (index.getOrderEntriesForFile(jarRoot).firstOrNull { it is LibraryOrderEntry } as? LibraryOrderEntry)?.library - }.distinct().forEach { - libraryCache[it]?.incModificationCount() - } - } - } - - private inner class JdkListener : ProjectJdkTable.Listener { - override fun jdkRemoved(jdk: Sdk) { - sdkCache.remove(jdk)?.invalidate() - } - } - - private inner class ModelChangeListener : WorkspaceModelChangeListener { - override fun beforeChanged(event: VersionedStorageChange) { - handleLibraryChanges(event) - handleModuleChanges(event) - handleContentRootInModuleChanges(event) - } - - private fun handleContentRootInModuleChanges(event: VersionedStorageChange) { - for (changedModule in event.getChangedModules()) { - sourceModuleCache[changedModule]?.incModificationCount() - } - } - - private fun VersionedStorageChange.getChangedModules(): Set = buildSet { - getChanges(ContentRootEntity::class.java).mapNotNullTo(this) { - getChangedModule(it.oldEntity, it.newEntity) - } - - getChanges(SourceRootEntity::class.java).mapNotNullTo(this) { - getChangedModule(it.oldEntity?.contentRoot, it.newEntity?.contentRoot) - } - - getChanges(JavaSourceRootPropertiesEntity::class.java).mapNotNullTo(this) { - getChangedModule(it.oldEntity?.sourceRoot?.contentRoot, it.newEntity?.sourceRoot?.contentRoot) - } - } - - private fun VersionedStorageChange.getChangedModule( - contentRootBefore: ContentRootEntity?, - contentRootAfter: ContentRootEntity? - ): Module? { - val oldModule = contentRootBefore?.module?.findModule(storageBefore) - val newModule = contentRootAfter?.module?.findModule(storageAfter) - if (newModule != null && oldModule != null) { - check(oldModule == newModule) { - "$oldModule should be equal to $newModule for ${EntityChange.Replaced::class.java}" - } - } - return oldModule ?: newModule - } - - private fun handleLibraryChanges(event: VersionedStorageChange) { - val libraryEntities = event.getChanges(LibraryEntity::class.java).ifEmpty { return } - for (change in libraryEntities) { - when (change) { - is EntityChange.Added -> {} - is EntityChange.Removed -> { - change.oldEntity.findLibraryBridge(event.storageBefore)?.let { library -> - libraryCache.remove(library)?.invalidate() - } - } - - is EntityChange.Replaced -> { - val changedLibrary = change.getReplacedEntity(event, LibraryEntity::findLibraryBridge) ?: continue - libraryCache[changedLibrary]?.incModificationCount() - } - } - } - } - - private fun handleModuleChanges(event: VersionedStorageChange) { - val moduleEntities = event.getChanges(ModuleEntity::class.java).ifEmpty { return } - for (change in moduleEntities) { - when (change) { - is EntityChange.Added -> {} - is EntityChange.Removed -> { - change.oldEntity.findModule(event.storageBefore)?.let { module -> - sourceModuleCache.remove(module)?.invalidate() - } - } - - is EntityChange.Replaced -> { - val changedModule = change.getReplacedEntity(event, ModuleEntity::findModule) ?: continue - sourceModuleCache[changedModule]?.incModificationCount() - } - } - } - } - } - - private fun EntityChange.Replaced.getReplacedEntity( - event: VersionedStorageChange, - get: (C, EntityStorage) -> E - ): E { - val old = get(oldEntity, event.storageBefore) - val new = get(newEntity, event.storageAfter) - check(old == new) { - "$old should be equal to $new for ${EntityChange.Replaced::class.java}" - } - return new - } - - @TestOnly - fun incrementModificationCountForAllModules(includeBinaryModules: Boolean) { - sourceModuleCache.forEach { _, tracker -> tracker.incModificationCount() } - if (includeBinaryModules) { - libraryCache.forEach { _, tracker -> tracker.incModificationCount() } - sdkCache.forEach { _, tracker -> tracker.incModificationCount() } - } - } - - override fun dispose() {} - - companion object { - fun getInstance(project: Project): KotlinModuleStateTrackerProvider = - project.getService(KotlinModuleStateTrackerProvider::class.java) - } - -} - -class ModuleStateTrackerImpl : KtModuleStateTracker { - private val modificationCount = AtomicLong() - - @Volatile - override var isValid: Boolean = true - private set - - fun incModificationCount() { - if (isValid) { - modificationCount.incrementAndGet() - } - } - - fun invalidate() { - incModificationCount() - isValid = false - } - - override val rootModificationCount: Long - get() = modificationCount.get() -} \ No newline at end of file diff --git a/plugins/kotlin/base/analysis-api/analysis-api-utils/kotlin.base.analysis-api.utils.iml b/plugins/kotlin/base/analysis-api/analysis-api-utils/kotlin.base.analysis-api.utils.iml index b3cd34085245..f5dea847af41 100644 --- a/plugins/kotlin/base/analysis-api/analysis-api-utils/kotlin.base.analysis-api.utils.iml +++ b/plugins/kotlin/base/analysis-api/analysis-api-utils/kotlin.base.analysis-api.utils.iml @@ -36,5 +36,7 @@ + + \ 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/KtSymbolFromIndexProvider.kt b/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/analysis/api/utils/KtSymbolFromIndexProvider.kt index 46b807266f71..f5144e18865b 100644 --- a/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/analysis/api/utils/KtSymbolFromIndexProvider.kt +++ b/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/analysis/api/utils/KtSymbolFromIndexProvider.kt @@ -10,11 +10,7 @@ import com.intellij.psi.search.PsiShortNamesCache import com.intellij.util.SmartList import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.analyze -import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol -import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol -import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol -import org.jetbrains.kotlin.analysis.api.symbols.getSymbolOfTypeSafe -import org.jetbrains.kotlin.analysis.api.symbols.receiverType +import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability @@ -22,56 +18,58 @@ import org.jetbrains.kotlin.idea.base.psi.isExpectDeclaration import org.jetbrains.kotlin.idea.stubindex.* import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.platform.isCommon -import org.jetbrains.kotlin.psi.KtCallableDeclaration -import org.jetbrains.kotlin.psi.KtClassOrObject -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.psi.KtNamedDeclaration -import org.jetbrains.kotlin.psi.KtNamedFunction +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.utils.yieldIfNotNull class KtSymbolFromIndexProvider private constructor(private val project: Project, private val scope: GlobalSearchScope) { context(KtAnalysisSession) fun getKotlinClassesByName( name: Name, - psiFilter: (KtClassOrObject) -> Boolean = { true }, - ): Sequence { + psiFilter: (KtClassLikeDeclaration) -> Boolean = { true }, + ): Sequence { val isCommon = useSiteModule.platform.isCommon() - val values = KotlinClassShortNameIndex.getAllElements( - name.asString(), - project, - scope - ) { - (isCommon || !it.isExpectDeclaration()) && psiFilter(it) - } - return sequence { - for (value in values) { - value.getNamedClassOrObjectSymbol()?.let { yield(it) } - } - yieldAll( - getResolveExtensionScopeWithTopLevelDeclarations().getClassifierSymbols(name).filterIsInstance() - ) - } + + val valueFilter: (KtClassLikeDeclaration) -> Boolean = { (isCommon || !it.isExpectDeclaration()) && psiFilter(it) } + val resolveExtensionScope = getResolveExtensionScopeWithTopLevelDeclarations() + + return getClassLikeSymbols( + classDeclarations = KotlinClassShortNameIndex.getAllElements(name.asString(), project, scope, valueFilter), + typeAliasDeclarations = KotlinTypeAliasShortNameIndex.getAllElements(name.asString(), project, scope, valueFilter), + declarationsFromExtension = resolveExtensionScope.getClassifierSymbols(name).filterIsInstance(), + ) } context(KtAnalysisSession) fun getKotlinClassesByNameFilter( nameFilter: (Name) -> Boolean, - psiFilter: (KtClassOrObject) -> Boolean = { true }, - ): Sequence { + psiFilter: (KtClassLikeDeclaration) -> Boolean = { true }, + ): Sequence { val isCommon = useSiteModule.platform.isCommon() - val values = KotlinFullClassNameIndex.getAllElements( - project, - scope, - keyFilter = { nameFilter(getShortName(it)) }, - valueFilter = { (isCommon || !it.isExpectDeclaration()) && psiFilter(it) } + + val keyFilter: (String) -> Boolean = { nameFilter(getShortName(it)) } + val valueFilter: (KtClassLikeDeclaration) -> Boolean = { (isCommon || !it.isExpectDeclaration()) && psiFilter(it) } + val resolveExtensionScope = getResolveExtensionScopeWithTopLevelDeclarations() + + return getClassLikeSymbols( + classDeclarations = KotlinFullClassNameIndex.getAllElements(project, scope, keyFilter, valueFilter), + typeAliasDeclarations = KotlinTypeAliasShortNameIndex.getAllElements(project, scope, keyFilter, valueFilter), + declarationsFromExtension = resolveExtensionScope.getClassifierSymbols(nameFilter).filterIsInstance(), ) - return sequence { - for (ktClassOrObject in values) { - ktClassOrObject.getNamedClassOrObjectSymbol()?.let { yield(it) } - } - yieldAll( - getResolveExtensionScopeWithTopLevelDeclarations().getClassifierSymbols(nameFilter).filterIsInstance() - ) + } + + context(KtAnalysisSession) + private fun getClassLikeSymbols( + classDeclarations: List, + typeAliasDeclarations: List, + declarationsFromExtension: Sequence + ): Sequence = sequence { + for (ktClassOrObject in classDeclarations) { + yieldIfNotNull(ktClassOrObject.getNamedClassOrObjectSymbol()) } + for (typeAlias in typeAliasDeclarations) { + yield(typeAlias.getTypeAliasSymbol()) + } + yieldAll(declarationsFromExtension) } context(KtAnalysisSession) @@ -130,7 +128,7 @@ class KtSymbolFromIndexProvider private constructor(private val project: Project return sequence { for (callableDeclaration in values) { - callableDeclaration.getSymbolOfTypeSafe()?.let { yield(it) } + yieldIfNotNull(callableDeclaration.getSymbolOfTypeSafe()) } yieldAll( getResolveExtensionScopeWithTopLevelDeclarations().getCallableSymbols(name) @@ -174,7 +172,7 @@ class KtSymbolFromIndexProvider private constructor(private val project: Project return sequence { for (callableDeclaration in values) { - callableDeclaration.getSymbolOfTypeSafe()?.let { yield(it) } + yieldIfNotNull(callableDeclaration.getSymbolOfTypeSafe()) } yieldAll( getResolveExtensionScopeWithTopLevelDeclarations().getCallableSymbols(nameFilter).filter { !it.isExtension } @@ -197,10 +195,10 @@ class KtSymbolFromIndexProvider private constructor(private val project: Project return sequence { for (extension in values) { - extension.getSymbolOfTypeSafe()?.let { yield(it) } + yieldIfNotNull(extension.getSymbolOfTypeSafe()) } - val extensionScope = getResolveExtensionScopeWithTopLevelDeclarations() - yieldAll(extensionScope.getCallableSymbols(name).filterExtensionsByReceiverTypes(receiverTypes)) + val resolveExtensionScope = getResolveExtensionScopeWithTopLevelDeclarations() + yieldAll(resolveExtensionScope.getCallableSymbols(name).filterExtensionsByReceiverTypes(receiverTypes)) } } @@ -223,10 +221,10 @@ class KtSymbolFromIndexProvider private constructor(private val project: Project return sequence { for (extension in values) { - extension.getSymbolOfTypeSafe()?.let { yield(it) } + yieldIfNotNull(extension.getSymbolOfTypeSafe()) } - val extensionScope = getResolveExtensionScopeWithTopLevelDeclarations() - yieldAll(extensionScope.getCallableSymbols(nameFilter).filterExtensionsByReceiverTypes(receiverTypes)) + val resolveExtensionScope = getResolveExtensionScopeWithTopLevelDeclarations() + yieldAll(resolveExtensionScope.getCallableSymbols(nameFilter).filterExtensionsByReceiverTypes(receiverTypes)) } } diff --git a/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/analysis/api/utils/analyzeUtils.kt b/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/analysis/api/utils/analyzeUtils.kt new file mode 100644 index 000000000000..2d4e44878db7 --- /dev/null +++ b/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/analysis/api/utils/analyzeUtils.kt @@ -0,0 +1,32 @@ +// Copyright 2000-2023 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.analysis.api.utils + +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.application.runReadAction +import com.intellij.openapi.progress.ProgressIndicator +import com.intellij.openapi.progress.Task +import com.intellij.openapi.util.NlsContexts.DialogTitle +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.analyze +import org.jetbrains.kotlin.psi.KtElement + +/** + * Show a modal window with a progress bar and specified [windowTitle] + * and execute given [action] task with [KtAnalysisSession] context + * If [action] throws some exception, then [analyzeInModalWindow] will rethrow it + * Should be executed from EDT only + * If you want to analyse something from non-EDT thread, consider using [analyze] + */ +inline fun analyzeInModalWindow( + contextElement: KtElement, + @DialogTitle windowTitle: String, + crossinline action: KtAnalysisSession.() -> R +): R { + ApplicationManager.getApplication().assertIsDispatchThread() + val task = object : Task.WithResult(contextElement.project, windowTitle, /*canBeCancelled*/ true) { + override fun compute(indicator: ProgressIndicator): R = + runReadAction { analyze(contextElement, action) } + } + task.queue() + return task.result +} diff --git a/plugins/kotlin/base/psi/src/org/jetbrains/kotlin/idea/base/psi/imports/ImportInsertion.kt b/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/psi/imports/ImportInsertion.kt similarity index 100% rename from plugins/kotlin/base/psi/src/org/jetbrains/kotlin/idea/base/psi/imports/ImportInsertion.kt rename to plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/psi/imports/ImportInsertion.kt diff --git a/plugins/kotlin/base/psi/src/org/jetbrains/kotlin/idea/base/psi/imports/KotlinImportPathComparator.kt b/plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/psi/imports/KotlinImportPathComparator.kt similarity index 100% rename from plugins/kotlin/base/psi/src/org/jetbrains/kotlin/idea/base/psi/imports/KotlinImportPathComparator.kt rename to plugins/kotlin/base/analysis-api/analysis-api-utils/src/org/jetbrains/kotlin/idea/base/psi/imports/KotlinImportPathComparator.kt diff --git a/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/base/analysis/LibraryDependenciesCache.kt b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/base/analysis/LibraryDependenciesCache.kt index 29a73cf73fb2..618efc787e2e 100644 --- a/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/base/analysis/LibraryDependenciesCache.kt +++ b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/base/analysis/LibraryDependenciesCache.kt @@ -3,19 +3,16 @@ package org.jetbrains.kotlin.idea.base.analysis import com.intellij.ProjectTopics -import com.intellij.java.library.JavaLibraryModificationTracker import com.intellij.openapi.Disposable import com.intellij.openapi.application.runReadAction import com.intellij.openapi.components.service import com.intellij.openapi.module.Module -import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.progress.ProgressManager.checkCanceled import com.intellij.openapi.project.Project import com.intellij.openapi.projectRoots.ProjectJdkTable import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.roots.* import com.intellij.openapi.roots.impl.libraries.LibraryEx -import com.intellij.openapi.roots.libraries.Library import com.intellij.openapi.util.Disposer import com.intellij.platform.backend.workspace.WorkspaceModelChangeListener import com.intellij.platform.backend.workspace.WorkspaceModelTopics @@ -29,7 +26,6 @@ import com.intellij.util.concurrency.annotations.RequiresReadLock import com.intellij.util.containers.MultiMap import com.intellij.workspaceModel.ide.impl.legacyBridge.module.findModule import org.jetbrains.kotlin.idea.base.analysis.libraries.LibraryDependencyCandidate -import org.jetbrains.kotlin.idea.base.facet.isHMPPEnabled import org.jetbrains.kotlin.idea.base.projectStructure.* import org.jetbrains.kotlin.idea.base.projectStructure.LibraryDependenciesCache.LibraryDependencies import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.LibraryInfo @@ -39,7 +35,6 @@ import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.checkValidity import org.jetbrains.kotlin.idea.base.util.caching.ModuleEntityChangeListener import org.jetbrains.kotlin.idea.base.util.caching.SynchronizedFineGrainedEntityCache import org.jetbrains.kotlin.idea.caches.project.* -import org.jetbrains.kotlin.idea.caches.trackers.ModuleModificationTracker import org.jetbrains.kotlin.idea.configuration.isMavenized import org.jetbrains.kotlin.platform.jvm.isJvm import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -161,8 +156,7 @@ class LibraryDependenciesCacheImpl(private val project: Project) : LibraryDepend private fun computeLibrariesAndSdksUsedWithNoFilter(libraryInfo: LibraryInfo): LibraryDependencyCandidatesAndSdkInfos { val libraryDependencyCandidatesAndSdkInfos = LibraryDependencyCandidatesAndSdkInfosBuilder() - val modulesLibraryIsUsedIn = - getLibraryUsageIndex().getModulesLibraryIsUsedIn(libraryInfo) + val modulesLibraryIsUsedIn = project.service().getDependentModules(libraryInfo) for (module in modulesLibraryIsUsedIn) { checkCanceled() @@ -200,15 +194,6 @@ class LibraryDependenciesCacheImpl(private val project: Project) : LibraryDepend } } - private fun getLibraryUsageIndex(): LibraryUsageIndex = - CachedValuesManager.getManager(project).getCachedValue(project) { - CachedValueProvider.Result( - LibraryUsageIndex(), - ModuleModificationTracker.getInstance(project), - JavaLibraryModificationTracker.getInstance(project) - ) - }!! - private inner class LibraryDependenciesInnerCache : SynchronizedFineGrainedEntityCache(project, doSelfInitialization = false, cleanOnLowMemory = true), LibraryInfoListener, @@ -543,32 +528,4 @@ class LibraryDependenciesCacheImpl(private val project: Project) : LibraryDepend ) } } - - private inner class LibraryUsageIndex { - private val modulesLibraryIsUsedIn: MultiMap = runReadAction { - val map: MultiMap = MultiMap.createSet() - val libraryCache = LibraryInfoCache.getInstance(project) - for (module in ModuleManager.getInstance(project).modules) { - checkCanceled() - for (entry in ModuleRootManager.getInstance(module).orderEntries) { - if (entry !is LibraryOrderEntry) continue - val library = entry.library ?: continue - val keyLibrary = libraryCache.deduplicatedLibrary(library) - map.putValue(keyLibrary, module) - } - } - - map - } - - fun getModulesLibraryIsUsedIn(libraryInfo: LibraryInfo) = sequence { - val ideaModelInfosCache = getIdeaModelInfosCache(project) - for (module in modulesLibraryIsUsedIn[libraryInfo.library]) { - val mappedModuleInfos = ideaModelInfosCache.getModuleInfosForModule(module) - if (mappedModuleInfos.any { it.platform.canDependOn(libraryInfo, module.isHMPPEnabled) }) { - yield(module) - } - } - } - } } diff --git a/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/base/analysis/libraries/LibraryUsageIndexImpl.kt b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/base/analysis/libraries/LibraryUsageIndexImpl.kt new file mode 100644 index 000000000000..c0c128492740 --- /dev/null +++ b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/base/analysis/libraries/LibraryUsageIndexImpl.kt @@ -0,0 +1,60 @@ +// Copyright 2000-2023 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.analysis.libraries + +import com.intellij.java.library.JavaLibraryModificationTracker +import com.intellij.openapi.application.runReadAction +import com.intellij.openapi.module.ModuleManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.module.Module +import com.intellij.openapi.roots.LibraryOrderEntry +import com.intellij.openapi.roots.ModuleRootManager +import com.intellij.openapi.roots.libraries.Library +import com.intellij.psi.util.CachedValue +import com.intellij.psi.util.CachedValueProvider +import org.jetbrains.kotlin.idea.base.facet.isHMPPEnabled +import com.intellij.psi.util.CachedValuesManager +import com.intellij.util.containers.MultiMap +import org.jetbrains.kotlin.idea.base.projectStructure.LibraryInfoCache +import org.jetbrains.kotlin.idea.base.projectStructure.LibraryUsageIndex +import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.LibraryInfo +import org.jetbrains.kotlin.idea.caches.project.canDependOn +import org.jetbrains.kotlin.idea.caches.project.getIdeaModelInfosCache +import org.jetbrains.kotlin.idea.caches.trackers.ModuleModificationTracker +import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus.checkCanceled + +class LibraryUsageIndexImpl(private val project: Project) : LibraryUsageIndex { + private val moduleDependentsByLibrary: CachedValue> = + CachedValuesManager.getManager(project).createCachedValue { + CachedValueProvider.Result( + computeLibraryModuleDependents(), + ModuleModificationTracker.getInstance(project), + JavaLibraryModificationTracker.getInstance(project), + ) + } + + override fun getDependentModules(libraryInfo: LibraryInfo): Sequence = sequence { + val ideaModelInfosCache = getIdeaModelInfosCache(project) + for (module in moduleDependentsByLibrary.value[libraryInfo.library]) { + val mappedModuleInfos = ideaModelInfosCache.getModuleInfosForModule(module) + if (mappedModuleInfos.any { it.platform.canDependOn(libraryInfo, module.isHMPPEnabled) }) { + yield(module) + } + } + } + + private fun computeLibraryModuleDependents(): MultiMap = runReadAction { + val moduleDependentsByLibrary = MultiMap.createSet() + val libraryCache = LibraryInfoCache.getInstance(project) + for (module in ModuleManager.getInstance(project).modules) { + checkCanceled() + for (entry in ModuleRootManager.getInstance(module).orderEntries) { + if (entry !is LibraryOrderEntry) continue + val library = entry.library ?: continue + val keyLibrary = libraryCache.deduplicatedLibrary(library) + moduleDependentsByLibrary.putValue(keyLibrary, module) + } + } + + moduleDependentsByLibrary + } +} diff --git a/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ResolutionAnchorCacheService.kt b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ResolutionAnchorCacheService.kt index 8b604c1cd98a..2c2d5c38db96 100644 --- a/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ResolutionAnchorCacheService.kt +++ b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ResolutionAnchorCacheService.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.idea.base.projectStructure.LibraryDependenciesCache import org.jetbrains.kotlin.idea.base.projectStructure.libraryToSourceAnalysis.ResolutionAnchorCacheService import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.LibraryInfo import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.ModuleSourceInfo +import org.jetbrains.kotlin.idea.base.projectStructure.util.getTransitiveLibraryDependencyInfos import org.jetbrains.kotlin.idea.caches.project.getModuleInfosFromIdeaModel import org.jetbrains.kotlin.idea.caches.trackers.ModuleModificationTracker import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus.checkCanceled @@ -46,16 +47,27 @@ class ResolutionAnchorCacheServiceImpl( myState = State(mapping) } - override val resolutionAnchorsForLibraries: Map + private class AnchorMapping( + val anchorByLibrary: Map, + val librariesByAnchor: Map>, + ) + + private val anchorMapping: AnchorMapping get() = CachedValuesManager.getManager(project).getCachedValue(project) { CachedValueProvider.Result.create( - mapResolutionAnchorForLibraries(), - ModuleModificationTracker.getInstance(project), - JavaLibraryModificationTracker.getInstance(project) + createResolutionAnchorMapping(), + ModuleModificationTracker.getInstance(project), + JavaLibraryModificationTracker.getInstance(project) ) } + override val resolutionAnchorsForLibraries: Map + get() = anchorMapping.anchorByLibrary + + override val librariesForResolutionAnchors: Map> + get() = anchorMapping.librariesByAnchor + private val resolutionAnchorDependenciesCache: MutableMap> get() = CachedValuesManager.getManager(project).getCachedValue(project) { @@ -71,13 +83,7 @@ class ResolutionAnchorCacheServiceImpl( return it } - val allTransitiveLibraryDependencies = with(LibraryDependenciesCache.getInstance(project)) { - val directDependenciesOnLibraries = getLibraryDependencies(libraryInfo).libraries - directDependenciesOnLibraries.closure { libraryDependency -> - checkCanceled() - getLibraryDependencies(libraryDependency).libraries - } - } + val allTransitiveLibraryDependencies = LibraryDependenciesCache.getInstance(project).getTransitiveLibraryDependencyInfos(libraryInfo) val dependencyResolutionAnchors = allTransitiveLibraryDependencies.mapNotNullTo(mutableSetOf()) { resolutionAnchorsForLibraries[it] } resolutionAnchorDependenciesCache.putIfAbsent(libraryInfo, dependencyResolutionAnchors)?.let { @@ -106,41 +112,31 @@ class ResolutionAnchorCacheServiceImpl( } } - private fun mapResolutionAnchorForLibraries(): Map { + private fun createResolutionAnchorMapping(): AnchorMapping { val modulesByNames: Map = associateModulesByNames() - return myState.moduleNameToAnchorName.entries.mapNotNull { (libraryName, anchorName) -> + val anchorByLibrary = mutableMapOf() + val librariesByAnchor = mutableMapOf>() + + myState.moduleNameToAnchorName.entries.forEach { (libraryName, anchorName) -> val library: LibraryInfo = modulesByNames[libraryName]?.safeAs() ?: run { logger.warn("Resolution anchor mapping key doesn't point to a known library: $libraryName. Skipping this anchor") - return@mapNotNull null + return@forEach } val anchor: ModuleSourceInfo = modulesByNames[anchorName]?.safeAs() ?: run { logger.warn("Resolution anchor mapping value doesn't point to a source module: $anchorName. Skipping this anchor") - return@mapNotNull null + return@forEach } - library to anchor - }.toMap() + anchorByLibrary.put(library, anchor) + librariesByAnchor.getOrPut(anchor) { mutableListOf() }.add(library) + } + + return AnchorMapping(anchorByLibrary, librariesByAnchor) } companion object { private val logger = logger() } } -fun Collection.closure(f: (T) -> Collection): Collection { - if (isEmpty()) return this - - val result = HashSet(this) - var elementsToCheck = result - var oldSize = 0 - while (result.size > oldSize) { - oldSize = result.size - val toAdd = hashSetOf() - elementsToCheck.forEach { toAdd.addAll(f(it)) } - result.addAll(toAdd) - elementsToCheck = toAdd - } - - return result -} diff --git a/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinRequestResultProcessor.kt b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinRequestResultProcessor.kt index ef9b17695163..f48447fbe017 100644 --- a/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinRequestResultProcessor.kt +++ b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinRequestResultProcessor.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.SearchUtils.is import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.SearchUtils.isInvokeOfCompanionObject import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.SearchUtils.isUsageInContainingDeclaration import org.jetbrains.kotlin.psi.KtDestructuringDeclaration +import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.psi.KtNamedDeclaration class KotlinRequestResultProcessor( @@ -61,7 +62,7 @@ class KotlinRequestResultProcessor( if (options.acceptCallableOverrides && isCallableOverrideUsage(originalElement)) { return true } - if (options.acceptOverloads && isUsageInContainingDeclaration(originalElement)) { + if (options.acceptOverloads && originalElement is KtFunction && isUsageInContainingDeclaration(originalElement)) { return true } if (options.acceptExtensionsOfDeclarationClass && isExtensionOfDeclarationClassUsage(originalElement)) { diff --git a/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/util/AbstractSingleFileModuleFileEventListener.kt b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/util/AbstractSingleFileModuleFileEventListener.kt new file mode 100644 index 000000000000..6ad097c7533d --- /dev/null +++ b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/util/AbstractSingleFileModuleFileEventListener.kt @@ -0,0 +1,75 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.util + +import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.ProjectFileIndex +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.newvfs.BulkFileListener +import com.intellij.openapi.vfs.newvfs.events.VFileEvent +import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.analysis.project.structure.KtNotUnderContentRootModule +import org.jetbrains.kotlin.analysis.project.structure.KtScriptDependencyModule +import org.jetbrains.kotlin.analysis.project.structure.KtScriptModule +import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider +import org.jetbrains.kotlin.idea.core.util.toPsiFile +import org.jetbrains.kotlin.parsing.KotlinParserDefinition + +/** + * [AbstractSingleFileModuleFileEventListener] listens to file events and calls [processEvent] with the single-file [KtModule] associated + * with the event's file. An event is only processed if it passes [isRelevantEvent]. + * + * Use one of the *before* or *after* variants to implement this listener: + * + * - [AbstractSingleFileModuleBeforeFileEventListener] + * - [AbstractSingleFileModuleAfterFileEventListener] + */ +sealed class AbstractSingleFileModuleFileEventListener(private val project: Project) : BulkFileListener { + protected abstract fun isRelevantEvent(event: VFileEvent, file: VirtualFile): Boolean + + protected abstract fun processEvent(event: VFileEvent, module: KtModule) + + internal fun processEvents(events: List) { + for (event in events) { + val file = event.file ?: continue + if (!isRelevantEvent(event, file)) continue + if (!file.mayBeFromSingleFileModule(project)) continue + + // A `BulkFileListener` may receive events from other projects, which need to be ignored. This check is placed after + // `mayBeFromSingleFileModule` because (1) `mayBeFromSingleFileModule` establishes that `file` is a Kotlin file, and we do not + // need to check `isInContent` for non-Kotlin files, as we don't want to process them, and (2) for the common case where the + // user has opened only one project and most Kotlin files are inside a source set, checking `!isInSourceContent` first excludes + // most files in a single check, as opposed to checking `isInContent` first and then `!isInSourceContent`. + if (!ProjectFileIndex.getInstance(project).isInContent(file)) continue + + val module = file.getSingleFileModule() ?: continue + processEvent(event, module) + } + } + + /** + * Checks whether the given [VirtualFile] may come from a single-file [KtModule] with the following heuristics: + * + * 1. The file is a script if its extension is `.kts`. + * 2. The file can only belong to a not-under-content-root `KtModule` if it isn't in some module's source content. + */ + private fun VirtualFile.mayBeFromSingleFileModule(project: Project): Boolean = + extension == KotlinParserDefinition.STD_SCRIPT_SUFFIX || + isKotlinFileType() && !ProjectFileIndex.getInstance(project).isInSourceContent(this) + + private fun VirtualFile.getSingleFileModule(): KtModule? = + toPsiFile(project) + ?.let { ProjectStructureProvider.getModule(project, it, contextualModule = null) } + ?.takeIf { it is KtScriptModule || it is KtScriptDependencyModule || it is KtNotUnderContentRootModule } +} + +abstract class AbstractSingleFileModuleBeforeFileEventListener(project: Project) : AbstractSingleFileModuleFileEventListener(project) { + override fun before(events: List) { + processEvents(events) + } +} + +abstract class AbstractSingleFileModuleAfterFileEventListener(project: Project) : AbstractSingleFileModuleFileEventListener(project) { + override fun after(events: List) { + processEvents(events) + } +} diff --git a/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/util/modificationEventUtils.kt b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/util/modificationEventUtils.kt new file mode 100644 index 000000000000..1dbfb89f4227 --- /dev/null +++ b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/util/modificationEventUtils.kt @@ -0,0 +1,19 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.util + +import com.intellij.openapi.module.Module +import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.idea.base.projectStructure.productionSourceInfo +import org.jetbrains.kotlin.idea.base.projectStructure.testSourceInfo +import org.jetbrains.kotlin.idea.base.projectStructure.toKtModule + +/** + * Returns the [KtModule]s for which modification events need to be published when this [Module] is affected. + * + * An event should be published for the production source info first, so this function cannot use `sourceModuleInfos` as is. Ordering the + * production source module first allows some subscribers like session invalidation to *also* invalidate the test source module right away + * via friend dependencies. Then the invalidation service can quickly skip invalidation of the test source module on the second event, as it + * will already be invalidated. + */ +fun Module.toKtModulesForModificationEvents(): List = + listOfNotNull(productionSourceInfo?.toKtModule(), testSourceInfo?.toKtModule()) diff --git a/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/KotlinDeclarationNameValidator.kt b/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/KotlinDeclarationNameValidator.kt index 0e9fabec453e..f2cea0a64115 100644 --- a/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/KotlinDeclarationNameValidator.kt +++ b/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/KotlinDeclarationNameValidator.kt @@ -1,7 +1,9 @@ // Copyright 2000-2023 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 org.jetbrains.kotlin.analysis.api.KtAllowAnalysisOnEdt import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.lifetime.allowAnalysisOnEdt import org.jetbrains.kotlin.analysis.api.symbols.KtVariableLikeSymbol import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* @@ -18,19 +20,24 @@ class KotlinDeclarationNameValidator( init { check( - target == KotlinNameSuggestionProvider.ValidatorTarget.PROPERTY || - target == KotlinNameSuggestionProvider.ValidatorTarget.VARIABLE || - target == KotlinNameSuggestionProvider.ValidatorTarget.PARAMETER + target == KotlinNameSuggestionProvider.ValidatorTarget.PROPERTY || + target == KotlinNameSuggestionProvider.ValidatorTarget.VARIABLE || + target == KotlinNameSuggestionProvider.ValidatorTarget.PARAMETER || + target == KotlinNameSuggestionProvider.ValidatorTarget.CLASS ) { "Unsupported yet target $target" } } + override fun invoke(name: String): Boolean { val identifier = Name.identifier(name) - with(analysisSession) { - if (hasConflict(identifier)) return false + @OptIn(KtAllowAnalysisOnEdt::class) + allowAnalysisOnEdt { + with(analysisSession) { + if (hasConflict(identifier)) return false + } } return visibleDeclarationsContext.siblings(withItself = checkVisibleDeclarationsContext).none { declaration -> @@ -49,6 +56,11 @@ class KotlinDeclarationNameValidator( !it.isExtension && (containingClassSymbol.value?.let { cl -> it.isVisibleInClass(cl) } != false) } } + KotlinNameSuggestionProvider.ValidatorTarget.CLASS -> { + val scope = + visibleDeclarationsContext.containingKtFile.getScopeContextForPosition(visibleDeclarationsContext).getCompositeScope() + scope.getClassifierSymbols(identifier).any() + } else -> false } } diff --git a/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/KotlinNameSuggester.kt b/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/KotlinNameSuggester.kt index 00e316beb74d..f2abb95eb566 100644 --- a/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/KotlinNameSuggester.kt +++ b/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/KotlinNameSuggester.kt @@ -9,11 +9,11 @@ import com.intellij.util.containers.addIfNotNull import com.intellij.util.text.NameUtilCore import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.calls.singleFunctionCallOrNull -import org.jetbrains.kotlin.analysis.api.calls.symbol import org.jetbrains.kotlin.analysis.api.types.* import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.builtins.StandardNames.FqNames import org.jetbrains.kotlin.idea.base.codeInsight.KotlinNameSuggester.Case.CAMEL +import org.jetbrains.kotlin.idea.base.psi.getCallElement import org.jetbrains.kotlin.idea.base.psi.unquoteKotlinIdentifier import org.jetbrains.kotlin.lexer.KotlinLexer import org.jetbrains.kotlin.lexer.KtKeywordToken @@ -25,9 +25,7 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getOutermostParenthesizerOrThis import org.jetbrains.kotlin.psi.psiUtil.isIdentifier -import org.jetbrains.kotlin.psi.psiUtil.parents import org.jetbrains.kotlin.util.capitalizeDecapitalize.* -import org.jetbrains.kotlin.util.match @DslMarker private annotation class NameSuggesterDsl @@ -169,19 +167,10 @@ class KotlinNameSuggester( val valueArgument = argumentExpression.parent as? KtValueArgument ?: return emptySequence() val callElement = getCallElement(valueArgument) ?: return emptySequence() val resolvedCall = callElement.resolveCall()?.singleFunctionCallOrNull() ?: return emptySequence() - if (!resolvedCall.symbol.hasStableParameterNames) return emptySequence() val parameter = resolvedCall.argumentMapping[valueArgument.getArgumentExpression()]?.symbol ?: return emptySequence() return suggestNameByValidIdentifierName(parameter.name.asString(), validator)?.let { sequenceOf(it) } ?: emptySequence() } - private fun getCallElement(valueArgument: KtValueArgument): KtCallElement? { - return if (valueArgument is KtLambdaArgument) { - valueArgument.parent as? KtCallElement - } else { - valueArgument.parents.match(KtValueArgumentList::class, last = KtCallElement::class) - } - } - /** * Returns names based on a given type. * Examples: diff --git a/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/compiler/KtCompilerFacilityUtils.kt b/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/compiler/KtCompilerFacilityUtils.kt new file mode 100644 index 000000000000..3c40ee373865 --- /dev/null +++ b/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/compiler/KtCompilerFacilityUtils.kt @@ -0,0 +1,65 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. + +@file:JvmName("KtCompilerFacilityUtils") + +package org.jetbrains.kotlin.idea.base.codeInsight.compiler + +import com.intellij.openapi.components.service +import org.jetbrains.annotations.ApiStatus +import org.jetbrains.kotlin.analysis.api.components.KtCompilationResult +import org.jetbrains.kotlin.analysis.api.components.KtCompilerFacilityMixIn +import org.jetbrains.kotlin.analysis.api.components.KtCompilerTarget +import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnostic +import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.psi.KtFile +import java.io.File +import java.util.zip.ZipEntry +import java.util.zip.ZipOutputStream + +interface KotlinCompilerIdeAllowedErrorFilter : (KtDiagnostic) -> Boolean { + companion object { + fun getInstance(): KotlinCompilerIdeAllowedErrorFilter = service() + } +} + +@ApiStatus.Internal +fun KtCompilerFacilityMixIn.compileToDirectory( + file: KtFile, + configuration: CompilerConfiguration, + target: KtCompilerTarget, + allowedErrorFilter: (KtDiagnostic) -> Boolean, + destination: File +): KtCompilationResult { + val result = compile(file, configuration, target, allowedErrorFilter) + if (result is KtCompilationResult.Success) { + for (outputFile in result.output) { + val target = File(destination, outputFile.path) + (target.parentFile ?: error("Can't find parent for file $target")).mkdirs() + target.writeBytes(outputFile.content) + } + } + return result +} + +@ApiStatus.Internal +fun KtCompilerFacilityMixIn.compileToJar( + file: KtFile, + configuration: CompilerConfiguration, + target: KtCompilerTarget, + allowedErrorFilter: (KtDiagnostic) -> Boolean, + destination: File +): KtCompilationResult { + val result = compile(file, configuration, target, allowedErrorFilter) + if (result is KtCompilationResult.Success) { + destination.outputStream().buffered().use { os -> + ZipOutputStream(os).use { zos -> + for (outputFile in result.output) { + zos.putNextEntry(ZipEntry(outputFile.path)) + zos.write(outputFile.content) + zos.closeEntry() + } + } + } + } + return result +} \ No newline at end of file diff --git a/plugins/kotlin/base/fe10/analysis/src/org/jetbrains/kotlin/idea/core/OriginTracingClassBuilderFactory.kt b/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/compiler/OriginTracingClassBuilderFactory.kt similarity index 88% rename from plugins/kotlin/base/fe10/analysis/src/org/jetbrains/kotlin/idea/core/OriginTracingClassBuilderFactory.kt rename to plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/compiler/OriginTracingClassBuilderFactory.kt index c20f84c2610a..af57ba1df014 100644 --- a/plugins/kotlin/base/fe10/analysis/src/org/jetbrains/kotlin/idea/core/OriginTracingClassBuilderFactory.kt +++ b/plugins/kotlin/base/code-insight/src/org/jetbrains/kotlin/idea/base/codeInsight/compiler/OriginTracingClassBuilderFactory.kt @@ -1,8 +1,9 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package org.jetbrains.kotlin.idea.core +package org.jetbrains.kotlin.idea.base.codeInsight.compiler import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile +import org.jetbrains.annotations.ApiStatus import org.jetbrains.kotlin.codegen.ClassBuilder import org.jetbrains.kotlin.codegen.ClassBuilderFactory import org.jetbrains.kotlin.codegen.DelegatingClassBuilder @@ -10,10 +11,11 @@ import org.jetbrains.kotlin.codegen.DelegatingClassBuilderFactory import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin /** - * A [ClassBuilderFactory] which maps the file names of generated classes to their original [PsiFile], allowing for example to filter code - * generation output by class name. + * A [ClassBuilderFactory] which maps the file names of generated classes to their original [PsiFile], + * allowing for example to filter code generation output by class name. */ -internal class OriginTracingClassBuilderFactory( +@ApiStatus.Internal +class OriginTracingClassBuilderFactory( private val delegateFactory: ClassBuilderFactory, ) : DelegatingClassBuilderFactory(delegateFactory) { private val origins = mutableMapOf>() diff --git a/plugins/kotlin/base/facet/src/org/jetbrains/kotlin/idea/facet/KotlinFacetModificationTracker.kt b/plugins/kotlin/base/facet/src/org/jetbrains/kotlin/idea/facet/KotlinFacetModificationTracker.kt index 225cebcec864..e9bf6dc7916d 100644 --- a/plugins/kotlin/base/facet/src/org/jetbrains/kotlin/idea/facet/KotlinFacetModificationTracker.kt +++ b/plugins/kotlin/base/facet/src/org/jetbrains/kotlin/idea/facet/KotlinFacetModificationTracker.kt @@ -48,9 +48,10 @@ class KotlinFacetModificationTracker(project: Project) : override fun dispose() = Unit companion object { - fun FacetEntity.isKotlinFacet() = name == KotlinFacetType.NAME @JvmStatic fun getInstance(project: Project): KotlinFacetModificationTracker = project.service() } } + +fun FacetEntity.isKotlinFacet(): Boolean = name == KotlinFacetType.NAME diff --git a/plugins/kotlin/base/facet/src/org/jetbrains/kotlin/idea/facet/KotlinFacetSettingsProviderImpl.kt b/plugins/kotlin/base/facet/src/org/jetbrains/kotlin/idea/facet/KotlinFacetSettingsProviderImpl.kt index 6f80631a3ead..0566adf116c9 100644 --- a/plugins/kotlin/base/facet/src/org/jetbrains/kotlin/idea/facet/KotlinFacetSettingsProviderImpl.kt +++ b/plugins/kotlin/base/facet/src/org/jetbrains/kotlin/idea/facet/KotlinFacetSettingsProviderImpl.kt @@ -16,7 +16,6 @@ import org.jetbrains.kotlin.config.KotlinFacetSettings import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider import org.jetbrains.kotlin.idea.base.util.caching.* import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerSettingsListener -import org.jetbrains.kotlin.idea.facet.KotlinFacetModificationTracker.Companion.isKotlinFacet class KotlinFacetSettingsProviderImpl(project: Project) : SynchronizedFineGrainedEntityCache(project, doSelfInitialization = false), diff --git a/plugins/kotlin/base/fe10/analysis-api-providers/resources/kotlin.base.fe10.analysis-api-providers.xml b/plugins/kotlin/base/fe10/analysis-api-providers/resources/kotlin.base.fe10.analysis-api-providers.xml index 8e5d7f8e1137..c8771683844d 100644 --- a/plugins/kotlin/base/fe10/analysis-api-providers/resources/kotlin.base.fe10.analysis-api-providers.xml +++ b/plugins/kotlin/base/fe10/analysis-api-providers/resources/kotlin.base.fe10.analysis-api-providers.xml @@ -5,7 +5,10 @@ serviceInterface="org.jetbrains.kotlin.analysis.providers.KotlinModificationTrackerFactory" serviceImplementation="org.jetbrains.kotlin.idea.base.fe10.analysisApiProviders.Fe10KotlinModificationTrackerFactory"/> + serviceImplementation="org.jetbrains.kotlin.idea.base.analysisApiProviders.KotlinModuleStateModificationService"/> + diff --git a/plugins/kotlin/base/fe10/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fe10/analysisApiProviders/Fe10KotlinGlobalModificationService.kt b/plugins/kotlin/base/fe10/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fe10/analysisApiProviders/Fe10KotlinGlobalModificationService.kt new file mode 100644 index 000000000000..1a79e278899b --- /dev/null +++ b/plugins/kotlin/base/fe10/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fe10/analysisApiProviders/Fe10KotlinGlobalModificationService.kt @@ -0,0 +1,16 @@ +// Copyright 2000-2023 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.fe10.analysisApiProviders + +import com.intellij.openapi.project.Project +import org.jetbrains.annotations.TestOnly +import org.jetbrains.kotlin.analysis.providers.impl.KotlinGlobalModificationServiceBase +import org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener +import org.jetbrains.kotlin.idea.caches.trackers.KotlinModuleOutOfCodeBlockModificationTracker + +internal class Fe10KotlinGlobalModificationService(private val project: Project) : KotlinGlobalModificationServiceBase(project) { + @TestOnly + override fun incrementModificationTrackers(includeBinaryTrackers: Boolean) { + KotlinCodeBlockModificationListener.getInstance(project).incModificationCount() + KotlinModuleOutOfCodeBlockModificationTracker.incrementModificationCountForAllModules(project) + } +} diff --git a/plugins/kotlin/base/fe10/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fe10/analysisApiProviders/Fe10KotlinModificationTrackerFactory.kt b/plugins/kotlin/base/fe10/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fe10/analysisApiProviders/Fe10KotlinModificationTrackerFactory.kt index 21182bceb18b..4db137359b53 100644 --- a/plugins/kotlin/base/fe10/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fe10/analysisApiProviders/Fe10KotlinModificationTrackerFactory.kt +++ b/plugins/kotlin/base/fe10/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fe10/analysisApiProviders/Fe10KotlinModificationTrackerFactory.kt @@ -4,37 +4,15 @@ package org.jetbrains.kotlin.idea.base.fe10.analysisApiProviders import com.intellij.java.library.JavaLibraryModificationTracker import com.intellij.openapi.project.Project import com.intellij.openapi.util.ModificationTracker -import org.jetbrains.annotations.TestOnly -import org.jetbrains.kotlin.analysis.project.structure.KtModule -import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule import org.jetbrains.kotlin.analysis.providers.KotlinModificationTrackerFactory -import org.jetbrains.kotlin.analysis.providers.KtModuleStateTracker -import org.jetbrains.kotlin.idea.base.analysisApiProviders.KotlinModuleStateTrackerProvider -import org.jetbrains.kotlin.idea.base.projectStructure.ideaModule import org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener -import org.jetbrains.kotlin.idea.caches.trackers.KotlinModuleOutOfCodeBlockModificationTracker internal class Fe10KotlinModificationTrackerFactory(private val project: Project) : KotlinModificationTrackerFactory() { override fun createProjectWideOutOfBlockModificationTracker(): ModificationTracker { return KotlinCodeBlockModificationListener.getInstance(project).kotlinOutOfCodeBlockTracker } - override fun createModuleWithoutDependenciesOutOfBlockModificationTracker(module: KtSourceModule): ModificationTracker { - return KotlinModuleOutOfCodeBlockModificationTracker(module.ideaModule) - } - override fun createLibrariesWideModificationTracker(): ModificationTracker { return JavaLibraryModificationTracker.getInstance(project) } - - override fun createModuleStateTracker(module: KtModule): KtModuleStateTracker { - return KotlinModuleStateTrackerProvider.getInstance(project).getModuleStateTrackerFor(module) - } - - @TestOnly - override fun incrementModificationsCount(includeBinaryTrackers: Boolean) { - KotlinCodeBlockModificationListener.getInstance(project).incModificationCount() - KotlinModuleOutOfCodeBlockModificationTracker.incrementModificationCountForAllModules(project) - KotlinModuleStateTrackerProvider.getInstance(project).incrementModificationCountForAllModules(includeBinaryTrackers) - } } \ No newline at end of file diff --git a/plugins/kotlin/base/fe10/analysis/src/org/jetbrains/kotlin/base/fe10/analysis/IdeFe10AnalysisFacade.kt b/plugins/kotlin/base/fe10/analysis/src/org/jetbrains/kotlin/base/fe10/analysis/IdeFe10AnalysisFacade.kt index 0211a874b319..b920adc4ed21 100644 --- a/plugins/kotlin/base/fe10/analysis/src/org/jetbrains/kotlin/base/fe10/analysis/IdeFe10AnalysisFacade.kt +++ b/plugins/kotlin/base/fe10/analysis/src/org/jetbrains/kotlin/base/fe10/analysis/IdeFe10AnalysisFacade.kt @@ -8,8 +8,14 @@ import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.Analysis import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin import org.jetbrains.kotlin.caches.resolve.KotlinCacheService import org.jetbrains.kotlin.idea.FrontendInternals +import org.jetbrains.kotlin.idea.base.projectStructure.RootKindFilter +import org.jetbrains.kotlin.idea.base.projectStructure.matches +import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade +import org.jetbrains.kotlin.idea.resolve.ResolutionFacade +import org.jetbrains.kotlin.psi.KtCodeFragment import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.CallResolver import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall @@ -51,7 +57,7 @@ internal class IdeFe10AnalysisFacade(private val project: Project): Fe10Analysis } override fun analyze(elements: List, mode: AnalysisMode): BindingContext { - val resolutionFacade = KotlinCacheService.getInstance(project).getResolutionFacade(elements) + val resolutionFacade = getResolutionFacade(elements) ?: return BindingContext.EMPTY if (mode == AnalysisMode.ALL_COMPILER_CHECKS) { return resolutionFacade.analyzeWithAllCompilerChecks(elements).bindingContext @@ -68,6 +74,44 @@ internal class IdeFe10AnalysisFacade(private val project: Project): Fe10Analysis return resolutionFacade.analyze(elements, bodyResolveMode) } + private fun getResolutionFacade(elements: List): ResolutionFacade? { + val kotlinCacheService = KotlinCacheService.getInstance(project) + + if (elements.size == 1) { + kotlinCacheService.getResolutionFacade(elements.single()) + } + + val files = elements + .asSequence() + .mapNotNull { it.containingFile } + .mapNotNull { if (it is KtCodeFragment) it.context?.containingFile else it } + .filterIsInstance() + .distinct() + .toList() + + if (files.isEmpty()) { + return null + } + + val scriptFiles = files.filter { it.isScript() } + if (!scriptFiles.isEmpty()) { + return kotlinCacheService.getResolutionFacade(scriptFiles) + } + + // The following logic is taken from 'KotlinCacheServiceImpl.filterNotInProjectSource()' + val moduleInfo = files.first().moduleInfo + val specialFiles = files + .filterNot { RootKindFilter.projectSources.matches(it) && moduleInfo.contentScope.contains(it.virtualFile) } + + if (specialFiles.isNotEmpty()) { + // 'KotlinCacheServiceImpl' is bad in getting a resolution facade for multiple files outside the so-called 'main' module root. + // Here we artificially choose the facade for the first element. It's not quite correct, still it's better than nothing. + return kotlinCacheService.getResolutionFacade(specialFiles.first()) + } + + return kotlinCacheService.getResolutionFacade(files) + } + override fun getOrigin(file: VirtualFile): KtSymbolOrigin { return KtSymbolOrigin.SOURCE } diff --git a/plugins/kotlin/base/fe10/analysis/src/org/jetbrains/kotlin/idea/core/KotlinCompilerIde.kt b/plugins/kotlin/base/fe10/analysis/src/org/jetbrains/kotlin/idea/core/KotlinCompilerIde.kt deleted file mode 100644 index 4560ca43874d..000000000000 --- a/plugins/kotlin/base/fe10/analysis/src/org/jetbrains/kotlin/idea/core/KotlinCompilerIde.kt +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package org.jetbrains.kotlin.idea.core - -import org.jetbrains.kotlin.backend.common.output.OutputFile -import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig -import org.jetbrains.kotlin.backend.jvm.* -import org.jetbrains.kotlin.codegen.ClassBuilderFactories -import org.jetbrains.kotlin.codegen.ClassBuilderFactory -import org.jetbrains.kotlin.codegen.DefaultCodegenFactory -import org.jetbrains.kotlin.codegen.KotlinCodegenFacade -import org.jetbrains.kotlin.codegen.state.GenerationState -import org.jetbrains.kotlin.config.CommonConfigurationKeys -import org.jetbrains.kotlin.config.CompilerConfiguration -import org.jetbrains.kotlin.config.JVMConfigurationKeys -import org.jetbrains.kotlin.config.languageVersionSettings -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.idea.base.facet.platform.platform -import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings -import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade -import org.jetbrains.kotlin.idea.core.util.InlineFunctionAnalyzer -import org.jetbrains.kotlin.idea.resolve.ResolutionFacade -import org.jetbrains.kotlin.load.kotlin.toSourceElement -import org.jetbrains.kotlin.platform.isCommon -import org.jetbrains.kotlin.platform.jvm.isJvm -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.resolve.source.PsiSourceFile -import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource -import java.io.File -import java.util.zip.ZipEntry -import java.util.zip.ZipOutputStream - -/** - * @param shouldStubUnboundIrSymbols Whether unbound IR symbols should be stubbed instead of linked. This should be enabled if the [file] - * could refer to symbols defined in another file of the same module. Such symbols are not compiled by [KotlinCompilerIde] (only [file] - * itself is compiled) and cannot be linked from a dependency. [shouldStubUnboundIrSymbols] only has an effect if [JVMConfigurationKeys.IR] - * is set to `true` in [initialConfiguration]. - */ -class KotlinCompilerIde( - private val file: KtFile, - private val initialConfiguration: CompilerConfiguration = getDefaultCompilerConfiguration(file), - private val classBuilderFactory: ClassBuilderFactory = ClassBuilderFactories.BINARIES, - private val resolutionFacadeProvider: (KtFile) -> ResolutionFacade? = { file.getResolutionFacade() }, - private val classFilesOnly: Boolean = false, - private val shouldStubUnboundIrSymbols: Boolean = false, -) { - companion object { - private fun getDefaultCompilerConfiguration(file: KtFile): CompilerConfiguration { - return CompilerConfiguration().apply { - languageVersionSettings = file.languageVersionSettings - } - } - } - - class CompiledFile(val path: String, val bytecode: ByteArray) - - fun compileToDirectory(destination: File) { - destination.mkdirs() - - val state = compile() ?: return - - try { - for (outputFile in getFiles(state)) { - val target = File(destination, outputFile.relativePath) - (target.parentFile ?: error("Can't find parent for file $target")).mkdirs() - target.writeBytes(outputFile.asByteArray()) - } - } finally { - state.destroy() - } - } - - fun compileToJar(destination: File) { - destination.outputStream().buffered().use { os -> - ZipOutputStream(os).use { zos -> - val state = compile() - - if (state != null) { - try { - for (outputFile in getFiles(state)) { - zos.putNextEntry(ZipEntry(outputFile.relativePath)) - zos.write(outputFile.asByteArray()) - zos.closeEntry() - } - } finally { - state.destroy() - } - } - } - } - } - - fun compileToBytecode(): List { - val state = compile() ?: return emptyList() - - try { - return getFiles(state).map { CompiledFile(it.relativePath, it.asByteArray()) } - } finally { - state.destroy() - } - } - - fun compile(): GenerationState? = compileImpl(traceClassFileOrigins = false)?.first - - fun compileTracingOrigin(): Pair? = compileImpl(traceClassFileOrigins = true) - - private fun compileImpl(traceClassFileOrigins: Boolean): Pair? { - val project = file.project - val platform = file.platform - - if (!platform.isCommon() && !platform.isJvm()) return null - - val resolutionFacade = resolutionFacadeProvider(file) ?: return null - val configuration = initialConfiguration.copy().apply { - put(JVMConfigurationKeys.DO_NOT_CLEAR_BINDING_CONTEXT, true) - } - val isIrBackend = configuration.getBoolean(JVMConfigurationKeys.IR) - - // The binding context needs to be built from all files with reachable inline functions, as such files may contain classes whose - // descriptors must be available in the binding context for the IR backend. Note that the full bytecode is only generated for - // `file` because of filtering in `generateClassFilter`, while only select declarations from other files are generated if needed - // by the backend. - val inlineAnalyzer = InlineFunctionAnalyzer( - resolutionFacade, - analyzeOnlyReifiedInlineFunctions = configuration.getBoolean(CommonConfigurationKeys.DISABLE_INLINE), - ).apply { analyze(file) } - val toProcess = inlineAnalyzer.allFiles() - val bindingContext = resolutionFacade.analyzeWithAllCompilerChecks(toProcess).bindingContext - - // The IR backend will try to regenerate object literals defined in inline functions from generated class files during inlining. - // Hence, we need to be aware of which object declarations are defined in the relevant inline functions. - val inlineObjectDeclarations = when { - isIrBackend -> inlineAnalyzer.inlineObjectDeclarations() - else -> setOf() - } - val inlineObjectDeclarationFiles = inlineObjectDeclarations.mapTo(mutableSetOf()) { it.containingKtFile } - - val generateClassFilter = object : GenerationState.GenerateClassFilter() { - override fun shouldGeneratePackagePart(ktFile: KtFile): Boolean { - return file === ktFile || inlineObjectDeclarationFiles.contains(ktFile) - } - - override fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean { - return true - } - - override fun shouldGenerateClass(processingClassOrObject: KtClassOrObject): Boolean { - return processingClassOrObject.containingKtFile === file || - processingClassOrObject is KtObjectDeclaration && inlineObjectDeclarations.contains(processingClassOrObject) - } - - override fun shouldGenerateScript(script: KtScript): Boolean { - return script.containingKtFile === file - } - - override fun shouldGenerateCodeFragment(script: KtCodeFragment) = false - } - - val codegenFactory = when { - isIrBackend -> createJvmIrCodegenFactory(configuration) - else -> DefaultCodegenFactory - } - - val originTracingClassBuilderFactory = if (traceClassFileOrigins) OriginTracingClassBuilderFactory(classBuilderFactory) else null - - val state = GenerationState.Builder( - project, - originTracingClassBuilderFactory ?: classBuilderFactory, - resolutionFacade.moduleDescriptor, - bindingContext, - toProcess, - configuration, - ).generateDeclaredClassFilter(generateClassFilter) - .codegenFactory(codegenFactory) - .build() - - KotlinCodegenFacade.compileCorrectFiles(state) - return Pair(state, originTracingClassBuilderFactory?.classFileOrigins ?: emptyMap()) - } - - /** - * Creates a [JvmIrCodegenFactory] that stubs unbound symbols if [shouldStubUnboundIrSymbols] is enabled. - */ - private fun createJvmIrCodegenFactory(compilerConfiguration: CompilerConfiguration): JvmIrCodegenFactory { - val jvmGeneratorExtensions = if (shouldStubUnboundIrSymbols) { - object : JvmGeneratorExtensionsImpl(compilerConfiguration) { - override fun getContainerSource(descriptor: DeclarationDescriptor): DeserializedContainerSource? { - // Stubbed top-level function IR symbols (from other source files in the module) require a parent facade class to be - // generated, which requires a container source to be provided. Without a facade class, function IR symbols will have - // an `IrExternalPackageFragment` parent, which trips up code generation during IR lowering. - val psiSourceFile = - descriptor.toSourceElement.containingFile as? PsiSourceFile ?: return super.getContainerSource(descriptor) - return FacadeClassSourceShimForFragmentCompilation(psiSourceFile) - } - } - } else JvmGeneratorExtensionsImpl(compilerConfiguration) - - val ideCodegenSettings = JvmIrCodegenFactory.IdeCodegenSettings( - shouldStubAndNotLinkUnboundSymbols = shouldStubUnboundIrSymbols, - shouldDeduplicateBuiltInSymbols = shouldStubUnboundIrSymbols, - - // Because the file to compile may be contained in a "common" multiplatform module, an `expect` declaration doesn't necessarily - // have an obvious associated `actual` symbol. `shouldStubOrphanedExpectSymbols` generates stubs for such `expect` declarations. - shouldStubOrphanedExpectSymbols = true, - - // Likewise, the file to compile may be contained in a "platform" multiplatform module, where the `actual` declaration is - // referenced in the symbol table automatically, but not its `expect` counterpart, because it isn't contained in the files to - // compile. `shouldReferenceUndiscoveredExpectSymbols` references such `expect` symbols in the symbol table so that they can - // subsequently be stubbed. - shouldReferenceUndiscoveredExpectSymbols = true, - ) - - return JvmIrCodegenFactory( - compilerConfiguration, - PhaseConfig(jvmPhases), - jvmGeneratorExtensions = jvmGeneratorExtensions, - ideCodegenSettings = ideCodegenSettings, - ) - } - - private fun getFiles(state: GenerationState): List { - val allFiles = state.factory.asList() - if (classFilesOnly) { - return allFiles.filter { it.relativePath.endsWith(".class") } - } - return allFiles - } -} \ No newline at end of file diff --git a/plugins/kotlin/base/fe10/analysis/src/org/jetbrains/kotlin/idea/util/expectActualUtil.kt b/plugins/kotlin/base/fe10/analysis/src/org/jetbrains/kotlin/idea/util/expectActualUtil.kt index 9249d2c07eae..9407b20a2897 100644 --- a/plugins/kotlin/base/fe10/analysis/src/org/jetbrains/kotlin/idea/util/expectActualUtil.kt +++ b/plugins/kotlin/base/fe10/analysis/src/org/jetbrains/kotlin/idea/util/expectActualUtil.kt @@ -25,7 +25,7 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.multiplatform.* fun MemberDescriptor.expectedDescriptors(): List { - val expectedCompatibilityMap = ExpectedActualResolver.findExpectedForActual(this) + val expectedCompatibilityMap = ExpectedActualResolver.findExpectedForActual_incrementalCompilationWorkaround(this) ?: return emptyList() return expectedCompatibilityMap[ExpectActualCompatibility.Compatible] diff --git a/plugins/kotlin/base/fe10/code-insight/kotlin.base.fe10.code-insight.iml b/plugins/kotlin/base/fe10/code-insight/kotlin.base.fe10.code-insight.iml index e1dbf2e4f2a9..d11fdfd05b18 100644 --- a/plugins/kotlin/base/fe10/code-insight/kotlin.base.fe10.code-insight.iml +++ b/plugins/kotlin/base/fe10/code-insight/kotlin.base.fe10.code-insight.iml @@ -9,9 +9,11 @@ - + + + diff --git a/plugins/kotlin/base/fe10/code-insight/src/org/jetbrains/kotlin/idea/base/fe10/codeInsight/compiler/K1KotlinCompilerIdeAllowedErrorFilter.kt b/plugins/kotlin/base/fe10/code-insight/src/org/jetbrains/kotlin/idea/base/fe10/codeInsight/compiler/K1KotlinCompilerIdeAllowedErrorFilter.kt new file mode 100644 index 000000000000..12d8572f8a47 --- /dev/null +++ b/plugins/kotlin/base/fe10/code-insight/src/org/jetbrains/kotlin/idea/base/fe10/codeInsight/compiler/K1KotlinCompilerIdeAllowedErrorFilter.kt @@ -0,0 +1,29 @@ +// Copyright 2000-2023 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.fe10.codeInsight.compiler + +import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnostic +import org.jetbrains.kotlin.diagnostics.Errors +import org.jetbrains.kotlin.idea.base.codeInsight.compiler.KotlinCompilerIdeAllowedErrorFilter + +class K1KotlinCompilerIdeAllowedErrorFilter : KotlinCompilerIdeAllowedErrorFilter { + private companion object { + val ALLOWED_ERRORS = listOf( + Errors.INVISIBLE_REFERENCE, + Errors.INVISIBLE_MEMBER, + Errors.INVISIBLE_SETTER, + Errors.DEPRECATION_ERROR, + Errors.DIVISION_BY_ZERO, + Errors.OPT_IN_USAGE_ERROR, + Errors.OPT_IN_OVERRIDE_ERROR, + Errors.UNSAFE_CALL, + Errors.UNSAFE_OPERATOR_CALL, + Errors.ITERATOR_ON_NULLABLE, + Errors.UNEXPECTED_SAFE_CALL, + Errors.DSL_SCOPE_VIOLATION + ).map { it.name } + } + + override fun invoke(diagnostic: KtDiagnostic): Boolean { + return diagnostic.factoryName in ALLOWED_ERRORS + } +} \ No newline at end of file diff --git a/plugins/kotlin/base/fe10/highlighting/kotlin.base.fe10.highlighting.iml b/plugins/kotlin/base/fe10/highlighting/kotlin.base.fe10.highlighting.iml index b1fd714858cd..5577cfe9835d 100644 --- a/plugins/kotlin/base/fe10/highlighting/kotlin.base.fe10.highlighting.iml +++ b/plugins/kotlin/base/fe10/highlighting/kotlin.base.fe10.highlighting.iml @@ -18,7 +18,7 @@ - + diff --git a/plugins/kotlin/base/fe10/project-structure/kotlin.base.fe10.project-structure.iml b/plugins/kotlin/base/fe10/project-structure/kotlin.base.fe10.project-structure.iml new file mode 100644 index 000000000000..39dbeae67f48 --- /dev/null +++ b/plugins/kotlin/base/fe10/project-structure/kotlin.base.fe10.project-structure.iml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/kotlin/base/fe10/project-structure/resources/kotlin.base.fe10.project-structure.xml b/plugins/kotlin/base/fe10/project-structure/resources/kotlin.base.fe10.project-structure.xml new file mode 100644 index 000000000000..9068adc0c269 --- /dev/null +++ b/plugins/kotlin/base/fe10/project-structure/resources/kotlin.base.fe10.project-structure.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/plugins/kotlin/base/fe10/project-structure/src/org/jetbrains/kotlin/idea/base/fe10/projectStructure/Fe10OrderedWorkspaceModelChangeListener.kt b/plugins/kotlin/base/fe10/project-structure/src/org/jetbrains/kotlin/idea/base/fe10/projectStructure/Fe10OrderedWorkspaceModelChangeListener.kt new file mode 100644 index 000000000000..ada1794dbe9b --- /dev/null +++ b/plugins/kotlin/base/fe10/project-structure/src/org/jetbrains/kotlin/idea/base/fe10/projectStructure/Fe10OrderedWorkspaceModelChangeListener.kt @@ -0,0 +1,17 @@ +// Copyright 2000-2023 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.fe10.projectStructure + +import com.intellij.openapi.components.serviceIfCreated +import com.intellij.openapi.project.Project +import com.intellij.platform.backend.workspace.WorkspaceModelChangeListener +import com.intellij.platform.workspace.storage.VersionedStorageChange +import org.jetbrains.kotlin.idea.base.projectStructure.LibraryInfoCache + +/** + * See `FirOrderedWorkspaceModelChangeListener` for why this workspace model listener exists. + */ +internal class Fe10OrderedWorkspaceModelChangeListener(private val project: Project) : WorkspaceModelChangeListener { + override fun beforeChanged(event: VersionedStorageChange) { + project.serviceIfCreated()?.beforeWorkspaceModelChanged(event) + } +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/kotlin.base.fir.analysis-api-providers.iml b/plugins/kotlin/base/fir/analysis-api-providers/kotlin.base.fir.analysis-api-providers.iml index 64dbe9fe223b..88307efd391a 100644 --- a/plugins/kotlin/base/fir/analysis-api-providers/kotlin.base.fir.analysis-api-providers.iml +++ b/plugins/kotlin/base/fir/analysis-api-providers/kotlin.base.fir.analysis-api-providers.iml @@ -1,5 +1,21 @@ + + + + + + + + + + + + + + + @@ -15,6 +31,7 @@ + @@ -28,7 +45,11 @@ + + + + \ No newline at end of file diff --git a/plugins/kotlin/base/fir/analysis-api-providers/resources/kotlin.base.fir.analysis-api-providers.xml b/plugins/kotlin/base/fir/analysis-api-providers/resources/kotlin.base.fir.analysis-api-providers.xml index f9c2b4012ee2..d010f0be7d6d 100644 --- a/plugins/kotlin/base/fir/analysis-api-providers/resources/kotlin.base.fir.analysis-api-providers.xml +++ b/plugins/kotlin/base/fir/analysis-api-providers/resources/kotlin.base.fir.analysis-api-providers.xml @@ -4,14 +4,32 @@ - + serviceInterface="org.jetbrains.kotlin.idea.base.analysisApiProviders.KotlinModuleStateModificationService" + serviceImplementation="org.jetbrains.kotlin.idea.base.fir.analysisApiProviders.FirIdeKotlinModuleStateModificationService"/> + + + + + + + + + + + diff --git a/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirAnalysisEventSubscriptionProjectActivity.kt b/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirAnalysisEventSubscriptionProjectActivity.kt new file mode 100644 index 000000000000..90dc84373436 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirAnalysisEventSubscriptionProjectActivity.kt @@ -0,0 +1,23 @@ +// Copyright 2000-2023 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.fir.analysisApiProviders + +import com.intellij.openapi.project.Project +import com.intellij.openapi.startup.ProjectActivity +import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSessionInvalidationService +import org.jetbrains.kotlin.analysis.providers.analysisMessageBus + +/** + * [FirAnalysisEventSubscriptionProjectActivity] sets up subscriptions to events published via [analysisMessageBus] for FIR services. This + * approach is favored over defining `projectListeners` in the plugin XML configuration for two reasons: + * + * 1. [analysisMessageBus] is not guaranteed to be the same as the [Project]'s message bus, by design, and `projectListeners` registers + * listeners with the project message bus. + * 2. Services like [LLFirSessionInvalidationService] have to register listeners when running in the IDE, but also in Analysis API + * standalone mode. We cannot register listeners via XML in standalone mode, so this approach allows putting the subscription + * configuration in one place. + */ +internal class FirAnalysisEventSubscriptionProjectActivity : ProjectActivity { + override suspend fun execute(project: Project) { + LLFirSessionInvalidationService.getInstance(project).subscribeToModificationEvents() + } +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeKotlinGlobalModificationService.kt b/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeKotlinGlobalModificationService.kt new file mode 100644 index 000000000000..48d609285056 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeKotlinGlobalModificationService.kt @@ -0,0 +1,13 @@ +// Copyright 2000-2023 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.fir.analysisApiProviders + +import com.intellij.openapi.project.Project +import org.jetbrains.annotations.TestOnly +import org.jetbrains.kotlin.analysis.providers.impl.KotlinGlobalModificationServiceBase + +internal class FirIdeKotlinGlobalModificationService(private val project: Project) : KotlinGlobalModificationServiceBase(project) { + @TestOnly + override fun incrementModificationTrackers(includeBinaryTrackers: Boolean) { + FirIdeKotlinModificationTrackerFactory.getInstance(project).incrementModificationsCount(includeBinaryTrackers) + } +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeKotlinModificationTrackerFactory.kt b/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeKotlinModificationTrackerFactory.kt index c0259af91d5f..6331d6c3891e 100644 --- a/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeKotlinModificationTrackerFactory.kt +++ b/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeKotlinModificationTrackerFactory.kt @@ -5,39 +5,29 @@ import com.intellij.java.library.JavaLibraryModificationTracker import com.intellij.openapi.project.Project import com.intellij.openapi.util.ModificationTracker import org.jetbrains.annotations.TestOnly -import org.jetbrains.kotlin.analysis.project.structure.KtModule -import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule import org.jetbrains.kotlin.analysis.providers.KotlinModificationTrackerFactory -import org.jetbrains.kotlin.analysis.providers.KtModuleStateTracker -import org.jetbrains.kotlin.idea.base.analysisApiProviders.KotlinModuleStateTrackerProvider -import org.jetbrains.kotlin.idea.base.projectStructure.ideaModule internal class FirIdeKotlinModificationTrackerFactory(private val project: Project) : KotlinModificationTrackerFactory() { - private val modificationTrackerService = project.getService(FirIdeModificationTrackerService::class.java) + private val projectOutOfBlockModificationTracker + get() = FirIdeOutOfBlockModificationService.getInstance(project).projectOutOfBlockModificationTracker - override fun createProjectWideOutOfBlockModificationTracker(): ModificationTracker = - modificationTrackerService.projectOutOfBlockModificationTracker + private val libraryModificationTracker + get() = JavaLibraryModificationTracker.getInstance(project) as JavaLibraryModificationTracker - override fun createModuleWithoutDependenciesOutOfBlockModificationTracker(module: KtSourceModule): ModificationTracker = - modificationTrackerService.getModuleOutOfBlockModificationTracker(module.ideaModule) + override fun createProjectWideOutOfBlockModificationTracker(): ModificationTracker = projectOutOfBlockModificationTracker - override fun createLibrariesWideModificationTracker(): ModificationTracker { - return JavaLibraryModificationTracker.getInstance(project) - } - - override fun createModuleStateTracker(module: KtModule): KtModuleStateTracker { - return KotlinModuleStateTrackerProvider.getInstance(project).getModuleStateTrackerFor(module) - } + override fun createLibrariesWideModificationTracker(): ModificationTracker = libraryModificationTracker @TestOnly - override fun incrementModificationsCount(includeBinaryTrackers: Boolean) { + internal fun incrementModificationsCount(includeBinaryTrackers: Boolean) { + projectOutOfBlockModificationTracker.incModificationCount() if (includeBinaryTrackers) { - (createLibrariesWideModificationTracker() as JavaLibraryModificationTracker).incModificationCount() + libraryModificationTracker.incModificationCount() } + } - // `FirIdeModificationTrackerService` is for source modules only. - modificationTrackerService.increaseModificationCountForAllModules() - - KotlinModuleStateTrackerProvider.getInstance(project).incrementModificationCountForAllModules(includeBinaryTrackers) + companion object { + fun getInstance(project: Project): FirIdeKotlinModificationTrackerFactory = + KotlinModificationTrackerFactory.getInstance(project) as FirIdeKotlinModificationTrackerFactory } } diff --git a/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeKotlinModuleStateTrackerProvider.kt b/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeKotlinModuleStateModificationService.kt similarity index 68% rename from plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeKotlinModuleStateTrackerProvider.kt rename to plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeKotlinModuleStateModificationService.kt index c8269ee0f08a..5465e46dcc67 100644 --- a/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeKotlinModuleStateTrackerProvider.kt +++ b/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeKotlinModuleStateModificationService.kt @@ -4,16 +4,15 @@ package org.jetbrains.kotlin.idea.base.fir.analysisApiProviders import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent import com.intellij.openapi.vfs.newvfs.events.VFileEvent +import org.jetbrains.kotlin.idea.base.analysisApiProviders.KotlinModuleStateModificationService import java.util.regex.Pattern -import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirBuiltinsSessionFactory -import org.jetbrains.kotlin.idea.base.analysisApiProviders.KotlinModuleStateTrackerProvider private val STDLIB_PATTERN = Pattern.compile("kotlin-stdlib-(\\d*)\\.(\\d*)\\.(\\d*)\\.jar") -class FirIdeKotlinModuleStateTrackerProvider(project: Project) : KotlinModuleStateTrackerProvider(project) { - override fun shouldInvalidateBuiltinSession(events: List): Boolean { +class FirIdeKotlinModuleStateModificationService(project: Project) : KotlinModuleStateModificationService(project) { + override fun mayBuiltinsHaveChanged(events: List): Boolean { return events.find { event -> event is VFileContentChangeEvent && STDLIB_PATTERN.matcher(event.file.name).matches() } != null } -} \ No newline at end of file +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeModificationTrackerService.kt b/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeModificationTrackerService.kt deleted file mode 100644 index d0c456ddea30..000000000000 --- a/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeModificationTrackerService.kt +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2000-2022 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.fir.analysisApiProviders - -import com.intellij.openapi.Disposable -import com.intellij.openapi.module.Module -import com.intellij.openapi.project.Project -import com.intellij.openapi.util.ModificationTracker -import com.intellij.openapi.util.SimpleModificationTracker -import org.jetbrains.kotlin.analysis.api.fir.utils.createCompositeModificationTracker -import java.util.concurrent.ConcurrentHashMap - -internal class FirIdeModificationTrackerService(val project : Project) : Disposable { - /** - * A project-wide out-of-block modification tracker for Kotlin sources. The modification count of this tracker will be incremented on - * global PSI tree changes or for test purposes. - */ - val projectOutOfBlockModificationTracker: SimpleModificationTracker = SimpleModificationTracker() - - /** - * A module modification tracker is used by dependents which want to depend on *specific* module changes. This modification tracker for - * *all* modules gives us the option to force such an update for all source modules. - * - * That functionality is distinct from [projectOutOfBlockModificationTracker], because a dependent will explicitly use a project OOB - * tracker if it wants to depend on *any* OOB modification in the project. - */ - private val allModulesOutOfBlockModificationTracker: SimpleModificationTracker = SimpleModificationTracker() - - private val moduleOutOfBlockModificationTrackerWrappers = ConcurrentHashMap() - - fun getModuleOutOfBlockModificationTracker(module: Module): ModificationTracker = - getModuleOutOfBlockModificationTrackerWrapper(module).compositeModificationTracker - - private fun getModuleOutOfBlockModificationTrackerWrapper(module: Module): ModuleOutOfBlockModificationTrackerWrapper = - moduleOutOfBlockModificationTrackerWrappers.computeIfAbsent(module) { - ModuleOutOfBlockModificationTrackerWrapper( - allModulesOutOfBlockModificationTracker, - SimpleModificationTracker(), - ) - } - - override fun dispose() {} - - fun increaseModificationCountForAllModules() { - projectOutOfBlockModificationTracker.incModificationCount() - allModulesOutOfBlockModificationTracker.incModificationCount() - } - - fun increaseModificationCountForModule(module: Module) { - getModuleOutOfBlockModificationTrackerWrapper(module).moduleModificationTracker.incModificationCount() - } - - fun increaseModificationCountForModuleAndProject(module: Module?) { - if (module != null) { - increaseModificationCountForModule(module) - } - projectOutOfBlockModificationTracker.incModificationCount() - } -} - -/** - * The module's out-of-block modification tracker is a _composite_ modification tracker because it is made up of both the specific module's - * tracker and the tracker for _all_ modules. Should these trackers be flattened into another composite modification tracker, the - * "all modules" modification tracker will only be contained once in the resulting modification tracker, because modification trackers are - * flattened uniquely by identity and there must only be a single instance of the "all modules" modification tracker per project. - */ -internal class ModuleOutOfBlockModificationTrackerWrapper( - allModulesModificationTracker: ModificationTracker, - val moduleModificationTracker: SimpleModificationTracker, -) { - val compositeModificationTracker = listOf(allModulesModificationTracker, moduleModificationTracker).createCompositeModificationTracker() -} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeOutOfBlockModificationService.kt b/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeOutOfBlockModificationService.kt new file mode 100644 index 000000000000..83a19a7eb9d7 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeOutOfBlockModificationService.kt @@ -0,0 +1,74 @@ +// Copyright 2000-2022 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.fir.analysisApiProviders + +import com.intellij.openapi.Disposable +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.components.Service +import com.intellij.openapi.module.Module +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.SimpleModificationTracker +import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.analysis.providers.analysisMessageBus +import org.jetbrains.kotlin.analysis.providers.topics.KotlinTopics +import org.jetbrains.kotlin.idea.util.toKtModulesForModificationEvents + +/** + * [FirIdeOutOfBlockModificationService] increments modification trackers and publishes subscription events on out-of-block modification + * after PSI tree changes and for tests. + */ +@Service(Service.Level.PROJECT) +internal class FirIdeOutOfBlockModificationService(val project: Project) : Disposable { + /** + * A project-wide out-of-block modification tracker for Kotlin sources which will be incremented on global PSI tree changes, on any + * module out-of-block modification, and by tests. + */ + val projectOutOfBlockModificationTracker: SimpleModificationTracker = SimpleModificationTracker() + + override fun dispose() {} + + /** + * Publishes out-of-block modification for [module]. Must be called in a write action. + */ + fun publishModuleOutOfBlockModification(module: KtModule) { + ApplicationManager.getApplication().assertWriteAccessAllowed() + + project.analysisMessageBus.syncPublisher(KotlinTopics.MODULE_OUT_OF_BLOCK_MODIFICATION).onModification(module) + } + + /** + * Publishes out-of-block modification for [module]'s production and test source [KtModule]s. Must be called in a write action. + */ + fun publishModuleOutOfBlockModification(module: Module) { + module.toKtModulesForModificationEvents().forEach { publishModuleOutOfBlockModification(it) } + } + + /** + * Publishes out-of-block modification for [module] and the project itself. Must be called in a write action. + */ + fun publishModuleAndProjectOutOfBlockModification(module: KtModule) { + publishModuleOutOfBlockModification(module) + projectOutOfBlockModificationTracker.incModificationCount() + } + + /** + * Publishes out-of-block modification for [module]'s production and test source [KtModule]s and the project itself. Must be called in a + * write action. + */ + fun publishModuleAndProjectOutOfBlockModification(module: Module) { + publishModuleOutOfBlockModification(module) + projectOutOfBlockModificationTracker.incModificationCount() + } + + fun publishGlobalSourceOutOfBlockModification() { + projectOutOfBlockModificationTracker.incModificationCount() + + // We should not invalidate binary module content here, because global PSI tree changes have no effect on binary modules. + project.analysisMessageBus.syncPublisher(KotlinTopics.GLOBAL_SOURCE_OUT_OF_BLOCK_MODIFICATION).onModification() + } + + companion object { + fun getInstance(project: Project): FirIdeOutOfBlockModificationService = + project.getService(FirIdeOutOfBlockModificationService::class.java) + } +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeOutOfBlockPsiTreeChangePreprocessor.kt b/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeOutOfBlockPsiTreeChangePreprocessor.kt index 9e3b52adc5cb..c2c34bcd1d7d 100644 --- a/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeOutOfBlockPsiTreeChangePreprocessor.kt +++ b/plugins/kotlin/base/fir/analysis-api-providers/src/org/jetbrains/kotlin/idea/base/fir/analysisApiProviders/FirIdeOutOfBlockPsiTreeChangePreprocessor.kt @@ -12,9 +12,12 @@ import com.intellij.psi.impl.PsiTreeChangePreprocessor import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirInternals import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.getNonLocalReanalyzableContainingDeclaration import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.invalidateAfterInBlockModification +import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.base.util.module -import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtAnnotated +import org.jetbrains.kotlin.psi.KtCodeFragment @OptIn(LLFirInternals::class) internal class FirIdeOutOfBlockPsiTreeChangePreprocessor(private val project: Project) : PsiTreeChangePreprocessor { @@ -27,7 +30,7 @@ internal class FirIdeOutOfBlockPsiTreeChangePreprocessor(private val project: Pr } if (event.isGlobalChange()) { - project.getService(FirIdeModificationTrackerService::class.java).increaseModificationCountForAllModules() + FirIdeOutOfBlockModificationService.getInstance(project).publishGlobalSourceOutOfBlockModification() return } @@ -63,7 +66,17 @@ internal class FirIdeOutOfBlockPsiTreeChangePreprocessor(private val project: Pr } private fun outOfBlockInvalidation(element: PsiElement) { - project.getService(FirIdeModificationTrackerService::class.java).increaseModificationCountForModuleAndProject(element.module) + if (element.containingFile == null) { + // PSI elements without a containing file, such as `PsiJavaDirectory`, are not supported by `ProjectStructureProvider` + // and have no corresponding meaningful `KtModule`. + element.module?.let { module -> + FirIdeOutOfBlockModificationService.getInstance(project).publishModuleAndProjectOutOfBlockModification(module) + } + return + } + + val module = ProjectStructureProvider.getModule(project, element, contextualModule = null) + FirIdeOutOfBlockModificationService.getInstance(project).publishModuleAndProjectOutOfBlockModification(module) } private fun calculateChangeType( @@ -86,6 +99,8 @@ internal class FirIdeOutOfBlockPsiTreeChangePreprocessor(private val project: Pr psi is PsiWhiteSpace || psi is PsiComment -> ChangeType.Invisible else -> { val inBlockModificationOwner = psi.getNonLocalReanalyzableContainingDeclaration() + ?: psi.containingFile as? KtCodeFragment + if (inBlockModificationOwner != null && (psi.parent != inBlockModificationOwner || code != PsiEventType.CHILD_ADDED)) { ChangeType.InBlock(inBlockModificationOwner) } else { @@ -94,11 +109,18 @@ internal class FirIdeOutOfBlockPsiTreeChangePreprocessor(private val project: Pr } } - // Copy logic from PsiModificationTrackerImpl.treeChanged(). Some out-of-code-block events are written to language modification - // tracker in PsiModificationTrackerImpl but don't have correspondent PomModelEvent. Increase kotlinOutOfCodeBlockTracker - // manually if needed. + /** + * The logic for detecting global changes is taken from [PsiModificationTrackerImpl], with the following difference. + * + * We don't want to publish any global out-of-block modification on roots changes, because relevant roots changes already cause module + * state modification events. Such a module state modification event includes the exact module that was affected by the roots change, + * instead of a less specific global out-of-block modification event. This allows a consumer such as session invalidation to invalidate + * sessions more granularly. Additionally, many roots changes don't require any event to be published because a corresponding [KtModule] + * does not exist for the changed module (e.g. when no content roots have been added yet), so roots changes [PsiTreeChangeEvent]s are + * overzealous, while the module state modification service can handle such cases gracefully. + */ private fun PsiTreeChangeEventImpl.isGlobalChange() = when (code) { - PsiEventType.PROPERTY_CHANGED -> propertyName === PsiTreeChangeEvent.PROP_UNLOADED_PSI || propertyName === PsiTreeChangeEvent.PROP_ROOTS + PsiEventType.PROPERTY_CHANGED -> propertyName === PsiTreeChangeEvent.PROP_UNLOADED_PSI PsiEventType.CHILD_MOVED -> oldParent is PsiDirectory || newParent is PsiDirectory else -> parent is PsiDirectory } @@ -107,5 +129,5 @@ internal class FirIdeOutOfBlockPsiTreeChangePreprocessor(private val project: Pr private sealed class ChangeType { object OutOfBlock : ChangeType() object Invisible : ChangeType() - class InBlock(val blockOwner: KtDeclaration) : ChangeType() + class InBlock(val blockOwner: KtAnnotated) : ChangeType() } diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/AbstractProjectStructureTest.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/AbstractProjectStructureTest.kt new file mode 100644 index 000000000000..23ecc5907345 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/AbstractProjectStructureTest.kt @@ -0,0 +1,76 @@ +// Copyright 2000-2023 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.analysis.providers + +import com.intellij.openapi.command.WriteCommandAction +import com.intellij.openapi.module.Module +import com.intellij.openapi.roots.OrderRootType +import com.intellij.openapi.roots.libraries.Library +import com.intellij.openapi.vfs.LocalFileSystem +import com.intellij.testFramework.PsiTestUtil +import com.intellij.util.io.jarFile +import org.jetbrains.kotlin.idea.fir.analysis.providers.testProjectStructure.TestProjectStructureReader +import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest +import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil +import org.jetbrains.kotlin.idea.test.addRoot +import org.jetbrains.kotlin.test.util.addDependency +import java.nio.file.Paths + +typealias ProjectLibrariesByName = Map +typealias ModulesByName = Map + +abstract class AbstractProjectStructureTest : AbstractMultiModuleTest() { + protected fun initializeProjectStructure( + path: String, + parser: TestProjectStructureParser, + ): Triple { + val testStructure = TestProjectStructureReader.readToTestStructure( + Paths.get(path), + testProjectStructureParser = parser, + ) + + val jarFilesByRootLabel = testStructure.libraries + .flatMapTo(mutableSetOf()) { it.roots } + .associate { it to jarFile { }.generateInTempDir().toFile() } + + val projectLibrariesByName = testStructure.libraries.associate { libraryData -> + libraryData.name to ConfigLibraryUtil.addProjectLibrary(project, libraryData.name) { + libraryData.roots.forEach { rootLabel -> + addRoot(jarFilesByRootLabel.getValue(rootLabel), OrderRootType.CLASSES) + } + commit() + } + } + + val modulesByName = testStructure.modules.associate { moduleData -> + moduleData.name to createEmptyModule(moduleData.name) + } + + val duplicateNames = projectLibrariesByName.keys.intersect(modulesByName.keys) + if (duplicateNames.isNotEmpty()) { + error("Test project libraries and modules may not share names. Duplicate names: ${duplicateNames.joinToString()}.") + } + + testStructure.modules.forEach { moduleData -> + val module = modulesByName.getValue(moduleData.name) + moduleData.dependsOnModules.forEach { dependencyName -> + projectLibrariesByName[dependencyName] + ?.let { library -> module.addDependency(library) } + ?: module.addDependency(modulesByName.getValue(dependencyName)) + } + } + + return Triple(testStructure, projectLibrariesByName, modulesByName) + } + + private fun createEmptyModule(name: String): Module { + val tmpDir = createTempDirectory().toPath() + val module: Module = createModule("$tmpDir/$name", moduleType) + val root = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tmpDir.toFile())!! + WriteCommandAction.writeCommandAction(module.project).run { + root.refresh(false, true) + } + + PsiTestUtil.addSourceContentToRoots(module, root) + return module + } +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/TestProjectStructure.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/TestProjectStructure.kt deleted file mode 100644 index 9b73d569c74f..000000000000 --- a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/TestProjectStructure.kt +++ /dev/null @@ -1,60 +0,0 @@ -// 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. - -package org.jetbrains.kotlin.idea.fir.analysis.providers - -import com.google.gson.JsonElement -import com.google.gson.JsonObject -import com.google.gson.JsonParser -import com.google.gson.JsonPrimitive -import com.intellij.openapi.util.io.FileUtil -import org.jetbrains.kotlin.idea.jsonUtils.getString -import java.nio.file.Path - -internal data class TestProjectStructure( - val modules: List, - val json: JsonObject, -) { - companion object { - fun parse(json: JsonElement): TestProjectStructure { - require(json is JsonObject) - - return TestProjectStructure( - json.getAsJsonArray("modules").map(TestProjectModule.Companion::parse), - json, - ) - } - } -} - - -data class TestProjectModule(val name: String, val dependsOnModules: List) { - companion object { - fun parse(json: JsonElement): TestProjectModule { - require(json is JsonObject) - val dependencies = if (json.has(DEPENDS_ON_FIELD)) { - json.getAsJsonArray(DEPENDS_ON_FIELD).map { (it as JsonPrimitive).asString } - } else emptyList() - return TestProjectModule( - json.getString("name"), - dependencies - ) - } - - private const val DEPENDS_ON_FIELD = "dependsOn" - } -} - -internal object TestProjectStructureReader { - fun read(testDirectory: Path, jsonFileName: String = "structure.json"): TestProjectStructure { - val jsonFile = testDirectory.resolve(jsonFileName) - - val json = JsonParser.parseString(FileUtil.loadFile(jsonFile.toFile(), /*convertLineSeparators=*/true)) - return TestProjectStructure.parse(json) - } - - fun readToTestStructure( - testDirectory: Path, - jsonFileName: String = "structure.json", - toTestStructure: (TestProjectStructure) -> T, - ): T = read(testDirectory, jsonFileName).let(toTestStructure) -} \ No newline at end of file diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/dependents/AbstractModuleDependentsTest.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/dependents/AbstractModuleDependentsTest.kt new file mode 100644 index 000000000000..062325b743bd --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/dependents/AbstractModuleDependentsTest.kt @@ -0,0 +1,118 @@ +// Copyright 2000-2023 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.analysis.providers.dependents + +import com.google.gson.JsonObject +import java.io.File +import org.jetbrains.kotlin.analysis.project.structure.KotlinModuleDependentsProvider +import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule +import org.jetbrains.kotlin.idea.base.projectStructure.LibraryInfoCache +import org.jetbrains.kotlin.idea.base.projectStructure.getMainKtSourceModule +import org.jetbrains.kotlin.idea.base.projectStructure.toKtModule +import org.jetbrains.kotlin.idea.base.test.KotlinRoot +import org.jetbrains.kotlin.idea.fir.analysis.providers.AbstractProjectStructureTest +import org.jetbrains.kotlin.idea.fir.analysis.providers.TestProjectLibrary +import org.jetbrains.kotlin.idea.fir.analysis.providers.TestProjectModule +import org.jetbrains.kotlin.idea.fir.analysis.providers.TestProjectStructure +import org.jetbrains.kotlin.idea.fir.analysis.providers.TestProjectStructureParser +import org.jetbrains.kotlin.idea.fir.analysis.providers.testProjectStructure.TestProjectEntityReference +import org.jetbrains.kotlin.idea.fir.analysis.providers.testProjectStructure.TestProjectEntityReferenceParser +import org.jetbrains.kotlin.idea.fir.analysis.providers.testProjectStructure.TestProjectLibraryReference +import org.jetbrains.kotlin.idea.fir.analysis.providers.testProjectStructure.TestProjectModuleReference +import org.jetbrains.kotlin.idea.fir.analysis.providers.testProjectStructure.getAsJsonObjectList +import org.jetbrains.kotlin.idea.fir.analysis.providers.testProjectStructure.getAsStringList +import org.jetbrains.kotlin.idea.fir.analysis.providers.ProjectLibrariesByName +import org.jetbrains.kotlin.idea.fir.analysis.providers.ModulesByName + +abstract class AbstractModuleDependentsTest : AbstractProjectStructureTest() { + override fun isFirPlugin(): Boolean = true + + override fun getTestDataDirectory(): File = + KotlinRoot.DIR.resolve("base").resolve("fir").resolve("analysis-api-providers").resolve("testData").resolve("moduleDependents") + + private val moduleDependentsProvider get() = KotlinModuleDependentsProvider.getInstance(project) + + protected fun doTest(path: String) { + val (testStructure, projectLibrariesByName, modulesByName) = + initializeProjectStructure(path, ModuleDependentsTestProjectStructureParser) + + assertNotEmpty(testStructure.targets) + + testStructure.targets.forEach { checkTarget(it, projectLibrariesByName, modulesByName) } + } + + private fun checkTarget( + target: ModuleDependentsTestTarget, + projectLibrariesByName: ProjectLibrariesByName, + modulesByName: ModulesByName, + ) { + val entityReference = target.entityReference + + val targetModule = when (entityReference) { + is TestProjectLibraryReference -> + LibraryInfoCache.getInstance(project)[projectLibrariesByName.getValue(entityReference.name)].first().toKtModule() + + is TestProjectModuleReference -> + modulesByName.getValue(entityReference.name).getMainKtSourceModule()!! + } + + val directDependents = moduleDependentsProvider.getDirectDependents(targetModule) + assertEquals( + "Direct dependents of ${entityReference.name}:", + target.directDependents, + directDependents.map { (it as KtSourceModule).moduleName }.toSet(), + ) + + val transitiveDependents = moduleDependentsProvider.getTransitiveDependents(targetModule) + assertEquals( + "Transitive dependents of ${entityReference.name}:", + target.transitiveDependents, + transitiveDependents.map { (it as KtSourceModule).moduleName }.toSet(), + ) + } +} + +/** + * The module dependents test supports multiple module/library targets, which allows checking module dependents of all `KtModule`s defined + * in the project structure, without duplicating the same project structure in multiple tests. + */ +data class ModuleDependentsTestProjectStructure( + override val libraries: List, + override val modules: List, + val targets: List, +) : TestProjectStructure + +private object ModuleDependentsTestProjectStructureParser : TestProjectStructureParser { + private const val TARGETS_FIELD = "targets" + + override fun parse( + libraries: List, + modules: List, + json: JsonObject, + ): ModuleDependentsTestProjectStructure = ModuleDependentsTestProjectStructure( + libraries, + modules, + json.getAsJsonObjectList(TARGETS_FIELD)!!.map(ModuleDependentsTestTargetParser::parse), + ) +} + +data class ModuleDependentsTestTarget( + val entityReference: TestProjectEntityReference, + val directDependents: Set, + val transitiveDependents: Set, +) + +private object ModuleDependentsTestTargetParser { + private const val DIRECT_DEPENDENTS_FIELD = "directDependents" + private const val TRANSITIVE_DEPENDENTS_FIELD = "transitiveDependents" + + fun parse(json: JsonObject): ModuleDependentsTestTarget { + // We can parse `json` as the entity reference itself to avoid boilerplate around the entity reference. + val entityReference = TestProjectEntityReferenceParser.parse(json) + + return ModuleDependentsTestTarget( + entityReference, + json.getAsStringList(DIRECT_DEPENDENTS_FIELD)!!.toSet(), + json.getAsStringList(TRANSITIVE_DEPENDENTS_FIELD)!!.toSet(), + ) + } +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/dependents/ModuleDependentsTestGenerated.java b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/dependents/ModuleDependentsTestGenerated.java new file mode 100644 index 000000000000..21f740a5e630 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/dependents/ModuleDependentsTestGenerated.java @@ -0,0 +1,65 @@ +// Copyright 2000-2023 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.analysis.providers.dependents; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.idea.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.idea.test.KotlinTestUtils; +import org.jetbrains.kotlin.test.TestMetadata; +import org.jetbrains.kotlin.idea.base.test.TestRoot; +import org.junit.runner.RunWith; + +/** + * This class is generated by {@link org.jetbrains.kotlin.testGenerator.generator.TestGenerator}. + * DO NOT MODIFY MANUALLY. + */ +@SuppressWarnings("all") +@TestRoot("base/fir/analysis-api-providers") +@TestDataPath("$CONTENT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +@TestMetadata("testData/moduleDependents") +public class ModuleDependentsTestGenerated extends AbstractModuleDependentsTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("binaryTree") + public void testBinaryTree() throws Exception { + runTest("testData/moduleDependents/binaryTree/"); + } + + @TestMetadata("cyclical") + public void testCyclical() throws Exception { + runTest("testData/moduleDependents/cyclical/"); + } + + @TestMetadata("cyclicalSelf") + public void testCyclicalSelf() throws Exception { + runTest("testData/moduleDependents/cyclicalSelf/"); + } + + @TestMetadata("cyclicalWithOutsideDependency") + public void testCyclicalWithOutsideDependency() throws Exception { + runTest("testData/moduleDependents/cyclicalWithOutsideDependency/"); + } + + @TestMetadata("deduplicatedLibraries") + public void testDeduplicatedLibraries() throws Exception { + runTest("testData/moduleDependents/deduplicatedLibraries/"); + } + + @TestMetadata("linear") + public void testLinear() throws Exception { + runTest("testData/moduleDependents/linear/"); + } + + @TestMetadata("rhombus") + public void testRhombus() throws Exception { + runTest("testData/moduleDependents/rhombus/"); + } + + @TestMetadata("singleRoot") + public void testSingleRoot() throws Exception { + runTest("testData/moduleDependents/singleRoot/"); + } +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/dependents/TransitiveModuleDependentsCacheInvalidationTest.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/dependents/TransitiveModuleDependentsCacheInvalidationTest.kt new file mode 100644 index 000000000000..a81ba3060b48 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/dependents/TransitiveModuleDependentsCacheInvalidationTest.kt @@ -0,0 +1,76 @@ +// Copyright 2000-2023 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.analysis.providers.dependents + +import org.jetbrains.kotlin.analysis.project.structure.KotlinModuleDependentsProvider +import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule +import org.jetbrains.kotlin.idea.base.projectStructure.LibraryInfoCache +import org.jetbrains.kotlin.idea.base.projectStructure.getMainKtSourceModule +import org.jetbrains.kotlin.idea.base.projectStructure.toKtModule +import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest +import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil +import org.jetbrains.kotlin.test.util.addDependency +import org.junit.Assert +import java.io.File + +/** + * This test ensures that cached transitive dependents of the IDE's [KotlinModuleDependentsProvider] are properly invalidated. + */ +class TransitiveModuleDependentsCacheInvalidationTest : AbstractMultiModuleTest() { + override fun getTestDataDirectory(): File = error("Should not be called") + + override fun isFirPlugin(): Boolean = true + + private val moduleDependentsProvider get() = KotlinModuleDependentsProvider.getInstance(project) + + fun `test that cached transitive dependents of a module are invalidated after adding a new dependent`() { + val moduleA = createModuleInTmpDir("a") + val moduleB = createModuleInTmpDir("b") + val moduleC = createModuleInTmpDir("c") + val moduleD = createModuleInTmpDir("d") + + moduleB.addDependency(moduleA) + moduleC.addDependency(moduleB) + + val ktModuleA = moduleA.getMainKtSourceModule()!! + + Assert.assertEquals( + setOf("b", "c"), + ktModuleA.getTransitiveDependentNames(), + ) + + moduleD.addDependency(moduleA) + + Assert.assertEquals( + setOf("b", "c", "d"), + ktModuleA.getTransitiveDependentNames(), + ) + } + + fun `test that cached transitive dependents of a library are invalidated after adding a new dependent`() { + val libraryA = ConfigLibraryUtil.addProjectLibraryWithClassesRoot(project, "a") + val moduleB = createModuleInTmpDir("b") + val moduleC = createModuleInTmpDir("c") + val moduleD = createModuleInTmpDir("d") + + moduleB.addDependency(libraryA) + moduleC.addDependency(moduleB) + + val ktModuleA = LibraryInfoCache.getInstance(project)[libraryA].first().toKtModule() + + Assert.assertEquals( + setOf("b", "c"), + ktModuleA.getTransitiveDependentNames(), + ) + + moduleD.addDependency(libraryA) + + Assert.assertEquals( + setOf("b", "c", "d"), + ktModuleA.getTransitiveDependentNames(), + ) + } + + private fun KtModule.getTransitiveDependentNames(): Set = + moduleDependentsProvider.getTransitiveDependents(this).mapTo(mutableSetOf()) { (it as KtSourceModule).moduleName } +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/modificationEvents/AbstractKotlinGlobalModificationEventTest.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/modificationEvents/AbstractKotlinGlobalModificationEventTest.kt new file mode 100644 index 000000000000..364775fe97c3 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/modificationEvents/AbstractKotlinGlobalModificationEventTest.kt @@ -0,0 +1,12 @@ +// Copyright 2000-2023 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.analysis.providers.modificationEvents + +import com.intellij.openapi.project.Project + +abstract class AbstractKotlinGlobalModificationEventTest : AbstractKotlinModificationEventTest() { + abstract fun constructTracker(): TRACKER + + fun createTracker(): TRACKER = constructTracker().apply { initialize() } +} + +abstract class GlobalModificationEventTracker(project: Project, eventKind: String) : ModificationEventTracker(project, eventKind) diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/modificationEvents/AbstractKotlinModificationEventTest.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/modificationEvents/AbstractKotlinModificationEventTest.kt new file mode 100644 index 000000000000..7bca9cce17f1 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/modificationEvents/AbstractKotlinModificationEventTest.kt @@ -0,0 +1,81 @@ +// Copyright 2000-2023 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.analysis.providers.modificationEvents + +import com.intellij.openapi.Disposable +import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.libraries.Library +import com.intellij.openapi.util.Disposer +import com.intellij.util.messages.MessageBusConnection +import org.jetbrains.kotlin.analysis.providers.analysisMessageBus +import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest +import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil +import org.jetbrains.kotlin.psi.KtFile +import org.junit.Assert +import java.io.File + +abstract class AbstractKotlinModificationEventTest : AbstractMultiModuleTest() { + override fun getTestDataDirectory(): File = error("Should not be called") + + override fun isFirPlugin(): Boolean = true + + protected fun createProjectLibrary(name: String): Library = ConfigLibraryUtil.addProjectLibraryWithClassesRoot(myProject, name) + + protected fun createScript(name: String, text: String = ""): KtFile = + createKtFileUnderNewContentRoot(FileWithText("$name.kts", text)) + + protected fun createNotUnderContentRootFile(name: String, text: String = ""): KtFile = + // While the not-under-content-root module is named as it is, it is still decidedly under the project's content root, just not a + // part of any other kind of `KtModule`. + createKtFileUnderNewContentRoot(FileWithText("$name.kt", text)) + + protected fun disposeTrackers(vararg trackers: TRACKER) { + trackers.forEach { Disposer.dispose(it) } + } +} + +abstract class ModificationEventTracker( + private val project: Project, + private val eventKind: String, +) : Disposable { + protected class ReceivedEvent(val isRemoval: Boolean) + + protected val receivedEvents: MutableList = mutableListOf() + + fun initialize() { + val busConnection = project.analysisMessageBus.connect(this) + configureSubscriptions(busConnection) + } + + protected abstract fun configureSubscriptions(busConnection: MessageBusConnection) + + override fun dispose() { } + + fun assertNotModified(label: String) { + Assert.assertTrue( + "${eventKind.replaceFirstChar { it.uppercaseChar() }} events for '$label' should not have been published, but ${receivedEvents.size} events were received.", + receivedEvents.isEmpty(), + ) + } + + fun assertModifiedOnce(label: String, shouldBeRemoval: Boolean = false) { + assertModified(label, expectedEventCount = 1, shouldBeRemoval) + } + + fun assertModified(label: String, expectedEventCount: Int, shouldBeRemoval: Boolean = false) { + val eventCountString = if (expectedEventCount == 1) "A single" else expectedEventCount.toString() + val eventOrEvents = if (expectedEventCount == 1) "event" else "events" + Assert.assertTrue( + "$eventCountString $eventKind $eventOrEvents for '$label' should have been published, but ${receivedEvents.size} events were received.", + receivedEvents.size == expectedEventCount, + ) + + val shouldOrShouldNotBeRemoval = if (shouldBeRemoval) "should" else "should not" + receivedEvents.forEachIndexed { index, receivedEvent -> + val indexInfo = if (expectedEventCount > 0) " (event index: $index)" else "" + Assert.assertTrue( + "The $eventKind event for '$label' $shouldOrShouldNotBeRemoval be a removal event$indexInfo.", + receivedEvent.isRemoval == shouldBeRemoval, + ) + } + } +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/modificationEvents/AbstractKotlinModuleModificationEventTest.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/modificationEvents/AbstractKotlinModuleModificationEventTest.kt new file mode 100644 index 000000000000..13cb02c3b6cb --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/modificationEvents/AbstractKotlinModuleModificationEventTest.kt @@ -0,0 +1,41 @@ +// Copyright 2000-2023 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.analysis.providers.modificationEvents + +import com.intellij.openapi.module.Module +import com.intellij.openapi.roots.libraries.Library +import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider +import org.jetbrains.kotlin.analysis.providers.topics.KotlinModuleStateModificationKind +import org.jetbrains.kotlin.idea.base.projectStructure.LibraryInfoCache +import org.jetbrains.kotlin.idea.base.projectStructure.productionSourceInfo +import org.jetbrains.kotlin.idea.base.projectStructure.toKtModule +import org.jetbrains.kotlin.psi.KtFile + +abstract class AbstractKotlinModuleModificationEventTest : AbstractKotlinModificationEventTest() { + protected abstract fun constructTracker(module: KtModule): TRACKER + + protected fun createTracker(module: KtModule): TRACKER = constructTracker(module).apply { initialize() } + + protected fun createTracker(module: Module): TRACKER = createTracker(module.productionSourceInfo!!.toKtModule()) + + protected fun createTracker(library: Library): TRACKER = + createTracker(LibraryInfoCache.getInstance(myProject)[library].single().toKtModule()) + + protected fun createTracker(file: KtFile): TRACKER = + createTracker(ProjectStructureProvider.getModule(myProject, file, contextualModule = null)) +} + +abstract class ModuleModificationEventTracker( + private val module: KtModule, + eventKind: String, +) : ModificationEventTracker(module.project, eventKind) { + fun handleEvent(eventModule: KtModule, modificationKind: KotlinModuleStateModificationKind) { + if (eventModule == module) { + receivedEvents.add(ReceivedEvent(modificationKind == KotlinModuleStateModificationKind.REMOVAL)) + } + } + + fun handleEvent(eventModule: KtModule) { + handleEvent(eventModule, KotlinModuleStateModificationKind.UPDATE) + } +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/modificationEvents/KotlinGlobalSourceOutOfBlockModificationTest.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/modificationEvents/KotlinGlobalSourceOutOfBlockModificationTest.kt new file mode 100644 index 000000000000..78c5ff1c1fc9 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/modificationEvents/KotlinGlobalSourceOutOfBlockModificationTest.kt @@ -0,0 +1,149 @@ +// Copyright 2000-2023 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.analysis.providers.modificationEvents + +import com.intellij.openapi.application.runWriteAction +import com.intellij.openapi.project.Project +import com.intellij.testFramework.PsiTestUtil +import com.intellij.util.messages.MessageBusConnection +import org.jetbrains.kotlin.analysis.providers.topics.KotlinGlobalSourceOutOfBlockModificationListener +import org.jetbrains.kotlin.analysis.providers.topics.KotlinTopics +import org.jetbrains.kotlin.idea.util.sourceRoots + +class KotlinGlobalSourceOutOfBlockModificationTest : AbstractKotlinGlobalModificationEventTest() { + override fun constructTracker() = GlobalSourceOutOfBlockModificationEventTracker(myProject) + + fun `test that global source out-of-block modification occurs after a file is added to a module content root`() { + val moduleA = createModuleInTmpDir("a") + createModuleInTmpDir("b") + createModuleInTmpDir("c") + + val tracker = createTracker() + + runWriteAction { + moduleA.sourceRoots.first().createChildData(/* requestor = */ null, "file.kt") + } + + tracker.assertModifiedOnce("the project after a file is added to the content root of module A") + + disposeTrackers(tracker) + } + + fun `test that global source out-of-block modification occurs after a file is moved to another module content root`() { + val moduleA = createModuleInTmpDir("a") { + listOf( + FileWithText("main.kt", "fun main() {}") + ) + } + val moduleB = createModuleInTmpDir("b") + createModuleInTmpDir("c") + + val tracker = createTracker() + + val file = moduleA.sourceRoots.first().findChild("main.kt")!! + val destination = moduleB.sourceRoots.first() + move(file, destination) + + tracker.assertModifiedOnce("the project after a file from module A is moved to the content root of module B") + + disposeTrackers(tracker) + } + + fun `test that global source out-of-block modification occurs after moving a script file to a non-source module content root`() { + val scriptA = createScript("a") + val moduleB = createModuleInTmpDir("b") + + val destination = getVirtualFile(createTempDirectory()) + PsiTestUtil.addContentRoot(moduleB, destination) + + val tracker = createTracker() + + move(scriptA.virtualFile, destination) + + tracker.assertModifiedOnce("the project after a script file is moved to a non-source content root of module B") + + disposeTrackers(tracker) + } + + fun `test that global source out-of-block modification occurs after moving a script file outside the project content root`() { + val scriptA = createScript("a") + val destination = getVirtualFile(createTempDirectory()) + + val tracker = createTracker() + + move(scriptA.virtualFile, destination) + + tracker.assertModifiedOnce("the project after a script file is moved outside the project content root") + + disposeTrackers(tracker) + } + + // TODO (marco): This test can be enabled once IDEA-324516 is fixed. + //fun `test that global source out-of-block modification occurs after deleting a script file`() { + // val scriptA = createScript("a") + // + // val tracker = createTracker() + // + // delete(scriptA.virtualFile) + // + // tracker.assertModified("the project after a script file is deleted", expectedEventCount = 2) + // + // disposeTrackers(tracker) + //} + + fun `test that global source out-of-block modification occurs after moving a not-under-content-root file to a non-source module content root`() { + val fileA = createNotUnderContentRootFile("a") + val moduleB = createModuleInTmpDir("b") + + val destination = getVirtualFile(createTempDirectory()) + PsiTestUtil.addContentRoot(moduleB, destination) + + val tracker = createTracker() + + move(fileA.virtualFile, destination) + + tracker.assertModifiedOnce("the project after a not-under-content-root file is moved to a non-source content root of module B") + + disposeTrackers(tracker) + } + + fun `test that global source out-of-block modification occurs after moving a not-under-content-root file outside the project content root`() { + val fileA = createNotUnderContentRootFile("a") + val destination = getVirtualFile(createTempDirectory()) + + val tracker = createTracker() + + // Note that the "not-under-content-root" file is under the content root of the project, and so moving it outside the content root + // of the project does have an effect. + move(fileA.virtualFile, destination) + + tracker.assertModifiedOnce("the project after a not-under-content-root file is moved outside the project content root") + + disposeTrackers(tracker) + } + + fun `test that global source out-of-block modification occurs after deleting a not-under-content-root file`() { + val fileA = createNotUnderContentRootFile("a") + + val tracker = createTracker() + + delete(fileA.virtualFile) + + tracker.assertModified("the project after a not-under-content-root file is deleted", expectedEventCount = 2) + + disposeTrackers(tracker) + } +} + +class GlobalSourceOutOfBlockModificationEventTracker(project: Project) : GlobalModificationEventTracker( + project, + eventKind = "global source out-of-block modification", +) { + override fun configureSubscriptions(busConnection: MessageBusConnection) { + busConnection.subscribe( + KotlinTopics.GLOBAL_SOURCE_OUT_OF_BLOCK_MODIFICATION, + KotlinGlobalSourceOutOfBlockModificationListener { + receivedEvents.add(ReceivedEvent(isRemoval = false)) + }, + ) + } +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/modificationEvents/KotlinModuleOutOfBlockModificationTest.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/modificationEvents/KotlinModuleOutOfBlockModificationTest.kt new file mode 100644 index 000000000000..9d9af7e4feea --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/modificationEvents/KotlinModuleOutOfBlockModificationTest.kt @@ -0,0 +1,364 @@ +// Copyright 2000-2023 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.analysis.providers.modificationEvents + +import com.intellij.openapi.application.runWriteAction +import com.intellij.openapi.module.Module +import com.intellij.psi.PsiDocumentManager +import com.intellij.util.messages.MessageBusConnection +import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.analysis.providers.topics.KotlinModuleOutOfBlockModificationListener +import org.jetbrains.kotlin.analysis.providers.topics.KotlinTopics +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.startOffset +import org.junit.Assert + +class KotlinModuleOutOfBlockModificationTest : AbstractKotlinModuleModificationEventTest() { + override fun constructTracker(module: KtModule): ModuleOutOfBlockModificationEventTracker = ModuleOutOfBlockModificationEventTracker(module) + + fun `test that source module out-of-block modification affects a single module`() { + val moduleA = createModuleInTmpDir("a") { + listOf( + FileWithText("main.kt", "fun main() = 10") + ) + } + val moduleB = createModuleInTmpDir("b") + val moduleC = createModuleInTmpDir("c") + + val trackerA = createTracker(moduleA) + val trackerB = createTracker(moduleB) + val trackerC = createTracker(moduleC) + + moduleA.configureEditorForFile("main.kt").apply { + modify(textAfterModification = "fun main() = hello10", getSingleFunctionBodyOffset()) { + type("hello") + } + } + + // We expect two events: One published before and one after the PSI tree modification. + trackerA.assertModified("module A after out-of-block change", expectedEventCount = 2) + trackerB.assertNotModified("unmodified module B") + trackerC.assertNotModified("unmodified module C") + + disposeTrackers(trackerA, trackerB, trackerC) + } + + fun `test that source module out-of-block modification does not occur after deleting a symbol in a function body`() { + val moduleA = createModuleInTmpDir("a") { + listOf( + FileWithText( + "main.kt", + "fun main() {\n" + + "val v = \n" + + "}" + ) + ) + } + + val trackerA = createTracker(moduleA) + + moduleA.configureEditorForFile("main.kt").apply { + modify(textAfterModification = "fun main() {\n" + "val v =\n" + "}") { + backspace() + } + } + + trackerA.assertNotModified("module A with an in-block modification") + + disposeTrackers(trackerA) + } + + fun `test that source module out-of-block modification does not occur after deleting whitespace`() { + val moduleA = createModuleInTmpDir("a") { + listOf( + FileWithText( + "main.kt", + "class Main { fun main() {}\n}" + ) + ) + } + + val trackerA = createTracker(moduleA) + + moduleA.configureEditorForFile("main.kt").apply { + modify(textAfterModification = "class Main { fun main() {}\n}", getSingleMemberInClassOffset()) { + backspace() + } + } + + trackerA.assertNotModified("module A after deleting whitespace") + + disposeTrackers(trackerA) + } + + fun `test that source module out-of-block modification occurs after adding a space in an identifier`() { + val moduleA = createModuleInTmpDir("a") { + listOf( + FileWithText( + "main.kt", + "class Main { fun main() {}\n}" + ) + ) + } + + val trackerA = createTracker(moduleA) + + moduleA.configureEditorForFile("main.kt").apply { + modify( + textAfterModification = "class Main { fun m ain() {}\n}", + getSingleMemberInClassOffset() + "fun m".length, + ) { + type(" ") + } + } + + // In total, seven PSI tree changes are processed: Two `BEFORE_CHILD_REPLACEMENT`, one `CHILDREN_CHANGED`, and four `CHILD_ADDED`. + trackerA.assertModified("module A after adding a space in an identifier", expectedEventCount = 7) + + disposeTrackers(trackerA) + } + + fun `test that source module out-of-block modification occurs after commenting out a function`() { + val moduleA = createModuleInTmpDir("a") { + listOf( + FileWithText( + "main.kt", "class Main { fun main() {}\n}" + ) + ) + } + + val trackerA = createTracker(moduleA) + + moduleA.configureEditorForFile("main.kt").apply { + modify("class Main { //fun main() {}\n}", getSingleMemberInClassOffset()) { + type("//") + } + } + + trackerA.assertModifiedOnce("module A after commenting out a function") + + disposeTrackers(trackerA) + } + + fun `test that source module out-of-block modification does not occur after commenting out a type inside a function body`() { + val moduleA = createModuleInTmpDir("a") { + listOf( + FileWithText( + "main.kt", + "class Main {\n" + + " fun main() {\n" + + " class Local {}\n" + + " }\n" + + "}" + ) + ) + } + + val trackerA = createTracker(moduleA) + + moduleA.configureEditorForFile("main.kt").apply { + val textAfterModification = + "class Main {\n" + + " fun main() {\n" + + "// class Local {}\n" + + " }\n" + + "}" + + val singleFunction = (declarations[0] as KtClass).declarations.single() as KtFunction + val offset = singleFunction.bodyBlockExpression?.lBrace?.textOffset!! + 2 + + modify(textAfterModification, offset) { + type("//") + } + } + + trackerA.assertNotModified("module A after commenting out a type inside a function body") + + disposeTrackers(trackerA) + } + + fun `test that source module out-of-block modification occurs after commenting out a type`() { + val moduleA = createModuleInTmpDir("a") { + listOf( + FileWithText( + "main.kt", "class Main {}" + ) + ) + } + + val trackerA = createTracker(moduleA) + + moduleA.configureEditorForFile("main.kt").apply { + modify(textAfterModification = "//class Main {}", 0) { + type("//") + } + } + + trackerA.assertModifiedOnce("module A after commenting out a type") + + disposeTrackers(trackerA) + } + + fun `test that source module out-of-block modification occurs after adding a modifier to a function`() { + val moduleA = createModuleInTmpDir("a") { + listOf( + FileWithText( + "main.kt", "inline fun main() {}" + ) + ) + } + + val trackerA = createTracker(moduleA) + + moduleA.configureEditorForFile("main.kt").apply { + modify("private inline fun main() {}") { + type("private ") + } + } + + // In total, seven PSI tree changes are processed: Three `BEFORE_CHILD_REMOVAL`, three `CHILD_REMOVED`, and one `CHILD_ADDED`. + trackerA.assertModified("module A after adding a modifier to a function", expectedEventCount = 7) + + disposeTrackers(trackerA) + } + + fun `test that source module out-of-block modification occurs after adding a return type to a function`() { + val moduleA = createModuleInTmpDir("a") { + listOf( + FileWithText( + "main.kt", "fun foo() = 10" + ) + ) + } + + val trackerA = createTracker(moduleA) + + moduleA.configureEditorForFile("main.kt").apply { + modify("fun foo(): Byte = 10") { + type(": Byte") + } + } + + // In total, seventeen PSI tree changes are processed: Five `BEFORE_CHILD_REMOVAL`, two `CHILDREN_CHANGED`, seven `CHILD_REMOVED`, + // two `CHILD_ADDED`, and one `BEFORE_CHILD_REPLACEMENT`. + trackerA.assertModified("module A after adding a return type to a function", expectedEventCount = 17) + + disposeTrackers(trackerA) + } + + fun `test that source module out-of-block modification does not occur after changing a non-physical file`() { + val moduleA = createModuleInTmpDir("a") { + listOf( + FileWithText("main.kt", "fun main() {}") + ) + } + val moduleB = createModuleInTmpDir("b") + + val trackerA = createTracker(moduleA) + val trackerB = createTracker(moduleB) + + runWriteAction { + val nonPhysicalPsi = KtPsiFactory(moduleA.project).createFile("nonPhysical", "val a = c") + nonPhysicalPsi.add(KtPsiFactory(moduleA.project).createFunction("fun x(){}")) + } + + trackerA.assertNotModified("module A") + trackerB.assertNotModified("module B") + + disposeTrackers(trackerA, trackerB) + } + + fun `test that script module out-of-block modification affects a single script module`() { + val scriptA = createScript("a", "fun foo() = 10") + val scriptB = createScript("b", "fun bar() = 10") + val moduleC = createModuleInTmpDir("c") + val fileD = createNotUnderContentRootFile("d", "fun baz() = 10") + + val trackerA = createTracker(scriptA) + val trackerB = createTracker(scriptB) + val trackerC = createTracker(moduleC) + val trackerD = createTracker(fileD) + + scriptA.withConfiguredEditor { + val singleFunction = (declarations.single() as KtScript).declarations.single() as KtNamedFunction + val offset = singleFunction.bodyExpression!!.startOffset + modify(textAfterModification = "fun foo() = hello10", offset) { + type("hello") + } + } + + // We expect two events: One published before and one after the PSI tree modification. + trackerA.assertModified("script A after out-of-block modification", expectedEventCount = 2) + trackerB.assertNotModified("unmodified script B") + trackerC.assertNotModified("unmodified module C") + trackerD.assertNotModified("unmodified not-under-content-root file D") + + disposeTrackers(trackerA, trackerB, trackerC, trackerD) + } + + fun `test that not-under-content-root module out-of-block modification affects a single not-under-content-root module`() { + val fileA = createNotUnderContentRootFile("a", "fun foo() = 10") + val fileB = createNotUnderContentRootFile("b", "fun bar() = 10") + val moduleC = createModuleInTmpDir("c") + val scriptD = createScript("d", "fun baz() = 10") + + val trackerA = createTracker(fileA) + val trackerB = createTracker(fileB) + val trackerC = createTracker(moduleC) + val trackerD = createTracker(scriptD) + + fileA.withConfiguredEditor { + modify(textAfterModification = "fun foo() = hello10", getSingleFunctionBodyOffset()) { + type("hello") + } + } + + // We expect two events: One published before and one after the PSI tree modification. + trackerA.assertModified("not-under-content-root file A after out-of-block modification", expectedEventCount = 2) + trackerB.assertNotModified("unmodified not-under-content-root file B") + trackerC.assertNotModified("unmodified module C") + trackerD.assertNotModified("unmodified script D") + + disposeTrackers(trackerA, trackerB, trackerC, trackerD) + } + + private fun KtFile.configureEditor() { + configureByExistingFile(virtualFile) + } + + private fun KtFile.withConfiguredEditor(f: KtFile.() -> Unit) { + configureEditor() + f() + } + + private fun Module.configureEditorForFile(fileName: String): KtFile = findSourceKtFile(fileName).apply { configureEditor() } + + private fun KtFile.modify(textAfterModification: String, targetOffset: Int? = null, edit: () -> Unit) { + targetOffset?.let(editor.caretModel::moveToOffset) + edit() + PsiDocumentManager.getInstance(myProject).commitAllDocuments() + Assert.assertEquals(textAfterModification, text) + } + + private fun KtFile.getSingleFunctionBodyOffset(): Int { + val singleFunction = declarations.single() as KtNamedFunction + return singleFunction.bodyExpression!!.textOffset + } + + private fun KtFile.getSingleMemberInClassOffset(): Int { + val singleMember = (declarations[0] as KtClass).declarations.single() + return singleMember.startOffset + } +} + +class ModuleOutOfBlockModificationEventTracker(module: KtModule) : ModuleModificationEventTracker( + module, + eventKind = "module out-of-block modification", +) { + override fun configureSubscriptions(busConnection: MessageBusConnection) { + busConnection.subscribe( + KotlinTopics.MODULE_OUT_OF_BLOCK_MODIFICATION, + KotlinModuleOutOfBlockModificationListener(::handleEvent), + ) + } +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/modificationEvents/KotlinModuleStateModificationTest.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/modificationEvents/KotlinModuleStateModificationTest.kt new file mode 100644 index 000000000000..4133fca9ce4d --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/modificationEvents/KotlinModuleStateModificationTest.kt @@ -0,0 +1,410 @@ +// Copyright 2000-2023 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.analysis.providers.modificationEvents + +import com.intellij.openapi.application.runWriteAction +import com.intellij.openapi.externalSystem.service.project.ProjectDataManager +import com.intellij.openapi.module.ModuleManager +import com.intellij.openapi.roots.OrderRootType +import com.intellij.openapi.roots.libraries.Library +import com.intellij.testFramework.PsiTestUtil +import com.intellij.util.messages.MessageBusConnection +import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.analysis.providers.topics.KotlinModuleStateModificationListener +import org.jetbrains.kotlin.analysis.providers.topics.KotlinTopics +import org.jetbrains.kotlin.idea.base.plugin.artifacts.TestKotlinArtifacts +import org.jetbrains.kotlin.idea.facet.getOrCreateFacet +import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil +import org.jetbrains.kotlin.idea.test.addEmptyClassesRoot +import org.jetbrains.kotlin.test.util.addDependency + +class KotlinModuleStateModificationTest : AbstractKotlinModuleModificationEventTest() { + override fun constructTracker(module: KtModule): ModuleStateModificationEventTracker = ModuleStateModificationEventTracker(module) + + fun `test source module state modification after adding module dependency`() { + val moduleA = createModuleInTmpDir("a") + val moduleB = createModuleInTmpDir("b") + val moduleC = createModuleInTmpDir("c") + + val trackerA = createTracker(moduleA) + val trackerB = createTracker(moduleB) + val trackerC = createTracker(moduleC) + + moduleA.addDependency(moduleB) + + trackerA.assertModifiedOnce("module A with added module dependency") + trackerB.assertNotModified("unchanged module B") + trackerC.assertNotModified("unchanged module C") + + disposeTrackers(trackerA, trackerB, trackerC) + } + + fun `test source module state modification after adding module dependency with existing dependent`() { + val moduleA = createModuleInTmpDir("a") + val moduleB = createModuleInTmpDir("b") + val moduleC = createModuleInTmpDir("c") + + moduleC.addDependency(moduleA) + + val trackerA = createTracker(moduleA) + val trackerB = createTracker(moduleB) + val trackerC = createTracker(moduleC) + + moduleA.addDependency(moduleB) + + trackerA.assertModifiedOnce("module A with added module dependency") + trackerB.assertNotModified("unchanged module B") + trackerC.assertNotModified("unchanged module C with a dependency on module A") + + disposeTrackers(trackerA, trackerB, trackerC) + } + + fun `test source module state modification after removing module dependency`() { + val moduleA = createModuleInTmpDir("a") + val moduleB = createModuleInTmpDir("b") + val moduleC = createModuleInTmpDir("c") + + moduleA.addDependency(moduleB) + + val trackerA = createTracker(moduleA) + val trackerB = createTracker(moduleB) + val trackerC = createTracker(moduleC) + + moduleA.removeDependency(moduleB) + + trackerA.assertModifiedOnce("module A with removed module dependency") + trackerB.assertNotModified("unchanged module B") + trackerC.assertNotModified("unchanged module C") + + disposeTrackers(trackerA, trackerB, trackerC) + } + + fun `test source module state modification after adding module roots`() { + val moduleA = createModuleInTmpDir("a") + val moduleB = createModuleInTmpDir("b") + val moduleC = createModuleInTmpDir("c") + + val trackerA = createTracker(moduleA) + val trackerB = createTracker(moduleB) + val trackerC = createTracker(moduleC) + + moduleA.addContentRoot(createTempDirectory().toPath()) + + trackerA.assertModifiedOnce("module A with added module roots") + trackerB.assertNotModified("unchanged module B") + trackerC.assertNotModified("unchanged module C") + + disposeTrackers(trackerA, trackerB, trackerC) + } + + fun `test source module state modification after removing module roots`() { + val moduleA = createModuleInTmpDir("a") + val moduleB = createModuleInTmpDir("b") + val moduleC = createModuleInTmpDir("c") + + val root = moduleA.addContentRoot(createTempDirectory().toPath()) + + val trackerA = createTracker(moduleA) + val trackerB = createTracker(moduleB) + val trackerC = createTracker(moduleC) + + PsiTestUtil.removeContentEntry(moduleA, root.file!!) + + trackerA.assertModifiedOnce("module A with removed module roots") + trackerB.assertNotModified("unchanged module B") + trackerC.assertNotModified("unchanged module C") + + disposeTrackers(trackerA, trackerB, trackerC) + } + + fun `test source module state modification after adding library dependency`() { + val moduleA = createModuleInTmpDir("a") + val moduleB = createModuleInTmpDir("b") + val moduleC = createModuleInTmpDir("c") + + val trackerA = createTracker(moduleA) + val trackerB = createTracker(moduleB) + val trackerC = createTracker(moduleC) + + moduleA.addLibrary(TestKotlinArtifacts.kotlinTestJunit) + + trackerA.assertModifiedOnce("module A with added library dependency") + trackerB.assertNotModified("unchanged module B") + trackerC.assertNotModified("unchanged module C") + + disposeTrackers(trackerA, trackerB, trackerC) + } + + fun `test source module state modification after removing library dependency`() { + val moduleA = createModuleInTmpDir("a") + val moduleB = createModuleInTmpDir("b") + val moduleC = createModuleInTmpDir("c") + + moduleA.addLibrary(TestKotlinArtifacts.kotlinTestJunit, name = "junit") + + val trackerA = createTracker(moduleA) + val trackerB = createTracker(moduleB) + val trackerC = createTracker(moduleC) + + ConfigLibraryUtil.removeLibrary(moduleA, "junit") + + trackerA.assertModifiedOnce("module A with removed module dependency") + trackerB.assertNotModified("unchanged module B") + trackerC.assertNotModified("unchanged module C") + + disposeTrackers(trackerA, trackerB, trackerC) + } + + fun `test source module state modification after removal`() { + val moduleA = createModuleInTmpDir("a") + val moduleB = createModuleInTmpDir("b") + val moduleC = createModuleInTmpDir("c") + + val trackerA = createTracker(moduleA) + val trackerB = createTracker(moduleB) + val trackerC = createTracker(moduleC) + + ModuleManager.getInstance(myProject).disposeModule(moduleA) + + trackerA.assertModifiedOnce("disposed module A", shouldBeRemoval = true) + trackerB.assertNotModified("unchanged module B") + trackerC.assertNotModified("unchanged module C") + + disposeTrackers(trackerA, trackerB, trackerC) + } + + fun `test library module state modification after root replacement`() { + val libraryA = createProjectLibrary("a") + val libraryB = createProjectLibrary("b") + val moduleC = createModuleInTmpDir("c") + val moduleD = createModuleInTmpDir("d") + + moduleC.addDependency(libraryA) + moduleC.addDependency(libraryB) + + val trackerA = createTracker(libraryA) + val trackerB = createTracker(libraryB) + val trackerC = createTracker(moduleC) + val trackerD = createTracker(moduleD) + + libraryA.swapRoot() + + trackerA.assertModifiedOnce("project library A with replaced root") + trackerB.assertNotModified("unchanged library B") + trackerC.assertNotModified("unchanged module C") + trackerD.assertNotModified("unchanged module D") + + disposeTrackers(trackerA, trackerB, trackerC, trackerD) + } + + private fun Library.swapRoot() = runWriteAction { + val existingRootUrl = rootProvider.getUrls(OrderRootType.CLASSES)[0]!! + modifiableModel.apply { + removeRoot(existingRootUrl, OrderRootType.CLASSES) + addEmptyClassesRoot() + commit() + } + } + + fun `test library module state modification after removal`() { + val libraryA = createProjectLibrary("a") + val libraryB = createProjectLibrary("b") + val moduleC = createModuleInTmpDir("c") + val moduleD = createModuleInTmpDir("d") + + moduleC.addDependency(libraryA) + moduleC.addDependency(libraryB) + + val trackerA = createTracker(libraryA) + val trackerB = createTracker(libraryB) + val trackerC = createTracker(moduleC) + val trackerD = createTracker(moduleD) + + ConfigLibraryUtil.removeProjectLibrary(myProject, libraryA) + + trackerA.assertModifiedOnce("removed project library A", shouldBeRemoval = true) + trackerB.assertNotModified("unchanged library B") + trackerC.assertNotModified("unchanged module C") + trackerD.assertNotModified("unchanged module D") + + disposeTrackers(trackerA, trackerB, trackerC, trackerD) + } + + fun `test script module state modification after moving the script file to another module`() { + val scriptA = createScript("a") + val scriptB = createScript("b") + val libraryC = createProjectLibrary("c") + val moduleD = createModuleInTmpDir("d") + val moduleE = createModuleInTmpDir("e") + + val destination = getVirtualFile(createTempDirectory()) + PsiTestUtil.addContentRoot(moduleE, destination) + + val trackerA = createTracker(scriptA) + val trackerB = createTracker(scriptB) + val trackerC = createTracker(libraryC) + val trackerD = createTracker(moduleD) + val trackerE = createTracker(moduleE) + + move(scriptA.virtualFile, destination) + + trackerA.assertModifiedOnce("moved script A") + trackerB.assertNotModified("unchanged script B") + trackerC.assertNotModified("unchanged library C") + trackerD.assertNotModified("unchanged module D") + + // The file move will cause a global PSI tree change event, and thereby a global out-of-block modification event, but the module + // state of the destination module E is not affected by a file move, so the tracker should not register any module state + // modification events. + trackerE.assertNotModified("unchanged destination module E") + + disposeTrackers(trackerA, trackerB, trackerC, trackerD, trackerE) + } + + fun `test script module state modification after moving the script file outside the content root`() { + val scriptA = createScript("a") + val scriptB = createScript("b") + val libraryC = createProjectLibrary("c") + val moduleD = createModuleInTmpDir("d") + + val destination = getVirtualFile(createTempDirectory()) + + val trackerA = createTracker(scriptA) + val trackerB = createTracker(scriptB) + val trackerC = createTracker(libraryC) + val trackerD = createTracker(moduleD) + + move(scriptA.virtualFile, destination) + + trackerA.assertModifiedOnce("moved script A") + trackerB.assertNotModified("unchanged script B") + trackerC.assertNotModified("unchanged library C") + trackerD.assertNotModified("unchanged module D") + + disposeTrackers(trackerA, trackerB, trackerC, trackerD) + } + + fun `test script module state modification after deleting the script file`() { + val scriptA = createScript("a") + val scriptB = createScript("b") + val libraryC = createProjectLibrary("c") + val moduleD = createModuleInTmpDir("d") + + val trackerA = createTracker(scriptA) + val trackerB = createTracker(scriptB) + val trackerC = createTracker(libraryC) + val trackerD = createTracker(moduleD) + + delete(scriptA.virtualFile) + + trackerA.assertModifiedOnce("deleted script A", shouldBeRemoval = true) + trackerB.assertNotModified("unchanged script B") + trackerC.assertNotModified("unchanged library C") + trackerD.assertNotModified("unchanged module D") + + disposeTrackers(trackerA, trackerB, trackerC, trackerD) + } + + fun `test not-under-content-root module state modification after moving the file to another module`() { + val fileA = createNotUnderContentRootFile("a") + val fileB = createNotUnderContentRootFile("b") + val libraryC = createProjectLibrary("c") + val moduleD = createModuleInTmpDir("d") + val moduleE = createModuleInTmpDir("e") + + val destination = getVirtualFile(createTempDirectory()) + PsiTestUtil.addContentRoot(moduleE, destination) + + val trackerA = createTracker(fileA) + val trackerB = createTracker(fileB) + val trackerC = createTracker(libraryC) + val trackerD = createTracker(moduleD) + val trackerE = createTracker(moduleE) + + move(fileA.virtualFile, destination) + + trackerA.assertModifiedOnce("moved not-under-content-root file A") + trackerB.assertNotModified("unchanged not-under-content-root file B") + trackerC.assertNotModified("unchanged library C") + trackerD.assertNotModified("unchanged module D") + + // The file move will cause a global PSI tree change event, and thereby a global out-of-block modification event, but the module + // state of the destination module E is not affected by a file move, so the tracker should not register any module state + // modification events. + trackerE.assertNotModified("unchanged destination module E") + + disposeTrackers(trackerA, trackerB, trackerC, trackerD, trackerE) + } + + fun `test not-under-content-root module state modification after moving the file outside the content root`() { + val fileA = createNotUnderContentRootFile("a") + val fileB = createNotUnderContentRootFile("b") + val libraryC = createProjectLibrary("c") + val moduleD = createModuleInTmpDir("d") + + val destination = getVirtualFile(createTempDirectory()) + + val trackerA = createTracker(fileA) + val trackerB = createTracker(fileB) + val trackerC = createTracker(libraryC) + val trackerD = createTracker(moduleD) + + move(fileA.virtualFile, destination) + + trackerA.assertModifiedOnce("moved not-under-content-root file A") + trackerB.assertNotModified("unchanged not-under-content-root file B") + trackerC.assertNotModified("unchanged library C") + trackerD.assertNotModified("unchanged module D") + + disposeTrackers(trackerA, trackerB, trackerC, trackerD) + } + + fun `test not-under-content-root module state modification after deleting the file`() { + val fileA = createNotUnderContentRootFile("a") + val fileB = createNotUnderContentRootFile("b") + val libraryC = createProjectLibrary("c") + val moduleD = createModuleInTmpDir("d") + + val trackerA = createTracker(fileA) + val trackerB = createTracker(fileB) + val trackerC = createTracker(libraryC) + val trackerD = createTracker(moduleD) + + delete(fileA.virtualFile) + + trackerA.assertModifiedOnce("deleted not-under-content-root file A", shouldBeRemoval = true) + trackerB.assertNotModified("unchanged not-under-content-root file B") + trackerC.assertNotModified("unchanged library C") + trackerD.assertNotModified("unchanged module D") + + disposeTrackers(trackerA, trackerB, trackerC, trackerD) + } + + fun `test module facet`() { + val moduleA = createModuleInTmpDir("a") + val moduleB = createModuleInTmpDir("b") + + val trackerA = createTracker(moduleA) + val trackerB = createTracker(moduleB) + + val modelsProvider = ProjectDataManager.getInstance().createModifiableModelsProvider(project) + moduleA.getOrCreateFacet(modelsProvider, useProjectSettings = false) + runWriteAction { modelsProvider.commit() } + + trackerA.assertModifiedOnce("module A with added facet") + trackerB.assertNotModified("unchanged module B") + + disposeTrackers(trackerA, trackerB) + } +} + +class ModuleStateModificationEventTracker(module: KtModule) : ModuleModificationEventTracker( + module, + eventKind = "module state modification", +) { + override fun configureSubscriptions(busConnection: MessageBusConnection) { + busConnection.subscribe( + KotlinTopics.MODULE_STATE_MODIFICATION, + KotlinModuleStateModificationListener(::handleEvent), + ) + } +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/sessions/AbstractSessionsInvalidationTest.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/sessions/AbstractSessionsInvalidationTest.kt index 89b7a3b868ee..a2c2e84d1e8e 100644 --- a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/sessions/AbstractSessionsInvalidationTest.kt +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/sessions/AbstractSessionsInvalidationTest.kt @@ -2,11 +2,9 @@ package org.jetbrains.kotlin.idea.fir.analysis.providers.sessions -import com.intellij.openapi.command.WriteCommandAction +import com.google.gson.JsonObject import com.intellij.openapi.module.Module import com.intellij.openapi.module.ModuleManager -import com.intellij.openapi.vfs.LocalFileSystem -import com.intellij.testFramework.PsiTestUtil import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirResolveSessionService import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirModuleSession import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession @@ -17,36 +15,23 @@ import org.jetbrains.kotlin.idea.base.projectStructure.sourceModuleInfos import org.jetbrains.kotlin.idea.base.projectStructure.toKtModule import org.jetbrains.kotlin.idea.fir.analysis.providers.TestProjectModule import org.jetbrains.kotlin.idea.fir.analysis.providers.TestProjectStructure -import org.jetbrains.kotlin.idea.fir.analysis.providers.TestProjectStructureReader -import org.jetbrains.kotlin.idea.fir.analysis.providers.incModificationTracker +import org.jetbrains.kotlin.idea.fir.analysis.providers.publishOutOfBlockModification import org.jetbrains.kotlin.idea.jsonUtils.getString -import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest import org.jetbrains.kotlin.idea.base.test.KotlinRoot import java.io.File -import java.nio.file.Paths +import org.jetbrains.kotlin.idea.fir.analysis.providers.AbstractProjectStructureTest +import org.jetbrains.kotlin.idea.fir.analysis.providers.TestProjectLibrary +import org.jetbrains.kotlin.idea.fir.analysis.providers.TestProjectStructureParser -abstract class AbstractSessionsInvalidationTest : AbstractMultiModuleTest() { +abstract class AbstractSessionsInvalidationTest : AbstractProjectStructureTest() { override fun isFirPlugin(): Boolean = true override fun getTestDataDirectory(): File = - KotlinRoot.DIR.resolve("fir-low-level-api-ide-impl").resolve("testData").resolve("sessionInvalidation") + KotlinRoot.DIR.resolve("base").resolve("fir").resolve("analysis-api-providers").resolve("testData").resolve("sessionInvalidation") protected fun doTest(path: String) { - val testStructure = TestProjectStructureReader.readToTestStructure( - Paths.get(path), - toTestStructure = MultiModuleTestProjectStructure.Companion::fromTestProjectStructure - ) - - val modulesByNames = testStructure.modules.associate { moduleData -> - moduleData.name to createEmptyModule(moduleData.name) - } - - testStructure.modules.forEach { moduleData -> - val module = modulesByNames.getValue(moduleData.name) - moduleData.dependsOnModules.forEach { dependencyName -> - module.addDependency(modulesByNames.getValue(dependencyName)) - } - } + val (testStructure, projectLibrariesByName, modulesByNames) = + initializeProjectStructure(path, SessionInvalidationTestProjectStructureParser) val rootIdeaModule = modulesByNames.getValue(testStructure.rootModule) val rootModule = rootIdeaModule.getMainKtSourceModule()!! @@ -54,7 +39,7 @@ abstract class AbstractSessionsInvalidationTest : AbstractMultiModuleTest() { val sessionsBeforeOOBM = getAllModuleSessions(rootModule) val modulesToMakeOOBM = testStructure.modulesToMakeOOBM.map(modulesByNames::getValue) - modulesToMakeOOBM.forEach { it.incModificationTracker() } + modulesToMakeOOBM.forEach { it.publishOutOfBlockModification() } val sessionsAfterOOBM = getAllModuleSessions(rootModule) @@ -84,40 +69,31 @@ abstract class AbstractSessionsInvalidationTest : AbstractMultiModuleTest() { val resolveSession = LLFirResolveSessionService.getInstance(project).getFirResolveSession(mainModule) return projectModules.map(resolveSession::getSessionFor) } - - private fun createEmptyModule(name: String): Module { - val tmpDir = createTempDirectory().toPath() - val module: Module = createModule("$tmpDir/$name", moduleType) - val root = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tmpDir.toFile())!! - WriteCommandAction.writeCommandAction(module.project).run { - root.refresh(false, true) - } - - PsiTestUtil.addSourceContentToRoots(module, root) - return module - } } -private data class MultiModuleTestProjectStructure( - val modules: List, +data class SessionInvalidationTestProjectStructure( + override val libraries: List, + override val modules: List, val rootModule: String, val modulesToMakeOOBM: List, val expectedInvalidatedModules: List, -) { - companion object { - fun fromTestProjectStructure(testProjectStructure: TestProjectStructure): MultiModuleTestProjectStructure { - val json = testProjectStructure.json +) : TestProjectStructure - return MultiModuleTestProjectStructure( - testProjectStructure.modules, - json.getString(ROOT_MODULE_FIELD), - json.getAsJsonArray(MODULES_TO_MAKE_OOBM_IN_FIELD).map { it.asString }.sorted(), - json.getAsJsonArray(EXPECTED_INVALIDATED_MODULES_FIELD).map { it.asString }.sorted(), - ) - } +private object SessionInvalidationTestProjectStructureParser : TestProjectStructureParser { + private const val ROOT_MODULE_FIELD = "rootModule" + private const val MODULES_TO_MAKE_OOBM_IN_FIELD = "modulesToMakeOOBM" + private const val EXPECTED_INVALIDATED_MODULES_FIELD = "expectedInvalidatedModules" - private const val ROOT_MODULE_FIELD = "rootModule" - private const val MODULES_TO_MAKE_OOBM_IN_FIELD = "modulesToMakeOOBM" - private const val EXPECTED_INVALIDATED_MODULES_FIELD = "expectedInvalidatedModules" - } -} \ No newline at end of file + override fun parse( + libraries: List, + modules: List, + json: JsonObject, + ): SessionInvalidationTestProjectStructure = + SessionInvalidationTestProjectStructure( + libraries, + modules, + json.getString(ROOT_MODULE_FIELD), + json.getAsJsonArray(MODULES_TO_MAKE_OOBM_IN_FIELD)!!.map { it.asString }.sorted(), + json.getAsJsonArray(EXPECTED_INVALIDATED_MODULES_FIELD)!!.map { it.asString }.sorted(), + ) +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/sessions/CyclicDependenciesSymbolResolutionTest.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/sessions/CyclicDependenciesSymbolResolutionTest.kt new file mode 100644 index 000000000000..f05c8fe2fd29 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/sessions/CyclicDependenciesSymbolResolutionTest.kt @@ -0,0 +1,75 @@ +// Copyright 2000-2023 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.analysis.providers.sessions + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.idea.base.analysis.api.utils.analyzeInModalWindow +import org.jetbrains.kotlin.analysis.api.calls.successfulFunctionCallOrNull +import org.jetbrains.kotlin.analysis.api.calls.symbol +import org.jetbrains.kotlin.analysis.api.types.KtType +import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest +import org.jetbrains.kotlin.psi.KtCallExpression +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtNamedFunction +import org.jetbrains.kotlin.psi.KtSimpleNameExpression +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance +import org.junit.Assert +import java.io.File + +/** + * [CyclicDependenciesSymbolResolutionTest] ensures that sessions with cyclic dependencies can not only be created (which + * [AbstractSessionsInvalidationTest] already ensures), but also that these sessions' dependency symbol providers don't run into any stack + * overflow errors. + * + * A corresponding (or replacement) test on the Analysis API side does not exist yet, because the Analysis API test infrastructure does not + * support cyclic module dependencies, which makes this strictly an issue of JPS project structures. + */ +class CyclicDependenciesSymbolResolutionTest : AbstractMultiModuleTest() { + override fun getTestDataDirectory(): File = error("Should not be called") + + override fun isFirPlugin(): Boolean = true + + fun `test that function symbols from cyclic dependencies can be resolved`() { + val moduleA = createModuleInTmpDir("a") { + listOf( + FileWithText("a.kt", "fun foo(): Int = bar()") + ) + } + val moduleB = createModuleInTmpDir("b") { + listOf( + FileWithText("b.kt", "fun bar(): Int = foo()") + ) + } + + moduleA.addKotlinStdlib() + moduleB.addKotlinStdlib() + + moduleA.addDependency(moduleB) + moduleB.addDependency(moduleA) + + val fileA = moduleA.findSourceKtFile("a.kt") + analyzeInModalWindow(fileA, "test") { + fileA.getFirstFunctionDeclaration().getBodyCallExpression().assertCalleeNameAndType(fileA, "bar", builtinTypes.INT) + } + + val fileB = moduleB.findSourceKtFile("b.kt") + analyzeInModalWindow(fileB, "test") { + fileB.getFirstFunctionDeclaration().getBodyCallExpression().assertCalleeNameAndType(fileB, "foo", builtinTypes.INT) + } + } + + private fun KtFile.getFirstFunctionDeclaration(): KtNamedFunction = declarations.firstIsInstance() + + private fun KtNamedFunction.getBodyCallExpression(): KtCallExpression = bodyExpression!! as KtCallExpression + + context(KtAnalysisSession) + private fun KtCallExpression.assertCalleeNameAndType(file: KtFile, expectedName: String, expectedType: KtType) { + val ktFunction = file.declarations.first() as KtNamedFunction + val ktCall = ktFunction.bodyExpression!! as KtCallExpression + + val ktCallee = ktCall.calleeExpression as KtSimpleNameExpression + Assert.assertEquals(expectedName, ktCallee.getReferencedName()) + + val callableSymbol = ktCall.resolveCall()!!.successfulFunctionCallOrNull()!!.symbol + Assert.assertEquals(expectedType, callableSymbol.returnType) + } +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/sessions/SessionsInvalidationTestGenerated.java b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/sessions/SessionsInvalidationTestGenerated.java index 35c579784bb2..c123c6e11567 100644 --- a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/sessions/SessionsInvalidationTestGenerated.java +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/sessions/SessionsInvalidationTestGenerated.java @@ -43,11 +43,26 @@ public class SessionsInvalidationTestGenerated extends AbstractSessionsInvalidat runTest("testData/sessionInvalidation/binaryTreeWithInvalidInRoot/"); } + @TestMetadata("cyclical") + public void testCyclical() throws Exception { + runTest("testData/sessionInvalidation/cyclical/"); + } + + @TestMetadata("cyclicalWithOutsideDependency") + public void testCyclicalWithOutsideDependency() throws Exception { + runTest("testData/sessionInvalidation/cyclicalWithOutsideDependency/"); + } + @TestMetadata("linear") public void testLinear() throws Exception { runTest("testData/sessionInvalidation/linear/"); } + @TestMetadata("linearWithCyclicalDependency") + public void testLinearWithCyclicalDependency() throws Exception { + runTest("testData/sessionInvalidation/linearWithCyclicalDependency/"); + } + @TestMetadata("rhombus") public void testRhombus() throws Exception { runTest("testData/sessionInvalidation/rhombus/"); diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/testProjectStructure/TestProjectEntityReference.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/testProjectStructure/TestProjectEntityReference.kt new file mode 100644 index 000000000000..b0bf3b6bd74c --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/testProjectStructure/TestProjectEntityReference.kt @@ -0,0 +1,32 @@ +// Copyright 2000-2023 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.analysis.providers.testProjectStructure + +import com.google.gson.JsonObject +import org.jetbrains.kotlin.idea.jsonUtils.getNullableString + +/** + * A reference that points to a library or module in the test project structure. + */ +sealed interface TestProjectEntityReference { + val name: String +} + +data class TestProjectLibraryReference(override val name: String) : TestProjectEntityReference + +data class TestProjectModuleReference(override val name: String) : TestProjectEntityReference + +object TestProjectEntityReferenceParser { + private const val LIBRARY_FIELD = "library" + private const val MODULE_FIELD = "module" + + fun parse(json: JsonObject): TestProjectEntityReference { + val libraryTarget = json.getNullableString(LIBRARY_FIELD)?.let { TestProjectLibraryReference(it) } + val moduleTarget = json.getNullableString(MODULE_FIELD)?.let { TestProjectModuleReference(it) } + + if (libraryTarget == null && moduleTarget == null || libraryTarget != null && moduleTarget != null) { + error("Expected exactly one of `$LIBRARY_FIELD` and `$MODULE_FIELD` to be specified.") + } + + return libraryTarget ?: moduleTarget!! + } +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/testProjectStructure/TestProjectStructure.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/testProjectStructure/TestProjectStructure.kt new file mode 100644 index 000000000000..dfdb096ffa8d --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/testProjectStructure/TestProjectStructure.kt @@ -0,0 +1,59 @@ +// Copyright 2000-2023 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.analysis.providers + +import com.google.gson.JsonElement +import com.google.gson.JsonObject +import org.jetbrains.kotlin.idea.fir.analysis.providers.testProjectStructure.getAsStringList +import org.jetbrains.kotlin.idea.jsonUtils.getString +import java.util.UUID + +interface TestProjectStructure { + /** + * A list of *project-level* libraries in the test project structure. + */ + val libraries: List + + val modules: List +} + +fun interface TestProjectStructureParser { + /** + * Parses a [TestProjectStructure] from already parsed lists of [TestProjectLibrary]s and [TestProjectModule]s, and the original + * [JsonObject]. + */ + fun parse(libraries: List, modules: List, json: JsonObject): S +} + +/** + * @param roots A list of labels for the library's roots. The test infrastructure generates a unique, temporary JAR file for each such + * label. This allows adding the same root to multiple libraries without having to wrangle JAR files in the test data. + * The property is optional in `structure.json`. If absent, the library receives a single, unique root which won't be shared + * with other libraries. + */ +data class TestProjectLibrary(val name: String, val roots: List) + +object TestProjectLibraryParser { + private const val ROOTS_FIELD = "roots" + + fun parse(json: JsonElement): TestProjectLibrary { + require(json is JsonObject) + val roots = json.getAsStringList(ROOTS_FIELD) ?: listOf(UUID.randomUUID().toString()) + return TestProjectLibrary(json.getString("name"), roots) + } +} + +data class TestProjectModule(val name: String, val dependsOnModules: List) + +object TestProjectModuleParser { + private const val DEPENDS_ON_FIELD = "dependsOn" + + fun parse(json: JsonElement): TestProjectModule { + require(json is JsonObject) + val dependencies = json.getAsStringList(DEPENDS_ON_FIELD) ?: emptyList() + return TestProjectModule( + json.getString("name"), + dependencies + ) + } +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/testProjectStructure/TestProjectStructureReader.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/testProjectStructure/TestProjectStructureReader.kt new file mode 100644 index 000000000000..8f263714c4b2 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/testProjectStructure/TestProjectStructureReader.kt @@ -0,0 +1,35 @@ +// Copyright 2000-2023 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.analysis.providers.testProjectStructure + +import com.google.gson.JsonObject +import com.google.gson.JsonParser +import com.intellij.openapi.util.io.FileUtil +import java.nio.file.Path +import org.jetbrains.kotlin.idea.fir.analysis.providers.TestProjectLibraryParser +import org.jetbrains.kotlin.idea.fir.analysis.providers.TestProjectModuleParser +import org.jetbrains.kotlin.idea.fir.analysis.providers.TestProjectStructure +import org.jetbrains.kotlin.idea.fir.analysis.providers.TestProjectStructureParser + +internal object TestProjectStructureReader { + fun read( + testDirectory: Path, + jsonFileName: String = "structure.json", + parser: TestProjectStructureParser, + ): S { + val jsonFile = testDirectory.resolve(jsonFileName) + + @Suppress("DEPRECATION") // AS 4.0 + val json = JsonParser().parse(FileUtil.loadFile(jsonFile.toFile(), /*convertLineSeparators=*/true)) + require(json is JsonObject) + + val libraries = json.getAsJsonArray("libraries")?.map(TestProjectLibraryParser::parse) ?: emptyList() + val modules = json.getAsJsonArray("modules")!!.map(TestProjectModuleParser::parse) + return parser.parse(libraries, modules, json) + } + + fun readToTestStructure( + testDirectory: Path, + jsonFileName: String = "structure.json", + testProjectStructureParser: TestProjectStructureParser, + ): S = read(testDirectory, jsonFileName, testProjectStructureParser) +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/testProjectStructure/jsonUtils.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/testProjectStructure/jsonUtils.kt new file mode 100644 index 000000000000..acbff89f8b85 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/testProjectStructure/jsonUtils.kt @@ -0,0 +1,9 @@ +// Copyright 2000-2023 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.analysis.providers.testProjectStructure + +import com.google.gson.JsonObject +import com.google.gson.JsonPrimitive + +fun JsonObject.getAsStringList(memberName: String): List? = getAsJsonArray(memberName)?.map { (it as JsonPrimitive).asString } + +fun JsonObject.getAsJsonObjectList(memberName: String): List? = getAsJsonArray(memberName)?.map { it as JsonObject } diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/testUtils.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/testUtils.kt index e09510b52a6b..3eaaddc36aef 100644 --- a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/testUtils.kt +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/testUtils.kt @@ -2,10 +2,12 @@ package org.jetbrains.kotlin.idea.fir.analysis.providers -import com.intellij.openapi.components.service +import com.intellij.openapi.application.runWriteAction import com.intellij.openapi.module.Module -import org.jetbrains.kotlin.idea.base.fir.analysisApiProviders.FirIdeModificationTrackerService +import org.jetbrains.kotlin.idea.base.fir.analysisApiProviders.FirIdeOutOfBlockModificationService -internal fun Module.incModificationTracker() { - project.service().increaseModificationCountForModule(this) -} \ No newline at end of file +internal fun Module.publishOutOfBlockModification() { + runWriteAction { + FirIdeOutOfBlockModificationService.getInstance(project).publishModuleOutOfBlockModification(this) + } +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/trackers/KotlinModuleOutOfBlockTrackerTest.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/trackers/KotlinModuleOutOfBlockTrackerTest.kt deleted file mode 100644 index 705763644b8a..000000000000 --- a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/trackers/KotlinModuleOutOfBlockTrackerTest.kt +++ /dev/null @@ -1,328 +0,0 @@ -// Copyright 2000-2022 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.analysis.providers.trackers - -import com.intellij.openapi.application.runWriteAction -import com.intellij.openapi.module.Module -import com.intellij.openapi.project.Project -import com.intellij.openapi.util.ModificationTracker -import com.intellij.openapi.vfs.VirtualFileManager -import com.intellij.psi.PsiDocumentManager -import com.intellij.psi.PsiManager -import org.jetbrains.kotlin.analysis.providers.createModuleWithoutDependenciesOutOfBlockModificationTracker -import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker -import org.jetbrains.kotlin.idea.base.projectStructure.getMainKtSourceModule -import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest -import org.jetbrains.kotlin.idea.util.sourceRoots -import org.jetbrains.kotlin.psi.* -import org.junit.Assert -import java.io.File - -class KotlinModuleOutOfBlockTrackerTest : AbstractMultiModuleTest() { - override fun getTestDataDirectory(): File = error("Should not be called") - - override fun isFirPlugin(): Boolean = true - - fun testThatModuleOutOfBlockChangeInfluenceOnlySingleModule() { - val moduleA = createModuleInTmpDir("a") { - listOf( - FileWithText("main.kt", "fun main() = 10") - ) - } - val moduleB = createModuleInTmpDir("b") - val moduleC = createModuleInTmpDir("c") - - - val moduleAWithTracker = ModuleWithModificationTracker(moduleA) - val moduleBWithTracker = ModuleWithModificationTracker(moduleB) - val moduleCWithTracker = ModuleWithModificationTracker(moduleC) - - moduleA.typeInFunctionBody("main.kt", textAfterTyping = "fun main() = hello10") - - Assert.assertTrue( - "Out of block modification count for module A with out of block should change after typing, modification count is ${moduleAWithTracker.modificationCount}", - moduleAWithTracker.changed() - ) - Assert.assertFalse( - "Out of block modification count for module B without out of block should not change after typing, modification count is ${moduleBWithTracker.modificationCount}", - moduleBWithTracker.changed() - ) - Assert.assertFalse( - "Out of block modification count for module C without out of block should not change after typing, modification count is ${moduleCWithTracker.modificationCount}", - moduleCWithTracker.changed() - ) - } - - fun testThatDeleteSymbolInBodyDoesNotLeadToOutOfBlockChange() { - val moduleA = createModuleInTmpDir("a") { - listOf( - FileWithText( - "main.kt", "fun main() {\n" + - "val v = \n" + - "}" - ) - ) - } - - val moduleAWithTracker = ModuleWithModificationTracker(moduleA) - - val file = "${moduleA.sourceRoots.first().url}/${"main.kt"}" - val virtualFile = VirtualFileManager.getInstance().findFileByUrl(file)!! - val ktFile = PsiManager.getInstance(moduleA.project).findFile(virtualFile) as KtFile - configureByExistingFile(virtualFile) - backspace() - PsiDocumentManager.getInstance(moduleA.project).commitAllDocuments() - - Assert.assertFalse( - "Out of block modification count for module A should not change after deleting, modification count is ${moduleAWithTracker.modificationCount}", - moduleAWithTracker.changed() - ) - Assert.assertEquals("fun main() {\n" + - "val v =\n" + - "}", ktFile.text) - } - - //1. outside function - //2. in function identifier - fun testWhitespace() { - val moduleA = createModuleInTmpDir("a") { - listOf( - FileWithText( - "main.kt", "class Main {" + - " fun main() {}\n" + - "}" - ) - ) - } - - val moduleAWithTracker = ModuleWithModificationTracker(moduleA) - - val file = "${moduleA.sourceRoots.first().url}/${"main.kt"}" - val virtualFile = VirtualFileManager.getInstance().findFileByUrl(file)!! - val ktFile = PsiManager.getInstance(moduleA.project).findFile(virtualFile) as KtFile - configureByExistingFile(virtualFile) - val singleFunction = (ktFile.declarations[0] as KtClass).declarations.single() - val startOffset = singleFunction.textRange.startOffset - editor.caretModel.moveToOffset(startOffset) - backspace() - PsiDocumentManager.getInstance(moduleA.project).commitAllDocuments() - - Assert.assertFalse( - "Out of block modification count for module A should not change after deleting, modification count is ${moduleAWithTracker.modificationCount}", - moduleAWithTracker.changed() - ) - Assert.assertEquals("class Main { fun main() {}\n" + - "}", ktFile.text) - - editor.caretModel.moveToOffset(startOffset + "fun ".length) - type(" ") - PsiDocumentManager.getInstance(moduleA.project).commitAllDocuments() - Assert.assertTrue( - "Out of block modification count for module A should change after adding space in identifier, modification count is ${moduleAWithTracker.modificationCount}", - moduleAWithTracker.changed() - ) - Assert.assertEquals("class Main { fun m ain() {}\n" + - "}", ktFile.text) - - } - - fun testCommentFunction() { - val moduleA = createModuleInTmpDir("a") { - listOf( - FileWithText( - "main.kt", "class Main {" + - " fun main() {}\n" + - "}" - ) - ) - } - - val moduleAWithTracker = ModuleWithModificationTracker(moduleA) - - val file = "${moduleA.sourceRoots.first().url}/${"main.kt"}" - val virtualFile = VirtualFileManager.getInstance().findFileByUrl(file)!! - val ktFile = PsiManager.getInstance(moduleA.project).findFile(virtualFile) as KtFile - configureByExistingFile(virtualFile) - val singleFunction = (ktFile.declarations[0] as KtClass).declarations.single() - val startOffset = singleFunction.textRange.startOffset - editor.caretModel.moveToOffset(startOffset) - type("//") - PsiDocumentManager.getInstance(moduleA.project).commitAllDocuments() - - Assert.assertTrue( - "Out of block modification count for module A should change after commenting, modification count is ${moduleAWithTracker.modificationCount}", - moduleAWithTracker.changed() - ) - } - - fun testLocalCommentType() { - val moduleA = createModuleInTmpDir("a") { - listOf( - FileWithText( - "main.kt", "class Main {\n" + - " fun main() {\n" + - " class Local {}\n" + - " }\n" + - "}" - ) - ) - } - - val moduleAWithTracker = ModuleWithModificationTracker(moduleA) - - val file = "${moduleA.sourceRoots.first().url}/${"main.kt"}" - val virtualFile = VirtualFileManager.getInstance().findFileByUrl(file)!! - val ktFile = PsiManager.getInstance(moduleA.project).findFile(virtualFile) as KtFile - configureByExistingFile(virtualFile) - val singleFunction = (ktFile.declarations[0] as KtClass).declarations.single() as KtFunction - val startOffset = (singleFunction.bodyBlockExpression?.lBrace?.textOffset ?: 0) + 2 - editor.caretModel.moveToOffset(startOffset) - type("//") - PsiDocumentManager.getInstance(moduleA.project).commitAllDocuments() - - Assert.assertFalse( - "Out of block modification count for module A should not change after commenting, local classes are not available outside of the method," + - "modification count is ${moduleAWithTracker.modificationCount}", - moduleAWithTracker.changed() - ) - } - - fun testCommentType() { - val moduleA = createModuleInTmpDir("a") { - listOf( - FileWithText( - "main.kt", "class Main {}" - ) - ) - } - val moduleAWithTracker = ModuleWithModificationTracker(moduleA) - val file = "${moduleA.sourceRoots.first().url}/${"main.kt"}" - val virtualFile = VirtualFileManager.getInstance().findFileByUrl(file)!! - configureByExistingFile(virtualFile) - editor.caretModel.moveToOffset(0) - type("//") - PsiDocumentManager.getInstance(moduleA.project).commitAllDocuments() - - Assert.assertTrue( - "Out of block modification count for module A should change after commenting, local classes are not available outside of the method," + - "modification count is ${moduleAWithTracker.modificationCount}", - moduleAWithTracker.changed() - ) - } - - fun testThatAddModifierDoesLeadToOutOfBlockChange() { - val moduleA = createModuleInTmpDir("a") { - listOf( - FileWithText( - "main.kt", "inline fun main() {}" - ) - ) - } - - val moduleAWithTracker = ModuleWithModificationTracker(moduleA) - - val file = "${moduleA.sourceRoots.first().url}/${"main.kt"}" - val virtualFile = VirtualFileManager.getInstance().findFileByUrl(file)!! - val ktFile = PsiManager.getInstance(moduleA.project).findFile(virtualFile) as KtFile - configureByExistingFile(virtualFile) - type("private ") - PsiDocumentManager.getInstance(moduleA.project).commitAllDocuments() - - Assert.assertTrue( - "Out of block modification count for module A should be changed after specifying return type, modification count is ${moduleAWithTracker.modificationCount}", - moduleAWithTracker.changed() - ) - Assert.assertEquals("private inline fun main() {}", ktFile.text) - } - - fun testThatInEveryModuleOutOfBlockWillHappenAfterContentRootChange() { - val moduleA = createModuleInTmpDir("a") - val moduleB = createModuleInTmpDir("b") - val moduleC = createModuleInTmpDir("c") - - val moduleAWithTracker = ModuleWithModificationTracker(moduleA) - val moduleBWithTracker = ModuleWithModificationTracker(moduleB) - val moduleCWithTracker = ModuleWithModificationTracker(moduleC) - - runWriteAction { - moduleA.sourceRoots.first().createChildData(/* requestor = */ null, "file.kt") - } - - Assert.assertTrue( - "Out of block modification count for module A should change after content root change, modification count is ${moduleAWithTracker.modificationCount}", - moduleAWithTracker.changed() - ) - Assert.assertTrue( - "Out of block modification count for module B should change after content root change, modification count is ${moduleBWithTracker.modificationCount}", - moduleBWithTracker.changed() - ) - Assert.assertTrue( - "Out of block modification count for module C should change after content root change modification count is ${moduleCWithTracker.modificationCount}", - moduleCWithTracker.changed() - ) - } - - fun testThatNonPhysicalFileChangeNotCausingBOOM() { - val moduleA = createModuleInTmpDir("a") { - listOf( - FileWithText("main.kt", "fun main() {}") - ) - } - val moduleB = createModuleInTmpDir("b") - - val moduleAWithTracker = ModuleWithModificationTracker(moduleA) - val moduleBWithTracker = ModuleWithModificationTracker(moduleB) - - - val projectWithModificationTracker = ProjectWithModificationTracker(project) - - runWriteAction { - val nonPhysicalPsi = KtPsiFactory(moduleA.project).createFile("nonPhysical", "val a = c") - nonPhysicalPsi.add(KtPsiFactory(moduleA.project).createFunction("fun x(){}")) - } - - Assert.assertFalse( - "Out of block modification count for module A should not change after non physical file change, modification count is ${moduleAWithTracker.modificationCount}", - moduleAWithTracker.changed() - ) - Assert.assertFalse( - "Out of block modification count for module B should not change after non physical file change, modification count is ${moduleBWithTracker.modificationCount}", - moduleBWithTracker.changed() - ) - - Assert.assertFalse( - "Out of block modification count for project should not change after non physical file change, modification count is ${projectWithModificationTracker.modificationCount}", - projectWithModificationTracker.changed() - ) - } - - private fun Module.typeInFunctionBody(fileName: String, textAfterTyping: String) { - val file = "${sourceRoots.first().url}/$fileName" - val virtualFile = VirtualFileManager.getInstance().findFileByUrl(file)!! - val ktFile = PsiManager.getInstance(project).findFile(virtualFile) as KtFile - configureByExistingFile(virtualFile) - - val singleFunction = ktFile.declarations.single() as KtNamedFunction - - editor.caretModel.moveToOffset(singleFunction.bodyExpression!!.textOffset) - type("hello") - PsiDocumentManager.getInstance(project).commitAllDocuments() - Assert.assertEquals(textAfterTyping, ktFile.text) - } - - abstract class WithModificationTracker(private val modificationTracker: ModificationTracker) { - private val initialModificationCount = modificationTracker.modificationCount - val modificationCount: Long get() = modificationTracker.modificationCount - - fun changed(): Boolean = - modificationTracker.modificationCount != initialModificationCount - } - - private class ModuleWithModificationTracker(module: Module) : WithModificationTracker( - module.getMainKtSourceModule()!!.createModuleWithoutDependenciesOutOfBlockModificationTracker(module.project) - ) - - private class ProjectWithModificationTracker(project: Project) : WithModificationTracker( - project.createProjectWideOutOfBlockModificationTracker() - ) -} \ No newline at end of file diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/trackers/ModuleStateTrackerTest.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/trackers/ModuleStateTrackerTest.kt deleted file mode 100644 index aade2124bb9d..000000000000 --- a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/trackers/ModuleStateTrackerTest.kt +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright 2000-2022 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.analysis.providers.trackers - -import com.intellij.openapi.module.Module -import com.intellij.openapi.module.ModuleManager -import com.intellij.testFramework.PsiTestUtil -import org.jetbrains.kotlin.analysis.providers.KotlinModificationTrackerFactory -import org.jetbrains.kotlin.analysis.providers.KtModuleStateTracker -import org.jetbrains.kotlin.idea.base.plugin.artifacts.TestKotlinArtifacts -import org.jetbrains.kotlin.idea.base.projectStructure.getMainKtSourceModule -import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest -import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil -import org.junit.Assert -import java.io.File - -class ModuleStateTrackerTest : AbstractMultiModuleTest() { - override fun isFirPlugin(): Boolean = true - - override fun getTestDataDirectory(): File = error("Should not be called") - - fun testThatModuleModificationTrackedChangedAfterAddingModuleDependency() { - val moduleA = createModuleInTmpDir("a") - val moduleB = createModuleInTmpDir("b") - val moduleC = createModuleInTmpDir("c") - - val moduleAWithTracker = ModuleWithModuleStateTracker(moduleA) - val moduleBWithTracker = ModuleWithModuleStateTracker(moduleB) - val moduleCWithTracker = ModuleWithModuleStateTracker(moduleC) - - moduleA.addDependency(moduleB) - - Assert.assertTrue( - "Root modification count for module A with dependencies added should change, modification count is ${moduleAWithTracker.modificationCount}", - moduleAWithTracker.changed() - ) - Assert.assertFalse( - "Root modification count for module B without dependencies added should not change, modification count is ${moduleBWithTracker.modificationCount}", - moduleBWithTracker.changed() - ) - Assert.assertFalse( - "Root modification count for module C without dependencies added should not change, modification count is ${moduleCWithTracker.modificationCount}", - moduleCWithTracker.changed() - ) - } - - fun testThatModuleModificationTrackedChangedAfterAddingModuleRoots() { - val moduleA = createModuleInTmpDir("a") - val moduleB = createModuleInTmpDir("b") - val moduleC = createModuleInTmpDir("c") - - val moduleAWithTracker = ModuleWithModuleStateTracker(moduleA) - val moduleBWithTracker = ModuleWithModuleStateTracker(moduleB) - val moduleCWithTracker = ModuleWithModuleStateTracker(moduleC) - - moduleA.addContentRoot(createTempDirectory().toPath()) - - Assert.assertTrue( - "Root modification count for module A with dependencies added should change, modification count is ${moduleAWithTracker.modificationCount}", - moduleAWithTracker.changed() - ) - Assert.assertFalse( - "Root modification count for module B without dependencies added should not change, modification count is ${moduleBWithTracker.modificationCount}", - moduleBWithTracker.changed() - ) - Assert.assertFalse( - "Root modification count for module C without dependencies added should not change, modification count is ${moduleCWithTracker.modificationCount}", - moduleCWithTracker.changed() - ) - } - - fun testThatModuleModificationTrackedChangedAfterRemovingModuleRoots() { - val moduleA = createModuleInTmpDir("a") - val moduleB = createModuleInTmpDir("b") - val moduleC = createModuleInTmpDir("c") - - val root = moduleA.addContentRoot(createTempDirectory().toPath()) - - val moduleAWithTracker = ModuleWithModuleStateTracker(moduleA) - val moduleBWithTracker = ModuleWithModuleStateTracker(moduleB) - val moduleCWithTracker = ModuleWithModuleStateTracker(moduleC) - - PsiTestUtil.removeContentEntry(moduleA, root.file!!) - - Assert.assertTrue( - "Root modification count for module A with dependencies added should change, modification count is ${moduleAWithTracker.modificationCount}", - moduleAWithTracker.changed() - ) - Assert.assertFalse( - "Root modification count for module B without dependencies added should not change, modification count is ${moduleBWithTracker.modificationCount}", - moduleBWithTracker.changed() - ) - Assert.assertFalse( - "Root modification count for module C without dependencies added should not change, modification count is ${moduleCWithTracker.modificationCount}", - moduleCWithTracker.changed() - ) - } - - - fun testThatModuleModificationTrackedChangedAfterAddingLibraryDependency() { - val moduleA = createModuleInTmpDir("a") - val moduleB = createModuleInTmpDir("b") - val moduleC = createModuleInTmpDir("c") - - val moduleAWithTracker = ModuleWithModuleStateTracker(moduleA) - val moduleBWithTracker = ModuleWithModuleStateTracker(moduleB) - val moduleCWithTracker = ModuleWithModuleStateTracker(moduleC) - - moduleA.addLibrary(TestKotlinArtifacts.kotlinTestJunit) - - Assert.assertTrue( - "Root modification count for module A with dependencies added should change, modification count is ${moduleAWithTracker.modificationCount}", - moduleAWithTracker.changed() - ) - Assert.assertFalse( - "Root modification count for module B without dependencies added should not change, modification count is ${moduleBWithTracker.modificationCount}", - moduleBWithTracker.changed() - ) - Assert.assertFalse( - "Root modification count for module C without dependencies added should not change, modification count is ${moduleCWithTracker.modificationCount}", - moduleCWithTracker.changed() - ) - } - - - fun testThatModuleModificationTrackedChangedAfterRemovingModuleDependency() { - val moduleA = createModuleInTmpDir("a") - val moduleB = createModuleInTmpDir("b") - val moduleC = createModuleInTmpDir("c") - - moduleA.addDependency(moduleB) - - val moduleAWithTracker = ModuleWithModuleStateTracker(moduleA) - val moduleBWithTracker = ModuleWithModuleStateTracker(moduleB) - val moduleCWithTracker = ModuleWithModuleStateTracker(moduleC) - - moduleA.removeDependency(moduleB) - - Assert.assertTrue( - "Root modification count for module A with dependencies removed should change, modification count is ${moduleAWithTracker.modificationCount}", - moduleAWithTracker.changed() - ) - Assert.assertFalse( - "Root modification count for module B without dependencies removed should not change, modification count is ${moduleBWithTracker.modificationCount}", - moduleBWithTracker.changed() - ) - Assert.assertFalse( - "Root modification count for module C without dependencies removed should not change, modification count is ${moduleCWithTracker.modificationCount}", - moduleCWithTracker.changed() - ) - } - - fun testThatModuleModificationTrackedChangedAfterRemovingLibraryDependency() { - val moduleA = createModuleInTmpDir("a") - val moduleB = createModuleInTmpDir("b") - val moduleC = createModuleInTmpDir("c") - - moduleA.addLibrary(TestKotlinArtifacts.kotlinTestJunit, name = "junit") - - val moduleAWithTracker = ModuleWithModuleStateTracker(moduleA) - val moduleBWithTracker = ModuleWithModuleStateTracker(moduleB) - val moduleCWithTracker = ModuleWithModuleStateTracker(moduleC) - - ConfigLibraryUtil.removeLibrary(moduleA, "junit") - - Assert.assertTrue( - "Root modification count for module A with dependencies removed should change, modification count is ${moduleAWithTracker.modificationCount}", - moduleAWithTracker.changed() - ) - Assert.assertFalse( - "Root modification count for module B without dependencies removed should not change, modification count is ${moduleBWithTracker.modificationCount}", - moduleBWithTracker.changed() - ) - Assert.assertFalse( - "Root modification count for module C without dependencies removed should not change, modification count is ${moduleCWithTracker.modificationCount}", - moduleCWithTracker.changed() - ) - } - - fun testThatModuleIsInvalidatedAfterRemoval() { - val moduleA = createModuleInTmpDir("a") - val moduleB = createModuleInTmpDir("b") - val moduleC = createModuleInTmpDir("c") - - val moduleAWithTracker = ModuleWithModuleStateTracker(moduleA) - val moduleBWithTracker = ModuleWithModuleStateTracker(moduleB) - val moduleCWithTracker = ModuleWithModuleStateTracker(moduleC) - - ModuleManager.getInstance(myProject).disposeModule(moduleA) - - Assert.assertTrue( - "Disposed module A should be invalidated", - moduleAWithTracker.isInvalidated() - ) - Assert.assertFalse( - "not disposed module B should not be invalidated", - moduleBWithTracker.isInvalidated() - ) - Assert.assertFalse( - "not disposed module C should not be invalidated", - moduleCWithTracker.isInvalidated() - ) - } - - - abstract class WithModuleStateTracker(val state: KtModuleStateTracker) { - private val initialModificationCount = state.rootModificationCount - val modificationCount: Long get() = state.rootModificationCount - - fun changed(): Boolean = - modificationCount != initialModificationCount - - fun isInvalidated(): Boolean = !state.isValid - } - - - private class ModuleWithModuleStateTracker(module: Module) : WithModuleStateTracker( - KotlinModificationTrackerFactory.getService(module.project).createModuleStateTracker(module.getMainKtSourceModule()!!) - ) -} \ No newline at end of file diff --git a/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/trackers/ProjectWideOutOfBlockModificationTrackerTest.kt b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/trackers/ProjectWideOutOfBlockModificationTrackerTest.kt new file mode 100644 index 000000000000..da4bc3ba41f1 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/test/org/jetbrains/kotlin/idea/fir/analysis/providers/trackers/ProjectWideOutOfBlockModificationTrackerTest.kt @@ -0,0 +1,46 @@ +// Copyright 2000-2023 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.analysis.providers.trackers + +import com.intellij.openapi.application.runWriteAction +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.ModificationTracker +import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker +import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest +import org.jetbrains.kotlin.psi.KtPsiFactory +import org.junit.Assert +import java.io.File + +class ProjectWideOutOfBlockModificationTrackerTest : AbstractMultiModuleTest() { + override fun getTestDataDirectory(): File = error("Should not be called") + + override fun isFirPlugin(): Boolean = true + + fun `test that the project-wide out-of-block modification tracker remains unchanged after changing a non-physical file`() { + val moduleA = createModuleInTmpDir("a") { + listOf(FileWithText("main.kt", "fun main() {}")) + } + + val projectModificationCountChecker = createModificationCountChecker(myProject) + + runWriteAction { + val nonPhysicalPsi = KtPsiFactory(moduleA.project).createFile("nonPhysical", "val a = c") + nonPhysicalPsi.add(KtPsiFactory(moduleA.project).createFunction("fun x(){}")) + } + + Assert.assertFalse( + "Out-of-block modification count for the project should not change after a non-physical file change, modification count is ${projectModificationCountChecker.modificationCount}", + projectModificationCountChecker.hasChanged() + ) + } + + private fun createModificationCountChecker(project: Project): ProjectOutOfBlockModificationCountChecker = + ProjectOutOfBlockModificationCountChecker(project.createProjectWideOutOfBlockModificationTracker()) + + class ProjectOutOfBlockModificationCountChecker(private val modificationTracker: ModificationTracker) { + private val initialModificationCount = modificationTracker.modificationCount + + val modificationCount: Long get() = modificationTracker.modificationCount + + fun hasChanged(): Boolean = modificationTracker.modificationCount != initialModificationCount + } +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/binaryTree/structure.json b/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/binaryTree/structure.json new file mode 100644 index 000000000000..b7c7a431deb5 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/binaryTree/structure.json @@ -0,0 +1,56 @@ +{ + "libraries": [ + { "name": "L1" } + ], + "modules" : [ + { "name": "A", "dependsOn": ["B", "C"] }, + { "name": "B", "dependsOn": ["D", "E"] }, + { "name": "C", "dependsOn": ["F", "G"] }, + { "name": "D", "dependsOn": [] }, + { "name": "E", "dependsOn": [] }, + { "name": "F", "dependsOn": ["L1"] }, + { "name": "G", "dependsOn": [] } + ], + "targets": [ + { + "library": "L1", + "directDependents": ["F"], + "transitiveDependents": ["F", "C", "A"] + }, + { + "module": "A", + "directDependents": [], + "transitiveDependents": [] + }, + { + "module": "B", + "directDependents": ["A"], + "transitiveDependents": ["A"] + }, + { + "module": "C", + "directDependents": ["A"], + "transitiveDependents": ["A"] + }, + { + "module": "D", + "directDependents": ["B"], + "transitiveDependents": ["B", "A"] + }, + { + "module": "E", + "directDependents": ["B"], + "transitiveDependents": ["B", "A"] + }, + { + "module": "F", + "directDependents": ["C"], + "transitiveDependents": ["C", "A"] + }, + { + "module": "G", + "directDependents": ["C"], + "transitiveDependents": ["C", "A"] + } + ] +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/cyclical/structure.json b/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/cyclical/structure.json new file mode 100644 index 000000000000..b15f0aaa0636 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/cyclical/structure.json @@ -0,0 +1,32 @@ +{ + "libraries": [ + { "name": "L1" } + ], + "modules" : [ + { "name": "A", "dependsOn": ["B"] }, + { "name": "B", "dependsOn": ["C", "L1"] }, + { "name": "C", "dependsOn": ["A"] } + ], + "targets": [ + { + "library": "L1", + "directDependents": ["B"], + "transitiveDependents": ["A", "B", "C"] + }, + { + "module": "A", + "directDependents": ["C"], + "transitiveDependents": ["B", "C"] + }, + { + "module": "B", + "directDependents": ["A"], + "transitiveDependents": ["A", "C"] + }, + { + "module": "C", + "directDependents": ["B"], + "transitiveDependents": ["A", "B"] + } + ] +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/cyclicalSelf/structure.json b/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/cyclicalSelf/structure.json new file mode 100644 index 000000000000..a81121242a80 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/cyclicalSelf/structure.json @@ -0,0 +1,18 @@ +{ + "modules" : [ + { "name": "A", "dependsOn": ["A"] }, + { "name": "B", "dependsOn": ["A"] } + ], + "targets": [ + { + "module": "A", + "directDependents": ["B"], + "transitiveDependents": ["B"] + }, + { + "module": "B", + "directDependents": [], + "transitiveDependents": [] + } + ] +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/cyclicalWithOutsideDependency/structure.json b/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/cyclicalWithOutsideDependency/structure.json new file mode 100644 index 000000000000..17a33b09ae2f --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/cyclicalWithOutsideDependency/structure.json @@ -0,0 +1,30 @@ +{ + "modules" : [ + { "name": "A", "dependsOn": ["B"] }, + { "name": "B", "dependsOn": ["C", "O"] }, + { "name": "C", "dependsOn": ["A"] }, + { "name": "O", "dependsOn": [] } + ], + "targets": [ + { + "module": "A", + "directDependents": ["C"], + "transitiveDependents": ["B", "C"] + }, + { + "module": "B", + "directDependents": ["A"], + "transitiveDependents": ["A", "C"] + }, + { + "module": "C", + "directDependents": ["B"], + "transitiveDependents": ["A", "B"] + }, + { + "module": "O", + "directDependents": ["B"], + "transitiveDependents": ["A", "B", "C"] + } + ] +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/deduplicatedLibraries/description.md b/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/deduplicatedLibraries/description.md new file mode 100644 index 000000000000..51f11cd9b074 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/deduplicatedLibraries/description.md @@ -0,0 +1,7 @@ +Different libraries with the same roots are deduplicated by `LibraryInfoCache` into the same `LibraryInfo`. As explained in `LibraryInfo`'s +documentation, a library info and by extension a `KtLibraryModule` should be considered a *collection* of `LibraryEx`s. This test ensures +that `IdeKotlinModuleDependentsProvider` provides the correct dependents for such "collective" `LibraryInfo`s. It is a bit unintuitive that +`L1` and `L2` have the same dependents, but it's the correct result when viewing `LibraryInfo`s as a collection. + +Furthermore, the test ensures that another library `L3` with partially matching roots is not considered in the calculation of the dependents +of `L1` and `L2`. diff --git a/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/deduplicatedLibraries/structure.json b/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/deduplicatedLibraries/structure.json new file mode 100644 index 000000000000..73110e49b670 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/deduplicatedLibraries/structure.json @@ -0,0 +1,29 @@ +{ + "libraries": [ + { "name": "L1", "roots": ["R1", "R2"] }, + { "name": "L2", "roots": ["R1", "R2"] }, + { "name": "L3", "roots": ["R1", "R3"] } + ], + "modules": [ + { "name": "A", "dependsOn": ["L1", "L3"] }, + { "name": "B", "dependsOn": ["L2"] }, + { "name": "C", "dependsOn": ["L3"] } + ], + "targets": [ + { + "library": "L1", + "directDependents": ["A", "B"], + "transitiveDependents": ["A", "B"] + }, + { + "library": "L2", + "directDependents": ["A", "B"], + "transitiveDependents": ["A", "B"] + }, + { + "library": "L3", + "directDependents": ["A", "C"], + "transitiveDependents": ["A", "C"] + } + ] +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/linear/structure.json b/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/linear/structure.json new file mode 100644 index 000000000000..8852ef6dab3d --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/linear/structure.json @@ -0,0 +1,44 @@ +{ + "libraries": [ + { "name": "L1" } + ], + "modules" : [ + { "name": "A", "dependsOn": ["B"] }, + { "name": "B", "dependsOn": ["C"] }, + { "name": "C", "dependsOn": ["D"] }, + { "name": "D", "dependsOn": ["E"] }, + { "name": "E", "dependsOn": ["L1"] } + ], + "targets": [ + { + "library": "L1", + "directDependents": ["E"], + "transitiveDependents": ["E", "D", "C", "B", "A"] + }, + { + "module": "A", + "directDependents": [], + "transitiveDependents": [] + }, + { + "module": "B", + "directDependents": ["A"], + "transitiveDependents": ["A"] + }, + { + "module": "C", + "directDependents": ["B"], + "transitiveDependents": ["B", "A"] + }, + { + "module": "D", + "directDependents": ["C"], + "transitiveDependents": ["C", "B", "A"] + }, + { + "module": "E", + "directDependents": ["D"], + "transitiveDependents": ["D", "C", "B", "A"] + } + ] +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/rhombus/structure.json b/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/rhombus/structure.json new file mode 100644 index 000000000000..214efc4cc715 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/rhombus/structure.json @@ -0,0 +1,44 @@ +{ + "libraries": [ + { "name": "L1" }, + { "name": "L2" } + ], + "modules" : [ + { "name": "A", "dependsOn": ["B", "C"] }, + { "name": "B", "dependsOn": ["D"] }, + { "name": "C", "dependsOn": ["D", "L2"] }, + { "name": "D", "dependsOn": ["L1"] } + ], + "targets": [ + { + "library": "L1", + "directDependents": ["D"], + "transitiveDependents": ["A", "B", "C", "D"] + }, + { + "library": "L2", + "directDependents": ["C"], + "transitiveDependents": ["A", "C"] + }, + { + "module": "A", + "directDependents": [], + "transitiveDependents": [] + }, + { + "module": "B", + "directDependents": ["A"], + "transitiveDependents": ["A"] + }, + { + "module": "C", + "directDependents": ["A"], + "transitiveDependents": ["A"] + }, + { + "module": "D", + "directDependents": ["B", "C"], + "transitiveDependents": ["A", "B", "C"] + } + ] +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/singleRoot/structure.json b/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/singleRoot/structure.json new file mode 100644 index 000000000000..2b7551714695 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/testData/moduleDependents/singleRoot/structure.json @@ -0,0 +1,74 @@ +{ + "libraries": [ + { "name": "L1" }, + { "name": "L2" } + ], + "modules" : [ + { "name": "A", "dependsOn": ["B", "C", "H"] }, + { "name": "B", "dependsOn": ["D", "E"] }, + { "name": "C", "dependsOn": ["F", "G"] }, + { "name": "D", "dependsOn": ["L1"] }, + { "name": "E", "dependsOn": ["L1"] }, + { "name": "F", "dependsOn": ["L2"] }, + { "name": "G", "dependsOn": ["L2"] }, + { "name": "H", "dependsOn": ["I"] }, + { "name": "I", "dependsOn": ["L1"] } + ], + "targets": [ + { + "library": "L1", + "directDependents": ["D", "E", "I"], + "transitiveDependents": ["D", "E", "I", "H", "B", "A"] + }, + { + "library": "L2", + "directDependents": ["F", "G"], + "transitiveDependents": ["F", "G", "C", "A"] + }, + { + "module": "A", + "directDependents": [], + "transitiveDependents": [] + }, + { + "module": "B", + "directDependents": ["A"], + "transitiveDependents": ["A"] + }, + { + "module": "C", + "directDependents": ["A"], + "transitiveDependents": ["A"] + }, + { + "module": "D", + "directDependents": ["B"], + "transitiveDependents": ["B", "A"] + }, + { + "module": "E", + "directDependents": ["B"], + "transitiveDependents": ["B", "A"] + }, + { + "module": "F", + "directDependents": ["C"], + "transitiveDependents": ["C", "A"] + }, + { + "module": "G", + "directDependents": ["C"], + "transitiveDependents": ["C", "A"] + }, + { + "module": "H", + "directDependents": ["A"], + "transitiveDependents": ["A"] + }, + { + "module": "I", + "directDependents": ["H"], + "transitiveDependents": ["H", "A"] + } + ] +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/testData/sessionInvalidation/cyclical/structure.json b/plugins/kotlin/base/fir/analysis-api-providers/testData/sessionInvalidation/cyclical/structure.json new file mode 100644 index 000000000000..3d89bf5bb593 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/testData/sessionInvalidation/cyclical/structure.json @@ -0,0 +1,10 @@ +{ + "modules" : [ + { "name": "A", "dependsOn": ["B"] }, + { "name": "B", "dependsOn": ["C"] }, + { "name": "C", "dependsOn": ["A"] } + ], + "rootModule": "A", + "modulesToMakeOOBM": ["C"], + "expectedInvalidatedModules": ["A", "B", "C"] +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/testData/sessionInvalidation/cyclicalWithOutsideDependency/structure.json b/plugins/kotlin/base/fir/analysis-api-providers/testData/sessionInvalidation/cyclicalWithOutsideDependency/structure.json new file mode 100644 index 000000000000..1297a653ad61 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/testData/sessionInvalidation/cyclicalWithOutsideDependency/structure.json @@ -0,0 +1,11 @@ +{ + "modules" : [ + { "name": "A", "dependsOn": ["B"] }, + { "name": "B", "dependsOn": ["C", "O"] }, + { "name": "C", "dependsOn": ["A"] }, + { "name": "O", "dependsOn": [] } + ], + "rootModule": "A", + "modulesToMakeOOBM": ["O"], + "expectedInvalidatedModules": ["A", "B", "C", "O"] +} diff --git a/plugins/kotlin/base/fir/analysis-api-providers/testData/sessionInvalidation/linearWithCyclicalDependency/structure.json b/plugins/kotlin/base/fir/analysis-api-providers/testData/sessionInvalidation/linearWithCyclicalDependency/structure.json new file mode 100644 index 000000000000..04a8f4747515 --- /dev/null +++ b/plugins/kotlin/base/fir/analysis-api-providers/testData/sessionInvalidation/linearWithCyclicalDependency/structure.json @@ -0,0 +1,12 @@ +{ + "modules" : [ + { "name": "A", "dependsOn": ["B"] }, + { "name": "B", "dependsOn": ["C1"] }, + { "name": "C1", "dependsOn": ["C2"] }, + { "name": "C2", "dependsOn": ["C3"] }, + { "name": "C3", "dependsOn": ["C1"] } + ], + "rootModule": "A", + "modulesToMakeOOBM": ["B"], + "expectedInvalidatedModules": ["A", "B"] +} diff --git a/plugins/kotlin/base/fir/code-insight/kotlin.base.fir.code-insight.iml b/plugins/kotlin/base/fir/code-insight/kotlin.base.fir.code-insight.iml index d4cfa662ff03..cc5314a1ba1b 100644 --- a/plugins/kotlin/base/fir/code-insight/kotlin.base.fir.code-insight.iml +++ b/plugins/kotlin/base/fir/code-insight/kotlin.base.fir.code-insight.iml @@ -26,7 +26,10 @@ + + + @@ -34,6 +37,7 @@ + diff --git a/plugins/kotlin/base/fir/code-insight/src/org/jetbrains/kotlin/idea/base/fir/codeInsight/compiler/K2KotlinCompilerIdeAllowedErrorFilter.kt b/plugins/kotlin/base/fir/code-insight/src/org/jetbrains/kotlin/idea/base/fir/codeInsight/compiler/K2KotlinCompilerIdeAllowedErrorFilter.kt new file mode 100644 index 000000000000..49237ca0021d --- /dev/null +++ b/plugins/kotlin/base/fir/code-insight/src/org/jetbrains/kotlin/idea/base/fir/codeInsight/compiler/K2KotlinCompilerIdeAllowedErrorFilter.kt @@ -0,0 +1,30 @@ +// Copyright 2000-2023 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.fir.codeInsight.compiler + +import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnostic +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.idea.base.codeInsight.compiler.KotlinCompilerIdeAllowedErrorFilter + +class K2KotlinCompilerIdeAllowedErrorFilter : KotlinCompilerIdeAllowedErrorFilter { + private companion object { + val ALLOWED_ERRORS = listOf( + FirErrors.INVISIBLE_REFERENCE, + FirErrors.INVISIBLE_SETTER, + FirErrors.DEPRECATION_ERROR, + FirErrors.DIVISION_BY_ZERO, + FirErrors.OPT_IN_USAGE_ERROR, + FirErrors.OPT_IN_OVERRIDE_ERROR, + FirErrors.UNSAFE_CALL, + FirErrors.UNSAFE_IMPLICIT_INVOKE_CALL, + FirErrors.UNSAFE_INFIX_CALL, + FirErrors.UNSAFE_OPERATOR_CALL, + FirErrors.ITERATOR_ON_NULLABLE, + FirErrors.UNEXPECTED_SAFE_CALL, + FirErrors.DSL_SCOPE_VIOLATION, + ).map { it.name } + } + + override fun invoke(diagnostic: KtDiagnostic): Boolean { + return diagnostic.factoryName in ALLOWED_ERRORS + } +} \ No newline at end of file diff --git a/plugins/kotlin/base/fir/project-structure/kotlin.base.fir.project-structure.iml b/plugins/kotlin/base/fir/project-structure/kotlin.base.fir.project-structure.iml new file mode 100644 index 000000000000..f11ffa14cf47 --- /dev/null +++ b/plugins/kotlin/base/fir/project-structure/kotlin.base.fir.project-structure.iml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/kotlin/base/fir/project-structure/resources/kotlin.base.fir.project-structure.xml b/plugins/kotlin/base/fir/project-structure/resources/kotlin.base.fir.project-structure.xml new file mode 100644 index 000000000000..434401a915ad --- /dev/null +++ b/plugins/kotlin/base/fir/project-structure/resources/kotlin.base.fir.project-structure.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/plugins/kotlin/base/fir/project-structure/src/org/jetbrains/kotlin/idea/base/fir/projectStructure/FirOrderedWorkspaceModelChangeListener.kt b/plugins/kotlin/base/fir/project-structure/src/org/jetbrains/kotlin/idea/base/fir/projectStructure/FirOrderedWorkspaceModelChangeListener.kt new file mode 100644 index 000000000000..5372b881b02c --- /dev/null +++ b/plugins/kotlin/base/fir/project-structure/src/org/jetbrains/kotlin/idea/base/fir/projectStructure/FirOrderedWorkspaceModelChangeListener.kt @@ -0,0 +1,37 @@ +// Copyright 2000-2023 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.fir.projectStructure + +import com.intellij.openapi.components.serviceIfCreated +import com.intellij.openapi.project.Project +import com.intellij.platform.backend.workspace.WorkspaceModelChangeListener +import com.intellij.platform.workspace.storage.VersionedStorageChange +import org.jetbrains.kotlin.idea.base.analysisApiProviders.KotlinModuleStateModificationService +import org.jetbrains.kotlin.idea.base.projectStructure.LibraryInfoCache + +/** + * [FirOrderedWorkspaceModelChangeListener] delegates to other components which process workspace model change events in a pre-defined + * order. + */ +internal class FirOrderedWorkspaceModelChangeListener(private val project: Project) : WorkspaceModelChangeListener { + override fun beforeChanged(event: VersionedStorageChange) { + KotlinModuleStateModificationService.getInstance(project).beforeWorkspaceModelChanged(event) + + // `LibraryInfoCache` is ordered last so that other listeners can still access `LibraryInfo`s before they might be invalidated in + // the context of the current event. If `LibraryInfoCache`'s invalidation was ordered first, the following hypothetical situation + // might occur: + // + // 1. A root is added to some library `L` and `FirOrderedWorkspaceModelChangeListener.beforeChanged` is called. + // 2. `LibraryInfoCache` receives the "before change" event and removes the library info for `L` from its cache. + // 3. `KotlinModuleStateModificationService` processes the same library change event. To publish a module state modification event + // for the `KtModule` of `L`, `KotlinModuleStateModificationService` accesses `LibraryInfoCache` to get `L`'s library infos. + // 4. Because `LibraryInfoCache` has already thrown away the library info for `L`, the cache returns a new `LibraryInfo`. + // 5. `LibraryInfo`s are referentially equal, so `KotlinModuleStateModificationService` publishes a module state modification event + // for a `KtModule` based on a *new* `LibraryInfo`. + // 6. The session invalidation service receives the module state modification event for the `KtModule`, but doesn't invalidate any + // sessions, because the new `LibraryInfo` key doesn't match the old `LibraryInfo` key still used in session hash maps. + // + // In the worst case, this will cause session invalidation to skip invalidation for all dependent modules as well, because it might + // think that `L` has already been invalidated. + project.serviceIfCreated()?.beforeWorkspaceModelChanged(event) + } +} diff --git a/plugins/kotlin/base/platforms/src/org/jetbrains/kotlin/idea/base/platforms/KotlinJavaScriptStdlibDetectorFacility.kt b/plugins/kotlin/base/platforms/src/org/jetbrains/kotlin/idea/base/platforms/KotlinJavaScriptStdlibDetectorFacility.kt index d1d5ee90da12..6eea2d0db29e 100644 --- a/plugins/kotlin/base/platforms/src/org/jetbrains/kotlin/idea/base/platforms/KotlinJavaScriptStdlibDetectorFacility.kt +++ b/plugins/kotlin/base/platforms/src/org/jetbrains/kotlin/idea/base/platforms/KotlinJavaScriptStdlibDetectorFacility.kt @@ -11,10 +11,12 @@ import org.jetbrains.kotlin.idea.base.plugin.artifacts.KotlinArtifactNames import org.jetbrains.kotlin.utils.LibraryUtils import org.jetbrains.kotlin.utils.PathUtil import java.io.File +import java.util.regex.Pattern @ApiStatus.Internal object KotlinJavaScriptStdlibDetectorFacility : StdlibDetectorFacility() { private val IS_JS_LIBRARY_STD_LIB = Key.create("IS_JS_LIBRARY_STD_LIB") + private val KOTLIN_JS_LIBRARY_KLIB_PATTERN = Pattern.compile("kotlin-stdlib-js.*\\.klib") override val supportedLibraryKind: KotlinLibraryKind get() = KotlinJavaScriptLibraryKind @@ -28,11 +30,13 @@ object KotlinJavaScriptStdlibDetectorFacility : StdlibDetectorFacility() { || name == "kotlin-jslib.jar" // Outdated JS stdlib name || PathUtil.KOTLIN_STDLIB_JS_JAR_PATTERN.matcher(name).matches() || PathUtil.KOTLIN_JS_LIBRARY_JAR_PATTERN.matcher(name).matches() + || KOTLIN_JS_LIBRARY_KLIB_PATTERN.matcher(name).matches() ) { val jar = VfsUtilCore.getVirtualFileForJar(root) ?: continue var isJSStdLib = jar.getUserData(IS_JS_LIBRARY_STD_LIB) if (isJSStdLib == null) { - isJSStdLib = LibraryUtils.isKotlinJavascriptStdLibrary(File(jar.path)) + isJSStdLib = KOTLIN_JS_LIBRARY_KLIB_PATTERN.matcher(name).matches() + || LibraryUtils.isKotlinJavascriptStdLibrary(File(jar.path)) jar.putUserData(IS_JS_LIBRARY_STD_LIB, isJSStdLib) } diff --git a/plugins/kotlin/base/plugin/src/org/jetbrains/kotlin/idea/base/plugin/artifacts/KotlinArtifactNames.kt b/plugins/kotlin/base/plugin/src/org/jetbrains/kotlin/idea/base/plugin/artifacts/KotlinArtifactNames.kt index f268d4b86718..c6798fa0fa99 100644 --- a/plugins/kotlin/base/plugin/src/org/jetbrains/kotlin/idea/base/plugin/artifacts/KotlinArtifactNames.kt +++ b/plugins/kotlin/base/plugin/src/org/jetbrains/kotlin/idea/base/plugin/artifacts/KotlinArtifactNames.kt @@ -13,7 +13,7 @@ object KotlinArtifactNames { const val KOTLIN_STDLIB_JDK8 = "kotlin-stdlib-jdk8.jar" const val KOTLIN_STDLIB_JDK8_SOURCES = "kotlin-stdlib-jdk8-sources.jar" const val KOTLIN_REFLECT = "kotlin-reflect.jar" - const val KOTLIN_STDLIB_JS = "kotlin-stdlib-js.jar" + const val KOTLIN_STDLIB_JS = "kotlin-stdlib-js.klib" const val KOTLIN_TEST = "kotlin-test.jar" const val KOTLIN_TEST_JUNIT = "kotlin-test-junit.jar" const val KOTLIN_TEST_JS = "kotlin-test-js.jar" diff --git a/plugins/kotlin/base/plugin/test/org/jetbrains/kotlin/idea/artifacts/TestKotlinArtifacts.kt b/plugins/kotlin/base/plugin/test/org/jetbrains/kotlin/idea/artifacts/TestKotlinArtifacts.kt index 9913c0c89e3c..00c02b6ca9bb 100644 --- a/plugins/kotlin/base/plugin/test/org/jetbrains/kotlin/idea/artifacts/TestKotlinArtifacts.kt +++ b/plugins/kotlin/base/plugin/test/org/jetbrains/kotlin/idea/artifacts/TestKotlinArtifacts.kt @@ -57,7 +57,13 @@ object TestKotlinArtifacts { @JvmStatic val kotlinStdlibJdk7Sources: File by lazy { getSourcesJar("kotlin-stdlib-jdk7") } @JvmStatic val kotlinStdlibJdk8: File by lazy { getJar("kotlin-stdlib-jdk8") } @JvmStatic val kotlinStdlibJdk8Sources: File by lazy { getSourcesJar("kotlin-stdlib-jdk8") } - @JvmStatic val kotlinStdlibJs: File by lazy { getJar("kotlin-stdlib-js") } + @JvmStatic val kotlinStdlibJs: File by lazy { + downloadOrReportUnavailability( + "kotlin-stdlib-js", + KotlinMavenUtils.findLibraryVersion(kotlincStdlibFileName), + ".klib" + ) + } @JvmStatic val kotlinStdlibWasm: File by lazy { downloadOrReportUnavailability( "kotlin-stdlib-wasm", diff --git a/plugins/kotlin/base/project-structure/kotlin.base.project-structure.iml b/plugins/kotlin/base/project-structure/kotlin.base.project-structure.iml index 17399f405794..129a4ff8b328 100644 --- a/plugins/kotlin/base/project-structure/kotlin.base.project-structure.iml +++ b/plugins/kotlin/base/project-structure/kotlin.base.project-structure.iml @@ -46,5 +46,6 @@ + \ No newline at end of file diff --git a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/IdeKotlinModuleDependentsProvider.kt b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/IdeKotlinModuleDependentsProvider.kt new file mode 100644 index 000000000000..38c62b15ae75 --- /dev/null +++ b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/IdeKotlinModuleDependentsProvider.kt @@ -0,0 +1,138 @@ +// Copyright 2000-2023 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.projectStructure + +import com.github.benmanes.caffeine.cache.Cache +import com.github.benmanes.caffeine.cache.Caffeine +import com.intellij.openapi.components.service +import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.ProjectRootModificationTracker +import com.intellij.platform.backend.workspace.WorkspaceModel +import com.intellij.platform.workspace.jps.entities.ModuleEntity +import com.intellij.platform.workspace.storage.SymbolicEntityId +import com.intellij.platform.workspace.storage.WorkspaceEntityWithSymbolicId +import com.intellij.psi.util.CachedValue +import com.intellij.psi.util.CachedValueProvider +import com.intellij.psi.util.CachedValuesManager +import com.intellij.workspaceModel.ide.impl.legacyBridge.module.findModule +import org.jetbrains.kotlin.analysis.project.structure.KtBuiltinsModule +import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.analysis.project.structure.KtScriptDependencyModule +import org.jetbrains.kotlin.analysis.project.structure.KtScriptModule +import org.jetbrains.kotlin.analysis.project.structure.KtSdkModule +import org.jetbrains.kotlin.analysis.project.structure.impl.KotlinModuleDependentsProviderBase +import org.jetbrains.kotlin.idea.base.projectStructure.libraryToSourceAnalysis.ResolutionAnchorCacheService +import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.LibraryInfo +import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.ModuleProductionSourceInfo +import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.ModuleSourceInfo +import org.jetbrains.kotlin.idea.base.projectStructure.util.getTransitiveLibraryDependencyInfos +import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments +import org.jetbrains.kotlin.utils.addIfNotNull + +/** + * [IdeKotlinModuleDependentsProvider] provides [KtModule] dependents by querying the workspace model and Kotlin plugin indices/caches. + */ +internal class IdeKotlinModuleDependentsProvider(private val project: Project) : KotlinModuleDependentsProviderBase() { + override fun getDirectDependents(module: KtModule): Set { + return when (module) { + is KtSourceModuleByModuleInfo -> getDirectDependentsForSourceModule(module) + is KtLibraryModuleByModuleInfo -> getDirectDependentsForLibraryModule(module) + is KtLibrarySourceModuleByModuleInfo -> getDirectDependents(module.binaryLibrary) + + // No dependents need to be provided for `KtSdkModule` and `KtBuiltinsModule` (see `KotlinModuleDependentsProvider`). + is KtSdkModule -> emptySet() + is KtBuiltinsModule -> emptySet() + + // Script modules are not supported yet (see KTIJ-25620). + is KtScriptModule, is KtScriptDependencyModule -> emptySet() + + is NotUnderContentRootModuleByModuleInfo -> emptySet() + + else -> throw KotlinExceptionWithAttachments("Unexpected ${KtModule::class.simpleName}").withAttachment("module.txt", module) + } + } + + private fun getDirectDependentsForSourceModule(module: KtSourceModuleByModuleInfo): Set = + mutableSetOf().apply { + addFriendDependentsForSourceModule(module) + addWorkspaceModelDependents(module.moduleId) + addAnchorModuleDependents(module) + } + + private fun MutableSet.addFriendDependentsForSourceModule(module: KtSourceModuleByModuleInfo) { + // The only friend dependency that currently exists in the IDE is the dependency of an IDEA module's test sources on its production + // sources. Hence, a test source `KtModule` is a direct dependent of its production source `KtModule`. + if (module.ideaModuleInfo is ModuleProductionSourceInfo) { + addIfNotNull(module.ideaModule.testSourceInfo?.toKtModule()) + } + } + + private fun MutableSet.addAnchorModuleDependents(module: KtSourceModuleByModuleInfo) { + val moduleInfo = module.ideaModuleInfo as? ModuleSourceInfo ?: return + + // If `module` is an anchor module, it has library dependents in the form of anchoring libraries. See + // `ResolutionAnchorCacheService` for additional documentation. + val anchoringLibraries = ResolutionAnchorCacheService.getInstance(project).librariesForResolutionAnchors[moduleInfo] ?: return + + // Because dependency relationships between libraries aren't supported by the project model (as noted in + // `ResolutionAnchorCacheService`), library dependencies are approximated by the following relationship: If a module `M1` depends on + // two libraries `L1` and `L2`, `L1` depends on `L2` and `L2` depends on `L1` (`L1 <--> L2`). This does not apply without + // restriction for multi-platform projects. However, anchor module usage is strictly limited to the `intellij` project, which is not + // a multi-platform project. Because the approximate library dependencies are bidirectional, library dependencies are also library + // dependents, and we can simply use `getTransitiveLibraryDependencyInfos`. + // + // Because anchor modules are rare and `getTransitiveDependents` already caches dependents as a whole, there is currently no need to + // cache these transitive library dependencies. + LibraryDependenciesCache.getInstance(project) + .getTransitiveLibraryDependencyInfos(anchoringLibraries) + .forEach { libraryInfo -> + add(libraryInfo.toKtModule()) + add(libraryInfo.sourcesModuleInfo.toKtModule()) + } + } + + private fun getDirectDependentsForLibraryModule(module: KtLibraryModuleByModuleInfo): Set = + project.service() + .getDependentModules(module.libraryInfo) + .mapNotNullTo(mutableSetOf()) { it.productionOrTestSourceModuleInfo?.toKtModule() } + + private fun MutableSet.addWorkspaceModelDependents(symbolicId: SymbolicEntityId) { + val snapshot = WorkspaceModel.getInstance(project).currentSnapshot + snapshot + .referrers(symbolicId, ModuleEntity::class.java) + .forEach { moduleEntity -> + // The set of dependents should not include `module` itself. + if (moduleEntity.symbolicId == symbolicId) return@forEach + + // We can skip the module entity if `findModule` returns `null` because the module won't have been added to the project + // model yet and thus cannot be a proper `KtModule`. If there is a production source `KtModule`, we only need to add that + // because the test source `KtModule` will be a direct friend dependent of the production source `KtModule`. + addIfNotNull(moduleEntity.findModule(snapshot)?.productionOrTestSourceModuleInfo?.toKtModule()) + } + } + + /** + * Caching transitive dependents is crucial. [getTransitiveDependents] will frequently be called by session invalidation when typing in + * a Kotlin file. Large projects might have core modules with over a hundred or even a thousand transitive dependents. At the same time, + * we can keep the size of this cache small, because transitive dependents will usually only be requested for a single module (e.g. the + * module to be invalidated after an out-of-block modification). + * + * The timing of invalidation is important, since the [IdeKotlinModuleDependentsProvider] may be used in workspace model listeners when + * project structure changes. Using a *before change* workspace model listener is not an option, because we'd have to guarantee that + * this listener is placed after all other listeners which might use `IdeKotlinModuleDependentsProvider`. It's not entirely impossible + * due to the existence of `Fe10/FirOrderedWorkspaceModelChangeListener`, but a simpler solution such as the project root modification + * tracker, which is incremented after *before change* events have been handled, seems preferable. + */ + private val transitiveDependentsCache: CachedValue>> = CachedValuesManager.getManager(project).createCachedValue { + CachedValueProvider.Result.create( + Caffeine.newBuilder().maximumSize(100).build(), + ProjectRootModificationTracker.getInstance(project), + ) + } + + override fun getTransitiveDependents(module: KtModule): Set = + transitiveDependentsCache.value.get(module) { + // The computation does not reuse sub-results that may already have been cached because transitive dependents are usually only + // computed for select modules, so the performance impact of this computation is expected to be negligible. + computeTransitiveDependents(it) + } +} diff --git a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/KotlinProjectStructureUtils.kt b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/KotlinProjectStructureUtils.kt index f0b2a340afe2..0546dc5f3130 100644 --- a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/KotlinProjectStructureUtils.kt +++ b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/KotlinProjectStructureUtils.kt @@ -12,6 +12,8 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.project.rootManager import com.intellij.openapi.roots.FileIndex import com.intellij.openapi.roots.ProjectFileIndex +import com.intellij.openapi.roots.impl.libraries.LibraryEx +import com.intellij.openapi.roots.libraries.Library import com.intellij.openapi.util.Key import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.JavaPsiFacade @@ -90,10 +92,20 @@ fun Module.asSourceInfo(sourceRootType: KotlinSourceRootType?): ModuleSourceInfo val Module.sourceModuleInfos: List get() = listOfNotNull(testSourceInfo, productionSourceInfo) +val Module.productionOrTestSourceModuleInfo: ModuleSourceInfo? + get() = productionSourceInfo ?: testSourceInfo + private fun Module.hasRootsOfType(rootTypes: Set>): Boolean { return rootManager.contentEntries.any { it.getSourceFolders(rootTypes).isNotEmpty() } } +fun Library.getBinaryAndSourceModuleInfos(project: Project): List = buildList { + LibraryInfoCache.getInstance(project)[this@getBinaryAndSourceModuleInfos].forEach { libraryInfo -> + add(libraryInfo) + add(libraryInfo.sourcesModuleInfo) + } +} + /** * [forcedModuleInfo] provides a [ModuleInfo] instance for a dummy file. It must not be changed after the first assignment because * [ModuleInfoProvider] might cache the module info. diff --git a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/LibraryInfoCache.kt b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/LibraryInfoCache.kt index 0c26bf45ceeb..70cd4cfc71bc 100644 --- a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/LibraryInfoCache.kt +++ b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/LibraryInfoCache.kt @@ -11,8 +11,6 @@ import com.intellij.openapi.roots.libraries.Library import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.ModificationTracker import com.intellij.openapi.util.SimpleModificationTracker -import com.intellij.platform.backend.workspace.WorkspaceModelChangeListener -import com.intellij.platform.backend.workspace.WorkspaceModelTopics import com.intellij.platform.workspace.jps.entities.LibraryEntity import com.intellij.platform.workspace.jps.entities.ModuleDependencyItem import com.intellij.platform.workspace.jps.entities.ModuleEntity @@ -56,9 +54,15 @@ class LibraryInfoCache(project: Project) : Disposable { initialize() } - override fun subscribe() { - project.messageBus.connect(this).subscribe(WorkspaceModelTopics.CHANGED, ModelChangeListener(project)) - } + // Due to ordering issues with other workspace model listeners that access `LibraryInfoCache`, workspace model changes for + // `LibraryInfoCache` are listened to via `FirOrderedWorkspaceModelChangeListener` and `FE10IdeOrderedWorkspaceModelChangeListener`. + // Note that, even if the order was insignificant, `LibraryInfoCache`'s workspace model listener would still need to be registered + // eagerly. The reason is that some other workspace model listener might access `LibraryInfoCache` and cause first-time + // initialization (including a call to `subscribe`). Subscribing to workspace model events while a workspace model event is being + // processed means that that event won't be propagated to the new subscription. Hence, for exactly that event, `LibraryInfoCache` + // would not be cleared, as its workspace model listener wouldn't be called. This can lead to cache inconsistency if a cache entry + // containing a changing library was added during that event by some other workspace listener. + override fun subscribe() { } override fun doInvalidate(cache: MutableMap>) { super.doInvalidate(cache) @@ -312,45 +316,43 @@ class LibraryInfoCache(project: Project) : Disposable { JvmPlatforms.defaultJvmPlatform } - inner class ModelChangeListener(project: Project) : WorkspaceModelChangeListener { - override fun beforeChanged(event: VersionedStorageChange) { - val storageBefore = event.storageBefore - val libraryChanges = event.getChanges(LibraryEntity::class.java) - val moduleChanges = event.getChanges(ModuleEntity::class.java) + fun beforeWorkspaceModelChanged(event: VersionedStorageChange) { + val storageBefore = event.storageBefore + val libraryChanges = event.getChanges(LibraryEntity::class.java) + val moduleChanges = event.getChanges(ModuleEntity::class.java) - if (libraryChanges.none() && moduleChanges.none()) return + if (libraryChanges.none() && moduleChanges.none()) return - val outdatedLibraries: MutableList = libraryChanges - .mapNotNull { it.oldEntity?.findLibraryBridge(storageBefore) } - .toMutableList() + val outdatedLibraries: MutableList = libraryChanges + .mapNotNull { it.oldEntity?.findLibraryBridge(storageBefore) } + .toMutableList() - val oldLibDependencies = moduleChanges.mapNotNull { - it.oldEntity?.dependencies?.filterIsInstance() - }.flatten().associateBy { it.library } + val oldLibDependencies = moduleChanges.mapNotNull { + it.oldEntity?.dependencies?.filterIsInstance() + }.flatten().associateBy { it.library } - val newLibDependencies = moduleChanges.mapNotNull { - it.newEntity?.dependencies?.filterIsInstance() - }.flatten().associateBy { it.library } + val newLibDependencies = moduleChanges.mapNotNull { + it.newEntity?.dependencies?.filterIsInstance() + }.flatten().associateBy { it.library } - for (entry in oldLibDependencies.entries) { - val value = entry.value - if (value != newLibDependencies[entry.key]) { - val libraryBridge = value.library.findLibraryBridge(storageBefore, project) - outdatedLibraries.addIfNotNull(libraryBridge) + for (entry in oldLibDependencies.entries) { + val value = entry.value + if (value != newLibDependencies[entry.key]) { + val libraryBridge = value.library.findLibraryBridge(storageBefore, project) + outdatedLibraries.addIfNotNull(libraryBridge) + } } - } - if (outdatedLibraries.isNotEmpty()) { - val droppedLibraryInfos = - invalidateKeysAndGetOutdatedValues(outdatedLibraries.map { it as LibraryEx }).flattenTo(hashSetOf()) + if (outdatedLibraries.isNotEmpty()) { + val droppedLibraryInfos = + invalidateKeysAndGetOutdatedValues(outdatedLibraries.map { it as LibraryEx }).flattenTo(hashSetOf()) - if (droppedLibraryInfos.isNotEmpty()) { - removedLibraryInfoTracker.incModificationCount() - project.messageBus.syncPublisher(LibraryInfoListener.TOPIC).libraryInfosRemoved(droppedLibraryInfos) + if (droppedLibraryInfos.isNotEmpty()) { + removedLibraryInfoTracker.incModificationCount() + project.messageBus.syncPublisher(LibraryInfoListener.TOPIC).libraryInfosRemoved(droppedLibraryInfos) + } } - } } - } } operator fun get(key: Library): List { @@ -360,6 +362,11 @@ class LibraryInfoCache(project: Project) : Disposable { fun deduplicatedLibrary(key: Library): Library = get(key).first().library + @ApiStatus.Internal + fun beforeWorkspaceModelChanged(event: VersionedStorageChange) { + libraryInfoCache.beforeWorkspaceModelChanged(event) + } + override fun dispose() = Unit fun removedLibraryInfoTracker(): ModificationTracker = libraryInfoCache.removedLibraryInfoTracker diff --git a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/LibraryUsageIndex.kt b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/LibraryUsageIndex.kt new file mode 100644 index 000000000000..a4b5db746e5e --- /dev/null +++ b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/LibraryUsageIndex.kt @@ -0,0 +1,17 @@ +// Copyright 2000-2023 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.projectStructure + +import com.intellij.openapi.module.Module +import com.intellij.openapi.roots.libraries.Library +import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.LibraryInfo + +/** + * For each [LibraryInfo], [LibraryUsageIndex] contains all [Module]s which depend on that library info. The index supports deduplicated + * libraries: if a [LibraryInfo] comprises two [Library] instances with the same roots, [getDependentModules] will return the union of both + * [Library]'s dependents. + * + * The resulting dependents are stable and do not depend on the state of [LibraryInfoCache], as they are computed from the project model. + */ +interface LibraryUsageIndex { + fun getDependentModules(libraryInfo: LibraryInfo): Sequence +} diff --git a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/ModuleInfoProvider.kt b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/ModuleInfoProvider.kt index 8429871dcfef..168d3ff02171 100644 --- a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/ModuleInfoProvider.kt +++ b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/ModuleInfoProvider.kt @@ -155,14 +155,16 @@ class ModuleInfoProvider(private val project: Project) { } } - val virtualFile = containingFile.originalFile.virtualFile - if (virtualFile != null) { - val isLibrarySource = if (containingKtFile != null) isLibrarySource(containingKtFile, config) else false - collectByFile(virtualFile, isLibrarySource) - callExtensions { collectByElement(element, containingFile, virtualFile) } - } else { - val message = "Analyzing element of type ${element::class.java} in non-physical file of type ${containingFile::class.java}" - reportError(KotlinExceptionWithAttachments(message).withAttachment("file.kt", containingFile.text)) + if (containingFile != null) { + val virtualFile = containingFile.originalFile.virtualFile + if (virtualFile != null) { + val isLibrarySource = if (containingKtFile != null) isLibrarySource(containingKtFile, config) else false + collectByFile(virtualFile, isLibrarySource) + callExtensions { collectByElement(element, containingFile, virtualFile) } + } else { + val message = "Analyzing element of type ${element::class.java} in non-physical file of type ${containingFile::class.java}" + reportError(KotlinExceptionWithAttachments(message).withAttachment("file.kt", containingFile.text)) + } } } diff --git a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/ModuleInfoProviderUtils.kt b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/ModuleInfoProviderUtils.kt index e60870aa431c..a01569f331e9 100644 --- a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/ModuleInfoProviderUtils.kt +++ b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/ModuleInfoProviderUtils.kt @@ -34,7 +34,7 @@ private fun cachedModuleInfo(psiFile: PsiFile): IdeaModuleInfo? = CachedValuesMa ModuleInfoProvider.getInstance(project).firstOrNull(psiFile), ProjectRootModificationTracker.getInstance(project), JavaLibraryModificationTracker.getInstance(project), - KotlinModificationTrackerFactory.getService(project).createProjectWideOutOfBlockModificationTracker(), + KotlinModificationTrackerFactory.getInstance(project).createProjectWideOutOfBlockModificationTracker(), ) } diff --git a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/ProjectModuleByModuleInfo.kt b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/ProjectModuleByModuleInfo.kt index d89c685158c1..0ecdb1a2e6e8 100644 --- a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/ProjectModuleByModuleInfo.kt +++ b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/ProjectModuleByModuleInfo.kt @@ -7,12 +7,15 @@ import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.roots.ProjectRootModificationTracker import com.intellij.openapi.util.Key import com.intellij.openapi.vfs.VirtualFile +import com.intellij.platform.workspace.jps.entities.LibraryId +import com.intellij.platform.workspace.jps.entities.ModuleId import com.intellij.psi.PsiFile import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScopes import com.intellij.psi.util.CachedValue import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValuesManager +import com.intellij.workspaceModel.ide.impl.legacyBridge.library.LibraryBridge import org.jetbrains.annotations.ApiStatus import org.jetbrains.kotlin.analysis.project.structure.* import org.jetbrains.kotlin.analyzer.ModuleInfo @@ -71,6 +74,8 @@ open class KtSourceModuleByModuleInfo(private val moduleInfo: ModuleSourceInfo) override val stableModuleName: String? get() = moduleInfo.stableName?.asString() + val moduleId: ModuleId get() = ModuleId(moduleName) + override val directRegularDependencies: List get() = moduleInfo.collectDependencies(ModuleDependencyCollector.CollectionMode.COLLECT_NON_IGNORED) @@ -154,20 +159,20 @@ private object DependencyKeys { val TEST_MODULE_DEPENDENCIES_IGNORED = Key.create>>("TEST_MODULE_DEPENDENCIES_IGNORED") } -internal class KtLibraryModuleByModuleInfo(private val moduleInfo: LibraryInfo) : KtModuleByModuleInfoBase(moduleInfo), KtLibraryModule { +internal class KtLibraryModuleByModuleInfo(val libraryInfo: LibraryInfo) : KtModuleByModuleInfoBase(libraryInfo), KtLibraryModule { override val libraryName: String - get() = moduleInfo.library.name ?: "Unnamed library" + get() = libraryInfo.library.name ?: "Unnamed library" override val librarySources: KtLibrarySourceModule - get() = moduleInfo.sourcesModuleInfo.toKtModuleOfType() + get() = libraryInfo.sourcesModuleInfo.toKtModuleOfType() override fun getBinaryRoots(): Collection { - return moduleInfo.getLibraryRoots().map(Paths::get) + return libraryInfo.getLibraryRoots().map(Paths::get) } override val contentScope: GlobalSearchScope get() = ideaModuleInfo.contentScope - override val project: Project get() = moduleInfo.project + override val project: Project get() = libraryInfo.project } internal class SdkKtModuleByModuleInfo(private val moduleInfo: SdkInfo) : KtModuleByModuleInfoBase(moduleInfo), KtSdkModule { diff --git a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/ProjectStructureProviderIdeImpl.kt b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/ProjectStructureProviderIdeImpl.kt index 848a83d6a62f..81d11c62f8b3 100644 --- a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/ProjectStructureProviderIdeImpl.kt +++ b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/ProjectStructureProviderIdeImpl.kt @@ -67,7 +67,7 @@ private fun cachedKtModule(psiFile: PsiFile): KtModule = CachedValuesManager.get calculateKtModule(psiFile), ProjectRootModificationTracker.getInstance(project), JavaLibraryModificationTracker.getInstance(project), - KotlinModificationTrackerFactory.getService(project).createProjectWideOutOfBlockModificationTracker(), + KotlinModificationTrackerFactory.getInstance(project).createProjectWideOutOfBlockModificationTracker(), ) } diff --git a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/libraryToSourceAnalysis/ResolutionAnchorCacheService.kt b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/libraryToSourceAnalysis/ResolutionAnchorCacheService.kt index 701e2f81c885..bc9b5f8d2b7a 100644 --- a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/libraryToSourceAnalysis/ResolutionAnchorCacheService.kt +++ b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/libraryToSourceAnalysis/ResolutionAnchorCacheService.kt @@ -9,6 +9,8 @@ import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.ModuleSourceIn interface ResolutionAnchorCacheService { val resolutionAnchorsForLibraries: Map + val librariesForResolutionAnchors: Map> + /** * Anchor module is a source module that could replace library. * @@ -29,6 +31,7 @@ interface ResolutionAnchorCacheService { companion object { val Empty = object : ResolutionAnchorCacheService { override val resolutionAnchorsForLibraries: Map get() = emptyMap() + override val librariesForResolutionAnchors: Map> get() = emptyMap() override fun getDependencyResolutionAnchors(libraryInfo: LibraryInfo): Set = emptySet() } diff --git a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/moduleInfo/LibraryInfo.kt b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/moduleInfo/LibraryInfo.kt index df434d3d66d5..d46601a0394e 100644 --- a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/moduleInfo/LibraryInfo.kt +++ b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/moduleInfo/LibraryInfo.kt @@ -22,7 +22,19 @@ import org.jetbrains.kotlin.platform.* import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices /** - * @see [org.jetbrains.kotlin.idea.base.projectStructure.LibraryInfoCache] + * [LibraryInfo] is the Kotlin plugin's view on a [LibraryEx]. + * + * Multiple different [LibraryEx]s with the same content may be mapped to a single [LibraryInfo]. For example, two different module-level + * libraries with the same roots will have the same [LibraryInfo]. Such libraries are called *deduplicated*. The deduplication is performed + * by [LibraryInfoCache]. This avoids keeping multiple, duplicate cache entries for [LibraryEx]s with effectively the same content. + * + * The dependencies and dependents of a [LibraryInfo] are calculated from *all* [LibraryEx]s associated with it. In that sense, a + * [LibraryInfo] is a *collection* of [LibraryEx]s. + * + * @param library The *anchor library* which acts as the content reference for the [LibraryInfo]. It is sometimes used as a cache key in + * deduplication contexts. It is *not* necessarily the only [LibraryEx] associated with this [LibraryInfo]. + * + * @see LibraryInfoCache */ abstract class LibraryInfo internal constructor( override val project: Project, diff --git a/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/util/libraryDependenciesUtil.kt b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/util/libraryDependenciesUtil.kt new file mode 100644 index 000000000000..bc61d8cb6691 --- /dev/null +++ b/plugins/kotlin/base/project-structure/src/org/jetbrains/kotlin/idea/base/projectStructure/util/libraryDependenciesUtil.kt @@ -0,0 +1,32 @@ +// Copyright 2000-2023 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.projectStructure.util + +import org.jetbrains.kotlin.idea.base.projectStructure.LibraryDependenciesCache +import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.LibraryInfo +import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus.checkCanceled + +fun LibraryDependenciesCache.getTransitiveLibraryDependencyInfos(libraryInfo: LibraryInfo): Collection = + getTransitiveLibraryDependencyInfos(getLibraryDependencies(libraryInfo).libraries) + +fun LibraryDependenciesCache.getTransitiveLibraryDependencyInfos(libraryInfos: Collection): Collection = + libraryInfos.closure { libraryDependency -> + checkCanceled() + getLibraryDependencies(libraryDependency).libraries + } + +private fun Collection.closure(f: (T) -> Collection): Collection { + if (isEmpty()) return this + + val result = HashSet(this) + var elementsToCheck = result + var oldSize = 0 + while (result.size > oldSize) { + oldSize = result.size + val toAdd = hashSetOf() + elementsToCheck.forEach { toAdd.addAll(f(it)) } + result.addAll(toAdd) + elementsToCheck = toAdd + } + + return result +} diff --git a/plugins/kotlin/base/psi/kotlin.base.psi.iml b/plugins/kotlin/base/psi/kotlin.base.psi.iml index 67c4cfffb9e9..5c3dd38f7007 100644 --- a/plugins/kotlin/base/psi/kotlin.base.psi.iml +++ b/plugins/kotlin/base/psi/kotlin.base.psi.iml @@ -17,7 +17,6 @@ - \ No newline at end of file diff --git a/plugins/kotlin/base/psi/src/org/jetbrains/kotlin/idea/base/psi/KotlinPsiModificationUtils.kt b/plugins/kotlin/base/psi/src/org/jetbrains/kotlin/idea/base/psi/KotlinPsiModificationUtils.kt index 938ed1b9d70c..3b4fda0c3695 100644 --- a/plugins/kotlin/base/psi/src/org/jetbrains/kotlin/idea/base/psi/KotlinPsiModificationUtils.kt +++ b/plugins/kotlin/base/psi/src/org/jetbrains/kotlin/idea/base/psi/KotlinPsiModificationUtils.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-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. @file:JvmName("KotlinPsiModificationUtils") package org.jetbrains.kotlin.idea.base.psi @@ -118,22 +118,23 @@ fun KtParameter.setDefaultValue(newDefaultValue: KtExpression): PsiElement { return addAfter(newDefaultValue, eq) as KtExpression } +/** + * Moves the lambda argument inside parentheses and replaces it with the specified replacement expression. + * + * @param replacement The replacement expression to be used. + * @param lambdaArgumentName The name of the lambda argument; use `null` if no name is needed. + * @return The modified `KtCallExpression` with the lambda argument moved inside parentheses and replaced with + * the specified replacement expression. + */ fun KtLambdaArgument.moveInsideParenthesesAndReplaceWith( replacement: KtExpression, - functionLiteralArgumentName: Name?, - withNameCheck: Boolean = true, + lambdaArgumentName: Name?, ): KtCallExpression { val oldCallExpression = parent as KtCallExpression val newCallExpression = oldCallExpression.copy() as KtCallExpression val psiFactory = KtPsiFactory(project) - - val argument = - if (withNameCheck && shouldLambdaParameterBeNamed(newCallExpression.getValueArgumentsInParentheses(), oldCallExpression)) { - psiFactory.createArgument(replacement, functionLiteralArgumentName) - } else { - psiFactory.createArgument(replacement) - } + val argument = psiFactory.createArgument(replacement, lambdaArgumentName) val functionLiteralArgument = newCallExpression.lambdaArguments.firstOrNull()!! val valueArgumentList = newCallExpression.valueArgumentList ?: psiFactory.createCallArguments("()") @@ -149,8 +150,13 @@ fun KtLambdaArgument.moveInsideParenthesesAndReplaceWith( return oldCallExpression.replace(newCallExpression) as KtCallExpression } -private fun shouldLambdaParameterBeNamed(args: List, callExpr: KtCallExpression): Boolean { +/** + * Returns `true` if the lambda argument should be named, `false` otherwise. + */ +fun shouldLambdaParameterBeNamed(argument: KtLambdaArgument): Boolean { + val callExpression = argument.parent as KtCallExpression + val args = callExpression.getValueArgumentsInParentheses() if (args.any { it.isNamed() }) return true - val callee = (callExpr.calleeExpression?.mainReference?.resolve() as? KtFunction) ?: return false + val callee = (callExpression.calleeExpression?.mainReference?.resolve() as? KtFunction) ?: return false return if (callee.valueParameters.any { it.isVarArg }) true else callee.valueParameters.size - 1 > args.size } \ No newline at end of file diff --git a/plugins/kotlin/base/psi/src/org/jetbrains/kotlin/idea/base/psi/KotlinPsiUtils.kt b/plugins/kotlin/base/psi/src/org/jetbrains/kotlin/idea/base/psi/KotlinPsiUtils.kt index fc295717b99e..25dadba484e0 100644 --- a/plugins/kotlin/base/psi/src/org/jetbrains/kotlin/idea/base/psi/KotlinPsiUtils.kt +++ b/plugins/kotlin/base/psi/src/org/jetbrains/kotlin/idea/base/psi/KotlinPsiUtils.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-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. @file:JvmName("KotlinPsiUtils") @@ -17,10 +17,8 @@ import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.containingClass -import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject -import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier -import org.jetbrains.kotlin.psi.psiUtil.isTopLevelInFileOrScript +import org.jetbrains.kotlin.psi.psiUtil.* +import org.jetbrains.kotlin.util.match import org.jetbrains.kotlin.utils.addToStdlib.safeAs val KtClassOrObject.classIdIfNonLocal: ClassId? @@ -238,4 +236,12 @@ fun KtExpression.unwrapIfLabeled(): KtExpression { while (true) { statement = statement.parent as? KtLabeledExpression ?: return statement } +} + +fun getCallElement(argument: KtValueArgument): KtCallElement? { + return if (argument is KtLambdaArgument) { + argument.parent as? KtCallElement + } else { + argument.parents.match(KtValueArgumentList::class, last = KtCallElement::class) + } } \ No newline at end of file diff --git a/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/applicable/intentions/AbstractKotlinApplicableIntentionWithContext.kt b/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/applicable/intentions/AbstractKotlinApplicableIntentionWithContext.kt index 18c2c2111e54..be25a5a72e4d 100644 --- a/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/applicable/intentions/AbstractKotlinApplicableIntentionWithContext.kt +++ b/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/applicable/intentions/AbstractKotlinApplicableIntentionWithContext.kt @@ -33,7 +33,7 @@ abstract class AbstractKotlinApplicableIntentionWithContext + \ No newline at end of file diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/TrailingCommaPostFormatProcessor.kt b/plugins/kotlin/code-insight/impl-base/src/org/jetbrains/kotlin/idea/formatter/TrailingCommaPostFormatProcessor.kt similarity index 100% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/TrailingCommaPostFormatProcessor.kt rename to plugins/kotlin/code-insight/impl-base/src/org/jetbrains/kotlin/idea/formatter/TrailingCommaPostFormatProcessor.kt diff --git a/plugins/kotlin/code-insight/inspections-k2/kotlin.code-insight.inspections-k2.iml b/plugins/kotlin/code-insight/inspections-k2/kotlin.code-insight.inspections-k2.iml index 5ae409020ec8..0501d6cc3980 100644 --- a/plugins/kotlin/code-insight/inspections-k2/kotlin.code-insight.inspections-k2.iml +++ b/plugins/kotlin/code-insight/inspections-k2/kotlin.code-insight.inspections-k2.iml @@ -50,7 +50,8 @@ - - + + + \ No newline at end of file diff --git a/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/KotlinUnusedImportInspection.kt b/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/KotlinUnusedImportInspection.kt index a55315778b90..85a77edc4203 100644 --- a/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/KotlinUnusedImportInspection.kt +++ b/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/KotlinUnusedImportInspection.kt @@ -23,11 +23,15 @@ internal class KotlinUnusedImportInspection : AbstractKotlinInspection() { analyseImports(file) } - if (result.unusedImports.isEmpty()) return null + // Imports in a 'KtCodeFragment' aren't a part of the AST, so we can't attach an inspection on them. + val unusedImports = result.unusedImports + .filter { it.isPhysical } + .takeIf { it.isNotEmpty() } + ?: return null val quickFixes = arrayOf(KotlinOptimizeImportsQuickFix(file)) - val problems = result.unusedImports.map { importPsiElement -> + val problems = unusedImports.map { importPsiElement -> manager.createProblemDescriptor( importPsiElement, KotlinBundle.message("unused.import.directive"), diff --git a/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/NullableBooleanElvisInspection.kt b/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/NullableBooleanElvisInspection.kt index 84be7449af20..fd1619c21d52 100644 --- a/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/NullableBooleanElvisInspection.kt +++ b/plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/NullableBooleanElvisInspection.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.idea.base.psi.replaced import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.codeinsight.api.applicable.inspections.AbstractKotlinApplicableInspection import org.jetbrains.kotlin.idea.codeinsight.api.applicators.KotlinApplicabilityRange -import org.jetbrains.kotlin.idea.codeinsights.impl.base.applicators.ApplicabilityRanges +import org.jetbrains.kotlin.idea.codeinsight.api.applicators.applicabilityRange import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* @@ -34,7 +34,9 @@ internal class NullableBooleanElvisInspection : AbstractKotlinApplicableInspecti override fun getProblemDescription(element: KtBinaryExpression): String = KotlinBundle.message("inspection.nullable.boolean.elvis.display.name") override fun getActionFamilyName(): String = KotlinBundle.message("inspection.nullable.boolean.elvis.action.name") - override fun getApplicabilityRange(): KotlinApplicabilityRange = ApplicabilityRanges.SELF + override fun getApplicabilityRange(): KotlinApplicabilityRange = applicabilityRange { expr -> + (expr as? KtBinaryExpression)?.operationReference?.textRangeInParent + } override fun isApplicableByPsi(element: KtBinaryExpression): Boolean = element.isTargetOfNullableBooleanElvisInspection() diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/kotlin.code-insight.inspections-k2.tests.iml b/plugins/kotlin/code-insight/inspections-k2/tests/kotlin.code-insight.inspections-k2.tests.iml index edcf41d70ad6..d80d527e43f3 100644 --- a/plugins/kotlin/code-insight/inspections-k2/tests/kotlin.code-insight.inspections-k2.tests.iml +++ b/plugins/kotlin/code-insight/inspections-k2/tests/kotlin.code-insight.inspections-k2.tests.iml @@ -37,7 +37,7 @@ - + diff --git a/plugins/kotlin/code-insight/inspections-shared/src/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/RedundantValueArgumentInspection.kt b/plugins/kotlin/code-insight/inspections-shared/src/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/RedundantValueArgumentInspection.kt index d207f66a7eda..623461caa568 100644 --- a/plugins/kotlin/code-insight/inspections-shared/src/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/RedundantValueArgumentInspection.kt +++ b/plugins/kotlin/code-insight/inspections-shared/src/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/RedundantValueArgumentInspection.kt @@ -18,7 +18,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol import org.jetbrains.kotlin.analysis.api.symbols.sourcePsiSafe import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.codeinsight.api.classic.inspections.AbstractKotlinInspection -import org.jetbrains.kotlin.idea.codeinsight.utils.AddArgumentNamesUtils +import org.jetbrains.kotlin.idea.codeinsight.utils.NamedArgumentUtils import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType @@ -99,7 +99,7 @@ internal class RedundantValueArgumentInspection : AbstractKotlinInspection() { for ((followingArgumentIndex, name) in followingArgumentMapping) { val followingArgument = argumentList.arguments[followingArgumentIndex] - AddArgumentNamesUtils.addArgumentName(followingArgument, name) + NamedArgumentUtils.addArgumentName(followingArgument, name) } argumentList.removeArgument(argument) diff --git a/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/AddNameToArgumentIntention.kt b/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/AddNameToArgumentIntention.kt index 2909a1c38bd6..aaed16f21b73 100644 --- a/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/AddNameToArgumentIntention.kt +++ b/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/AddNameToArgumentIntention.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-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.k2.codeinsight.intentions import com.intellij.codeInsight.intention.LowPriorityAction @@ -10,9 +10,9 @@ import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.codeinsight.api.applicable.intentions.AbstractKotlinApplicableIntentionWithContext -import org.jetbrains.kotlin.idea.codeinsight.utils.getValueArgumentName +import org.jetbrains.kotlin.idea.codeinsight.utils.NamedArgumentUtils.addArgumentName +import org.jetbrains.kotlin.idea.codeinsight.utils.NamedArgumentUtils.getStableNameFor import org.jetbrains.kotlin.idea.codeinsights.impl.base.applicators.ApplicabilityRanges -import org.jetbrains.kotlin.idea.codeinsight.utils.AddArgumentNamesUtils.addArgumentName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtContainerNode import org.jetbrains.kotlin.psi.KtLambdaArgument @@ -47,7 +47,7 @@ internal class AddNameToArgumentIntention : context(KtAnalysisSession) override fun prepareContext(element: KtValueArgument): Context? { - return element.getValueArgumentName()?.let { Context(it) } + return getStableNameFor(element)?.let { Context(it) } } override fun apply(element: KtValueArgument, context: Context, project: Project, editor: Editor?) = diff --git a/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/AddNamesToCallArgumentsIntention.kt b/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/AddNamesToCallArgumentsIntention.kt index 157343f608bb..2e73ade67c81 100644 --- a/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/AddNamesToCallArgumentsIntention.kt +++ b/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/AddNamesToCallArgumentsIntention.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-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.k2.codeinsight.intentions import com.intellij.openapi.editor.Editor @@ -10,9 +10,9 @@ import org.jetbrains.kotlin.idea.base.psi.textRangeIn import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.codeinsight.api.applicable.intentions.AbstractKotlinApplicableIntentionWithContext import org.jetbrains.kotlin.idea.codeinsight.api.applicators.applicabilityRanges +import org.jetbrains.kotlin.idea.codeinsight.utils.NamedArgumentUtils.addArgumentNames +import org.jetbrains.kotlin.idea.codeinsight.utils.NamedArgumentUtils.associateArgumentNamesStartingAt import org.jetbrains.kotlin.idea.codeinsight.utils.dereferenceValidKeys -import org.jetbrains.kotlin.idea.codeinsight.utils.AddArgumentNamesUtils.addArgumentNames -import org.jetbrains.kotlin.idea.codeinsight.utils.AddArgumentNamesUtils.associateArgumentNamesStartingAt import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtCallElement import org.jetbrains.kotlin.psi.KtValueArgument diff --git a/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/AddNamesToFollowingArgumentsIntention.kt b/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/AddNamesToFollowingArgumentsIntention.kt index 20d6d09e11ba..3c03906368b9 100644 --- a/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/AddNamesToFollowingArgumentsIntention.kt +++ b/plugins/kotlin/code-insight/intentions-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/intentions/AddNamesToFollowingArgumentsIntention.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-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.k2.codeinsight.intentions import com.intellij.codeInsight.intention.LowPriorityAction @@ -6,19 +6,19 @@ import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project import com.intellij.psi.SmartPsiElementPointer import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.util.match import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.codeinsight.api.applicable.intentions.AbstractKotlinApplicableIntentionWithContext +import org.jetbrains.kotlin.idea.codeinsight.utils.NamedArgumentUtils.addArgumentNames +import org.jetbrains.kotlin.idea.codeinsight.utils.NamedArgumentUtils.associateArgumentNamesStartingAt import org.jetbrains.kotlin.idea.codeinsight.utils.dereferenceValidKeys import org.jetbrains.kotlin.idea.codeinsights.impl.base.applicators.ApplicabilityRanges -import org.jetbrains.kotlin.idea.codeinsight.utils.AddArgumentNamesUtils.addArgumentNames -import org.jetbrains.kotlin.idea.codeinsight.utils.AddArgumentNamesUtils.associateArgumentNamesStartingAt import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtCallElement import org.jetbrains.kotlin.psi.KtLambdaArgument import org.jetbrains.kotlin.psi.KtValueArgument import org.jetbrains.kotlin.psi.KtValueArgumentList import org.jetbrains.kotlin.psi.psiUtil.parents +import org.jetbrains.kotlin.util.match internal class AddNamesToFollowingArgumentsIntention : AbstractKotlinApplicableIntentionWithContext(KtValueArgument::class), diff --git a/plugins/kotlin/code-insight/intentions-k2/tests/test/org/jetbrains/kotlin/idea/k2/intentions/tests/K2IntentionTestGenerated.java b/plugins/kotlin/code-insight/intentions-k2/tests/test/org/jetbrains/kotlin/idea/k2/intentions/tests/K2IntentionTestGenerated.java index 60279ccde550..c9b56312c3b8 100644 --- a/plugins/kotlin/code-insight/intentions-k2/tests/test/org/jetbrains/kotlin/idea/k2/intentions/tests/K2IntentionTestGenerated.java +++ b/plugins/kotlin/code-insight/intentions-k2/tests/test/org/jetbrains/kotlin/idea/k2/intentions/tests/K2IntentionTestGenerated.java @@ -1588,6 +1588,11 @@ public abstract class K2IntentionTestGenerated extends AbstractK2IntentionTest { runTest("../../../idea/tests/testData/intentions/convertToBlockBody/nothingFun.kt"); } + @TestMetadata("nullableNothing.kt") + public void testNullableNothing() throws Exception { + runTest("../../../idea/tests/testData/intentions/convertToBlockBody/nullableNothing.kt"); + } + @TestMetadata("overrideWithPlatformType.kt") public void testOverrideWithPlatformType() throws Exception { runTest("../../../idea/tests/testData/intentions/convertToBlockBody/overrideWithPlatformType.kt"); diff --git a/plugins/kotlin/code-insight/line-markers-shared/kotlin.code-insight.line-markers-shared.iml b/plugins/kotlin/code-insight/line-markers-shared/kotlin.code-insight.line-markers-shared.iml index 6509bb0da6b0..0c64fe6b7bb2 100644 --- a/plugins/kotlin/code-insight/line-markers-shared/kotlin.code-insight.line-markers-shared.iml +++ b/plugins/kotlin/code-insight/line-markers-shared/kotlin.code-insight.line-markers-shared.iml @@ -18,5 +18,6 @@ + \ No newline at end of file diff --git a/plugins/kotlin/code-insight/line-markers-shared/resources/messages/KotlinLineMarkersSharedBundle.properties b/plugins/kotlin/code-insight/line-markers-shared/resources/messages/KotlinLineMarkersSharedBundle.properties index 3175cb50660f..f31d7869b3dd 100644 --- a/plugins/kotlin/code-insight/line-markers-shared/resources/messages/KotlinLineMarkersSharedBundle.properties +++ b/plugins/kotlin/code-insight/line-markers-shared/resources/messages/KotlinLineMarkersSharedBundle.properties @@ -1,4 +1,5 @@ highlighter.title.actuals.for=Actuals for {0} highlighter.title.choose.actual.for=Choose Actual For {0} highlighter.title.choose.expected.for=Choose Expected For {0} -highlighter.title.expected.for=Expected for {0} \ No newline at end of file +highlighter.title.expected.for=Expected for {0} +highlighter.name.kotlin.line.markers=Kotlin line markers \ No newline at end of file diff --git a/plugins/kotlin/code-insight/line-markers-shared/src/org/jetbrains/kotlin/idea/codeInsight/lineMarkers/shared/AbstractKotlinLineMarkerProvider.kt b/plugins/kotlin/code-insight/line-markers-shared/src/org/jetbrains/kotlin/idea/codeInsight/lineMarkers/shared/AbstractKotlinLineMarkerProvider.kt new file mode 100644 index 000000000000..892f180d25eb --- /dev/null +++ b/plugins/kotlin/code-insight/line-markers-shared/src/org/jetbrains/kotlin/idea/codeInsight/lineMarkers/shared/AbstractKotlinLineMarkerProvider.kt @@ -0,0 +1,75 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.codeInsight.lineMarkers.shared + +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings +import com.intellij.codeInsight.daemon.LineMarkerInfo +import com.intellij.codeInsight.daemon.LineMarkerProviderDescriptor +import com.intellij.openapi.editor.colors.CodeInsightColors +import com.intellij.openapi.editor.colors.EditorColorsManager +import com.intellij.openapi.editor.markup.SeparatorPlacement +import com.intellij.openapi.project.DumbService +import com.intellij.openapi.util.text.StringUtil +import com.intellij.psi.PsiElement +import com.intellij.psi.util.PsiTreeUtil +import org.jetbrains.kotlin.idea.base.projectStructure.RootKindFilter +import org.jetbrains.kotlin.idea.base.projectStructure.matches +import org.jetbrains.kotlin.idea.highlighter.markers.KotlinLineMarkerOptions +import org.jetbrains.kotlin.psi.KtClassInitializer +import org.jetbrains.kotlin.psi.KtFunction +import org.jetbrains.kotlin.psi.KtObjectDeclaration +import org.jetbrains.kotlin.psi.KtProperty +import org.jetbrains.kotlin.psi.psiUtil.getPrevSiblingIgnoringWhitespaceAndComments + +typealias LineMarkerInfos = MutableCollection> + +abstract class AbstractKotlinLineMarkerProvider : LineMarkerProviderDescriptor() { + override fun getName() = KotlinLineMarkersSharedBundle.message("highlighter.name.kotlin.line.markers") + + override fun getOptions(): Array \ No newline at end of file diff --git a/plugins/kotlin/code-insight/line-markers/resources/kotlin.code-insight.line-markers-k2.xml b/plugins/kotlin/code-insight/line-markers/resources/kotlin.code-insight.line-markers-k2.xml index 5673c571dfc6..044b3bf831fa 100644 --- a/plugins/kotlin/code-insight/line-markers/resources/kotlin.code-insight.line-markers-k2.xml +++ b/plugins/kotlin/code-insight/line-markers/resources/kotlin.code-insight.line-markers-k2.xml @@ -17,6 +17,7 @@ + (true) ?: return null + val targetPresentation = getTargetPresentation(declaration) ?: return null + return TargetPresentation.builder(KotlinBundle.message("presentation.text.object.in.container", targetPresentation.presentableText)) + .icon(KotlinIcons.OBJECT) + .locationText(targetPresentation.locationText, targetPresentation.locationIcon) + .containerText(targetPresentation.containerText) + .presentation() + } + return getTargetPresentation(container) + } + + fun getTargetPresentation(declaration: KtNamedDeclaration): TargetPresentation? { + val presentation = declaration.presentation ?: return null + val presentableText = presentation.presentableText ?: return null + val ktFile = declaration.containingKtFile + val moduleTextWithIcon = PsiElementListCellRenderer.getModuleTextWithIcon(declaration) + return TargetPresentation.builder(presentableText) + .icon(presentation.getIcon(true)) + .locationText(moduleTextWithIcon?.text, moduleTextWithIcon?.icon) + .containerText(ktFile.packageFqName.asString()) + .presentation() + } +} \ No newline at end of file diff --git a/plugins/kotlin/code-insight/line-markers/src/org/jetbrains/kotlin/idea/codeInsight/lineMarkers/KotlinLineMarkerProvider.kt b/plugins/kotlin/code-insight/line-markers/src/org/jetbrains/kotlin/idea/codeInsight/lineMarkers/KotlinLineMarkerProvider.kt index 165536cc2d67..fe0f84ac9469 100644 --- a/plugins/kotlin/code-insight/line-markers/src/org/jetbrains/kotlin/idea/codeInsight/lineMarkers/KotlinLineMarkerProvider.kt +++ b/plugins/kotlin/code-insight/line-markers/src/org/jetbrains/kotlin/idea/codeInsight/lineMarkers/KotlinLineMarkerProvider.kt @@ -8,7 +8,6 @@ import com.intellij.codeInsight.daemon.impl.InheritorsLineMarkerNavigator import com.intellij.codeInsight.navigation.GotoTargetHandler import com.intellij.openapi.actionSystem.IdeActions import com.intellij.openapi.editor.markup.GutterIconRenderer -import com.intellij.openapi.project.DumbService import com.intellij.psi.PsiElement import com.intellij.psi.impl.source.tree.LeafPsiElement import com.intellij.ui.awt.RelativePoint @@ -21,6 +20,8 @@ import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithModality import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.codeInsight.lineMarkers.dsl.collectHighlightingDslMarkers +import org.jetbrains.kotlin.idea.codeInsight.lineMarkers.shared.AbstractKotlinLineMarkerProvider +import org.jetbrains.kotlin.idea.codeInsight.lineMarkers.shared.LineMarkerInfos import org.jetbrains.kotlin.idea.highlighter.markers.InheritanceMergeableLineMarkerInfo import org.jetbrains.kotlin.idea.highlighter.markers.KotlinGutterTooltipHelper import org.jetbrains.kotlin.idea.highlighter.markers.KotlinLineMarkerOptions @@ -37,19 +38,9 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import java.awt.event.MouseEvent import java.util.concurrent.atomic.AtomicReference -class KotlinLineMarkerProvider : LineMarkerProviderDescriptor() { - override fun getName() = KotlinBundle.message("highlighter.name.kotlin.line.markers") - - override fun getOptions(): Array \ No newline at end of file diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/BaseKotlinImportLayoutPanel.kt b/plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/BaseKotlinImportLayoutPanel.kt similarity index 100% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/BaseKotlinImportLayoutPanel.kt rename to plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/BaseKotlinImportLayoutPanel.kt diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/ImportSettingsPanel.kt b/plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/ImportSettingsPanel.kt similarity index 100% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/ImportSettingsPanel.kt rename to plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/ImportSettingsPanel.kt diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinBlock.kt b/plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinBlock.kt similarity index 100% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinBlock.kt rename to plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinBlock.kt diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinCodeStyleGenerationConfigurable.kt b/plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinCodeStyleGenerationConfigurable.kt similarity index 100% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinCodeStyleGenerationConfigurable.kt rename to plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinCodeStyleGenerationConfigurable.kt diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinCodeStylePanel.kt b/plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinCodeStylePanel.kt similarity index 100% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinCodeStylePanel.kt rename to plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinCodeStylePanel.kt diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinCodeStylePropertyAccessor.kt b/plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinCodeStylePropertyAccessor.kt similarity index 100% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinCodeStylePropertyAccessor.kt rename to plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinCodeStylePropertyAccessor.kt diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinFormatterUsageCollector.kt b/plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinFormatterUsageCollector.kt similarity index 96% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinFormatterUsageCollector.kt rename to plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinFormatterUsageCollector.kt index 6b133d19553e..330a6d0422a2 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinFormatterUsageCollector.kt +++ b/plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinFormatterUsageCollector.kt @@ -7,14 +7,13 @@ import com.intellij.internal.statistic.beans.MetricEvent import com.intellij.internal.statistic.eventLog.EventLogGroup import com.intellij.internal.statistic.eventLog.events.EventFields import com.intellij.internal.statistic.service.fus.collectors.ProjectUsagesCollector -import com.intellij.internal.statistic.utils.getPluginInfoById +import com.intellij.internal.statistic.utils.getPluginInfo import com.intellij.openapi.project.Project import com.intellij.psi.codeStyle.CodeStyleSettings import com.intellij.psi.codeStyle.CodeStyleSettingsManager import org.jetbrains.kotlin.idea.base.util.KotlinPlatformUtils import org.jetbrains.kotlin.idea.base.util.containsNonScriptKotlinFile import org.jetbrains.kotlin.idea.base.util.runReadActionInSmartMode -import org.jetbrains.kotlin.idea.compiler.configuration.KotlinIdePlugin import org.jetbrains.kotlin.idea.formatter.KotlinFormatterUsageCollector.KotlinFormatterKind.* class KotlinFormatterUsageCollector : ProjectUsagesCollector() { @@ -30,7 +29,7 @@ class KotlinFormatterUsageCollector : ProjectUsagesCollector() { return setOf( settingsEvent.metric( value1 = getKotlinFormatterKind(project), - value2 = getPluginInfoById(KotlinIdePlugin.id), + value2 = getPluginInfo(KotlinFormatterUsageCollector::class.java), ) ) } diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinFormattingModelBuilder.kt b/plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinFormattingModelBuilder.kt similarity index 100% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinFormattingModelBuilder.kt rename to plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinFormattingModelBuilder.kt diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinLanguageCodeStyleSettingsProvider.kt b/plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinLanguageCodeStyleSettingsProvider.kt similarity index 100% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinLanguageCodeStyleSettingsProvider.kt rename to plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinLanguageCodeStyleSettingsProvider.kt diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinLineIndentProvider.kt b/plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinLineIndentProvider.kt similarity index 100% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinLineIndentProvider.kt rename to plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinLineIndentProvider.kt diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinOtherSettingsPanel.kt b/plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinOtherSettingsPanel.kt similarity index 100% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinOtherSettingsPanel.kt rename to plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinOtherSettingsPanel.kt diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinPackageEntryTableAccessor.kt b/plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinPackageEntryTableAccessor.kt similarity index 100% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinPackageEntryTableAccessor.kt rename to plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinPackageEntryTableAccessor.kt diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinPreFormatProcessor.kt b/plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinPreFormatProcessor.kt similarity index 100% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinPreFormatProcessor.kt rename to plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinPreFormatProcessor.kt diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinSaveStylePanel.kt b/plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinSaveStylePanel.kt similarity index 100% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/KotlinSaveStylePanel.kt rename to plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinSaveStylePanel.kt diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/NodeAlignmentStrategy.java b/plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/NodeAlignmentStrategy.java similarity index 100% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/NodeAlignmentStrategy.java rename to plugins/kotlin/formatter/src/org/jetbrains/kotlin/idea/formatter/NodeAlignmentStrategy.java diff --git a/plugins/kotlin/frontend-independent/kotlin.fir.frontend-independent.iml b/plugins/kotlin/frontend-independent/kotlin.fir.frontend-independent.iml index bb7a55b7c09d..7d0e4433d4f0 100644 --- a/plugins/kotlin/frontend-independent/kotlin.fir.frontend-independent.iml +++ b/plugins/kotlin/frontend-independent/kotlin.fir.frontend-independent.iml @@ -17,7 +17,7 @@ - + diff --git a/plugins/kotlin/frontend-independent/src/org/jetbrains/kotlin/idea/actions/KotlinAddImportActionInfo.kt b/plugins/kotlin/frontend-independent/src/org/jetbrains/kotlin/idea/actions/KotlinAddImportActionInfo.kt index 45e0c3e8b111..739dd3a05e6f 100644 --- a/plugins/kotlin/frontend-independent/src/org/jetbrains/kotlin/idea/actions/KotlinAddImportActionInfo.kt +++ b/plugins/kotlin/frontend-independent/src/org/jetbrains/kotlin/idea/actions/KotlinAddImportActionInfo.kt @@ -3,8 +3,11 @@ package org.jetbrains.kotlin.idea.actions import com.intellij.openapi.Disposable import com.intellij.openapi.util.Disposer +import com.intellij.openapi.util.Key +import com.intellij.psi.PsiFile import org.jetbrains.annotations.TestOnly import org.jetbrains.kotlin.idea.quickfix.AutoImportVariant +import org.jetbrains.kotlin.psi.UserDataProperty /** Test hooks allowing inspection of data used for KotlinAddImportAction. **/ object KotlinAddImportActionInfo { @@ -12,13 +15,12 @@ object KotlinAddImportActionInfo { fun onExecute(variants: List) } - @Volatile - var executeListener: ExecuteListener? = null + var PsiFile.executeListener: ExecuteListener? by UserDataProperty(Key("KOTLIN_IMPORT_EXECUTE_LISTENER")) @TestOnly - fun setExecuteListener(disposable: Disposable, listener: ExecuteListener) { - assert(executeListener == null) - executeListener = listener - Disposer.register(disposable) { executeListener = null } + fun setExecuteListener(file: PsiFile, disposable: Disposable, listener: ExecuteListener) { + assert(file.executeListener == null) + file.executeListener = listener + Disposer.register(disposable) { file.executeListener = null } } } \ No newline at end of file diff --git a/plugins/kotlin/base/highlighting/kotlin.base.highlighting.iml b/plugins/kotlin/highlighting/highlighting-k1/kotlin.highlighting.k1.iml similarity index 73% rename from plugins/kotlin/base/highlighting/kotlin.base.highlighting.iml rename to plugins/kotlin/highlighting/highlighting-k1/kotlin.highlighting.k1.iml index 3874bcbd6e14..7007cb111342 100644 --- a/plugins/kotlin/base/highlighting/kotlin.base.highlighting.iml +++ b/plugins/kotlin/highlighting/highlighting-k1/kotlin.highlighting.k1.iml @@ -8,17 +8,15 @@ + - - - @@ -27,5 +25,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/HighlightingFactory.kt b/plugins/kotlin/highlighting/highlighting-k1/resources/dummy similarity index 100% rename from plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/HighlightingFactory.kt rename to plugins/kotlin/highlighting/highlighting-k1/resources/dummy diff --git a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinChangeLocalityDetector.kt b/plugins/kotlin/highlighting/highlighting-k1/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinChangeLocalityDetector.kt similarity index 100% rename from plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinChangeLocalityDetector.kt rename to plugins/kotlin/highlighting/highlighting-k1/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinChangeLocalityDetector.kt diff --git a/plugins/kotlin/highlighting/kotlin.highlighting.iml b/plugins/kotlin/highlighting/highlighting-k2/kotlin.highlighting.k2.iml similarity index 97% rename from plugins/kotlin/highlighting/kotlin.highlighting.iml rename to plugins/kotlin/highlighting/highlighting-k2/kotlin.highlighting.k2.iml index efa4ab4f21d9..1e4a7c5c4b12 100644 --- a/plugins/kotlin/highlighting/kotlin.highlighting.iml +++ b/plugins/kotlin/highlighting/highlighting-k2/kotlin.highlighting.k2.iml @@ -29,7 +29,7 @@ - + diff --git a/plugins/kotlin/highlighting/resources/kotlin.highlighting.xml b/plugins/kotlin/highlighting/highlighting-k2/resources/kotlin.highlighting.xml similarity index 100% rename from plugins/kotlin/highlighting/resources/kotlin.highlighting.xml rename to plugins/kotlin/highlighting/highlighting-k2/resources/kotlin.highlighting.xml diff --git a/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/HighlightingFactory.kt b/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/HighlightingFactory.kt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/KotlinCallHighlighterExtension.kt b/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/KotlinCallHighlighterExtension.kt similarity index 100% rename from plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/KotlinCallHighlighterExtension.kt rename to plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/KotlinCallHighlighterExtension.kt diff --git a/plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/KotlinDiagnosticHighlightVisitor.kt b/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/KotlinDiagnosticHighlightVisitor.kt similarity index 100% rename from plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/KotlinDiagnosticHighlightVisitor.kt rename to plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/KotlinDiagnosticHighlightVisitor.kt diff --git a/plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/KotlinHighlightExitPointsHandlerFactory.kt b/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/KotlinHighlightExitPointsHandlerFactory.kt similarity index 100% rename from plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/KotlinHighlightExitPointsHandlerFactory.kt rename to plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/KotlinHighlightExitPointsHandlerFactory.kt diff --git a/plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/KotlinSemanticHighlightingVisitor.kt b/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/KotlinSemanticHighlightingVisitor.kt similarity index 100% rename from plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/KotlinSemanticHighlightingVisitor.kt rename to plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/KotlinSemanticHighlightingVisitor.kt diff --git a/plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/KotlinUnusedHighlightingVisitor.kt b/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/KotlinUnusedHighlightingVisitor.kt similarity index 100% rename from plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/KotlinUnusedHighlightingVisitor.kt rename to plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/KotlinUnusedHighlightingVisitor.kt diff --git a/plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/beforeResolve/AnnotationEntryHighlightingVisitor.kt b/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/beforeResolve/AnnotationEntryHighlightingVisitor.kt similarity index 100% rename from plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/beforeResolve/AnnotationEntryHighlightingVisitor.kt rename to plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/beforeResolve/AnnotationEntryHighlightingVisitor.kt diff --git a/plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/beforeResolve/DeclarationHighlightingVisitor.kt b/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/beforeResolve/DeclarationHighlightingVisitor.kt similarity index 100% rename from plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/beforeResolve/DeclarationHighlightingVisitor.kt rename to plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/beforeResolve/DeclarationHighlightingVisitor.kt diff --git a/plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/highlighters/DslHighlighter.kt b/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/highlighters/DslHighlighter.kt similarity index 100% rename from plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/highlighters/DslHighlighter.kt rename to plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/highlighters/DslHighlighter.kt diff --git a/plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/highlighters/ExpressionsSmartcastHighlighter.kt b/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/highlighters/ExpressionsSmartcastHighlighter.kt similarity index 100% rename from plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/highlighters/ExpressionsSmartcastHighlighter.kt rename to plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/highlighters/ExpressionsSmartcastHighlighter.kt diff --git a/plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/highlighters/FunctionCallHighlighter.kt b/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/highlighters/FunctionCallHighlighter.kt similarity index 100% rename from plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/highlighters/FunctionCallHighlighter.kt rename to plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/highlighters/FunctionCallHighlighter.kt diff --git a/plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/highlighters/KotlinSemanticAnalyzer.kt b/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/highlighters/KotlinSemanticAnalyzer.kt similarity index 100% rename from plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/highlighters/KotlinSemanticAnalyzer.kt rename to plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/highlighters/KotlinSemanticAnalyzer.kt diff --git a/plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/highlighters/TypeHighlighter.kt b/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/highlighters/TypeHighlighter.kt similarity index 100% rename from plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/highlighters/TypeHighlighter.kt rename to plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/highlighters/TypeHighlighter.kt diff --git a/plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/highlighters/VariableReferenceHighlighter.kt b/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/highlighters/VariableReferenceHighlighter.kt similarity index 100% rename from plugins/kotlin/highlighting/src/org/jetbrains/kotlin/idea/highlighting/highlighters/VariableReferenceHighlighter.kt rename to plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/highlighters/VariableReferenceHighlighter.kt diff --git a/plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractK2BundledCompilerPluginsHighlightingMetaInfoTest.kt b/plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractK2BundledCompilerPluginsHighlightingMetaInfoTest.kt similarity index 100% rename from plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractK2BundledCompilerPluginsHighlightingMetaInfoTest.kt rename to plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractK2BundledCompilerPluginsHighlightingMetaInfoTest.kt diff --git a/plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractK2HighlightExitPointsTest.kt b/plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractK2HighlightExitPointsTest.kt similarity index 100% rename from plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractK2HighlightExitPointsTest.kt rename to plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractK2HighlightExitPointsTest.kt diff --git a/plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractK2HighlightingMetaInfoTest.kt b/plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractK2HighlightingMetaInfoTest.kt similarity index 100% rename from plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractK2HighlightingMetaInfoTest.kt rename to plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractK2HighlightingMetaInfoTest.kt diff --git a/plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractK2HighlightingMetaInfoWithExtensionTest.kt b/plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractK2HighlightingMetaInfoWithExtensionTest.kt similarity index 100% rename from plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractK2HighlightingMetaInfoWithExtensionTest.kt rename to plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractK2HighlightingMetaInfoWithExtensionTest.kt diff --git a/plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractOutsiderHighlightingTest.kt b/plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractOutsiderHighlightingTest.kt similarity index 100% rename from plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractOutsiderHighlightingTest.kt rename to plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/AbstractOutsiderHighlightingTest.kt diff --git a/plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/K2BundledCompilerPluginsHighlightingMetaInfoTestGenerated.java b/plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/K2BundledCompilerPluginsHighlightingMetaInfoTestGenerated.java similarity index 68% rename from plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/K2BundledCompilerPluginsHighlightingMetaInfoTestGenerated.java rename to plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/K2BundledCompilerPluginsHighlightingMetaInfoTestGenerated.java index 04846a10c932..94b88e7b4bb3 100644 --- a/plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/K2BundledCompilerPluginsHighlightingMetaInfoTestGenerated.java +++ b/plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/K2BundledCompilerPluginsHighlightingMetaInfoTestGenerated.java @@ -14,10 +14,10 @@ import org.junit.runner.RunWith; * DO NOT MODIFY MANUALLY. */ @SuppressWarnings("all") -@TestRoot("highlighting") +@TestRoot("highlighting/highlighting-k2") @TestDataPath("$CONTENT_ROOT") @RunWith(JUnit3RunnerWithInners.class) -@TestMetadata("../idea/tests/testData/highlighterMetaInfoWithBundledCompilerPlugins") +@TestMetadata("../../idea/tests/testData/highlighterMetaInfoWithBundledCompilerPlugins") public class K2BundledCompilerPluginsHighlightingMetaInfoTestGenerated extends AbstractK2BundledCompilerPluginsHighlightingMetaInfoTest { private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); @@ -25,26 +25,26 @@ public class K2BundledCompilerPluginsHighlightingMetaInfoTestGenerated extends A @TestMetadata("allOpen.kt") public void testAllOpen() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfoWithBundledCompilerPlugins/allOpen.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfoWithBundledCompilerPlugins/allOpen.kt"); } @TestMetadata("lombok.kt") public void testLombok() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfoWithBundledCompilerPlugins/lombok.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfoWithBundledCompilerPlugins/lombok.kt"); } @TestMetadata("parcelize.kt") public void testParcelize() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfoWithBundledCompilerPlugins/parcelize.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfoWithBundledCompilerPlugins/parcelize.kt"); } @TestMetadata("samWithReceiver.kt") public void testSamWithReceiver() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfoWithBundledCompilerPlugins/samWithReceiver.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfoWithBundledCompilerPlugins/samWithReceiver.kt"); } @TestMetadata("serialize.kt") public void testSerialize() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfoWithBundledCompilerPlugins/serialize.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfoWithBundledCompilerPlugins/serialize.kt"); } } diff --git a/plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightExitPointsTestGenerated.java b/plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightExitPointsTestGenerated.java similarity index 54% rename from plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightExitPointsTestGenerated.java rename to plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightExitPointsTestGenerated.java index e0dca5e710ee..83bbb8e638e6 100644 --- a/plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightExitPointsTestGenerated.java +++ b/plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightExitPointsTestGenerated.java @@ -14,10 +14,10 @@ import org.junit.runner.RunWith; * DO NOT MODIFY MANUALLY. */ @SuppressWarnings("all") -@TestRoot("highlighting") +@TestRoot("highlighting/highlighting-k2") @TestDataPath("$CONTENT_ROOT") @RunWith(JUnit3RunnerWithInners.class) -@TestMetadata("../idea/tests/testData/exitPoints") +@TestMetadata("../../idea/tests/testData/exitPoints") public class K2HighlightExitPointsTestGenerated extends AbstractK2HighlightExitPointsTest { private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); @@ -25,206 +25,236 @@ public class K2HighlightExitPointsTestGenerated extends AbstractK2HighlightExitP @TestMetadata("anonymousFunction.kt") public void testAnonymousFunction() throws Exception { - runTest("../idea/tests/testData/exitPoints/anonymousFunction.kt"); + runTest("../../idea/tests/testData/exitPoints/anonymousFunction.kt"); } @TestMetadata("anonymousFunction2.kt") public void testAnonymousFunction2() throws Exception { - runTest("../idea/tests/testData/exitPoints/anonymousFunction2.kt"); + runTest("../../idea/tests/testData/exitPoints/anonymousFunction2.kt"); + } + + @TestMetadata("forLoopBreak.kt") + public void testForLoopBreak() throws Exception { + runTest("../../idea/tests/testData/exitPoints/forLoopBreak.kt"); + } + + @TestMetadata("forLoopNestedBreak.kt") + public void testForLoopNestedBreak() throws Exception { + runTest("../../idea/tests/testData/exitPoints/forLoopNestedBreak.kt"); + } + + @TestMetadata("forLoopNestedBreak2.kt") + public void testForLoopNestedBreak2() throws Exception { + runTest("../../idea/tests/testData/exitPoints/forLoopNestedBreak2.kt"); + } + + @TestMetadata("forLoopNestedLabeledBreak.kt") + public void testForLoopNestedLabeledBreak() throws Exception { + runTest("../../idea/tests/testData/exitPoints/forLoopNestedLabeledBreak.kt"); + } + + @TestMetadata("forLoopNestedLabeledBreakOnLoop.kt") + public void testForLoopNestedLabeledBreakOnLoop() throws Exception { + runTest("../../idea/tests/testData/exitPoints/forLoopNestedLabeledBreakOnLoop.kt"); + } + + @TestMetadata("forLoopNestedLabeledBreakOnLoop2.kt") + public void testForLoopNestedLabeledBreakOnLoop2() throws Exception { + runTest("../../idea/tests/testData/exitPoints/forLoopNestedLabeledBreakOnLoop2.kt"); } @TestMetadata("funKeyword.kt") public void testFunKeyword() throws Exception { - runTest("../idea/tests/testData/exitPoints/funKeyword.kt"); + runTest("../../idea/tests/testData/exitPoints/funKeyword.kt"); } @TestMetadata("funKeyword2.kt") public void testFunKeyword2() throws Exception { - runTest("../idea/tests/testData/exitPoints/funKeyword2.kt"); + runTest("../../idea/tests/testData/exitPoints/funKeyword2.kt"); } @TestMetadata("funKeyword3.kt") public void testFunKeyword3() throws Exception { - runTest("../idea/tests/testData/exitPoints/funKeyword3.kt"); + runTest("../../idea/tests/testData/exitPoints/funKeyword3.kt"); } @TestMetadata("funKeyword31.kt") public void testFunKeyword31() throws Exception { - runTest("../idea/tests/testData/exitPoints/funKeyword31.kt"); + runTest("../../idea/tests/testData/exitPoints/funKeyword31.kt"); } @TestMetadata("funName.kt") public void testFunName() throws Exception { - runTest("../idea/tests/testData/exitPoints/funName.kt"); + runTest("../../idea/tests/testData/exitPoints/funName.kt"); } @TestMetadata("getter.kt") public void testGetter() throws Exception { - runTest("../idea/tests/testData/exitPoints/getter.kt"); + runTest("../../idea/tests/testData/exitPoints/getter.kt"); } @TestMetadata("getter2.kt") public void testGetter2() throws Exception { - runTest("../idea/tests/testData/exitPoints/getter2.kt"); + runTest("../../idea/tests/testData/exitPoints/getter2.kt"); } @TestMetadata("getter3.kt") public void testGetter3() throws Exception { - runTest("../idea/tests/testData/exitPoints/getter3.kt"); + runTest("../../idea/tests/testData/exitPoints/getter3.kt"); } @TestMetadata("inLambda.kt") public void testInLambda() throws Exception { - runTest("../idea/tests/testData/exitPoints/inLambda.kt"); + runTest("../../idea/tests/testData/exitPoints/inLambda.kt"); } @TestMetadata("inLambda1.kt") public void testInLambda1() throws Exception { - runTest("../idea/tests/testData/exitPoints/inLambda1.kt"); + runTest("../../idea/tests/testData/exitPoints/inLambda1.kt"); } @TestMetadata("inLambda2.kt") public void testInLambda2() throws Exception { - runTest("../idea/tests/testData/exitPoints/inLambda2.kt"); + runTest("../../idea/tests/testData/exitPoints/inLambda2.kt"); } @TestMetadata("inLambdaLastStatement1.kt") public void testInLambdaLastStatement1() throws Exception { - runTest("../idea/tests/testData/exitPoints/inLambdaLastStatement1.kt"); + runTest("../../idea/tests/testData/exitPoints/inLambdaLastStatement1.kt"); } @TestMetadata("inLambdaLastStatement2.kt") public void testInLambdaLastStatement2() throws Exception { - runTest("../idea/tests/testData/exitPoints/inLambdaLastStatement2.kt"); + runTest("../../idea/tests/testData/exitPoints/inLambdaLastStatement2.kt"); } @TestMetadata("inLambdaLastStatement3.kt") public void testInLambdaLastStatement3() throws Exception { - runTest("../idea/tests/testData/exitPoints/inLambdaLastStatement3.kt"); + runTest("../../idea/tests/testData/exitPoints/inLambdaLastStatement3.kt"); } @TestMetadata("inLambdaLastStatement4.kt") public void testInLambdaLastStatement4() throws Exception { - runTest("../idea/tests/testData/exitPoints/inLambdaLastStatement4.kt"); + runTest("../../idea/tests/testData/exitPoints/inLambdaLastStatement4.kt"); } @TestMetadata("inLambdaLastStatement5.kt") public void testInLambdaLastStatement5() throws Exception { - runTest("../idea/tests/testData/exitPoints/inLambdaLastStatement5.kt"); + runTest("../../idea/tests/testData/exitPoints/inLambdaLastStatement5.kt"); } @TestMetadata("inLambdaLastStatement6.kt") public void testInLambdaLastStatement6() throws Exception { - runTest("../idea/tests/testData/exitPoints/inLambdaLastStatement6.kt"); + runTest("../../idea/tests/testData/exitPoints/inLambdaLastStatement6.kt"); } @TestMetadata("inline1.kt") public void testInline1() throws Exception { - runTest("../idea/tests/testData/exitPoints/inline1.kt"); + runTest("../../idea/tests/testData/exitPoints/inline1.kt"); } @TestMetadata("inline2.kt") public void testInline2() throws Exception { - runTest("../idea/tests/testData/exitPoints/inline2.kt"); + runTest("../../idea/tests/testData/exitPoints/inline2.kt"); } @TestMetadata("inline3.kt") public void testInline3() throws Exception { - runTest("../idea/tests/testData/exitPoints/inline3.kt"); + runTest("../../idea/tests/testData/exitPoints/inline3.kt"); } @TestMetadata("inlineLocalReturn1.kt") public void testInlineLocalReturn1() throws Exception { - runTest("../idea/tests/testData/exitPoints/inlineLocalReturn1.kt"); + runTest("../../idea/tests/testData/exitPoints/inlineLocalReturn1.kt"); } @TestMetadata("inlineLocalReturn2.kt") public void testInlineLocalReturn2() throws Exception { - runTest("../idea/tests/testData/exitPoints/inlineLocalReturn2.kt"); + runTest("../../idea/tests/testData/exitPoints/inlineLocalReturn2.kt"); } @TestMetadata("inlineLocalReturn3.kt") public void testInlineLocalReturn3() throws Exception { - runTest("../idea/tests/testData/exitPoints/inlineLocalReturn3.kt"); + runTest("../../idea/tests/testData/exitPoints/inlineLocalReturn3.kt"); } @TestMetadata("inlineWithNoInlineParam.kt") public void testInlineWithNoInlineParam() throws Exception { - runTest("../idea/tests/testData/exitPoints/inlineWithNoInlineParam.kt"); + runTest("../../idea/tests/testData/exitPoints/inlineWithNoInlineParam.kt"); } @TestMetadata("invalidReturn.kt") public void testInvalidReturn() throws Exception { - runTest("../idea/tests/testData/exitPoints/invalidReturn.kt"); + runTest("../../idea/tests/testData/exitPoints/invalidReturn.kt"); } @TestMetadata("invalidThrow.kt") public void testInvalidThrow() throws Exception { - runTest("../idea/tests/testData/exitPoints/invalidThrow.kt"); + runTest("../../idea/tests/testData/exitPoints/invalidThrow.kt"); } @TestMetadata("localFunction1.kt") public void testLocalFunction1() throws Exception { - runTest("../idea/tests/testData/exitPoints/localFunction1.kt"); + runTest("../../idea/tests/testData/exitPoints/localFunction1.kt"); } @TestMetadata("localFunction2.kt") public void testLocalFunction2() throws Exception { - runTest("../idea/tests/testData/exitPoints/localFunction2.kt"); + runTest("../../idea/tests/testData/exitPoints/localFunction2.kt"); } @TestMetadata("localFunctionThrow.kt") public void testLocalFunctionThrow() throws Exception { - runTest("../idea/tests/testData/exitPoints/localFunctionThrow.kt"); + runTest("../../idea/tests/testData/exitPoints/localFunctionThrow.kt"); } @TestMetadata("notInline1.kt") public void testNotInline1() throws Exception { - runTest("../idea/tests/testData/exitPoints/notInline1.kt"); + runTest("../../idea/tests/testData/exitPoints/notInline1.kt"); } @TestMetadata("notInline2.kt") public void testNotInline2() throws Exception { - runTest("../idea/tests/testData/exitPoints/notInline2.kt"); + runTest("../../idea/tests/testData/exitPoints/notInline2.kt"); } @TestMetadata("notInline3.kt") public void testNotInline3() throws Exception { - runTest("../idea/tests/testData/exitPoints/notInline3.kt"); + runTest("../../idea/tests/testData/exitPoints/notInline3.kt"); } @TestMetadata("notReturnedLabeledExpression.kt") public void testNotReturnedLabeledExpression() throws Exception { - runTest("../idea/tests/testData/exitPoints/notReturnedLabeledExpression.kt"); + runTest("../../idea/tests/testData/exitPoints/notReturnedLabeledExpression.kt"); } @TestMetadata("returnIfStatement.kt") public void testReturnIfStatement() throws Exception { - runTest("../idea/tests/testData/exitPoints/returnIfStatement.kt"); + runTest("../../idea/tests/testData/exitPoints/returnIfStatement.kt"); } @TestMetadata("returnTryStatement.kt") public void testReturnTryStatement() throws Exception { - runTest("../idea/tests/testData/exitPoints/returnTryStatement.kt"); + runTest("../../idea/tests/testData/exitPoints/returnTryStatement.kt"); } @TestMetadata("returnWhenStatement.kt") public void testReturnWhenStatement() throws Exception { - runTest("../idea/tests/testData/exitPoints/returnWhenStatement.kt"); + runTest("../../idea/tests/testData/exitPoints/returnWhenStatement.kt"); } @TestMetadata("simple.kt") public void testSimple() throws Exception { - runTest("../idea/tests/testData/exitPoints/simple.kt"); + runTest("../../idea/tests/testData/exitPoints/simple.kt"); } @TestMetadata("throw1.kt") public void testThrow1() throws Exception { - runTest("../idea/tests/testData/exitPoints/throw1.kt"); + runTest("../../idea/tests/testData/exitPoints/throw1.kt"); } @TestMetadata("throw2.kt") public void testThrow2() throws Exception { - runTest("../idea/tests/testData/exitPoints/throw2.kt"); + runTest("../../idea/tests/testData/exitPoints/throw2.kt"); } } diff --git a/plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightingMetaInfoTestGenerated.java b/plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightingMetaInfoTestGenerated.java similarity index 61% rename from plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightingMetaInfoTestGenerated.java rename to plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightingMetaInfoTestGenerated.java index a1db93b9184a..94a93eb3a87e 100644 --- a/plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightingMetaInfoTestGenerated.java +++ b/plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightingMetaInfoTestGenerated.java @@ -14,13 +14,13 @@ import org.junit.runner.RunWith; * DO NOT MODIFY MANUALLY. */ @SuppressWarnings("all") -@TestRoot("highlighting") +@TestRoot("highlighting/highlighting-k2") @TestDataPath("$CONTENT_ROOT") @RunWith(JUnit3RunnerWithInners.class) -@TestMetadata("../idea/tests/testData/highlighterMetaInfo") +@TestMetadata("../../idea/tests/testData/highlighterMetaInfo") public abstract class K2HighlightingMetaInfoTestGenerated extends AbstractK2HighlightingMetaInfoTest { @RunWith(JUnit3RunnerWithInners.class) - @TestMetadata("../idea/tests/testData/highlighterMetaInfo/diagnostics") + @TestMetadata("../../idea/tests/testData/highlighterMetaInfo/diagnostics") public static class Diagnostics extends AbstractK2HighlightingMetaInfoTest { private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); @@ -28,22 +28,22 @@ public abstract class K2HighlightingMetaInfoTestGenerated extends AbstractK2High @TestMetadata("classRedeclaration.kt") public void testClassRedeclaration() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/diagnostics/classRedeclaration.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/diagnostics/classRedeclaration.kt"); } @TestMetadata("javaCodeInKotlinFile1.kt") public void testJavaCodeInKotlinFile1() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/diagnostics/javaCodeInKotlinFile1.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/diagnostics/javaCodeInKotlinFile1.kt"); } @TestMetadata("mppIsNotEnabled.kt") public void testMppIsNotEnabled() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/diagnostics/mppIsNotEnabled.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/diagnostics/mppIsNotEnabled.kt"); } } @RunWith(JUnit3RunnerWithInners.class) - @TestMetadata("../idea/tests/testData/highlighterMetaInfo/dsl") + @TestMetadata("../../idea/tests/testData/highlighterMetaInfo/dsl") public static class Dsl extends AbstractK2HighlightingMetaInfoTest { private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); @@ -51,37 +51,37 @@ public abstract class K2HighlightingMetaInfoTestGenerated extends AbstractK2High @TestMetadata("AnnotatedTypeParameter.kt") public void testAnnotatedTypeParameter() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/dsl/AnnotatedTypeParameter.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/dsl/AnnotatedTypeParameter.kt"); } @TestMetadata("AnnotatedTypeSpecifier.kt") public void testAnnotatedTypeSpecifier() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/dsl/AnnotatedTypeSpecifier.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/dsl/AnnotatedTypeSpecifier.kt"); } @TestMetadata("ImplementsDslInterface.kt") public void testImplementsDslInterface() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/dsl/ImplementsDslInterface.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/dsl/ImplementsDslInterface.kt"); } @TestMetadata("NestedReceivers.kt") public void testNestedReceivers() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/dsl/NestedReceivers.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/dsl/NestedReceivers.kt"); } @TestMetadata("RegularDsl.kt") public void testRegularDsl() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/dsl/RegularDsl.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/dsl/RegularDsl.kt"); } @TestMetadata("SubclassOfDslClass.kt") public void testSubclassOfDslClass() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/dsl/SubclassOfDslClass.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/dsl/SubclassOfDslClass.kt"); } } @RunWith(JUnit3RunnerWithInners.class) - @TestMetadata("../idea/tests/testData/highlighterMetaInfo/smartCasts") + @TestMetadata("../../idea/tests/testData/highlighterMetaInfo/smartCasts") public static class SmartCasts extends AbstractK2HighlightingMetaInfoTest { private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); @@ -89,47 +89,47 @@ public abstract class K2HighlightingMetaInfoTestGenerated extends AbstractK2High @TestMetadata("Explicit.kt") public void testExplicit() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/smartCasts/Explicit.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/smartCasts/Explicit.kt"); } @TestMetadata("Explicit_qualifiedCalls.kt") public void testExplicit_qualifiedCalls() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/smartCasts/Explicit_qualifiedCalls.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/smartCasts/Explicit_qualifiedCalls.kt"); } @TestMetadata("Explicit_withInvokeCall.kt") public void testExplicit_withInvokeCall() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/smartCasts/Explicit_withInvokeCall.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/smartCasts/Explicit_withInvokeCall.kt"); } @TestMetadata("ImplicitAndExplicit_functions.kt") public void testImplicitAndExplicit_functions() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/smartCasts/ImplicitAndExplicit_functions.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/smartCasts/ImplicitAndExplicit_functions.kt"); } @TestMetadata("ImplicitAndExplicit_operators.kt") public void testImplicitAndExplicit_operators() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/smartCasts/ImplicitAndExplicit_operators.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/smartCasts/ImplicitAndExplicit_operators.kt"); } @TestMetadata("ImplicitAndExplicit_properties.kt") public void testImplicitAndExplicit_properties() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/smartCasts/ImplicitAndExplicit_properties.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/smartCasts/ImplicitAndExplicit_properties.kt"); } @TestMetadata("Implicit_stable.kt") public void testImplicit_stable() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/smartCasts/Implicit_stable.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/smartCasts/Implicit_stable.kt"); } @TestMetadata("Invokes.kt") public void testInvokes() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/smartCasts/Invokes.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/smartCasts/Invokes.kt"); } } @RunWith(JUnit3RunnerWithInners.class) - @TestMetadata("../idea/tests/testData/highlighterMetaInfo") + @TestMetadata("../../idea/tests/testData/highlighterMetaInfo") public static class Uncategorized extends AbstractK2HighlightingMetaInfoTest { private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); @@ -137,147 +137,147 @@ public abstract class K2HighlightingMetaInfoTestGenerated extends AbstractK2High @TestMetadata("Annotations.kt") public void testAnnotations() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/Annotations.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/Annotations.kt"); } @TestMetadata("AutoCreatedItParameter.kt") public void testAutoCreatedItParameter() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/AutoCreatedItParameter.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/AutoCreatedItParameter.kt"); } @TestMetadata("deprecation.kt") public void testDeprecation() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/deprecation.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/deprecation.kt"); } @TestMetadata("Destructuring.kt") public void testDestructuring() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/Destructuring.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/Destructuring.kt"); } @TestMetadata("Enums.kt") public void testEnums() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/Enums.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/Enums.kt"); } @TestMetadata("ExplicitInvokeCall.kt") public void testExplicitInvokeCall() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/ExplicitInvokeCall.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/ExplicitInvokeCall.kt"); } @TestMetadata("Field.kt") public void testField() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/Field.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/Field.kt"); } @TestMetadata("Functions.kt") public void testFunctions() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/Functions.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/Functions.kt"); } @TestMetadata("InvokeCall.kt") public void testInvokeCall() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/InvokeCall.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/InvokeCall.kt"); } @TestMetadata("javaFields.kt") public void testJavaFields() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/javaFields.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/javaFields.kt"); } @TestMetadata("JavaRecord.kt") public void testJavaRecord() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/JavaRecord.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/JavaRecord.kt"); } @TestMetadata("javaStaticFields.kt") public void testJavaStaticFields() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/javaStaticFields.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/javaStaticFields.kt"); } @TestMetadata("JavaTypes.kt") public void testJavaTypes() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/JavaTypes.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/JavaTypes.kt"); } @TestMetadata("KDoc.kt") public void testKDoc() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/KDoc.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/KDoc.kt"); } @TestMetadata("KotlinAnnotationsInJava.kt") public void testKotlinAnnotationsInJava() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/KotlinAnnotationsInJava.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/KotlinAnnotationsInJava.kt"); } @TestMetadata("KotlinInjection.kt") public void testKotlinInjection() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/KotlinInjection.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/KotlinInjection.kt"); } @TestMetadata("Labels.kt") public void testLabels() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/Labels.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/Labels.kt"); } @TestMetadata("NamedArguments.kt") public void testNamedArguments() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/NamedArguments.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/NamedArguments.kt"); } @TestMetadata("NonNullAssertion.kt") public void testNonNullAssertion() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/NonNullAssertion.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/NonNullAssertion.kt"); } @TestMetadata("Object.kt") public void testObject() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/Object.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/Object.kt"); } @TestMetadata("PropertiesWithPropertyDeclarations.kt") public void testPropertiesWithPropertyDeclarations() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/PropertiesWithPropertyDeclarations.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/PropertiesWithPropertyDeclarations.kt"); } @TestMetadata("Suspend.kt") public void testSuspend() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/Suspend.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/Suspend.kt"); } @TestMetadata("SyntheticExtensionProperty.kt") public void testSyntheticExtensionProperty() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/SyntheticExtensionProperty.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/SyntheticExtensionProperty.kt"); } @TestMetadata("Todo.kt") public void testTodo() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/Todo.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/Todo.kt"); } @TestMetadata("TypeAlias.kt") public void testTypeAlias() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/TypeAlias.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/TypeAlias.kt"); } @TestMetadata("TypesAndAnnotations.kt") public void testTypesAndAnnotations() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/TypesAndAnnotations.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/TypesAndAnnotations.kt"); } @TestMetadata("Variables.kt") public void testVariables() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/Variables.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/Variables.kt"); } @TestMetadata("VariablesAsFunctions.kt") public void testVariablesAsFunctions() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/VariablesAsFunctions.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/VariablesAsFunctions.kt"); } } @RunWith(JUnit3RunnerWithInners.class) - @TestMetadata("../idea/tests/testData/highlighterMetaInfo/unresolved") + @TestMetadata("../../idea/tests/testData/highlighterMetaInfo/unresolved") public static class Unresolved extends AbstractK2HighlightingMetaInfoTest { private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); @@ -285,17 +285,17 @@ public abstract class K2HighlightingMetaInfoTestGenerated extends AbstractK2High @TestMetadata("unresolvedImport.kt") public void testUnresolvedImport() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/unresolved/unresolvedImport.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/unresolved/unresolvedImport.kt"); } @TestMetadata("unresolvedLabel.kt") public void testUnresolvedLabel() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/unresolved/unresolvedLabel.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/unresolved/unresolvedLabel.kt"); } @TestMetadata("unresolvedReference.kt") public void testUnresolvedReference() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfo/unresolved/unresolvedReference.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfo/unresolved/unresolvedReference.kt"); } } } diff --git a/plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightingMetaInfoWithExtensionTestGenerated.java b/plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightingMetaInfoWithExtensionTestGenerated.java similarity index 83% rename from plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightingMetaInfoWithExtensionTestGenerated.java rename to plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightingMetaInfoWithExtensionTestGenerated.java index 5a3b88a8f7ee..6c2e66aeae5c 100644 --- a/plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightingMetaInfoWithExtensionTestGenerated.java +++ b/plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightingMetaInfoWithExtensionTestGenerated.java @@ -14,10 +14,10 @@ import org.junit.runner.RunWith; * DO NOT MODIFY MANUALLY. */ @SuppressWarnings("all") -@TestRoot("highlighting") +@TestRoot("highlighting/highlighting-k2") @TestDataPath("$CONTENT_ROOT") @RunWith(JUnit3RunnerWithInners.class) -@TestMetadata("../idea/tests/testData/highlighterMetaInfoWithExtension") +@TestMetadata("../../idea/tests/testData/highlighterMetaInfoWithExtension") public class K2HighlightingMetaInfoWithExtensionTestGenerated extends AbstractK2HighlightingMetaInfoWithExtensionTest { private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); @@ -25,6 +25,6 @@ public class K2HighlightingMetaInfoWithExtensionTestGenerated extends AbstractK2 @TestMetadata("Functions.kt") public void testFunctions() throws Exception { - runTest("../idea/tests/testData/highlighterMetaInfoWithExtension/Functions.kt"); + runTest("../../idea/tests/testData/highlighterMetaInfoWithExtension/Functions.kt"); } } diff --git a/plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightingOutsideSourceSetTest.kt b/plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightingOutsideSourceSetTest.kt similarity index 100% rename from plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightingOutsideSourceSetTest.kt rename to plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/K2HighlightingOutsideSourceSetTest.kt diff --git a/plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/OrphanOutsiderHighlightingTest.kt b/plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/OrphanOutsiderHighlightingTest.kt similarity index 100% rename from plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/OrphanOutsiderHighlightingTest.kt rename to plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/OrphanOutsiderHighlightingTest.kt diff --git a/plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/OutsiderHighlightingTestGenerated.java b/plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/OutsiderHighlightingTestGenerated.java similarity index 96% rename from plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/OutsiderHighlightingTestGenerated.java rename to plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/OutsiderHighlightingTestGenerated.java index 3f77a9267787..c753a959b691 100644 --- a/plugins/kotlin/highlighting/test/org/jetbrains/kotlin/idea/k2/highlighting/OutsiderHighlightingTestGenerated.java +++ b/plugins/kotlin/highlighting/highlighting-k2/test/org/jetbrains/kotlin/idea/k2/highlighting/OutsiderHighlightingTestGenerated.java @@ -13,7 +13,7 @@ import org.junit.runner.RunWith; * DO NOT MODIFY MANUALLY. */ @SuppressWarnings("all") -@TestRoot("highlighting") +@TestRoot("highlighting/highlighting-k2") @TestDataPath("$CONTENT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("testData/outsider") diff --git a/plugins/kotlin/highlighting/testData/outsider/badDiff/diff/main.kt b/plugins/kotlin/highlighting/highlighting-k2/testData/outsider/badDiff/diff/main.kt similarity index 100% rename from plugins/kotlin/highlighting/testData/outsider/badDiff/diff/main.kt rename to plugins/kotlin/highlighting/highlighting-k2/testData/outsider/badDiff/diff/main.kt diff --git a/plugins/kotlin/highlighting/testData/outsider/badDiff/src/lib.kt b/plugins/kotlin/highlighting/highlighting-k2/testData/outsider/badDiff/src/lib.kt similarity index 100% rename from plugins/kotlin/highlighting/testData/outsider/badDiff/src/lib.kt rename to plugins/kotlin/highlighting/highlighting-k2/testData/outsider/badDiff/src/lib.kt diff --git a/plugins/kotlin/highlighting/testData/outsider/badDiff/src/main.kt b/plugins/kotlin/highlighting/highlighting-k2/testData/outsider/badDiff/src/main.kt similarity index 100% rename from plugins/kotlin/highlighting/testData/outsider/badDiff/src/main.kt rename to plugins/kotlin/highlighting/highlighting-k2/testData/outsider/badDiff/src/main.kt diff --git a/plugins/kotlin/highlighting/testData/outsider/badSource/diff/main.kt b/plugins/kotlin/highlighting/highlighting-k2/testData/outsider/badSource/diff/main.kt similarity index 100% rename from plugins/kotlin/highlighting/testData/outsider/badSource/diff/main.kt rename to plugins/kotlin/highlighting/highlighting-k2/testData/outsider/badSource/diff/main.kt diff --git a/plugins/kotlin/highlighting/testData/outsider/badSource/src/lib.kt b/plugins/kotlin/highlighting/highlighting-k2/testData/outsider/badSource/src/lib.kt similarity index 100% rename from plugins/kotlin/highlighting/testData/outsider/badSource/src/lib.kt rename to plugins/kotlin/highlighting/highlighting-k2/testData/outsider/badSource/src/lib.kt diff --git a/plugins/kotlin/highlighting/testData/outsider/badSource/src/main.kt b/plugins/kotlin/highlighting/highlighting-k2/testData/outsider/badSource/src/main.kt similarity index 100% rename from plugins/kotlin/highlighting/testData/outsider/badSource/src/main.kt rename to plugins/kotlin/highlighting/highlighting-k2/testData/outsider/badSource/src/main.kt diff --git a/plugins/kotlin/highlighting/testData/outsider/badSourceDiff/diff/main.kt b/plugins/kotlin/highlighting/highlighting-k2/testData/outsider/badSourceDiff/diff/main.kt similarity index 100% rename from plugins/kotlin/highlighting/testData/outsider/badSourceDiff/diff/main.kt rename to plugins/kotlin/highlighting/highlighting-k2/testData/outsider/badSourceDiff/diff/main.kt diff --git a/plugins/kotlin/highlighting/testData/outsider/badSourceDiff/src/lib.kt b/plugins/kotlin/highlighting/highlighting-k2/testData/outsider/badSourceDiff/src/lib.kt similarity index 100% rename from plugins/kotlin/highlighting/testData/outsider/badSourceDiff/src/lib.kt rename to plugins/kotlin/highlighting/highlighting-k2/testData/outsider/badSourceDiff/src/lib.kt diff --git a/plugins/kotlin/highlighting/testData/outsider/badSourceDiff/src/main.kt b/plugins/kotlin/highlighting/highlighting-k2/testData/outsider/badSourceDiff/src/main.kt similarity index 100% rename from plugins/kotlin/highlighting/testData/outsider/badSourceDiff/src/main.kt rename to plugins/kotlin/highlighting/highlighting-k2/testData/outsider/badSourceDiff/src/main.kt diff --git a/plugins/kotlin/highlighting/testData/outsider/circularDependency/diff/main.kt b/plugins/kotlin/highlighting/highlighting-k2/testData/outsider/circularDependency/diff/main.kt similarity index 100% rename from plugins/kotlin/highlighting/testData/outsider/circularDependency/diff/main.kt rename to plugins/kotlin/highlighting/highlighting-k2/testData/outsider/circularDependency/diff/main.kt diff --git a/plugins/kotlin/highlighting/testData/outsider/circularDependency/diff/other.kt b/plugins/kotlin/highlighting/highlighting-k2/testData/outsider/circularDependency/diff/other.kt similarity index 100% rename from plugins/kotlin/highlighting/testData/outsider/circularDependency/diff/other.kt rename to plugins/kotlin/highlighting/highlighting-k2/testData/outsider/circularDependency/diff/other.kt diff --git a/plugins/kotlin/highlighting/testData/outsider/circularDependency/src/lib.kt b/plugins/kotlin/highlighting/highlighting-k2/testData/outsider/circularDependency/src/lib.kt similarity index 100% rename from plugins/kotlin/highlighting/testData/outsider/circularDependency/src/lib.kt rename to plugins/kotlin/highlighting/highlighting-k2/testData/outsider/circularDependency/src/lib.kt diff --git a/plugins/kotlin/highlighting/testData/outsider/circularDependency/src/main.kt b/plugins/kotlin/highlighting/highlighting-k2/testData/outsider/circularDependency/src/main.kt similarity index 100% rename from plugins/kotlin/highlighting/testData/outsider/circularDependency/src/main.kt rename to plugins/kotlin/highlighting/highlighting-k2/testData/outsider/circularDependency/src/main.kt diff --git a/plugins/kotlin/highlighting/testData/outsider/circularDependency/src/other.kt b/plugins/kotlin/highlighting/highlighting-k2/testData/outsider/circularDependency/src/other.kt similarity index 100% rename from plugins/kotlin/highlighting/testData/outsider/circularDependency/src/other.kt rename to plugins/kotlin/highlighting/highlighting-k2/testData/outsider/circularDependency/src/other.kt diff --git a/plugins/kotlin/highlighting/highlighting-shared/kotlin.highlighting.shared.iml b/plugins/kotlin/highlighting/highlighting-shared/kotlin.highlighting.shared.iml new file mode 100644 index 000000000000..971834542d02 --- /dev/null +++ b/plugins/kotlin/highlighting/highlighting-shared/kotlin.highlighting.shared.iml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/kotlin/base/highlighting/resources/messages/KotlinBaseHighlightingBundle.properties b/plugins/kotlin/highlighting/highlighting-shared/resources/messages/KotlinBaseHighlightingBundle.properties similarity index 100% rename from plugins/kotlin/base/highlighting/resources/messages/KotlinBaseHighlightingBundle.properties rename to plugins/kotlin/highlighting/highlighting-shared/resources/messages/KotlinBaseHighlightingBundle.properties diff --git a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/AbstractKotlinHighlightExitPointsHandlerFactory.kt b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/AbstractKotlinHighlightExitPointsHandlerFactory.kt similarity index 76% rename from plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/AbstractKotlinHighlightExitPointsHandlerFactory.kt rename to plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/AbstractKotlinHighlightExitPointsHandlerFactory.kt index aae19678aa4d..6af9d5cdeb4b 100644 --- a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/AbstractKotlinHighlightExitPointsHandlerFactory.kt +++ b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/AbstractKotlinHighlightExitPointsHandlerFactory.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.parents import org.jetbrains.kotlin.resolve.inline.InlineUtil import org.jetbrains.kotlin.utils.addIfNotNull +import java.util.* abstract class AbstractKotlinHighlightExitPointsHandlerFactory : HighlightUsagesHandlerFactoryBase() { private fun getOnReturnOrThrowUsageHandler(editor: Editor, file: PsiFile, target: PsiElement): HighlightUsagesHandlerBase<*>? { @@ -35,6 +36,15 @@ abstract class AbstractKotlinHighlightExitPointsHandlerFactory : HighlightUsages return OnExitUsagesHandler(editor, file, expression, false) } + private fun getOnBreakOrContinueUsageHandler(editor: Editor, file: PsiFile, target: PsiElement): HighlightUsagesHandlerBase<*>? { + val expression = when (val parent = target.parent) { + is KtBreakExpression, is KtContinueExpression -> parent + is KtLoopExpression -> parent + else -> null + } as? KtExpression ?: return null + return OnLoopUsagesHandler(editor, file, expression, false) + } + private fun getOnLambdaCallUsageHandler(editor: Editor, file: PsiFile, target: PsiElement): HighlightUsagesHandlerBase<*>? { if (target !is LeafPsiElement || target.elementType !is KtToken // do not trigger loading of KtTokens in Java @@ -57,6 +67,7 @@ abstract class AbstractKotlinHighlightExitPointsHandlerFactory : HighlightUsages override fun createHighlightUsagesHandler(editor: Editor, file: PsiFile, target: PsiElement): HighlightUsagesHandlerBase<*>? { return getOnReturnOrThrowUsageHandler(editor, file, target) + ?: getOnBreakOrContinueUsageHandler(editor, file, target) ?: getOnLambdaCallUsageHandler(editor, file, target) } @@ -91,7 +102,7 @@ abstract class AbstractKotlinHighlightExitPointsHandlerFactory : HighlightUsages private inner class OnExitUsagesHandler(editor: Editor, file: PsiFile, val target: KtExpression, val highlightReferences: Boolean) : HighlightUsagesHandlerBase(editor, file) { - override fun getTargets() = listOf(target) + override fun getTargets(): List = listOf(target) override fun selectTargets(targets: List, selectionConsumer: Consumer>) { selectionConsumer.consume(targets) @@ -290,6 +301,89 @@ abstract class AbstractKotlinHighlightExitPointsHandlerFactory : HighlightUsages override fun highlightReferences(): Boolean = highlightReferences } + private inner class OnLoopUsagesHandler(editor: Editor, file: PsiFile, val target: KtExpression, val highlightReferences: Boolean) : + HighlightUsagesHandlerBase(editor, file) { + override fun getTargets(): List = listOf(target) + + override fun selectTargets(targets: List, selectionConsumer: Consumer>) { + selectionConsumer.consume(targets) + } + + override fun computeUsages(targets: MutableList) { + val labelName = when (target) { + is KtExpressionWithLabel -> target.getLabelName() + is KtLoopExpression -> (target.parent as? KtLabeledExpression)?.getLabelName() + else -> null + } + val relevantLoop: KtLoopExpression = when (target) { + is KtLoopExpression -> target + else -> { + var element: PsiElement? = target + var targetLoop: KtLoopExpression? = null + while (element != null) { + val parent = element.parent + if (element is KtLoopExpression && (labelName == null || (parent as? KtLabeledExpression)?.getLabelName() == labelName)) { + targetLoop = element + break + } + element = parent + } + targetLoop + } + } ?: return + + when(relevantLoop) { + is KtForExpression -> addOccurrence(relevantLoop.forKeyword) + is KtDoWhileExpression -> relevantLoop.node.findChildByType(KtTokens.DO_KEYWORD)?.psi?.let(::addOccurrence) + is KtWhileExpression -> relevantLoop.node.findChildByType(KtTokens.WHILE_KEYWORD)?.psi?.let(::addOccurrence) + } + + + + relevantLoop.accept(object : KtVisitorVoid() { + var nestedLoopExpressions = Stack() + + override fun visitKtElement(element: KtElement) { + ProgressIndicatorProvider.checkCanceled() + element.acceptChildren(this) + } + + override fun visitExpression(expression: KtExpression) { + val nestedLoopFound = if (expression != relevantLoop && expression is KtLoopExpression) { + val loopLabelName = (expression.parent as? KtLabeledExpression)?.getLabelName() + // no reasons to step into another loop with the same label name or no label name + if (labelName == null || labelName == loopLabelName) return + + nestedLoopExpressions.push(expression) + true + } else { + false + } + + if (expression is KtBreakExpression || expression is KtContinueExpression) { + val expressionLabelName = (expression as? KtExpressionWithLabel)?.getLabelName() + if (nestedLoopExpressions.isEmpty()) { + if (expressionLabelName == null || expressionLabelName == labelName) { + addOccurrence(expression) + } + } else if (expressionLabelName == labelName) { + addOccurrence(expression) + } + } + + try { + super.visitExpression(expression) + } finally { + if (nestedLoopFound) { + nestedLoopExpressions.pop() + } + } + } + }) + } + + } + private fun MutableSet.addIfNotNullAndNotBlock(element: PsiElement?) { addIfNotNull(element.takeUnless { it is KtBlockExpression }) } diff --git a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/HighlightingFactory.kt b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/HighlightingFactory.kt similarity index 100% rename from plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/HighlightingFactory.kt rename to plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/HighlightingFactory.kt diff --git a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinBaseHighlightingBundle.kt b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinBaseHighlightingBundle.kt similarity index 100% rename from plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinBaseHighlightingBundle.kt rename to plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinBaseHighlightingBundle.kt diff --git a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinBeforeResolveHighlightingPass.kt b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinBeforeResolveHighlightingPass.kt similarity index 100% rename from plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinBeforeResolveHighlightingPass.kt rename to plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinBeforeResolveHighlightingPass.kt diff --git a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinHighlighterAttributeUtils.kt b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinHighlighterAttributeUtils.kt similarity index 100% rename from plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinHighlighterAttributeUtils.kt rename to plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinHighlighterAttributeUtils.kt diff --git a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinHighlightingUtils.kt b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinHighlightingUtils.kt similarity index 100% rename from plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinHighlightingUtils.kt rename to plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinHighlightingUtils.kt diff --git a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinSyntaxHighlighterFactory.kt b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinSyntaxHighlighterFactory.kt similarity index 100% rename from plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinSyntaxHighlighterFactory.kt rename to plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/KotlinSyntaxHighlighterFactory.kt diff --git a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/dsl/DslStyleUtils.kt b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/dsl/DslStyleUtils.kt similarity index 100% rename from plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/dsl/DslStyleUtils.kt rename to plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/dsl/DslStyleUtils.kt diff --git a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/visitor/AbstractHighlightingVisitor.kt b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/visitor/AbstractHighlightingVisitor.kt similarity index 100% rename from plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/base/highlighting/visitor/AbstractHighlightingVisitor.kt rename to plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/base/highlighting/visitor/AbstractHighlightingVisitor.kt diff --git a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/highlighter/AbstractHighlightingPassBase.kt b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/highlighter/AbstractHighlightingPassBase.kt similarity index 100% rename from plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/highlighter/AbstractHighlightingPassBase.kt rename to plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/highlighter/AbstractHighlightingPassBase.kt diff --git a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/highlighter/BeforeResolveHighlightingVisitor.kt b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/highlighter/BeforeResolveHighlightingVisitor.kt similarity index 100% rename from plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/highlighter/BeforeResolveHighlightingVisitor.kt rename to plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/highlighter/BeforeResolveHighlightingVisitor.kt diff --git a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/highlighter/KotlinColorSettingsPage.kt b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/highlighter/KotlinColorSettingsPage.kt similarity index 100% rename from plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/highlighter/KotlinColorSettingsPage.kt rename to plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/highlighter/KotlinColorSettingsPage.kt diff --git a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlightInfoTypeSemanticNames.kt b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlightInfoTypeSemanticNames.kt similarity index 100% rename from plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlightInfoTypeSemanticNames.kt rename to plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlightInfoTypeSemanticNames.kt diff --git a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlighter.java b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlighter.java similarity index 100% rename from plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlighter.java rename to plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlighter.java diff --git a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlightingColors.java b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlightingColors.java similarity index 100% rename from plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlightingColors.java rename to plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlightingColors.java diff --git a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlightingLexer.java b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlightingLexer.java similarity index 100% rename from plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlightingLexer.java rename to plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/highlighter/KotlinHighlightingLexer.java diff --git a/plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/highlighter/KotlinProblemHighlightFilter.kt b/plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/highlighter/KotlinProblemHighlightFilter.kt similarity index 100% rename from plugins/kotlin/base/highlighting/src/org/jetbrains/kotlin/idea/highlighter/KotlinProblemHighlightFilter.kt rename to plugins/kotlin/highlighting/highlighting-shared/src/org/jetbrains/kotlin/idea/highlighter/KotlinProblemHighlightFilter.kt diff --git a/plugins/kotlin/idea/kotlin.idea.iml b/plugins/kotlin/idea/kotlin.idea.iml index 530cceed6a65..4542047d3673 100644 --- a/plugins/kotlin/idea/kotlin.idea.iml +++ b/plugins/kotlin/idea/kotlin.idea.iml @@ -54,7 +54,7 @@ - + @@ -127,5 +127,6 @@ + \ No newline at end of file diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/actions/KotlinAddImportAction.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/actions/KotlinAddImportAction.kt index 17ff8cdff859..775af7c19fb0 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/actions/KotlinAddImportAction.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/actions/KotlinAddImportAction.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.PackageViewDescriptor import org.jetbrains.kotlin.idea.KotlinDescriptorIconProvider +import org.jetbrains.kotlin.idea.actions.KotlinAddImportActionInfo.executeListener import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference @@ -179,7 +180,7 @@ class KotlinAddImportAction internal constructor( if (!element.isValid) return false val variantsList = variantsList() - KotlinAddImportActionInfo.executeListener?.onExecute(variantsList) + element.containingKtFile.executeListener?.onExecute(variantsList) if (variantsList.isEmpty()) return false diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/codeInliner/ReplacementPerformer.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/codeInliner/ReplacementPerformer.kt index c5d604c0d964..cf92e95588eb 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/codeInliner/ReplacementPerformer.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/codeInliner/ReplacementPerformer.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-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.codeInliner @@ -102,8 +102,7 @@ private fun callWithoutLambdaArguments(callExpression: KtCallElement): String { val argumentExpression = lambdaArgument.getArgumentExpression() ?: return callExpression.text return lambdaArgument.moveInsideParenthesesAndReplaceWith( replacement = argumentExpression, - functionLiteralArgumentName = null, - withNameCheck = false + lambdaArgumentName = null, ).text ?: callExpression.text } diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/Utils.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/Utils.kt index d220af17b0e3..6a4210df70d4 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/Utils.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/formatter/Utils.kt @@ -7,6 +7,7 @@ import org.jetbrains.kotlin.idea.codeinsight.utils.commitAndUnblockDocument as _ @Deprecated( "Please use `org.jetbrains.kotlin.idea.codeinsight.utils.commitAndUnblockDocument` instead", - ReplaceWith("commitAndUnblockDocument()", "org.jetbrains.kotlin.idea.codeinsight.utils.commitAndUnblockDocument") + ReplaceWith("commitAndUnblockDocument()", "org.jetbrains.kotlin.idea.codeinsight.utils.commitAndUnblockDocument"), + level = DeprecationLevel.ERROR ) fun PsiFile.commitAndUnblockDocument(): Boolean = _commitAndUnblockDocument() \ No newline at end of file diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt index c17a00b5be2c..072e02f38663 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt @@ -2,20 +2,20 @@ package org.jetbrains.kotlin.idea.highlighter.markers -import com.intellij.codeInsight.daemon.* +import com.intellij.codeInsight.daemon.GutterIconNavigationHandler +import com.intellij.codeInsight.daemon.LineMarkerInfo +import com.intellij.codeInsight.daemon.NavigateAction import com.intellij.codeInsight.daemon.impl.InheritorsLineMarkerNavigator import com.intellij.codeInsight.daemon.impl.LineMarkerNavigator import com.intellij.codeInsight.daemon.impl.MarkerType import com.intellij.java.JavaBundle import com.intellij.openapi.actionSystem.IdeActions -import com.intellij.openapi.editor.colors.CodeInsightColors -import com.intellij.openapi.editor.colors.EditorColorsManager import com.intellij.openapi.editor.markup.GutterIconRenderer -import com.intellij.openapi.editor.markup.SeparatorPlacement import com.intellij.openapi.progress.ProgressManager -import com.intellij.openapi.project.DumbService -import com.intellij.openapi.util.text.StringUtil -import com.intellij.psi.* +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiIdentifier +import com.intellij.psi.PsiMethod +import com.intellij.psi.PsiNameIdentifierOwner import com.intellij.psi.search.searches.ClassInheritorsSearch import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.asJava.LightClassUtil @@ -24,9 +24,9 @@ import org.jetbrains.kotlin.asJava.toFakeLightClass import org.jetbrains.kotlin.asJava.toLightClass import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.idea.base.projectStructure.RootKindFilter -import org.jetbrains.kotlin.idea.base.projectStructure.matches import org.jetbrains.kotlin.idea.base.resources.KotlinBundle +import org.jetbrains.kotlin.idea.codeInsight.lineMarkers.shared.AbstractKotlinLineMarkerProvider +import org.jetbrains.kotlin.idea.codeInsight.lineMarkers.shared.LineMarkerInfos import org.jetbrains.kotlin.idea.codeInsight.lineMarkers.shared.NavigationPopupDescriptor import org.jetbrains.kotlin.idea.codeInsight.lineMarkers.shared.TestableLineMarkerNavigator import org.jetbrains.kotlin.idea.core.isInheritable @@ -38,53 +38,11 @@ import org.jetbrains.kotlin.idea.util.isEffectivelyActual import org.jetbrains.kotlin.idea.util.isExpectDeclaration import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.getPrevSiblingIgnoringWhitespaceAndComments import java.awt.event.MouseEvent -class KotlinLineMarkerProvider : LineMarkerProviderDescriptor() { - override fun getName() = KotlinBundle.message("highlighter.name.kotlin.line.markers") - - override fun getOptions(): Array \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java index 47245873c94f..b3b8c8af2c5c 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java @@ -772,6 +772,11 @@ public abstract class FindUsagesTestGenerated extends AbstractFindUsagesTest { runTest("testData/findUsages/kotlin/findFunctionUsages/kotlinOverloadAndExtensionUsages4.0.kt"); } + @TestMetadata("kotlinOverloadAndExtensionUsages5.0.kt") + public void testKotlinOverloadAndExtensionUsages5() throws Exception { + runTest("testData/findUsages/kotlin/findFunctionUsages/kotlinOverloadAndExtensionUsages5.0.kt"); + } + @TestMetadata("kotlinPrivateMethodUsages.0.kt") public void testKotlinPrivateMethodUsages() throws Exception { runTest("testData/findUsages/kotlin/findFunctionUsages/kotlinPrivateMethodUsages.0.kt"); diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/actions/AbstractAddImportActionTestBase.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/actions/AbstractAddImportActionTestBase.kt index 20a000dfb85e..e39d00fdfc71 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/actions/AbstractAddImportActionTestBase.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/actions/AbstractAddImportActionTestBase.kt @@ -36,7 +36,7 @@ abstract class AbstractAddImportActionTestBase : KotlinLightCodeInsightFixtureTe actualVariants = variants } } - KotlinAddImportActionInfo.setExecuteListener(testRootDisposable, executeListener) + KotlinAddImportActionInfo.setExecuteListener(file, testRootDisposable, executeListener) (StatisticsManager.getInstance() as StatisticsManagerImpl).enableStatistics(myFixture.testRootDisposable) increaseUseCountOf(InTextDirectivesUtils.findListWithPrefixes(fixture.file.text, INCREASE_USE_COUNT_DIRECTIVE)) diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/actions/NewKotlinFileActionTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/actions/NewKotlinFileActionTest.kt index e1af58f0fb08..25daffc61102 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/actions/NewKotlinFileActionTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/actions/NewKotlinFileActionTest.kt @@ -133,5 +133,6 @@ class NewKotlinFileActionTest : BasePlatformTestCase() { "class $expectedClassName" } assertEquals(expectedContent, file.text) + assertEquals("Create action should not modify predefined template", "", testTemplate.fileName) } } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/caches/resolve/AbstractMultiModuleHighlightingTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/caches/resolve/AbstractMultiModuleHighlightingTest.kt index d3d951a24e6b..e9372daed0a3 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/caches/resolve/AbstractMultiModuleHighlightingTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/caches/resolve/AbstractMultiModuleHighlightingTest.kt @@ -2,30 +2,16 @@ package org.jetbrains.kotlin.idea.caches.resolve -import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl import com.intellij.psi.PsiFile -import org.jetbrains.kotlin.idea.codeInsight.AbstractLineMarkersTest import org.jetbrains.kotlin.idea.multiplatform.setupMppProjectFromDirStructure import org.jetbrains.kotlin.idea.stubs.AbstractMultiHighlightingTest import org.jetbrains.kotlin.idea.test.IDEA_TEST_DATA_DIR import org.jetbrains.kotlin.idea.test.allJavaFiles import org.jetbrains.kotlin.idea.test.allKotlinFiles -import org.jetbrains.kotlin.psi.KtFile import java.io.File abstract class AbstractMultiModuleHighlightingTest : AbstractMultiHighlightingTest() { - protected open fun checkLineMarkersInProject( - findFiles: () -> List = { project.allKotlinFiles().excludeByDirective() } - ) { - checkFiles(findFiles) { - checkHighlighting(myEditor, true, false) - - val markers = DaemonCodeAnalyzerImpl.getLineMarkers(getDocument(file), project) - AbstractLineMarkersTest.assertNavigationElements(project, myFile as KtFile, myEditor, markers) - } - } - protected open fun checkHighlightingInProject( findFiles: () -> List = { project.allKotlinFiles().excludeByDirective() } ) { diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/caches/resolve/IdeaModuleInfoTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/caches/resolve/IdeaModuleInfoTest.kt index f4c47306fc21..99b64f70b2c7 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/caches/resolve/IdeaModuleInfoTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/caches/resolve/IdeaModuleInfoTest.kt @@ -2215,9 +2215,9 @@ class IdeaModuleInfoTest8 : JavaModuleTestCase() { private fun stdlibJvm(): LibraryEx = projectLibrary("kotlin-stdlib", TestKotlinArtifacts.kotlinStdlib.jarRoot) private fun stdlibJs(): LibraryEx = projectLibrary( - "kotlin-stdlib-js", - TestKotlinArtifacts.kotlinStdlibJs.jarRoot, - kind = KotlinJavaScriptLibraryKind + "kotlin-stdlib-js", + LocalFileSystem.getInstance().refreshAndFindFileByIoFile(TestKotlinArtifacts.kotlinStdlibJs), + kind = KotlinJavaScriptLibraryKind ) private fun stdlibWasm(): LibraryEx = projectLibrary( diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/codeInsight/AbstractLineMarkersTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/codeInsight/AbstractLineMarkersTest.kt index 53724a01e4cd..34cfafd94ad9 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/codeInsight/AbstractLineMarkersTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/codeInsight/AbstractLineMarkersTest.kt @@ -9,8 +9,8 @@ import com.intellij.codeInsight.daemon.LineMarkerSettings import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl import com.intellij.codeInsight.daemon.impl.InheritorsLineMarkerNavigator import com.intellij.codeInsight.navigation.GotoImplementationHandler +import com.intellij.openapi.actionSystem.ex.ActionUtil import com.intellij.openapi.editor.Document -import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project import com.intellij.openapi.util.io.FileUtil import com.intellij.psi.PsiDocumentManager @@ -38,7 +38,7 @@ abstract class AbstractLineMarkersTest : KotlinLightCodeInsightFixtureTestCase() return KotlinWithJdkAndRuntimeLightProjectDescriptor.getInstance() } - fun doTest(path: String) = doTest(path) {} + protected open fun doTest(path: String) = doTest(path) {} protected fun doAndCheckHighlighting( psiFile: PsiFile, @@ -48,7 +48,7 @@ abstract class AbstractLineMarkersTest : KotlinLightCodeInsightFixtureTestCase() ): List> { myFixture.doHighlighting() - return checkHighlighting(psiFile, documentToAnalyze, expectedHighlighting, expectedFile) + return checkHighlighting(project, psiFile, documentToAnalyze, expectedHighlighting, expectedFile) } fun doTest(@Suppress("UNUSED_PARAMETER") unused: String, additionalCheck: () -> Unit) { @@ -93,7 +93,7 @@ abstract class AbstractLineMarkersTest : KotlinLightCodeInsightFixtureTestCase() val markers = doAndCheckHighlighting(ktFile, document, data, dataFile()) - assertNavigationElements(myFixture.project, ktFile, myFixture.editor, markers) + assertNavigationElements(markers) additionalCheck() } catch (exc: Exception) { throw RuntimeException(exc) @@ -104,7 +104,97 @@ abstract class AbstractLineMarkersTest : KotlinLightCodeInsightFixtureTestCase() LineMarkerSettings.getSettings().setEnabled(it, true) } } + } + private fun assertNavigationElements(markers: List>) { + val navigationDataComments = KotlinTestUtils.getLastCommentsInFile( + myFixture.file as KtFile, KotlinTestUtils.CommentType.BLOCK_COMMENT, false + ) + if (navigationDataComments.isEmpty()) return + val markerCodeMetaInfos = markers.map { InnerLineMarkerCodeMetaInfo(InnerLineMarkerConfiguration.configuration, it) } + + for ((navigationCommentIndex, navigationComment) in navigationDataComments.reversed().withIndex()) { + val description = getLineMarkerDescription(navigationComment) + val navigateMarkers = ActionUtil.underModalProgress(project, "") { + markerCodeMetaInfos.filter { it.asString() == description } + } + val navigateMarker = navigateMarkers.singleOrNull() ?: navigateMarkers.getOrNull(navigationCommentIndex) + + TestCase.assertNotNull( + String.format("Can't find marker for navigation check with description \"%s\"\n\navailable: \n\n%s", + description, + ActionUtil.underModalProgress(project, "") { + markerCodeMetaInfos.joinToString("\n\n") { it.asString() } + }), + navigateMarker + ) + + val lineMarker = navigateMarker!!.lineMarker + + getActualNavigationDataAndCompare(lineMarker, navigationComment) + } + } + + open fun getActualNavigationDataAndCompare(lineMarker: LineMarkerInfo<*>, navigationComment: String) { + when (val handler = lineMarker.navigationHandler) { + is InheritorsLineMarkerNavigator -> { + val gotoData = + GotoImplementationHandler().createDataForSourceForTests(editor, lineMarker.element!!.parent!!) + val targets = gotoData.targets.toMutableList().sortedBy { + it.renderAsGotoImplementation() + } + val actualNavigationData = NavigationTestUtils.getNavigateElementsText(project, targets) + + UsefulTestCase.assertSameLines(getExpectedNavigationText(navigationComment), actualNavigationData) + + } + + is TestableLineMarkerNavigator -> { + val navigateElements = handler.getTargetsPopupDescriptor(lineMarker.element)?.targets?.sortedBy { + it.renderAsGotoImplementation() + } + val actualNavigationData = NavigationTestUtils.getNavigateElementsText(project, navigateElements) + + UsefulTestCase.assertSameLines(getExpectedNavigationText(navigationComment), actualNavigationData) + } + + else -> { + Assert.fail("Only TestableLineMarkerNavigator are supported in navigate check") + } + } + } + + private fun getLineMarkerDescription(navigationComment: String): String { + val firstLineEnd = navigationComment.indexOf("\n") + TestCase.assertTrue( + "The first line in block comment must contain description of marker for navigation check", firstLineEnd != -1 + ) + + var navigationMarkerText = navigationComment.substring(0, firstLineEnd) + + TestCase.assertTrue( + String.format("Add %s directive in first line of comment", LINE_MARKER_PREFIX), + navigationMarkerText.startsWith(LINE_MARKER_PREFIX) + ) + + navigationMarkerText = navigationMarkerText.substring(LINE_MARKER_PREFIX.length) + + return navigationMarkerText.trim { it <= ' ' } + } + + fun getExpectedNavigationText(navigationComment: String): String { + val firstLineEnd = navigationComment.indexOf("\n") + + var expectedNavigationText = navigationComment.substring(firstLineEnd + 1) + + TestCase.assertTrue( + String.format("Marker %s is expected before navigation data", TARGETS_PREFIX), + expectedNavigationText.startsWith(TARGETS_PREFIX) + ) + + expectedNavigationText = expectedNavigationText.substring(expectedNavigationText.indexOf("\n") + 1) + + return expectedNavigationText } companion object { @@ -113,90 +203,8 @@ abstract class AbstractLineMarkersTest : KotlinLightCodeInsightFixtureTestCase() private const val LINE_MARKER_PREFIX = "LINEMARKER:" private const val TARGETS_PREFIX = "TARGETS" - fun assertNavigationElements(project: Project, file: KtFile, editor : Editor, markers: List>) { - val navigationDataComments = KotlinTestUtils.getLastCommentsInFile( - file, KotlinTestUtils.CommentType.BLOCK_COMMENT, false - ) - if (navigationDataComments.isEmpty()) return - val markerCodeMetaInfos = markers.map { InnerLineMarkerCodeMetaInfo(InnerLineMarkerConfiguration.configuration, it) } - - for ((navigationCommentIndex, navigationComment) in navigationDataComments.reversed().withIndex()) { - val description = getLineMarkerDescription(navigationComment) - val navigateMarkers = markerCodeMetaInfos.filter { it.asString() == description } - val navigateMarker = navigateMarkers.singleOrNull() ?: navigateMarkers.getOrNull(navigationCommentIndex) - - TestCase.assertNotNull( - String.format("Can't find marker for navigation check with description \"%s\"\n\navailable: \n\n%s", - description, - markerCodeMetaInfos.joinToString("\n\n") { it.asString() }), - navigateMarker - ) - - val lineMarker = navigateMarker!!.lineMarker - - when (val handler = lineMarker.navigationHandler) { - is InheritorsLineMarkerNavigator -> { - val gotoData = - GotoImplementationHandler().createDataForSourceForTests(editor, lineMarker.element!!.parent!!) - val targets = gotoData.targets.toMutableList().sortedBy { - it.renderAsGotoImplementation() - } - val actualNavigationData = NavigationTestUtils.getNavigateElementsText(project, targets) - - UsefulTestCase.assertSameLines(getExpectedNavigationText(navigationComment), actualNavigationData) - - } - - is TestableLineMarkerNavigator -> { - val navigateElements = handler.getTargetsPopupDescriptor(lineMarker.element)?.targets?.sortedBy { - it.renderAsGotoImplementation() - } - val actualNavigationData = NavigationTestUtils.getNavigateElementsText(project, navigateElements) - - UsefulTestCase.assertSameLines(getExpectedNavigationText(navigationComment), actualNavigationData) - } - - else -> { - Assert.fail("Only TestableLineMarkerNavigator are supported in navigate check") - } - } - } - } - - private fun getLineMarkerDescription(navigationComment: String): String { - val firstLineEnd = navigationComment.indexOf("\n") - TestCase.assertTrue( - "The first line in block comment must contain description of marker for navigation check", firstLineEnd != -1 - ) - - var navigationMarkerText = navigationComment.substring(0, firstLineEnd) - - TestCase.assertTrue( - String.format("Add %s directive in first line of comment", LINE_MARKER_PREFIX), - navigationMarkerText.startsWith(LINE_MARKER_PREFIX) - ) - - navigationMarkerText = navigationMarkerText.substring(LINE_MARKER_PREFIX.length) - - return navigationMarkerText.trim { it <= ' ' } - } - - private fun getExpectedNavigationText(navigationComment: String): String { - val firstLineEnd = navigationComment.indexOf("\n") - - var expectedNavigationText = navigationComment.substring(firstLineEnd + 1) - - TestCase.assertTrue( - String.format("Marker %s is expected before navigation data", TARGETS_PREFIX), - expectedNavigationText.startsWith(TARGETS_PREFIX) - ) - - expectedNavigationText = expectedNavigationText.substring(expectedNavigationText.indexOf("\n") + 1) - - return expectedNavigationText - } - fun checkHighlighting( + project: Project, psiFile: PsiFile, documentToAnalyze: Document, expectedHighlighting: ExpectedHighlightingData, @@ -205,7 +213,9 @@ abstract class AbstractLineMarkersTest : KotlinLightCodeInsightFixtureTestCase() val markers = DaemonCodeAnalyzerImpl.getLineMarkers(documentToAnalyze, psiFile.project) try { - expectedHighlighting.checkLineMarkers(psiFile, markers, documentToAnalyze.text) + ActionUtil.underModalProgress(project, "") { + expectedHighlighting.checkLineMarkers(psiFile, markers, documentToAnalyze.text) + } // This is a workaround for sad bug in ExpectedHighlightingData: // the latter doesn't throw assertion error when some line markers are expected, but none are present. diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/codeInsight/LineMarkersTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/codeInsight/LineMarkersTestGenerated.java index 9008a726adbd..d918946d0500 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/codeInsight/LineMarkersTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/codeInsight/LineMarkersTestGenerated.java @@ -45,6 +45,19 @@ public abstract class LineMarkersTestGenerated extends AbstractLineMarkersTest { } } + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("testData/codeInsight/lineMarker/methodSeparators") + public static class MethodSeparators extends AbstractLineMarkersTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("MethodSeparators.kt") + public void testMethodSeparators() throws Exception { + runTest("testData/codeInsight/lineMarker/methodSeparators/MethodSeparators.kt"); + } + } + @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("testData/codeInsight/lineMarker/overrideImplement") public static class OverrideImplement extends AbstractLineMarkersTest { @@ -396,17 +409,4 @@ public abstract class LineMarkersTestGenerated extends AbstractLineMarkersTest { runTest("testData/codeInsight/lineMarker/suspendCall/suspendIteration.kt"); } } - - @RunWith(JUnit3RunnerWithInners.class) - @TestMetadata("testData/codeInsight/lineMarker") - public static class Uncategorized extends AbstractLineMarkersTest { - private void runTest(String testDataFilePath) throws Exception { - KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); - } - - @TestMetadata("MethodSeparators.kt") - public void testMethodSeparators() throws Exception { - runTest("testData/codeInsight/lineMarker/MethodSeparators.kt"); - } - } } diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/debugger/evaluate/AbstractCodeFragmentCompletionTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/debugger/evaluate/AbstractCodeFragmentCompletionTest.kt index 091801aa0443..9f293585ce3a 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/debugger/evaluate/AbstractCodeFragmentCompletionTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/debugger/evaluate/AbstractCodeFragmentCompletionTest.kt @@ -2,9 +2,9 @@ package org.jetbrains.kotlin.idea.debugger.evaluate -import org.jetbrains.kotlin.idea.completion.test.AbstractJvmBasicCompletionTest +import org.jetbrains.kotlin.idea.completion.test.AbstractJvmBasicCompletionTestBase -abstract class AbstractCodeFragmentCompletionTest : AbstractJvmBasicCompletionTest() { +abstract class AbstractCodeFragmentCompletionTest : AbstractJvmBasicCompletionTestBase() { override fun configureFixture(testPath: String) { myFixture.configureByCodeFragment(testPath) } diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/debugger/evaluate/CodeFragmentCompletionInLibraryTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/debugger/evaluate/CodeFragmentCompletionInLibraryTest.kt index 8babf345c56f..ab20d7643648 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/debugger/evaluate/CodeFragmentCompletionInLibraryTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/debugger/evaluate/CodeFragmentCompletionInLibraryTest.kt @@ -7,10 +7,10 @@ import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiManager import com.intellij.psi.search.GlobalSearchScope import com.intellij.util.ThrowableRunnable -import org.jetbrains.kotlin.idea.completion.test.AbstractJvmBasicCompletionTest +import org.jetbrains.kotlin.idea.completion.test.AbstractJvmBasicCompletionTestBase import org.jetbrains.kotlin.idea.completion.test.COMPLETION_TEST_DATA_BASE import org.jetbrains.kotlin.idea.completion.test.testCompletion -import org.jetbrains.kotlin.idea.debugger.core.getContextElement +import org.jetbrains.kotlin.idea.debugger.core.CodeFragmentContextTuner import org.jetbrains.kotlin.idea.test.MockLibraryFacility import org.jetbrains.kotlin.idea.test.runAll import org.jetbrains.kotlin.platform.jvm.JvmPlatforms @@ -22,7 +22,7 @@ import org.junit.runner.RunWith @RunWith(JUnit38ClassRunner::class) -class CodeFragmentCompletionInLibraryTest : AbstractJvmBasicCompletionTest() { +class CodeFragmentCompletionInLibraryTest : AbstractJvmBasicCompletionTestBase() { companion object { private val LIBRARY_SRC = COMPLETION_TEST_DATA_BASE.resolve("codeFragmentInLibrarySource/customLibrary/") } @@ -65,9 +65,14 @@ class CodeFragmentCompletionInLibraryTest : AbstractJvmBasicCompletionTest() { val sourceFile = findLibrarySourceDir().findChild("customLibrary.kt")!! val ktFile = PsiManager.getInstance(project).findFile(sourceFile) as KtFile val fooFunctionFromLibrary = ktFile.declarations.first() as KtFunction + + val contextTuner = CodeFragmentContextTuner.getInstance() + val contextElement = contextTuner.tuneContextElement(fooFunctionFromLibrary.bodyBlockExpression) + val psiFactory = KtPsiFactory(project) - val codeFragment = psiFactory.createExpressionCodeFragment(fragmentText, getContextElement(fooFunctionFromLibrary.bodyExpression)) + val codeFragment = psiFactory.createExpressionCodeFragment(fragmentText, contextElement) codeFragment.forceResolveScope(GlobalSearchScope.allScope(project)) + myFixture.configureFromExistingVirtualFile(codeFragment.virtualFile) } diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/debugger/evaluate/CodeFragmentTestUtils.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/debugger/evaluate/CodeFragmentTestUtils.kt index 46248d1b9eb3..b0d7ab72dbbd 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/debugger/evaluate/CodeFragmentTestUtils.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/debugger/evaluate/CodeFragmentTestUtils.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent import org.jetbrains.kotlin.idea.completion.test.ExpectedCompletionUtils import org.jetbrains.kotlin.idea.completion.test.ExpectedCompletionUtils.BLOCK_CODE_FRAGMENT import org.jetbrains.kotlin.idea.core.util.CodeFragmentUtils -import org.jetbrains.kotlin.idea.debugger.core.getContextElement +import org.jetbrains.kotlin.idea.debugger.core.CodeFragmentContextTuner import org.jetbrains.kotlin.psi.KtCodeFragment import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtPsiFactory @@ -61,14 +61,17 @@ internal fun JavaCodeInsightTestFixture.configureByCodeFragment(filePath: String configureFromExistingVirtualFile(file.virtualFile!!) } -internal fun createCodeFragment(filePath: String, contextElement: PsiElement, isBlock: Boolean): KtCodeFragment { +private fun createCodeFragment(filePath: String, contextElement: PsiElement, isBlock: Boolean): KtCodeFragment { + val contextTuner = CodeFragmentContextTuner.getInstance() + val effectiveContextElement = contextTuner.tuneContextElement(contextElement) + val fileForFragment = File("$filePath.fragment") val codeFragmentText = FileUtil.loadFile(fileForFragment, true).trim() val psiFactory = KtPsiFactory(contextElement.project) return if (isBlock) { - psiFactory.createBlockCodeFragment(codeFragmentText, getContextElement(contextElement)) + psiFactory.createBlockCodeFragment(codeFragmentText, effectiveContextElement) } else { - psiFactory.createExpressionCodeFragment(codeFragmentText, getContextElement(contextElement)) + psiFactory.createExpressionCodeFragment(codeFragmentText, effectiveContextElement) } } diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/decompiler/navigation/NavigateJavaToLibrarySourceTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/decompiler/navigation/NavigateJavaToLibrarySourceTestGenerated.java index a98c3a26b12f..74a16b26c1ef 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/decompiler/navigation/NavigateJavaToLibrarySourceTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/decompiler/navigation/NavigateJavaToLibrarySourceTestGenerated.java @@ -83,6 +83,11 @@ public class NavigateJavaToLibrarySourceTestGenerated extends AbstractNavigateJa runTest("testData/decompiler/navigation/userJavaCode/OverloadedFun.java"); } + @TestMetadata("PropertyFunctionOverload.java") + public void testPropertyFunctionOverload() throws Exception { + runTest("testData/decompiler/navigation/userJavaCode/PropertyFunctionOverload.java"); + } + @TestMetadata("RenamedElements.java") public void testRenamedElements() throws Exception { runTest("testData/decompiler/navigation/userJavaCode/RenamedElements.java"); diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/highlighter/CompiledFilesHighlightingTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/highlighter/CompiledFilesHighlightingTest.kt index 0c11546de23c..6f60a80bd892 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/highlighter/CompiledFilesHighlightingTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/highlighter/CompiledFilesHighlightingTest.kt @@ -4,6 +4,7 @@ package org.jetbrains.kotlin.idea.highlighter import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl import com.intellij.codeInsight.daemon.impl.analysis.FileHighlightingSetting import com.intellij.codeInsight.daemon.impl.analysis.HighlightingSettingsPerFile +import com.intellij.openapi.application.readAction import com.intellij.openapi.editor.impl.DocumentImpl import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.util.io.FileUtil @@ -16,8 +17,12 @@ import com.intellij.testFramework.ExpectedHighlightingData import com.intellij.testFramework.TestDataPath import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl import com.intellij.util.io.URLUtil +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runBlocking +import org.jetbrains.kotlin.idea.actions.bytecode.KotlinBytecodeToolWindow import org.jetbrains.kotlin.idea.base.plugin.artifacts.TestKotlinArtifacts import org.jetbrains.kotlin.idea.base.test.TestRoot +import org.jetbrains.kotlin.idea.jvmDecompiler.KotlinBytecodeDecompiler import org.jetbrains.kotlin.idea.jvmDecompiler.KotlinBytecodeDecompilerTask import org.jetbrains.kotlin.idea.test.* import org.jetbrains.kotlin.psi.KtFile @@ -51,7 +56,14 @@ class CompiledFilesHighlightingTest: KotlinLightCodeInsightFixtureTestCase() { doTestWithLibraryFile(TestKotlinArtifacts.kotlinStdlibCommonSources, FileHighlightingSetting.SKIP_HIGHLIGHTING) { val file = PsiManager.getInstance(project).findFile(it) ?: error("unable to locate PSI for $it") val ktFile = file as? KtFile ?: error("file expected to be KtFile") - KotlinBytecodeDecompilerTask(ktFile).generateDecompiledVirtualFile() ?: error("unable to generate decompiled file") + + val decompiledText = runBlocking(Dispatchers.Default) { + readAction { + KotlinBytecodeDecompiler.decompile(ktFile) ?: error("Cannot decompile file $ktFile") + } + } + + KotlinBytecodeDecompilerTask(ktFile).generateDecompiledVirtualFile(decompiledText) } } } diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/highlighter/HighlightExitPointsTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/highlighter/HighlightExitPointsTestGenerated.java index 8293f7a73901..838d88c6d11e 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/highlighter/HighlightExitPointsTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/highlighter/HighlightExitPointsTestGenerated.java @@ -33,6 +33,36 @@ public class HighlightExitPointsTestGenerated extends AbstractHighlightExitPoint runTest("testData/exitPoints/anonymousFunction2.kt"); } + @TestMetadata("forLoopBreak.kt") + public void testForLoopBreak() throws Exception { + runTest("testData/exitPoints/forLoopBreak.kt"); + } + + @TestMetadata("forLoopNestedBreak.kt") + public void testForLoopNestedBreak() throws Exception { + runTest("testData/exitPoints/forLoopNestedBreak.kt"); + } + + @TestMetadata("forLoopNestedBreak2.kt") + public void testForLoopNestedBreak2() throws Exception { + runTest("testData/exitPoints/forLoopNestedBreak2.kt"); + } + + @TestMetadata("forLoopNestedLabeledBreak.kt") + public void testForLoopNestedLabeledBreak() throws Exception { + runTest("testData/exitPoints/forLoopNestedLabeledBreak.kt"); + } + + @TestMetadata("forLoopNestedLabeledBreakOnLoop.kt") + public void testForLoopNestedLabeledBreakOnLoop() throws Exception { + runTest("testData/exitPoints/forLoopNestedLabeledBreakOnLoop.kt"); + } + + @TestMetadata("forLoopNestedLabeledBreakOnLoop2.kt") + public void testForLoopNestedLabeledBreakOnLoop2() throws Exception { + runTest("testData/exitPoints/forLoopNestedLabeledBreakOnLoop2.kt"); + } + @TestMetadata("funKeyword.kt") public void testFunKeyword() throws Exception { runTest("testData/exitPoints/funKeyword.kt"); diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/intentions/K1IntentionTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/intentions/K1IntentionTestGenerated.java index 700f4a383d6d..d2bb72df5c15 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/intentions/K1IntentionTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/intentions/K1IntentionTestGenerated.java @@ -8332,6 +8332,11 @@ public abstract class K1IntentionTestGenerated extends AbstractK1IntentionTest { runTest("testData/intentions/convertToBlockBody/nothingFun.kt"); } + @TestMetadata("nullableNothing.kt") + public void testNullableNothing() throws Exception { + runTest("testData/intentions/convertToBlockBody/nullableNothing.kt"); + } + @TestMetadata("overrideWithPlatformType.kt") public void testOverrideWithPlatformType() throws Exception { runTest("testData/intentions/convertToBlockBody/overrideWithPlatformType.kt"); diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/internal/AbstractBytecodeToolWindowMultiplatformTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/internal/AbstractBytecodeToolWindowMultiplatformTest.kt index afc857e31b6a..8ab9417751bb 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/internal/AbstractBytecodeToolWindowMultiplatformTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/internal/AbstractBytecodeToolWindowMultiplatformTest.kt @@ -1,9 +1,14 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.internal +import com.intellij.openapi.application.readAction +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runBlocking import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.config.languageVersionSettings +import org.jetbrains.kotlin.idea.actions.bytecode.BytecodeGenerationResult +import org.jetbrains.kotlin.idea.actions.bytecode.KotlinBytecodeToolWindow import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings import org.jetbrains.kotlin.idea.multiplatform.setupMppProjectFromDirStructure import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest @@ -34,7 +39,12 @@ private fun configureCompilerAndCheckBytecode(withIr: Boolean, file: KtFile) { languageVersionSettings = file.languageVersionSettings } - val bytecode = KotlinBytecodeToolWindow.getBytecodeForFile(file, configuration) + val bytecode = runBlocking(Dispatchers.Default) { + readAction { + KotlinBytecodeToolWindow.getBytecodeForFile(file, configuration) + } + } + assert(bytecode is BytecodeGenerationResult.Bytecode) { "Exception failed during compilation:\n$bytecode" } diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/internal/AbstractBytecodeToolWindowTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/internal/AbstractBytecodeToolWindowTest.kt index 15a02694d80c..ecc608267027 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/internal/AbstractBytecodeToolWindowTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/internal/AbstractBytecodeToolWindowTest.kt @@ -2,6 +2,9 @@ package org.jetbrains.kotlin.idea.internal +import com.intellij.openapi.application.readAction +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runBlocking import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.languageVersionSettings @@ -13,6 +16,8 @@ import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.idea.test.InTextDirectivesUtils import java.io.File import org.jetbrains.kotlin.config.JVMConfigurationKeys +import org.jetbrains.kotlin.idea.actions.bytecode.BytecodeGenerationResult +import org.jetbrains.kotlin.idea.actions.bytecode.KotlinBytecodeToolWindow abstract class AbstractBytecodeToolWindowTest : KotlinLightCodeInsightFixtureTestCase() { override fun getProjectDescriptor() = KotlinWithJdkAndRuntimeLightProjectDescriptor.getInstance() @@ -39,9 +44,14 @@ abstract class AbstractBytecodeToolWindowTest : KotlinLightCodeInsightFixtureTes languageVersionSettings = file.languageVersionSettings } - val bytecodes = KotlinBytecodeToolWindow.getBytecodeForFile(file, configuration) - assert(bytecodes is BytecodeGenerationResult.Bytecode) { - "Exception failed during compilation:\n$bytecodes" + val bytecode = runBlocking(Dispatchers.Default) { + readAction { + KotlinBytecodeToolWindow.getBytecodeForFile(file, configuration) + } + } + + assert(bytecode is BytecodeGenerationResult.Bytecode) { + "Exception failed during compilation:\n$bytecode" } } } diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/navigation/GotoDeclarationTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/navigation/GotoDeclarationTestGenerated.java index a54fbc5d02c2..394bf6e3e129 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/navigation/GotoDeclarationTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/navigation/GotoDeclarationTestGenerated.java @@ -23,6 +23,11 @@ public class GotoDeclarationTestGenerated extends AbstractGotoDeclarationTest { KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); } + @TestMetadata("annotationCallWithMissedTypeArgs.test") + public void testAnnotationCallWithMissedTypeArgs() throws Exception { + runTest("testData/navigation/gotoDeclaration/annotationCallWithMissedTypeArgs.test"); + } + @TestMetadata("dataClassToString.test") public void testDataClassToString() throws Exception { runTest("testData/navigation/gotoDeclaration/dataClassToString.test"); diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/refactoring/changeSignature/KotlinChangeSignatureTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/refactoring/changeSignature/KotlinChangeSignatureTest.kt index 7512f8255c23..6a22c3966042 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/refactoring/changeSignature/KotlinChangeSignatureTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/refactoring/changeSignature/KotlinChangeSignatureTest.kt @@ -361,7 +361,7 @@ class KotlinChangeSignatureTest : KotlinLightCodeInsightFixtureTestCase() { val adjustedDescriptor = kotlinChangeSignature.adjustDescriptor(declarations)!! val processor = kotlinChangeSignature.createSilentRefactoringProcessor(adjustedDescriptor) as KotlinChangeSignatureProcessor - processor.ktChangeInfo.also { it.checkUsedParameters = true } + processor.changeInfo.also { it.checkUsedParameters = true } processor.run() compareEditorsWithExpectedData() @@ -1618,5 +1618,5 @@ fun createChangeInfo( val declarations = callableDescriptor.safeAs()?.getDeepestSuperDeclarations() ?: listOf(callableDescriptor) val adjustedDescriptor = kotlinChangeSignature.adjustDescriptor(declarations) ?: return null val processor = kotlinChangeSignature.createSilentRefactoringProcessor(adjustedDescriptor) as KotlinChangeSignatureProcessor - return processor.ktChangeInfo.also { it.checkUsedParameters = true } + return processor.changeInfo.also { it.checkUsedParameters = true } } diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java index e1fbad6755cd..63bd9f0206c1 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java @@ -753,6 +753,11 @@ public class RenameTestGenerated extends AbstractRenameTest { runTest("testData/refactoring/rename/renameKotlinClassByConstructorRef/kotlinClass.test"); } + @TestMetadata("renameKotlinClassByImplicitConstructorRef/kotlinClass.test") + public void testRenameKotlinClassByImplicitConstructorRef_KotlinClass() throws Exception { + runTest("testData/refactoring/rename/renameKotlinClassByImplicitConstructorRef/kotlinClass.test"); + } + @TestMetadata("renameKotlinClassConstructor/renameKotlinConstructor.test") public void testRenameKotlinClassConstructor_RenameKotlinConstructor() throws Exception { runTest("testData/refactoring/rename/renameKotlinClassConstructor/renameKotlinConstructor.test"); diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/hints/lambda/ImplicitIt.kt b/plugins/kotlin/idea/tests/testData/codeInsight/hints/lambda/ImplicitIt.kt index f8f7af46023c..8520fb42d381 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/hints/lambda/ImplicitIt.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/hints/lambda/ImplicitIt.kt @@ -1,4 +1,4 @@ // MODE: receivers_params -val x = listOf("").filter {/*<# [it: [jar://kotlin-stdlib-sources.jar!/kotlin/String.kt:618]String] #>*/ +val x = listOf("").filter {/*<# [it: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/String.kt:618]String] #>*/ it.startsWith("") } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/hints/lambda/ImplicitThisAndIt.kt b/plugins/kotlin/idea/tests/testData/codeInsight/hints/lambda/ImplicitThisAndIt.kt index b162433c9ecb..7064f12e0752 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/hints/lambda/ImplicitThisAndIt.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/hints/lambda/ImplicitThisAndIt.kt @@ -1,5 +1,5 @@ // MODE: receivers_params -val x = foo {/*<# [[this: [jar://kotlin-stdlib-sources.jar!/kotlin/String.kt:618]String] [it: [jar://kotlin-stdlib-sources.jar!/kotlin/Primitives.kt:21054]Int]] #>*/ +val x = foo {/*<# [[this: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/String.kt:618]String] [it: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Primitives.kt:21054]Int]] #>*/ } diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/hints/lambda/ImplicitThisAndNamedSingleParameter.kt b/plugins/kotlin/idea/tests/testData/codeInsight/hints/lambda/ImplicitThisAndNamedSingleParameter.kt index ef1151fc4fd0..558d0c6f3311 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/hints/lambda/ImplicitThisAndNamedSingleParameter.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/hints/lambda/ImplicitThisAndNamedSingleParameter.kt @@ -1,5 +1,5 @@ // MODE: receivers_params -val x = foo {/*<# [this: [jar://kotlin-stdlib-sources.jar!/kotlin/String.kt:618]String] #>*/ props -> +val x = foo {/*<# [this: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/String.kt:618]String] #>*/ props -> } diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/AnonymousObject.kt b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/AnonymousObject.kt index a9adaf620f39..bf5b48f230f9 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/AnonymousObject.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/AnonymousObject.kt @@ -1,7 +1,7 @@ // MODE: function_return val o = object : Iterable { - override fun iterator()/*<# [: [jar://kotlin-stdlib-sources.jar!/kotlin/Iterator.kt:*]Iterator < [jar://kotlin-stdlib-sources.jar!/kotlin/Primitives.kt:*]Int >] #>*/ = object : Iterator { - override fun next()/*<# [: [jar://kotlin-stdlib-sources.jar!/kotlin/Primitives.kt:*]Int] #>*/ = 1 - override fun hasNext()/*<# [: [jar://kotlin-stdlib-sources.jar!/kotlin/Boolean.kt:*]Boolean] #>*/ = true + override fun iterator()/*<# [: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Iterator.kt:*]Iterator < [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Primitives.kt:*]Int >] #>*/ = object : Iterator { + override fun next()/*<# [: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Primitives.kt:*]Int] #>*/ = 1 + override fun hasNext()/*<# [: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Boolean.kt:*]Boolean] #>*/ = true } } diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/ConstructorWithoutExplicitTypeParametersType.kt b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/ConstructorWithoutExplicitTypeParametersType.kt index 527a39bc59f8..4cfb0727e677 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/ConstructorWithoutExplicitTypeParametersType.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/ConstructorWithoutExplicitTypeParametersType.kt @@ -1,2 +1,2 @@ // MODE: property -class Bar(val t: T); val a/*<# [: [temp:///src/KotlinReferencesTypeHintsProvider.kt:0]Bar < [jar://kotlin-stdlib-sources.jar!/kotlin/String.kt:*]String >] #>*/ = Bar("") \ No newline at end of file +class Bar(val t: T); val a/*<# [: [temp:///src/KotlinReferencesTypeHintsProvider.kt:0]Bar < [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/String.kt:*]String >] #>*/ = Bar("") \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/DefinitelyNonNullTypes.kt b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/DefinitelyNonNullTypes.kt index b543adf843fd..73c826e7a6a3 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/DefinitelyNonNullTypes.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/DefinitelyNonNullTypes.kt @@ -2,4 +2,4 @@ fun inlayHint(x: T & Any)/*<# [: []T & Any] #>*/ = x fun takeFun(f: (T & Any) -> Unit) {} -fun inlayHint2()/*<# [: [jar://kotlin-stdlib-sources.jar!/kotlin/Unit.kt:*]Unit] #>*/ = takeFun { it/*<# [: []T & Any] #>*/ -> println(it)} +fun inlayHint2()/*<# [: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Unit.kt:*]Unit] #>*/ = takeFun { it/*<# [: []T & Any] #>*/ -> println(it)} diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/DestructingType.kt b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/DestructingType.kt index 21f4c4caaca0..3821a1aea777 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/DestructingType.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/DestructingType.kt @@ -1,2 +1,2 @@ // MODE: local_variable -fun foo() { val (i/*<# [: [jar://kotlin-stdlib-sources.jar!/kotlin/Primitives.kt:*]Int] #>*/, s/*<# [: [jar://kotlin-stdlib-sources.jar!/kotlin/String.kt:*]String] #>*/) = 1 to "" } \ No newline at end of file +fun foo() { val (i/*<# [: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Primitives.kt:*]Int] #>*/, s/*<# [: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/String.kt:*]String] #>*/) = 1 to "" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/ExpandedTypeAlias.kt b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/ExpandedTypeAlias.kt index 9c180a26e30d..f662686da6a7 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/ExpandedTypeAlias.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/ExpandedTypeAlias.kt @@ -1,2 +1,2 @@ // MODE: property -val x/*<# [: [jar://kotlin-stdlib-common-sources.jar!/kotlin/collections/ArrayList.kt:*]ArrayList < [jar://kotlin-stdlib-sources.jar!/kotlin/Primitives.kt:*]Int >] #>*/ = arrayListOf(1) +val x/*<# [: [jar://kotlin-stdlib-sources.jar!/commonMain/kotlin/collections/ArrayList.kt:*]ArrayList < [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Primitives.kt:*]Int >] #>*/ = arrayListOf(1) diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/JavaFQName.kt b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/JavaFQName.kt index d0d84997ef02..ce2efcbd360f 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/JavaFQName.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/JavaFQName.kt @@ -1,3 +1,3 @@ // MODE: all val x = java.util.ArrayList() -val q/*<# [: [jar://rt.jar!/java/util/ArrayList.class:*]ArrayList < [jar://kotlin-stdlib-sources.jar!/kotlin/String.kt:*]String >] #>*/ = x \ No newline at end of file +val q/*<# [: [jar://rt.jar!/java/util/ArrayList.class:*]ArrayList < [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/String.kt:*]String >] #>*/ = x \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/LocalVariable.kt b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/LocalVariable.kt index 7e9640f98f4c..9b6ae5d7ad7d 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/LocalVariable.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/LocalVariable.kt @@ -1,2 +1,2 @@ // MODE: local_variable -fun foo() { val a/*<# [: [jar://kotlin-stdlib-sources.jar!/kotlin/Collections.kt:*]List < [jar://kotlin-stdlib-sources.jar!/kotlin/String.kt:*]String >] #>*/ = listOf("a") } \ No newline at end of file +fun foo() { val a/*<# [: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Collections.kt:*]List < [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/String.kt:*]String >] #>*/ = listOf("a") } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/LoopParameter.kt b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/LoopParameter.kt index 987b19449c14..a65388e1c8f9 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/LoopParameter.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/LoopParameter.kt @@ -1,2 +1,2 @@ // MODE: local_variable -fun foo() { for (x/*<# [: [jar://kotlin-stdlib-sources.jar!/kotlin/String.kt:*]String] #>*/ in listOf("a")) { } } \ No newline at end of file +fun foo() { for (x/*<# [: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/String.kt:*]String] #>*/ in listOf("a")) { } } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/NestedClassImports.kt b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/NestedClassImports.kt index 25122ba0a975..1ea661dc9f2d 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/NestedClassImports.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/NestedClassImports.kt @@ -1,3 +1,3 @@ // MODE: property import kotlin.collections.Map.Entry -val entries/*<# [: [jar://kotlin-stdlib-sources.jar!/kotlin/Collections.kt:*]Set < [jar://kotlin-stdlib-sources.jar!/kotlin/Collections.kt:*]Entry < [jar://kotlin-stdlib-sources.jar!/kotlin/Primitives.kt:*]Int , [jar://kotlin-stdlib-sources.jar!/kotlin/String.kt:*]String >>] #>*/ = mapOf(1 to "1").entries \ No newline at end of file +val entries/*<# [: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Collections.kt:*]Set < [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Collections.kt:*]Entry < [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Primitives.kt:*]Int , [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/String.kt:*]String >>] #>*/ = mapOf(1 to "1").entries \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/NestedClassWithoutImport.kt b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/NestedClassWithoutImport.kt index 8854e835d9be..415a663fe764 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/NestedClassWithoutImport.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/NestedClassWithoutImport.kt @@ -1,2 +1,2 @@ // MODE: property -val entries/*<# [: [jar://kotlin-stdlib-sources.jar!/kotlin/Collections.kt:*]Set < [jar://kotlin-stdlib-sources.jar!/kotlin/Collections.kt:*]Map.Entry < [jar://kotlin-stdlib-sources.jar!/kotlin/Primitives.kt:*]Int , [jar://kotlin-stdlib-sources.jar!/kotlin/String.kt:*]String >>] #>*/ = mapOf(1 to "1").entries \ No newline at end of file +val entries/*<# [: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Collections.kt:*]Set < [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Collections.kt:*]Map.Entry < [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Primitives.kt:*]Int , [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/String.kt:*]String >>] #>*/ = mapOf(1 to "1").entries \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/ParameterType.kt b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/ParameterType.kt index 118206f66695..42b04ef51dda 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/ParameterType.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/ParameterType.kt @@ -1,7 +1,7 @@ // MODE: parameter fun T.wrap(lambda: (T) -> T) {} fun foo() { - 12.wrap { elem/*<# [: [jar://kotlin-stdlib-sources.jar!/kotlin/Primitives.kt:*]Int] #>*/ -> + 12.wrap { elem/*<# [: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Primitives.kt:*]Int] #>*/ -> elem } } diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/PropertyType.kt b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/PropertyType.kt index cb5e840815d8..be5a53d00ded 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/PropertyType.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/PropertyType.kt @@ -1,2 +1,2 @@ // MODE: property -val a/*<# [: [jar://kotlin-stdlib-sources.jar!/kotlin/Collections.kt:*]List < [jar://kotlin-stdlib-sources.jar!/kotlin/String.kt:*]String >] #>*/ = listOf("a") +val a/*<# [: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Collections.kt:*]List < [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/String.kt:*]String >] #>*/ = listOf("a") diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/UnitLocalVariable2.kt b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/UnitLocalVariable2.kt index 3c272be46d20..20c06da2fb85 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/UnitLocalVariable2.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/UnitLocalVariable2.kt @@ -1,5 +1,5 @@ // MODE: all fun foo() { - val x/*<# [: [jar://kotlin-stdlib-sources.jar!/kotlin/Unit.kt:*]Unit] #>*/ = + val x/*<# [: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Unit.kt:*]Unit] #>*/ = println("Foo") // indent differs } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/UnitLocalVariable3.kt b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/UnitLocalVariable3.kt index 5e1db4a10127..e70a461e52c1 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/UnitLocalVariable3.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/UnitLocalVariable3.kt @@ -1,4 +1,4 @@ // MODE: local_variable fun foo() { - val x/*<# [: [jar://kotlin-stdlib-sources.jar!/kotlin/Unit.kt:*]Unit] #>*/ = println("Foo") + val x/*<# [: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Unit.kt:*]Unit] #>*/ = println("Foo") } diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/When.kt b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/When.kt index 14254e62c265..b5df2cef5a81 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/When.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/hints/types/When.kt @@ -1,5 +1,5 @@ // MODE: all -val x/*<# [: [jar://kotlin-stdlib-sources.jar!/kotlin/Primitives.kt:*]Int] #>*/ = run { +val x/*<# [: [jar://kotlin-stdlib-sources.jar!/jvmMain/kotlin/Primitives.kt:*]Int] #>*/ = run { when (true) { true -> 1 false -> 0 diff --git a/plugins/kotlin/idea/tests/testData/codeInsight/lineMarker/MethodSeparators.kt b/plugins/kotlin/idea/tests/testData/codeInsight/lineMarker/methodSeparators/MethodSeparators.kt similarity index 92% rename from plugins/kotlin/idea/tests/testData/codeInsight/lineMarker/MethodSeparators.kt rename to plugins/kotlin/idea/tests/testData/codeInsight/lineMarker/methodSeparators/MethodSeparators.kt index a63ddc5e07c2..0885d37a2ec1 100644 --- a/plugins/kotlin/idea/tests/testData/codeInsight/lineMarker/MethodSeparators.kt +++ b/plugins/kotlin/idea/tests/testData/codeInsight/lineMarker/methodSeparators/MethodSeparators.kt @@ -44,3 +44,7 @@ class Foo { const val C = 1 } } + +fun foo() {} + +fun bar() {} diff --git a/plugins/kotlin/idea/tests/testData/decompiler/navigation/fromJavaSource/propertyFunctionOverload.kt b/plugins/kotlin/idea/tests/testData/decompiler/navigation/fromJavaSource/propertyFunctionOverload.kt new file mode 100644 index 000000000000..474077bb18fb --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/decompiler/navigation/fromJavaSource/propertyFunctionOverload.kt @@ -0,0 +1,22 @@ +package testData.libraries + +class MyTest { + + fun newBuilder(): Builder = Builder() + + class Builder { + var cache: String? = null + fun cache(cache: String?) {} + + var m: String? = null + fun m(): String? = null + + var n: String? = null + @JvmName("getN") + fun n(s: String): String? = null + + @get:JvmName("o") + var o: String? = null + fun o(s: String): String? = null + } +} diff --git a/plugins/kotlin/idea/tests/testData/decompiler/navigation/userJavaCode/PropertyFunctionOverload.java b/plugins/kotlin/idea/tests/testData/decompiler/navigation/userJavaCode/PropertyFunctionOverload.java new file mode 100644 index 000000000000..22fa9a1e84b0 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/decompiler/navigation/userJavaCode/PropertyFunctionOverload.java @@ -0,0 +1,10 @@ +import testData.libraries.*; + +class TestOverload { + void test() { + new MyTest().newBuilder().cache(""); + String s = new MyTest().newBuilder().m(); + String s2 = new MyTest().newBuilder().getN(); + new MyTest().newBuilder().o(); + } +} diff --git a/plugins/kotlin/idea/tests/testData/decompiler/navigation/userJavaCode/PropertyFunctionOverload.source.expected b/plugins/kotlin/idea/tests/testData/decompiler/navigation/userJavaCode/PropertyFunctionOverload.source.expected new file mode 100644 index 000000000000..5a90d9c32519 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/decompiler/navigation/userJavaCode/PropertyFunctionOverload.source.expected @@ -0,0 +1,19 @@ +MyTest.class +public final class <1><5><9><12>MyTest public constructor() { + public final fun <2><6><10><13>newBuilder(): testData.libraries.MyTest.Builder { /* compiled code */ } + + public final class Builder public constructor() { + public final var cache: kotlin.String? /* compiled code */ + + public final var m: kotlin.String? /* compiled code */ + + public final var <11>n: kotlin.String? /* compiled code */ + + public final var <14>o: kotlin.String? /* compiled code */ + public final @kotlin.jvm.JvmName get + + public final fun <3>cache(cache: kotlin.String?): kotlin.Unit { /* compiled code */ } + + public final fun <7>m(): kotlin.String? { /* compiled code */ } + String.class +public final class <4><8>String implements Serializable, Comparable, CharSequence { diff --git a/plugins/kotlin/idea/tests/testData/exitPoints/forLoopBreak.kt b/plugins/kotlin/idea/tests/testData/exitPoints/forLoopBreak.kt new file mode 100644 index 000000000000..c6e241c2b5aa --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/exitPoints/forLoopBreak.kt @@ -0,0 +1,5 @@ +fun some() { + for (i in 0..5) { + break~ + } +} diff --git a/plugins/kotlin/idea/tests/testData/exitPoints/forLoopNestedBreak.kt b/plugins/kotlin/idea/tests/testData/exitPoints/forLoopNestedBreak.kt new file mode 100644 index 000000000000..c53a7cbd7c15 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/exitPoints/forLoopNestedBreak.kt @@ -0,0 +1,7 @@ +fun some() { + for (j in 0..5) { + for (i in 0..5) { + break~ + } + } +} diff --git a/plugins/kotlin/idea/tests/testData/exitPoints/forLoopNestedBreak2.kt b/plugins/kotlin/idea/tests/testData/exitPoints/forLoopNestedBreak2.kt new file mode 100644 index 000000000000..6535c305fabd --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/exitPoints/forLoopNestedBreak2.kt @@ -0,0 +1,12 @@ +fun some() { + for~ (j in 0..5) { + if (j == 1) break + for (i in 0..5) { + break + } + loop@ for (i in 0..5) { + break + } + if (j == 2) continue + } +} diff --git a/plugins/kotlin/idea/tests/testData/exitPoints/forLoopNestedLabeledBreak.kt b/plugins/kotlin/idea/tests/testData/exitPoints/forLoopNestedLabeledBreak.kt new file mode 100644 index 000000000000..9f5496ec5fa2 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/exitPoints/forLoopNestedLabeledBreak.kt @@ -0,0 +1,13 @@ +fun some(list: List) { + a@ for (j in 0..5) { + for (i in 0..5) { + break@a + } + if (j == 0) continue + if (j == 2) break + b@ for (i in 0..5) { + break@b + brea~k@a + } + } +} diff --git a/plugins/kotlin/idea/tests/testData/exitPoints/forLoopNestedLabeledBreakOnLoop.kt b/plugins/kotlin/idea/tests/testData/exitPoints/forLoopNestedLabeledBreakOnLoop.kt new file mode 100644 index 000000000000..fe8d06b9c3aa --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/exitPoints/forLoopNestedLabeledBreakOnLoop.kt @@ -0,0 +1,12 @@ +fun some(list: List) { + loop@ for~ (s in l) { + if (s == "a") break@loop + if (s == "b") continue + + for (s1 in l) { + if (s1 == "a") break + if (s1 == "b") continue + if (s1 == "c") break@loop + } + } +} diff --git a/plugins/kotlin/idea/tests/testData/exitPoints/forLoopNestedLabeledBreakOnLoop2.kt b/plugins/kotlin/idea/tests/testData/exitPoints/forLoopNestedLabeledBreakOnLoop2.kt new file mode 100644 index 000000000000..3e9e1551bc3a --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/exitPoints/forLoopNestedLabeledBreakOnLoop2.kt @@ -0,0 +1,34 @@ +fun some(list: List) { + loop@ for~ (s in l) { + if (s == "a") break@loop + if (s == "b") continue + + loop@ for (s1 in l) { + if (s1 == "a") break + if (s1 == "b") continue + if (s1 == "c") break@loop + } + + loop2@ for (s1 in l) { + if (s1 == "a") break + if (s1 == "b") continue + if (s1 == "c") break@loop + if (s1 == "d") break + } + + loop1@ for (s1 in l) { + if (s1 == "a") break + if (s1 == "b") continue + loop2@ for (s1 in l) { + if (s1 == "a") break + if (s1 == "b") continue + if (s1 == "c") break@loop + } + if (s1 == "c") break + } + + if (s == "c") continue + if (s == "d") break + if (s == "e") break@loop + } +} diff --git a/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findFunctionUsages/kotlinOverloadAndExtensionUsages5.0.kt b/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findFunctionUsages/kotlinOverloadAndExtensionUsages5.0.kt new file mode 100644 index 000000000000..81a81ef11959 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findFunctionUsages/kotlinOverloadAndExtensionUsages5.0.kt @@ -0,0 +1,12 @@ +// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtNamedFunction +// OPTIONS: overloadUsages +// PSI_ELEMENT_AS_TITLE: "fun c(): Unit" + +class Foo { + val c = 42 + fun c() {} + fun m() { + c() + val a = c + } +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findFunctionUsages/kotlinOverloadAndExtensionUsages5.results.txt b/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findFunctionUsages/kotlinOverloadAndExtensionUsages5.results.txt new file mode 100644 index 000000000000..f142cf80c658 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findFunctionUsages/kotlinOverloadAndExtensionUsages5.results.txt @@ -0,0 +1 @@ +Function call 9 c() diff --git a/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findTypeAliasUsages/classAlias.fir.results.txt b/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findTypeAliasUsages/classAlias.fir.results.txt index 57ca5ef0fc98..b13de724d422 100644 --- a/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findTypeAliasUsages/classAlias.fir.results.txt +++ b/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findTypeAliasUsages/classAlias.fir.results.txt @@ -1,6 +1,5 @@ Function return types 26 fun f2(par: Alias, par2: OOO) : Alias { Local variable declaration 28 val a: Alias -Nested class/object 35 Alias.CONST //not found in K1, found in K2 Parameter type 26 fun f2(par: Alias, par2: OOO) : Alias { Supertype 15 class Child : Alias() { Target type of 'is' operation 38 if (par2 is Alias) {} diff --git a/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findTypeParameterUsages/kotlinReifiedTypeParameterUsages.0.kt b/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findTypeParameterUsages/kotlinReifiedTypeParameterUsages.0.kt index 246bb308f4a3..8c242d754ec2 100644 --- a/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findTypeParameterUsages/kotlinReifiedTypeParameterUsages.0.kt +++ b/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findTypeParameterUsages/kotlinReifiedTypeParameterUsages.0.kt @@ -3,5 +3,5 @@ inline fun T> fff(labelText: String, a: Any): T { if (a is T) {} - return T::class.java.getConstructor().newInstance() //not found in K2, KTIJ-24230 + return T::class.java.getConstructor().newInstance() } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findTypeParameterUsages/kotlinReifiedTypeParameterUsages.fir.results.txt b/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findTypeParameterUsages/kotlinReifiedTypeParameterUsages.fir.results.txt deleted file mode 100644 index ef5aa14d81eb..000000000000 --- a/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findTypeParameterUsages/kotlinReifiedTypeParameterUsages.fir.results.txt +++ /dev/null @@ -1,2 +0,0 @@ -Function return types 4 inline fun fff(labelText: String, a: Any): T { -Target type of 'is' operation 5 if (a is T) {} diff --git a/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findTypeParameterUsages/kotlinReifiedTypeParameterUsages.results.txt b/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findTypeParameterUsages/kotlinReifiedTypeParameterUsages.results.txt index 70118629da9a..d6d5d6b971b3 100644 --- a/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findTypeParameterUsages/kotlinReifiedTypeParameterUsages.results.txt +++ b/plugins/kotlin/idea/tests/testData/findUsages/kotlin/findTypeParameterUsages/kotlinReifiedTypeParameterUsages.results.txt @@ -1,3 +1,3 @@ Function return types 4 inline fun fff(labelText: String, a: Any): T { Target type of 'is' operation 5 if (a is T) {} -Unclassified 6 return T::class.java.getConstructor().newInstance() //not found in K2, KTIJ-24230 +Unclassified 6 return T::class.java.getConstructor().newInstance() diff --git a/plugins/kotlin/idea/tests/testData/idea/actions/kotlinAddImportAction/ExtReceiver2.kt b/plugins/kotlin/idea/tests/testData/idea/actions/kotlinAddImportAction/ExtReceiver2.kt index 05022b0c2aa7..21d7bf84da9b 100644 --- a/plugins/kotlin/idea/tests/testData/idea/actions/kotlinAddImportAction/ExtReceiver2.kt +++ b/plugins/kotlin/idea/tests/testData/idea/actions/kotlinAddImportAction/ExtReceiver2.kt @@ -1,3 +1,4 @@ +// FIR_COMPARISON // EXPECT_VARIANT_IN_ORDER "public fun kotlin.Int.seconds(i: kotlin.Int): kotlin.Int defined in p2 in file ExtReceiver2.dependency1.kt" // EXPECT_VARIANT_IN_ORDER "public fun kotlin.Int.seconds(s: kotlin.String): kotlin.Int defined in p1 in file ExtReceiver2.dependency.kt" package root diff --git a/plugins/kotlin/idea/tests/testData/idea/actions/kotlinAddImportAction/ExtReceiver2.kt.after b/plugins/kotlin/idea/tests/testData/idea/actions/kotlinAddImportAction/ExtReceiver2.kt.after index d01a48002231..3a7ea74f563e 100644 --- a/plugins/kotlin/idea/tests/testData/idea/actions/kotlinAddImportAction/ExtReceiver2.kt.after +++ b/plugins/kotlin/idea/tests/testData/idea/actions/kotlinAddImportAction/ExtReceiver2.kt.after @@ -1,3 +1,4 @@ +// FIR_COMPARISON // EXPECT_VARIANT_IN_ORDER "public fun kotlin.Int.seconds(i: kotlin.Int): kotlin.Int defined in p2 in file ExtReceiver2.dependency1.kt" // EXPECT_VARIANT_IN_ORDER "public fun kotlin.Int.seconds(s: kotlin.String): kotlin.Int defined in p1 in file ExtReceiver2.dependency.kt" package root diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/nullableBooleanElvis/inIf3.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/nullableBooleanElvis/inIf3.kt index c3bdf0024608..4634dd57625b 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/nullableBooleanElvis/inIf3.kt +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/nullableBooleanElvis/inIf3.kt @@ -1,7 +1,7 @@ fun foo() { var a: Boolean? = null var b: Boolean? = null - if (a ?: false || !(b ?: true)) { + if (a ?: false || !(b ?: true)) { } } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/nullableBooleanElvis/notInIf.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/nullableBooleanElvis/notInIf.kt index 759ad185a074..f5ff4b7994a5 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/nullableBooleanElvis/notInIf.kt +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/nullableBooleanElvis/notInIf.kt @@ -1,4 +1,4 @@ fun foo() { var a: Boolean? = null - val x = a ?: false + val x = a ?: false } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/intentions/convertToBlockBody/nullableNothing.kt b/plugins/kotlin/idea/tests/testData/intentions/convertToBlockBody/nullableNothing.kt new file mode 100644 index 000000000000..5b8f2b61a500 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/intentions/convertToBlockBody/nullableNothing.kt @@ -0,0 +1 @@ +fun foo() = null \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/intentions/convertToBlockBody/nullableNothing.kt.after b/plugins/kotlin/idea/tests/testData/intentions/convertToBlockBody/nullableNothing.kt.after new file mode 100644 index 000000000000..589152a61248 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/intentions/convertToBlockBody/nullableNothing.kt.after @@ -0,0 +1,3 @@ +fun foo(): Nothing? { + return null +} diff --git a/plugins/kotlin/idea/tests/testData/multiplatform/useCorrectBuiltIns/js/js.kt b/plugins/kotlin/idea/tests/testData/multiplatform/useCorrectBuiltIns/js/js.kt index 3025f2b21298..1ff11366f2c6 100644 --- a/plugins/kotlin/idea/tests/testData/multiplatform/useCorrectBuiltIns/js/js.kt +++ b/plugins/kotlin/idea/tests/testData/multiplatform/useCorrectBuiltIns/js/js.kt @@ -1,7 +1,6 @@ // !DIAGNOSTICS: -UNUSED_VARIABLE -import kotlinx.browser.window -import kotlinx.cinterop.CPointed +import kotlinx.cinterop.CPointed fun jvmSpecific(args: Array) { val x: Cloneable? = null @@ -13,5 +12,5 @@ fun nativeSpecific() { } fun jsSpecific() { - val windowClosed = window.closed + console.log("Hello") } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/navigation/gotoDeclaration/annotationCallWithMissedTypeArgs.test b/plugins/kotlin/idea/tests/testData/navigation/gotoDeclaration/annotationCallWithMissedTypeArgs.test new file mode 100644 index 000000000000..c42a49d171c4 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/navigation/gotoDeclaration/annotationCallWithMissedTypeArgs.test @@ -0,0 +1,8 @@ +// FILE: before.kt +annotation class B +@B +class A +// FILE: after.kt +annotation class B +@B +class A \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/projectView/AnnotationFromStdlibWithSources.txt b/plugins/kotlin/idea/tests/testData/projectView/AnnotationFromStdlibWithSources.txt index 796a5f40ddd0..41f64935cfa8 100644 --- a/plugins/kotlin/idea/tests/testData/projectView/AnnotationFromStdlibWithSources.txt +++ b/plugins/kotlin/idea/tests/testData/projectView/AnnotationFromStdlibWithSources.txt @@ -7,7 +7,7 @@ Value file: kotlin-stdlib.jar!/kotlin/annotation/AnnotationTarget.class Navigation item #0: CLASS Navigation item file #0: kotlin-stdlib.jar!/kotlin/annotation/AnnotationTarget.class Navigation item #1: CLASS -Navigation item file #1: kotlin-stdlib-sources.jar!/kotlin/annotation/Annotations.kt +Navigation item file #1: kotlin-stdlib-sources.jar!/jvmMain/kotlin/annotation/Annotations.kt -Project diff --git a/plugins/kotlin/idea/tests/testData/projectView/ArraysJVMWithSources.txt b/plugins/kotlin/idea/tests/testData/projectView/ArraysJVMWithSources.txt index 3ce69eeb3712..b83bb84e2ebc 100644 --- a/plugins/kotlin/idea/tests/testData/projectView/ArraysJVMWithSources.txt +++ b/plugins/kotlin/idea/tests/testData/projectView/ArraysJVMWithSources.txt @@ -5,7 +5,7 @@ Value: KtLightClassForDecompiledDeclaration of PsiFile:ArraysKt__ArraysJVMKt.cla Value file: kotlin-stdlib.jar!/kotlin/collections/ArraysKt__ArraysJVMKt.class Navigation item #0: KtFile: ArraysJVM.kt -Navigation item file #0: kotlin-stdlib-sources.jar!/kotlin/collections/ArraysJVM.kt +Navigation item file #0: kotlin-stdlib-sources.jar!/jvmMain/kotlin/collections/ArraysJVM.kt -Project diff --git a/plugins/kotlin/idea/tests/testData/projectView/_ArraysWithSources.txt b/plugins/kotlin/idea/tests/testData/projectView/_ArraysWithSources.txt index f23ca0d37fd5..283cb53e7a92 100644 --- a/plugins/kotlin/idea/tests/testData/projectView/_ArraysWithSources.txt +++ b/plugins/kotlin/idea/tests/testData/projectView/_ArraysWithSources.txt @@ -5,7 +5,7 @@ Value: KtLightClassForDecompiledDeclaration of PsiFile:ArraysKt___ArraysKt.class Value file: kotlin-stdlib.jar!/kotlin/collections/ArraysKt___ArraysKt.class Navigation item #0: KtFile: _Arrays.kt -Navigation item file #0: kotlin-stdlib-common-sources.jar!/generated/_Arrays.kt +Navigation item file #0: kotlin-stdlib-sources.jar!/commonMain/generated/_Arrays.kt -Project diff --git a/plugins/kotlin/idea/tests/testData/projectView/_ArraysWithSourcesMembers.txt b/plugins/kotlin/idea/tests/testData/projectView/_ArraysWithSourcesMembers.txt index ddd722080428..5af032da39d9 100644 --- a/plugins/kotlin/idea/tests/testData/projectView/_ArraysWithSourcesMembers.txt +++ b/plugins/kotlin/idea/tests/testData/projectView/_ArraysWithSourcesMembers.txt @@ -5,7 +5,7 @@ Value: KtLightClassForDecompiledDeclaration of PsiFile:ArraysKt___ArraysKt.class Value file: kotlin-stdlib.jar!/kotlin/collections/ArraysKt___ArraysKt.class Navigation item #0: KtFile: _Arrays.kt -Navigation item file #0: kotlin-stdlib-common-sources.jar!/generated/_Arrays.kt +Navigation item file #0: kotlin-stdlib-sources.jar!/commonMain/generated/_Arrays.kt -Project diff --git a/plugins/kotlin/idea/tests/testData/projectView/___ArraysJvmWithSources.txt b/plugins/kotlin/idea/tests/testData/projectView/___ArraysJvmWithSources.txt index d33f12c02f9f..28deb9439b4d 100644 --- a/plugins/kotlin/idea/tests/testData/projectView/___ArraysJvmWithSources.txt +++ b/plugins/kotlin/idea/tests/testData/projectView/___ArraysJvmWithSources.txt @@ -5,7 +5,7 @@ Value: KtLightClassForDecompiledDeclaration of PsiFile:ArraysKt___ArraysJvmKt.cl Value file: kotlin-stdlib.jar!/kotlin/collections/ArraysKt___ArraysJvmKt.class Navigation item #0: KtFile: _ArraysJvm.kt -Navigation item file #0: kotlin-stdlib-sources.jar!/generated/_ArraysJvm.kt +Navigation item file #0: kotlin-stdlib-sources.jar!/jvmMain/generated/_ArraysJvm.kt -Project diff --git a/plugins/kotlin/idea/tests/testData/quickfix/autoImports/typeAliasImport.after.kt b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/typeAliasImport.after.kt index 108e60256c18..c1868c121b1d 100644 --- a/plugins/kotlin/idea/tests/testData/quickfix/autoImports/typeAliasImport.after.kt +++ b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/typeAliasImport.after.kt @@ -6,5 +6,3 @@ import dependency.TestAlias fun test() { val a = TestAlias } - -/* IGNORE_FIR */ \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/quickfix/autoImports/typeAliasImport.before.Main.kt b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/typeAliasImport.before.Main.kt index 726f1bf7a98b..34116ab4525a 100644 --- a/plugins/kotlin/idea/tests/testData/quickfix/autoImports/typeAliasImport.before.Main.kt +++ b/plugins/kotlin/idea/tests/testData/quickfix/autoImports/typeAliasImport.before.Main.kt @@ -4,5 +4,3 @@ fun test() { val a = TestAlias } - -/* IGNORE_FIR */ \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/importReference/ImportReference.kt b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/importReference/ImportReference.kt new file mode 100644 index 000000000000..28b03fc9813f --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/importReference/ImportReference.kt @@ -0,0 +1,19 @@ +// FILE: test/ChangeImport.kt +// BIND_TO test.bar.A +package test + +import test.foo.A + +fun foo() { + val x = A() +} + +// FILE: test/foo/A.kt +package test.foo + +class A { } + +// FILE: test/bar/A.kt +package test.bar + +class A { } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/importReference/ImportReference.kt.after b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/importReference/ImportReference.kt.after new file mode 100644 index 000000000000..d18d33c9a2b9 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/importReference/ImportReference.kt.after @@ -0,0 +1,10 @@ +// FILE: test/ChangeImport.kt +// BIND_TO test.bar.A +package test + +import test.bar.A + +fun foo() { + val x = A() +} + diff --git a/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/Qualified.kt b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/Qualified.kt new file mode 100644 index 000000000000..6d068fd7c57d --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/Qualified.kt @@ -0,0 +1,17 @@ +// FILE: test/Qualified.kt +// BIND_TO test.bar.fooBar +package test + +fun foo() { + test.foo.fooBar() +} + +// FILE: test/foo/Test.kt +package test.foo + +fun fooBar() { } + +// FILE: test/bar/Test.kt +package test.bar + +fun fooBar() { } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/Qualified.kt.after b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/Qualified.kt.after new file mode 100644 index 000000000000..1fce80d344ad --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/Qualified.kt.after @@ -0,0 +1,10 @@ +// FILE: test/Qualified.kt +// BIND_TO test.bar.fooBar +package test + +import test.bar.fooBar + +fun foo() { + fooBar() +} + diff --git a/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/RootPkg.kt b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/RootPkg.kt new file mode 100644 index 000000000000..ff9af11b44cc --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/RootPkg.kt @@ -0,0 +1,8 @@ +// BIND_TO barFoo +fun foo() { + fooBar() +} + +fun fooBar() { } + +fun barFoo() { } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/RootPkg.kt.after b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/RootPkg.kt.after new file mode 100644 index 000000000000..53579e6f3872 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/RootPkg.kt.after @@ -0,0 +1,8 @@ +// BIND_TO barFoo +fun foo() { + barFoo() +} + +fun fooBar() { } + +fun barFoo() { } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/UnQualified.kt b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/UnQualified.kt new file mode 100644 index 000000000000..aa73af95b890 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/UnQualified.kt @@ -0,0 +1,19 @@ +// FILE: test/UnQualified.kt +// BIND_TO test.bar.fooBar +package test + +import test.foo.fooBar + +fun foo() { + fooBar() +} + +// FILE: test/foo/Test.kt +package test.foo + +fun fooBar() { } + +// FILE: test/bar/Test.kt +package test.bar + +fun fooBar() { } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/UnQualified.kt.after b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/UnQualified.kt.after new file mode 100644 index 000000000000..60dbbf09bc3f --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/UnQualified.kt.after @@ -0,0 +1,11 @@ +// FILE: test/UnQualified.kt +// BIND_TO test.bar.fooBar +package test + + +import test.bar.fooBar + +fun foo() { + fooBar() +} + diff --git a/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelProperty/Qualified.kt b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelProperty/Qualified.kt new file mode 100644 index 000000000000..1fb073a90d0a --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelProperty/Qualified.kt @@ -0,0 +1,17 @@ +// FILE: test/Qualified.kt +// BIND_TO test.bar.fooBar +package test + +fun foo() { + val x = test.foo.fooBar +} + +// FILE: test/foo/Test.kt +package test.foo + +val fooBar = 0 + +// FILE: test/bar/Test.kt +package test.bar + +val fooBar = 0 \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelProperty/Qualified.kt.after b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelProperty/Qualified.kt.after new file mode 100644 index 000000000000..3c4281eaea50 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelProperty/Qualified.kt.after @@ -0,0 +1,10 @@ +// FILE: test/Qualified.kt +// BIND_TO test.bar.fooBar +package test + +import test.bar.fooBar + +fun foo() { + val x = fooBar +} + diff --git a/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelProperty/RootPkg.kt b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelProperty/RootPkg.kt new file mode 100644 index 000000000000..3c072a620587 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelProperty/RootPkg.kt @@ -0,0 +1,8 @@ +// BIND_TO barFoo +fun foo() { + val x = fooBar +} + +val fooBar = 0 + +val barFoo = 0 \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelProperty/RootPkg.kt.after b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelProperty/RootPkg.kt.after new file mode 100644 index 000000000000..14b94fc2229e --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelProperty/RootPkg.kt.after @@ -0,0 +1,8 @@ +// BIND_TO barFoo +fun foo() { + val x = barFoo +} + +val fooBar = 0 + +val barFoo = 0 \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelProperty/UnQualified.kt b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelProperty/UnQualified.kt new file mode 100644 index 000000000000..c3cd5f5ba14a --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelProperty/UnQualified.kt @@ -0,0 +1,19 @@ +// FILE: test/UnQualified.kt +// BIND_TO test.bar.fooBar +package test + +import test.foo.fooBar + +fun foo() { + val x = fooBar +} + +// FILE: test/foo/Test.kt +package test.foo + +val fooBar = 0 + +// FILE: test/bar/Test.kt +package test.bar + +val fooBar = 0 \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelProperty/UnQualified.kt.after b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelProperty/UnQualified.kt.after new file mode 100644 index 000000000000..62bff3680dba --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/bindToElement/topLevelProperty/UnQualified.kt.after @@ -0,0 +1,11 @@ +// FILE: test/UnQualified.kt +// BIND_TO test.bar.fooBar +package test + + +import test.bar.fooBar + +fun foo() { + val x = fooBar +} + diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/ambiguousReference/ambiguousReference.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/ambiguousReference/ambiguousReference.test index 349e625c9541..78b5fcb1f341 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/ambiguousReference/ambiguousReference.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/ambiguousReference/ambiguousReference.test @@ -2,5 +2,6 @@ "type": "MARKED_ELEMENT", "mainFile": "test.kt", "newName": "foo", - "withRuntime": "true" + "withRuntime": "true", + "enabledInK2": "false" } diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamer/simple.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamer/simple.test index e5f1b793992f..1fe90a20180a 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamer/simple.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamer/simple.test @@ -2,6 +2,5 @@ "type": "KOTLIN_CLASS", "classId": "/Foo", "newName": "Bar", - "mainFile": "main.kt", - "enabledInK2": "true" + "mainFile": "main.kt" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerForJavaClass/javaClass.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerForJavaClass/javaClass.test index 916961243271..169f9460232a 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerForJavaClass/javaClass.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerForJavaClass/javaClass.test @@ -2,6 +2,5 @@ "type": "JAVA_CLASS", "classId": "/Foo", "newName": "Bar", - "mainFile": "Foo.java", - "enabledInK2": "true" + "mainFile": "Foo.java" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerKotlinTestClass/automaticRenamerKotlinTestClass.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerKotlinTestClass/automaticRenamerKotlinTestClass.test index 5d09e3fca471..2092c3f20f8c 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerKotlinTestClass/automaticRenamerKotlinTestClass.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerKotlinTestClass/automaticRenamerKotlinTestClass.test @@ -3,5 +3,6 @@ "mainFile": "test/test.kt", "newName": "BarNew", "withRuntime": "true", - "libraries": ["JUnit4"] + "libraries": ["JUnit4"], + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloads/package.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloads/package.test index 2e9fb98e4f55..889d5c9d1cb6 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloads/package.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloads/package.test @@ -3,6 +3,5 @@ "packageFqn": "testing", "oldName": "foo", "newName": "bar", - "mainFile": "package.kt", - "enabledInK2": "true" + "mainFile": "package.kt" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloadsClass/class.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloadsClass/class.test index 9261e551d08d..5969ab60cf49 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloadsClass/class.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloadsClass/class.test @@ -3,6 +3,5 @@ "classId": "testing/Klass", "oldName": "foo", "newName": "bar", - "mainFile": "Klass.kt", - "enabledInK2": "true" + "mainFile": "Klass.kt" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloadsExtensionAndMember/automaticRenamerOverloadsExtensionAndMember.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloadsExtensionAndMember/automaticRenamerOverloadsExtensionAndMember.test index a1b5a273abfb..b119a405a822 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloadsExtensionAndMember/automaticRenamerOverloadsExtensionAndMember.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloadsExtensionAndMember/automaticRenamerOverloadsExtensionAndMember.test @@ -2,6 +2,5 @@ "type": "MARKED_ELEMENT", "mainFile": "test/test.kt", "newName": "funMe2", - "withRuntime": "true", - "enabledInK2": "true" + "withRuntime": "true" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloadsMemberAndExtension/automaticRenamerOverloadsMemberAndExtension.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloadsMemberAndExtension/automaticRenamerOverloadsMemberAndExtension.test index a1b5a273abfb..b119a405a822 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloadsMemberAndExtension/automaticRenamerOverloadsMemberAndExtension.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloadsMemberAndExtension/automaticRenamerOverloadsMemberAndExtension.test @@ -2,6 +2,5 @@ "type": "MARKED_ELEMENT", "mainFile": "test/test.kt", "newName": "funMe2", - "withRuntime": "true", - "enabledInK2": "true" + "withRuntime": "true" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloadsObject/object.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloadsObject/object.test index 017b59b4fac7..426cad6a0af5 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloadsObject/object.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerOverloadsObject/object.test @@ -3,6 +3,5 @@ "classId": "testing/Object", "oldName": "foo", "newName": "bar", - "mainFile": "Object.kt", - "enabledInK2": "true" + "mainFile": "Object.kt" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerParameter/parameter.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerParameter/parameter.test index e5e886119884..13a6d7a64941 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerParameter/parameter.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerParameter/parameter.test @@ -1,6 +1,5 @@ { "type": "MARKED_ELEMENT", "newName": "aa", - "mainFile": "main.kt", - "enabledInK2": "true" + "mainFile": "main.kt" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerParameterInExtension/parameter.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerParameterInExtension/parameter.test index e5e886119884..13a6d7a64941 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerParameterInExtension/parameter.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticRenamerParameterInExtension/parameter.test @@ -1,6 +1,5 @@ { "type": "MARKED_ELEMENT", "newName": "aa", - "mainFile": "main.kt", - "enabledInK2": "true" + "mainFile": "main.kt" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticVariableRenamerWithQuotation/automaticVariableRenamerWithQuotation.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticVariableRenamerWithQuotation/automaticVariableRenamerWithQuotation.test index 3a8cb00ec5f3..829da4acbc9d 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticVariableRenamerWithQuotation/automaticVariableRenamerWithQuotation.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/automaticVariableRenamerWithQuotation/automaticVariableRenamerWithQuotation.test @@ -2,6 +2,5 @@ "type": "MARKED_ELEMENT", "mainFile": "test/test.kt", "newName": "A B", - "withRuntime": "true", - "enabledInK2": "true" + "withRuntime": "true" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/backingField/backingField.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/backingField/backingField.test index 1a3321ecf765..d5a985357e1c 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/backingField/backingField.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/backingField/backingField.test @@ -3,6 +3,5 @@ "mainFile": "test.kt", "newName": "Bar", "forceInlineRename": "false", - "hint": "Rename is not applicable to backing field reference", - "enabledInK2": "true" + "hint": "Rename is not applicable to backing field reference" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/clashOfNestedWithOuterClass/clashOfNestedWithOuterClass.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/clashOfNestedWithOuterClass/clashOfNestedWithOuterClass.test index 488e8f0079ca..b92066d2c49c 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/clashOfNestedWithOuterClass/clashOfNestedWithOuterClass.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/clashOfNestedWithOuterClass/clashOfNestedWithOuterClass.test @@ -2,6 +2,5 @@ "type": "MARKED_ELEMENT", "mainFile": "test/test.kt", "newName": "A", - "withRuntime": "true", - "enabledInK2": "true" + "withRuntime": "true" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/clashParameterWithProperty/clashParameterWithProperty.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/clashParameterWithProperty/clashParameterWithProperty.test index 97c4fd11919c..525ff030dc13 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/clashParameterWithProperty/clashParameterWithProperty.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/clashParameterWithProperty/clashParameterWithProperty.test @@ -2,5 +2,6 @@ "type": "MARKED_ELEMENT", "mainFile": "test/test.kt", "newName": "foo", - "withRuntime": "true" + "withRuntime": "true", + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/clashWithInnerClass/clashWithInnerClass.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/clashWithInnerClass/clashWithInnerClass.test index 1836787075ba..665fedcc6ff8 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/clashWithInnerClass/clashWithInnerClass.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/clashWithInnerClass/clashWithInnerClass.test @@ -2,5 +2,6 @@ "type": "MARKED_ELEMENT", "mainFile": "test/test.kt", "newName": "C", - "withRuntime": "true" + "withRuntime": "true", + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/clashWithNestedClass/clashWithNestedClass.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/clashWithNestedClass/clashWithNestedClass.test index 1836787075ba..665fedcc6ff8 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/clashWithNestedClass/clashWithNestedClass.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/clashWithNestedClass/clashWithNestedClass.test @@ -2,5 +2,6 @@ "type": "MARKED_ELEMENT", "mainFile": "test/test.kt", "newName": "C", - "withRuntime": "true" + "withRuntime": "true", + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/clashWithOuterClass/clashWithOuterClass.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/clashWithOuterClass/clashWithOuterClass.test index 488e8f0079ca..b92066d2c49c 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/clashWithOuterClass/clashWithOuterClass.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/clashWithOuterClass/clashWithOuterClass.test @@ -2,6 +2,5 @@ "type": "MARKED_ELEMENT", "mainFile": "test/test.kt", "newName": "A", - "withRuntime": "true", - "enabledInK2": "true" + "withRuntime": "true" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/classAndTypeAliasRedeclaration/classAndTypeAliasRedeclaration.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/classAndTypeAliasRedeclaration/classAndTypeAliasRedeclaration.test index f70030b2f6a6..c3213f5bef79 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/classAndTypeAliasRedeclaration/classAndTypeAliasRedeclaration.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/classAndTypeAliasRedeclaration/classAndTypeAliasRedeclaration.test @@ -3,6 +3,5 @@ "mainFile": "test.kt", "newName": "Foo", "withRuntime": "true", - "hint": "Class 'Foo' is already declared in package", - "enabledInK2": "true" + "hint": "Class 'Foo' is already declared in package" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/companionShortRef/companionShortRef.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/companionShortRef/companionShortRef.test index e21d4f45316e..86f96713269b 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/companionShortRef/companionShortRef.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/companionShortRef/companionShortRef.test @@ -1,6 +1,5 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "Bar", - "enabledInK2": "true" + "newName": "Bar" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/importAlias/importAlias.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/importAlias/importAlias.test index fae0e39d66eb..4c5cbda0a7be 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/importAlias/importAlias.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/importAlias/importAlias.test @@ -1,5 +1,6 @@ { "type": "MARKED_ELEMENT", "mainFile": "test.kt", - "newName": "Baz" + "newName": "Baz", + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/importAliasByRef/importAliasByRef.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/importAliasByRef/importAliasByRef.test index 11866799bf6c..2ea62f4a5718 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/importAliasByRef/importAliasByRef.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/importAliasByRef/importAliasByRef.test @@ -1,5 +1,6 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "Baz" + "newName": "Baz", + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/javaClassImportAliasByRef/javaClassImportAliasByRef.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/javaClassImportAliasByRef/javaClassImportAliasByRef.test index 11866799bf6c..2ea62f4a5718 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/javaClassImportAliasByRef/javaClassImportAliasByRef.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/javaClassImportAliasByRef/javaClassImportAliasByRef.test @@ -1,5 +1,6 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "Baz" + "newName": "Baz", + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/javaGetterToOrdinaryMethod/javaGetterToOrdinaryMethod.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/javaGetterToOrdinaryMethod/javaGetterToOrdinaryMethod.test index 2e7d311dfffc..24b4fcfe461d 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/javaGetterToOrdinaryMethod/javaGetterToOrdinaryMethod.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/javaGetterToOrdinaryMethod/javaGetterToOrdinaryMethod.test @@ -2,6 +2,5 @@ "type": "AUTO_DETECT", "mainFile": "SyntheticProperty.java", "newName": "foo", - "withRuntime": "true", - "enabledInK2": "true" + "withRuntime": "true" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/javaSetterToOrdinaryMethod/javaSetterToOrdinaryMethod.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/javaSetterToOrdinaryMethod/javaSetterToOrdinaryMethod.test index 2e7d311dfffc..24b4fcfe461d 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/javaSetterToOrdinaryMethod/javaSetterToOrdinaryMethod.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/javaSetterToOrdinaryMethod/javaSetterToOrdinaryMethod.test @@ -2,6 +2,5 @@ "type": "AUTO_DETECT", "mainFile": "SyntheticProperty.java", "newName": "foo", - "withRuntime": "true", - "enabledInK2": "true" + "withRuntime": "true" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLambdaByLabelRef/labeledLambdaByLabelRef.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLambdaByLabelRef/labeledLambdaByLabelRef.test index 9cc31b2bcc00..dae046abfe1a 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLambdaByLabelRef/labeledLambdaByLabelRef.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLambdaByLabelRef/labeledLambdaByLabelRef.test @@ -1,6 +1,5 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "baz", - "enabledInK2": "true" + "newName": "baz" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabel/labeledLoopByLabel.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabel/labeledLoopByLabel.test index a9bdd5e30b0a..9e08b548cbdf 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabel/labeledLoopByLabel.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabel/labeledLoopByLabel.test @@ -1,6 +1,5 @@ { "type": "MARKED_ELEMENT", "mainFile": "test.kt", - "newName": "bar", - "enabledInK2": "true" + "newName": "bar" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabelRefInBreak/labeledLoopByLabelRefInBreak.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabelRefInBreak/labeledLoopByLabelRefInBreak.test index a9bdd5e30b0a..9e08b548cbdf 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabelRefInBreak/labeledLoopByLabelRefInBreak.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabelRefInBreak/labeledLoopByLabelRefInBreak.test @@ -1,6 +1,5 @@ { "type": "MARKED_ELEMENT", "mainFile": "test.kt", - "newName": "bar", - "enabledInK2": "true" + "newName": "bar" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabelRefInBreak2/labeledLoopByLabelRefInBreak.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabelRefInBreak2/labeledLoopByLabelRefInBreak.test index c28862cfaef6..29ce6c16b628 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabelRefInBreak2/labeledLoopByLabelRefInBreak.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabelRefInBreak2/labeledLoopByLabelRefInBreak.test @@ -1,6 +1,5 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "bar", - "enabledInK2": "true" + "newName": "bar" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabelRefInContinue/labeledLoopByLabelRefInContinue.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabelRefInContinue/labeledLoopByLabelRefInContinue.test index a9bdd5e30b0a..9e08b548cbdf 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabelRefInContinue/labeledLoopByLabelRefInContinue.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabelRefInContinue/labeledLoopByLabelRefInContinue.test @@ -1,6 +1,5 @@ { "type": "MARKED_ELEMENT", "mainFile": "test.kt", - "newName": "bar", - "enabledInK2": "true" + "newName": "bar" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabelRefInContinue2/labeledLoopByLabelRefInContinue.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabelRefInContinue2/labeledLoopByLabelRefInContinue.test index c28862cfaef6..29ce6c16b628 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabelRefInContinue2/labeledLoopByLabelRefInContinue.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledLoopByLabelRefInContinue2/labeledLoopByLabelRefInContinue.test @@ -1,6 +1,5 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "bar", - "enabledInK2": "true" + "newName": "bar" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledReturnInAnonymousFun/labeledReturnInAnonymousFun.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledReturnInAnonymousFun/labeledReturnInAnonymousFun.test index c28862cfaef6..29ce6c16b628 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledReturnInAnonymousFun/labeledReturnInAnonymousFun.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledReturnInAnonymousFun/labeledReturnInAnonymousFun.test @@ -1,6 +1,5 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "bar", - "enabledInK2": "true" + "newName": "bar" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledReturnInAnonymousFunBeforeWhitespace/labeledReturnInAnonymousFunBeforeWhitespace.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledReturnInAnonymousFunBeforeWhitespace/labeledReturnInAnonymousFunBeforeWhitespace.test index c28862cfaef6..29ce6c16b628 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledReturnInAnonymousFunBeforeWhitespace/labeledReturnInAnonymousFunBeforeWhitespace.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledReturnInAnonymousFunBeforeWhitespace/labeledReturnInAnonymousFunBeforeWhitespace.test @@ -1,6 +1,5 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "bar", - "enabledInK2": "true" + "newName": "bar" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledReturnInLambda/labeledReturnInLambda.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledReturnInLambda/labeledReturnInLambda.test index c28862cfaef6..29ce6c16b628 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledReturnInLambda/labeledReturnInLambda.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/labeledReturnInLambda/labeledReturnInLambda.test @@ -1,6 +1,5 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "bar", - "enabledInK2": "true" + "newName": "bar" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/lambdaParameterRedeclaration/lambdaParameterRedeclaration.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/lambdaParameterRedeclaration/lambdaParameterRedeclaration.test index e0fde92a09a2..4e3058e70684 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/lambdaParameterRedeclaration/lambdaParameterRedeclaration.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/lambdaParameterRedeclaration/lambdaParameterRedeclaration.test @@ -3,6 +3,5 @@ "mainFile": "test.kt", "newName": "b", "withRuntime": "true", - "hint": "Parameter 'b' is already declared in lambda", - "enabledInK2": "true" + "hint": "Parameter 'b' is already declared in lambda" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/memberPropertyRedeclaration/memberPropertyRedeclaration.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/memberPropertyRedeclaration/memberPropertyRedeclaration.test index 2b741478d986..b059772e0a32 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/memberPropertyRedeclaration/memberPropertyRedeclaration.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/memberPropertyRedeclaration/memberPropertyRedeclaration.test @@ -3,6 +3,5 @@ "mainFile": "test/test.kt", "newName": "foo", "withRuntime": "true", - "hint": "Property 'foo' is already declared in class 'A'", - "enabledInK2": "true" + "hint": "Property 'foo' is already declared in class 'A'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/memberPropertyShadowedByLocalVar/memberPropertyShadowedByLocalVar.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/memberPropertyShadowedByLocalVar/memberPropertyShadowedByLocalVar.test index 5e68c14cbbdd..45e03a9af533 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/memberPropertyShadowedByLocalVar/memberPropertyShadowedByLocalVar.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/memberPropertyShadowedByLocalVar/memberPropertyShadowedByLocalVar.test @@ -2,5 +2,6 @@ "type": "MARKED_ELEMENT", "mainFile": "test/test.kt", "newName": "name2", - "withRuntime": "true" + "withRuntime": "true", + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/memberPropertyWithInnerInstanceProperty/memberPropertyWithInnerInstanceProperty.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/memberPropertyWithInnerInstanceProperty/memberPropertyWithInnerInstanceProperty.test index 283c8da05000..e2319da1ae5a 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/memberPropertyWithInnerInstanceProperty/memberPropertyWithInnerInstanceProperty.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/memberPropertyWithInnerInstanceProperty/memberPropertyWithInnerInstanceProperty.test @@ -2,5 +2,6 @@ "type": "MARKED_ELEMENT", "mainFile": "test/test.kt", "newName": "xx", - "withRuntime": "true" + "withRuntime": "true", + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/nestedClassRedeclaration/nestedClassRedeclaration.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/nestedClassRedeclaration/nestedClassRedeclaration.test index f19553ac98aa..07c158eaae95 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/nestedClassRedeclaration/nestedClassRedeclaration.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/nestedClassRedeclaration/nestedClassRedeclaration.test @@ -3,6 +3,5 @@ "mainFile": "test/test.kt", "newName": "Foo", "withRuntime": "true", - "hint": "Class 'Foo' is already declared in class 'A'", - "enabledInK2": "true" + "hint": "Class 'Foo' is already declared in class 'A'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/noShadowingConflictForSiblingDeclarations/noShadowingConflictForSiblingDeclarations.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/noShadowingConflictForSiblingDeclarations/noShadowingConflictForSiblingDeclarations.test index a2fbc86cb53a..d4b7dfd82686 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/noShadowingConflictForSiblingDeclarations/noShadowingConflictForSiblingDeclarations.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/noShadowingConflictForSiblingDeclarations/noShadowingConflictForSiblingDeclarations.test @@ -3,6 +3,5 @@ "mainFile": "test.kt", "newName": "SameScopeB", "withRuntime": "true", - "hint": "Class 'SameScopeB' is already declared in package 'test'", - "enabledInK2": "true" + "hint": "Class 'SameScopeB' is already declared in package 'test'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/nonPrivateTopLevelDeclarationsConflict/nonPrivateTopLevelDeclarationsNoConflict.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/nonPrivateTopLevelDeclarationsConflict/nonPrivateTopLevelDeclarationsNoConflict.test index 475115bcf13a..6e66dd6fcbf5 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/nonPrivateTopLevelDeclarationsConflict/nonPrivateTopLevelDeclarationsNoConflict.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/nonPrivateTopLevelDeclarationsConflict/nonPrivateTopLevelDeclarationsNoConflict.test @@ -2,6 +2,5 @@ "type": "MARKED_ELEMENT", "mainFile": "test1.kt", "newName": "bar", - "hint": "Property 'bar' is already declared in package 'p'", - "enabledInK2": "true" + "hint": "Property 'bar' is already declared in package 'p'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/objectFunctionImportAliasByRef/objectFunctionImportAliasByRef.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/objectFunctionImportAliasByRef/objectFunctionImportAliasByRef.test index dae046abfe1a..cde718b0573e 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/objectFunctionImportAliasByRef/objectFunctionImportAliasByRef.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/objectFunctionImportAliasByRef/objectFunctionImportAliasByRef.test @@ -1,5 +1,6 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "baz" + "newName": "baz", + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/objectPropertyImportAliasByRef/objectPropertyImportAliasByRef.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/objectPropertyImportAliasByRef/objectPropertyImportAliasByRef.test index dae046abfe1a..cde718b0573e 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/objectPropertyImportAliasByRef/objectPropertyImportAliasByRef.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/objectPropertyImportAliasByRef/objectPropertyImportAliasByRef.test @@ -1,5 +1,6 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "baz" + "newName": "baz", + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/parameterHierarchyMiddle/parameterHierarchyMiddle.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/parameterHierarchyMiddle/parameterHierarchyMiddle.test index 68d5cbf52a46..ec57f250b068 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/parameterHierarchyMiddle/parameterHierarchyMiddle.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/parameterHierarchyMiddle/parameterHierarchyMiddle.test @@ -1,6 +1,5 @@ { "type": "MARKED_ELEMENT", "mainFile": "test.kt", - "newName": "x", - "enabledInK2": "true" + "newName": "x" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/parameterHierarchyRoot/parameterHierarchyRoot.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/parameterHierarchyRoot/parameterHierarchyRoot.test index 68d5cbf52a46..ec57f250b068 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/parameterHierarchyRoot/parameterHierarchyRoot.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/parameterHierarchyRoot/parameterHierarchyRoot.test @@ -1,6 +1,5 @@ { "type": "MARKED_ELEMENT", "mainFile": "test.kt", - "newName": "x", - "enabledInK2": "true" + "newName": "x" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/parameterRedeclaration/parameterRedeclaration.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/parameterRedeclaration/parameterRedeclaration.test index 844c3be4cb40..723a26f04288 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/parameterRedeclaration/parameterRedeclaration.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/parameterRedeclaration/parameterRedeclaration.test @@ -3,6 +3,5 @@ "mainFile": "test/test.kt", "newName": "b", "withRuntime": "true", - "hint": "Parameter 'b' is already declared in function 'foo'", - "enabledInK2": "true" + "hint": "Parameter 'b' is already declared in function 'foo'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/primaryConstructorParameterRedeclaration/primaryConstructorParameterRedeclaration.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/primaryConstructorParameterRedeclaration/primaryConstructorParameterRedeclaration.test index 0ae78684ce05..c2bd090a8b37 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/primaryConstructorParameterRedeclaration/primaryConstructorParameterRedeclaration.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/primaryConstructorParameterRedeclaration/primaryConstructorParameterRedeclaration.test @@ -3,6 +3,5 @@ "mainFile": "test.kt", "newName": "cpb", "withRuntime": "true", - "hint": "Parameter 'cpb' is already declared in class 'A'", - "enabledInK2": "true" + "hint": "Parameter 'cpb' is already declared in class 'A'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyAccidentalOverrideSubclass/propertyAccidentalOverrideSubclass.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyAccidentalOverrideSubclass/propertyAccidentalOverrideSubclass.test index 846142421240..f91170482e0c 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyAccidentalOverrideSubclass/propertyAccidentalOverrideSubclass.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyAccidentalOverrideSubclass/propertyAccidentalOverrideSubclass.test @@ -3,6 +3,5 @@ "mainFile": "test/test.kt", "newName": "bar", "withRuntime": "true", - "hint": "Property after rename will clash with existing property 'bar' in class 'B'", - "enabledInK2": "true" + "hint": "Property after rename will clash with existing property 'bar' in class 'B'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyAccidentalOverrideSuperclass/propertyAccidentalOverrideSuperclass.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyAccidentalOverrideSuperclass/propertyAccidentalOverrideSuperclass.test index 267d7f814bff..e7d1b6107680 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyAccidentalOverrideSuperclass/propertyAccidentalOverrideSuperclass.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyAccidentalOverrideSuperclass/propertyAccidentalOverrideSuperclass.test @@ -3,6 +3,5 @@ "mainFile": "test/test.kt", "newName": "foo", "withRuntime": "true", - "hint": "Property after rename will clash with existing property 'foo' in class 'A'", - "enabledInK2": "true" + "hint": "Property after rename will clash with existing property 'foo' in class 'A'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyImportAliasByRef/propertyImportAliasByRef.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyImportAliasByRef/propertyImportAliasByRef.test index 7f96d932dc78..a6002418b92f 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyImportAliasByRef/propertyImportAliasByRef.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyImportAliasByRef/propertyImportAliasByRef.test @@ -1,5 +1,6 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "referWithAli" + "newName": "referWithAli", + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyParameterAccidentalOverrideSubclass/propertyParameterAccidentalOverrideSubclass.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyParameterAccidentalOverrideSubclass/propertyParameterAccidentalOverrideSubclass.test index 8a0354cf1c29..f4d11f2598a0 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyParameterAccidentalOverrideSubclass/propertyParameterAccidentalOverrideSubclass.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyParameterAccidentalOverrideSubclass/propertyParameterAccidentalOverrideSubclass.test @@ -3,6 +3,5 @@ "mainFile": "test/test.kt", "newName": "bar", "withRuntime": "true", - "hint": "Parameter after rename will clash with existing property 'bar' in class 'B'", - "enabledInK2": "true" + "hint": "Parameter after rename will clash with existing property 'bar' in class 'B'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyParameterAccidentalOverrideSuperclass/propertyParameterAccidentalOverrideSuperclass.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyParameterAccidentalOverrideSuperclass/propertyParameterAccidentalOverrideSuperclass.test index 38d7a0122c0c..9a114ae8ca87 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyParameterAccidentalOverrideSuperclass/propertyParameterAccidentalOverrideSuperclass.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyParameterAccidentalOverrideSuperclass/propertyParameterAccidentalOverrideSuperclass.test @@ -3,6 +3,5 @@ "mainFile": "test/test.kt", "newName": "foo", "withRuntime": "true", - "hint": "Property after rename will clash with existing parameter 'foo' in class 'A'", - "enabledInK2": "true" + "hint": "Property after rename will clash with existing parameter 'foo' in class 'A'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyParameterRedeclaredByProperty/propertyParameterRedeclaredByProperty.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyParameterRedeclaredByProperty/propertyParameterRedeclaredByProperty.test index 92c9eaed5af9..03b04f881cf2 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyParameterRedeclaredByProperty/propertyParameterRedeclaredByProperty.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyParameterRedeclaredByProperty/propertyParameterRedeclaredByProperty.test @@ -3,6 +3,5 @@ "mainFile": "test/test.kt", "newName": "b", "withRuntime": "true", - "hint": "Property 'b' is already declared in class 'Foo'", - "enabledInK2": "true" + "hint": "Property 'b' is already declared in class 'Foo'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyRedeclaredByPropertyParameter/propertyRedeclaredByPropertyParameter.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyRedeclaredByPropertyParameter/propertyRedeclaredByPropertyParameter.test index e8618792dc9b..ee6657662d4a 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyRedeclaredByPropertyParameter/propertyRedeclaredByPropertyParameter.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/propertyRedeclaredByPropertyParameter/propertyRedeclaredByPropertyParameter.test @@ -3,6 +3,5 @@ "mainFile": "test/test.kt", "newName": "a", "withRuntime": "true", - "hint": "Parameter 'a' is already declared in class 'Foo'", - "enabledInK2": "true" + "hint": "Parameter 'a' is already declared in class 'Foo'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameClassTypeParameterRedeclaration/renameClassTypeParameterRedeclaration.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameClassTypeParameterRedeclaration/renameClassTypeParameterRedeclaration.test index b7174fa10ca6..ba2ae803f6b1 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameClassTypeParameterRedeclaration/renameClassTypeParameterRedeclaration.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameClassTypeParameterRedeclaration/renameClassTypeParameterRedeclaration.test @@ -2,6 +2,5 @@ "type": "MARKED_ELEMENT", "mainFile": "test.kt", "newName": "V", - "hint": "Type parameter 'V' is already declared in class 'A'", - "enabledInK2": "true" + "hint": "Type parameter 'V' is already declared in class 'A'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameClassTypeParameterRedeclarationWithOuterScope/renameClassTypeParameterRedeclarationWithOuterScope.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameClassTypeParameterRedeclarationWithOuterScope/renameClassTypeParameterRedeclarationWithOuterScope.test index ab0c5baefd37..88ba60d9af94 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameClassTypeParameterRedeclarationWithOuterScope/renameClassTypeParameterRedeclarationWithOuterScope.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameClassTypeParameterRedeclarationWithOuterScope/renameClassTypeParameterRedeclarationWithOuterScope.test @@ -2,6 +2,5 @@ "type": "MARKED_ELEMENT", "mainFile": "test.kt", "newName": "T", - "hint": "Type parameter 'T' is already declared in class 'A'", - "enabledInK2": "true" + "hint": "Type parameter 'T' is already declared in class 'A'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameClassWithAutoVarConventions/renameClassWithAutoVarConventions.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameClassWithAutoVarConventions/renameClassWithAutoVarConventions.test index f433f31b6279..88b4ce89d63c 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameClassWithAutoVarConventions/renameClassWithAutoVarConventions.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameClassWithAutoVarConventions/renameClassWithAutoVarConventions.test @@ -2,6 +2,5 @@ "type": "KOTLIN_CLASS", "mainFile": "test.kt", "classId": "test/Foo", - "newName": "Bar", - "enabledInK2": "true" + "newName": "Bar" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameDefaultKotlinAnnotationMethod/renameDefaultKotlinAnnotationMethod.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameDefaultKotlinAnnotationMethod/renameDefaultKotlinAnnotationMethod.test index 4861275fb93c..1a90cd07d17c 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameDefaultKotlinAnnotationMethod/renameDefaultKotlinAnnotationMethod.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameDefaultKotlinAnnotationMethod/renameDefaultKotlinAnnotationMethod.test @@ -2,6 +2,5 @@ "type": "MARKED_ELEMENT", "mainFile": "test/KAnn.kt", "newName": "valueNew", - "withRuntime": "true", - "enabledInK2": "true" + "withRuntime": "true" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameFieldIdentifier/fieldIdentifier.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameFieldIdentifier/fieldIdentifier.test index 92d1274466fc..259565da1a4d 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameFieldIdentifier/fieldIdentifier.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameFieldIdentifier/fieldIdentifier.test @@ -2,5 +2,6 @@ "type": "MARKED_ELEMENT", "newName": "prop11", "mainFile": "test.kt", - "checkErrorsAfter": "true" + "checkErrorsAfter": "true", + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameFunctionTypeParameterRedeclaration/renameFunctionTypeParameterRedeclaration.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameFunctionTypeParameterRedeclaration/renameFunctionTypeParameterRedeclaration.test index b0c29ca64549..729a01fa9607 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameFunctionTypeParameterRedeclaration/renameFunctionTypeParameterRedeclaration.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameFunctionTypeParameterRedeclaration/renameFunctionTypeParameterRedeclaration.test @@ -2,6 +2,5 @@ "type": "MARKED_ELEMENT", "mainFile": "test.kt", "newName": "V", - "hint": "Type parameter 'V' is already declared in function 'foo'", - "enabledInK2": "true" + "hint": "Type parameter 'V' is already declared in function 'foo'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameFunctionTypeParameterRedeclarationWithOuterScope/renameFunctionTypeParameterRedeclarationWithOuterScope.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameFunctionTypeParameterRedeclarationWithOuterScope/renameFunctionTypeParameterRedeclarationWithOuterScope.test index ab0c5baefd37..88ba60d9af94 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameFunctionTypeParameterRedeclarationWithOuterScope/renameFunctionTypeParameterRedeclarationWithOuterScope.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameFunctionTypeParameterRedeclarationWithOuterScope/renameFunctionTypeParameterRedeclarationWithOuterScope.test @@ -2,6 +2,5 @@ "type": "MARKED_ELEMENT", "mainFile": "test.kt", "newName": "T", - "hint": "Type parameter 'T' is already declared in class 'A'", - "enabledInK2": "true" + "hint": "Type parameter 'T' is already declared in class 'A'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameGetToInvoke/renameGetToInvoke.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameGetToInvoke/renameGetToInvoke.test index ba3d1c672479..09faec9d5bee 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameGetToInvoke/renameGetToInvoke.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameGetToInvoke/renameGetToInvoke.test @@ -3,5 +3,6 @@ "classId": "/Foo", "oldName": "get", "newName": "invoke", - "mainFile": "main.kt" + "mainFile": "main.kt", + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticIsPropertyByGetterRef/renameJavaSyntheticIsPropertyByGetterRef.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticIsPropertyByGetterRef/renameJavaSyntheticIsPropertyByGetterRef.test index 6e996fa95a02..6f23f4f94898 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticIsPropertyByGetterRef/renameJavaSyntheticIsPropertyByGetterRef.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticIsPropertyByGetterRef/renameJavaSyntheticIsPropertyByGetterRef.test @@ -1,6 +1,5 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "isProp2", - "enabledInK2": "true" + "newName": "isProp2" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticIsPropertyByRef0/renameJavaSyntheticIsPropertyByRef0.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticIsPropertyByRef0/renameJavaSyntheticIsPropertyByRef0.test index 6e996fa95a02..6f23f4f94898 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticIsPropertyByRef0/renameJavaSyntheticIsPropertyByRef0.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticIsPropertyByRef0/renameJavaSyntheticIsPropertyByRef0.test @@ -1,6 +1,5 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "isProp2", - "enabledInK2": "true" + "newName": "isProp2" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticIsPropertyByRef1/renameJavaSyntheticIsPropertyByRef1.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticIsPropertyByRef1/renameJavaSyntheticIsPropertyByRef1.test index 6e996fa95a02..6f23f4f94898 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticIsPropertyByRef1/renameJavaSyntheticIsPropertyByRef1.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticIsPropertyByRef1/renameJavaSyntheticIsPropertyByRef1.test @@ -1,6 +1,5 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "isProp2", - "enabledInK2": "true" + "newName": "isProp2" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticIsPropertyBySetterRef/renameJavaSyntheticIsPropertyBySetterRef.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticIsPropertyBySetterRef/renameJavaSyntheticIsPropertyBySetterRef.test index 6e996fa95a02..6f23f4f94898 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticIsPropertyBySetterRef/renameJavaSyntheticIsPropertyBySetterRef.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticIsPropertyBySetterRef/renameJavaSyntheticIsPropertyBySetterRef.test @@ -1,6 +1,5 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "isProp2", - "enabledInK2": "true" + "newName": "isProp2" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyByGetterRef/renameJavaSyntheticPropertyByGetterRef.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyByGetterRef/renameJavaSyntheticPropertyByGetterRef.test index b6ba424e47f0..9f0eddf1f465 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyByGetterRef/renameJavaSyntheticPropertyByGetterRef.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyByGetterRef/renameJavaSyntheticPropertyByGetterRef.test @@ -1,6 +1,5 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "prop2", - "enabledInK2": "true" + "newName": "prop2" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyByGetterSetterRef/renameJavaSyntheticPropertyByGetterSetterRef.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyByGetterSetterRef/renameJavaSyntheticPropertyByGetterSetterRef.test index b6ba424e47f0..9f0eddf1f465 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyByGetterSetterRef/renameJavaSyntheticPropertyByGetterSetterRef.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyByGetterSetterRef/renameJavaSyntheticPropertyByGetterSetterRef.test @@ -1,6 +1,5 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "prop2", - "enabledInK2": "true" + "newName": "prop2" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyByRef0/renameJavaSyntheticPropertyByRef0.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyByRef0/renameJavaSyntheticPropertyByRef0.test index b6ba424e47f0..9f0eddf1f465 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyByRef0/renameJavaSyntheticPropertyByRef0.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyByRef0/renameJavaSyntheticPropertyByRef0.test @@ -1,6 +1,5 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "prop2", - "enabledInK2": "true" + "newName": "prop2" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyByRef1/renameJavaSyntheticPropertyByRef1.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyByRef1/renameJavaSyntheticPropertyByRef1.test index b6ba424e47f0..9f0eddf1f465 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyByRef1/renameJavaSyntheticPropertyByRef1.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyByRef1/renameJavaSyntheticPropertyByRef1.test @@ -1,6 +1,5 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "prop2", - "enabledInK2": "true" + "newName": "prop2" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyBySetterRef/renameJavaSyntheticPropertyBySetterRef.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyBySetterRef/renameJavaSyntheticPropertyBySetterRef.test index b6ba424e47f0..9f0eddf1f465 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyBySetterRef/renameJavaSyntheticPropertyBySetterRef.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameJavaSyntheticPropertyBySetterRef/renameJavaSyntheticPropertyBySetterRef.test @@ -1,6 +1,5 @@ { "type": "AUTO_DETECT", "mainFile": "test.kt", - "newName": "prop2", - "enabledInK2": "true" + "newName": "prop2" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinClassByImplicitConstructorRef/after/test.kt b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinClassByImplicitConstructorRef/after/test.kt new file mode 100644 index 000000000000..5db915c9bf32 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinClassByImplicitConstructorRef/after/test.kt @@ -0,0 +1,8 @@ +package testing.rename + +public open class B { +} + +fun test() { + B() +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinClassByImplicitConstructorRef/before/test.kt b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinClassByImplicitConstructorRef/before/test.kt new file mode 100644 index 000000000000..98041d62f67d --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinClassByImplicitConstructorRef/before/test.kt @@ -0,0 +1,8 @@ +package testing.rename + +public open class A { +} + +fun test() { + /*rename*/A() +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinClassByImplicitConstructorRef/kotlinClass.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinClassByImplicitConstructorRef/kotlinClass.test new file mode 100644 index 000000000000..f433352d5e08 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinClassByImplicitConstructorRef/kotlinClass.test @@ -0,0 +1,7 @@ +{ + "type": "MARKED_ELEMENT", + "mainFile": "test.kt", + "newName": "B", + "byRef": "true", + "enabledInK2": true +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinClassConstructor/renameKotlinConstructor.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinClassConstructor/renameKotlinConstructor.test index e4139cba7314..604e88d05250 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinClassConstructor/renameKotlinConstructor.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinClassConstructor/renameKotlinConstructor.test @@ -1,6 +1,5 @@ { "type": "KOTLIN_CLASS", "classId": "/X", - "newName": "TestX", - "enabledInK2": "true" + "newName": "TestX" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinEnumEntry/renameKotlinEnumEntry.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinEnumEntry/renameKotlinEnumEntry.test index 45666304e60a..21b09f3b8e1d 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinEnumEntry/renameKotlinEnumEntry.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinEnumEntry/renameKotlinEnumEntry.test @@ -1,6 +1,5 @@ { "type": "KOTLIN_CLASS", "classId": "testing/E.FOO", - "newName": "BAR", - "enabledInK2": "true" + "newName": "BAR" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinFunctionInEnum/renameKotlinFunctionInEnumFromSubclass.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinFunctionInEnum/renameKotlinFunctionInEnumFromSubclass.test index 1f3e19ba5320..205398aca208 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinFunctionInEnum/renameKotlinFunctionInEnumFromSubclass.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinFunctionInEnum/renameKotlinFunctionInEnumFromSubclass.test @@ -2,6 +2,5 @@ "type": "KOTLIN_FUNCTION", "classId": "test/E.A", "oldName": "foo", - "newName": "bar", - "enabledInK2": "true" + "newName": "bar" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinPackage/renameInOtherFile.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinPackage/renameInOtherFile.test index a71d6795b849..1e0ee7576a7b 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinPackage/renameInOtherFile.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinPackage/renameInOtherFile.test @@ -3,6 +3,5 @@ "fqn": "some.foo", "newName": "bar", "mainFile": "ForClassImport.kt", - "comment": "KT-365 Support renaming packages", - "enabledInK2": "true" + "comment": "KT-365 Support renaming packages" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinPackage/renameKotlinPackage.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinPackage/renameKotlinPackage.test index 9583a5faa992..016ba6260ba9 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinPackage/renameKotlinPackage.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinPackage/renameKotlinPackage.test @@ -2,6 +2,5 @@ "type": "KOTLIN_PACKAGE", "fqn": "some.foo", "newName": "bar", - "comment": "KT-365 Support renaming packages", - "enabledInK2": "true" + "comment": "KT-365 Support renaming packages" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinPrimaryConstructorPropertyFromOverride/renameKotlinPrimaryConstructorPropertyFromOverride.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinPrimaryConstructorPropertyFromOverride/renameKotlinPrimaryConstructorPropertyFromOverride.test index 0a10ed0e59f6..36df31631ecc 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinPrimaryConstructorPropertyFromOverride/renameKotlinPrimaryConstructorPropertyFromOverride.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renameKotlinPrimaryConstructorPropertyFromOverride/renameKotlinPrimaryConstructorPropertyFromOverride.test @@ -1,6 +1,5 @@ { "type": "MARKED_ELEMENT", "newName": "second", - "mainFile": "RenameKotlinPrimaryConstructorPropertyFromOverride.kt", - "enabledInK2": "true" + "mainFile": "RenameKotlinPrimaryConstructorPropertyFromOverride.kt" } diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renamePackageFqNameStarImport/renamePackageFqNameStarImport.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renamePackageFqNameStarImport/renamePackageFqNameStarImport.test index c3090416aef2..299d77f1108f 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renamePackageFqNameStarImport/renamePackageFqNameStarImport.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renamePackageFqNameStarImport/renamePackageFqNameStarImport.test @@ -3,5 +3,6 @@ "mainFile": "a/b/bar.kt", "newName": "x.y", "withRuntime": "true", - "byRef": "true" + "byRef": "true", + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renamePropertyInEnumCompanionWithEntryConflict/renameKotlinPropertyInEnumCompanionWithEntryConflict.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renamePropertyInEnumCompanionWithEntryConflict/renameKotlinPropertyInEnumCompanionWithEntryConflict.test index b92066d2c49c..b2ba18d75372 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renamePropertyInEnumCompanionWithEntryConflict/renameKotlinPropertyInEnumCompanionWithEntryConflict.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renamePropertyInEnumCompanionWithEntryConflict/renameKotlinPropertyInEnumCompanionWithEntryConflict.test @@ -2,5 +2,6 @@ "type": "MARKED_ELEMENT", "mainFile": "test/test.kt", "newName": "A", - "withRuntime": "true" + "withRuntime": "true", + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renamedClassShadowingImplicitlyImportedClassUsage/renamedClassShadowingImplicitlyImportedClassUsage.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renamedClassShadowingImplicitlyImportedClassUsage/renamedClassShadowingImplicitlyImportedClassUsage.test index a87ac35f27fd..3e5b2b151738 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renamedClassShadowingImplicitlyImportedClassUsage/renamedClassShadowingImplicitlyImportedClassUsage.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renamedClassShadowingImplicitlyImportedClassUsage/renamedClassShadowingImplicitlyImportedClassUsage.test @@ -2,5 +2,6 @@ "type": "MARKED_ELEMENT", "mainFile": "test/ref.kt", "newName": "String", - "withRuntime": "true" + "withRuntime": "true", + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/renamedClassShadowingImportedClassUsage/renamedClassShadowingImportedClassUsage.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/renamedClassShadowingImportedClassUsage/renamedClassShadowingImportedClassUsage.test index a0d5dbcfb638..9b7759a22e50 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/renamedClassShadowingImportedClassUsage/renamedClassShadowingImportedClassUsage.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/renamedClassShadowingImportedClassUsage/renamedClassShadowingImportedClassUsage.test @@ -2,5 +2,6 @@ "type": "MARKED_ELEMENT", "mainFile": "test/ref.kt", "newName": "LibType", - "withRuntime": "true" + "withRuntime": "true", + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/samConstructorTypeAlias/samConstructorTypeAlias.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/samConstructorTypeAlias/samConstructorTypeAlias.test index 9bebc6a9bbb8..5d544950f218 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/samConstructorTypeAlias/samConstructorTypeAlias.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/samConstructorTypeAlias/samConstructorTypeAlias.test @@ -2,5 +2,6 @@ "type": "MARKED_ELEMENT", "mainFile": "test/test.kt", "newName": "S", - "withRuntime": "true" + "withRuntime": "true", + "enabledInK2": "false" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/secondaryCnstructorParameterRedeclaration/secondaryConstructorParameterRedeclaration.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/secondaryCnstructorParameterRedeclaration/secondaryConstructorParameterRedeclaration.test index a2707c40ade8..df86e64b390c 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/secondaryCnstructorParameterRedeclaration/secondaryConstructorParameterRedeclaration.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/secondaryCnstructorParameterRedeclaration/secondaryConstructorParameterRedeclaration.test @@ -3,6 +3,5 @@ "mainFile": "test.kt", "newName": "cpb", "withRuntime": "true", - "hint": "Parameter 'cpb' is already declared in constructor 'A'", - "enabledInK2": "true" + "hint": "Parameter 'cpb' is already declared in constructor 'A'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/syntheticPropertyUsages1/renameGetMethod.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/syntheticPropertyUsages1/renameGetMethod.test index 9971bb116067..bdf2e8456859 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/syntheticPropertyUsages1/renameGetMethod.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/syntheticPropertyUsages1/renameGetMethod.test @@ -2,6 +2,5 @@ "type": "JAVA_METHOD", "classId": "testing/JavaClass", "methodSignature": "int getSomething()", - "newName": "getSomethingNew", - "enabledInK2": "true" + "newName": "getSomethingNew" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/syntheticPropertyUsages2/renameSetMethod.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/syntheticPropertyUsages2/renameSetMethod.test index ac695a9aa0b4..41fee1bdcf5d 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/syntheticPropertyUsages2/renameSetMethod.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/syntheticPropertyUsages2/renameSetMethod.test @@ -2,6 +2,5 @@ "type": "JAVA_METHOD", "classId": "testing/JavaClass", "methodSignature": "void setSomething(int value)", - "newName": "setSomethingNew", - "enabledInK2": "true" + "newName": "setSomethingNew" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/syntheticPropertyUsages3/renameSetMethod.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/syntheticPropertyUsages3/renameSetMethod.test index 6a740fc2acfb..cfbc1f7d38a3 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/syntheticPropertyUsages3/renameSetMethod.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/syntheticPropertyUsages3/renameSetMethod.test @@ -2,6 +2,5 @@ "type": "JAVA_METHOD", "classId": "testing/JavaClass", "methodSignature": "void setSomething(boolean value)", - "newName": "setSomethingNew", - "enabledInK2": "true" + "newName": "setSomethingNew" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/topLevelClassRedeclaration/topLevelClassRedeclaration.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/topLevelClassRedeclaration/topLevelClassRedeclaration.test index becfc6d07082..575b1e99e9c5 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/topLevelClassRedeclaration/topLevelClassRedeclaration.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/topLevelClassRedeclaration/topLevelClassRedeclaration.test @@ -3,6 +3,5 @@ "mainFile": "test/test.kt", "newName": "Foo", "withRuntime": "true", - "hint": "Class 'Foo' is already declared in package 'test'", - "enabledInK2": "true" + "hint": "Class 'Foo' is already declared in package 'test'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/topLevelFunctionRedeclaration/topLevelFunctionRedeclaration.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/topLevelFunctionRedeclaration/topLevelFunctionRedeclaration.test index 5e07dd98d818..d35d7a1d768a 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/topLevelFunctionRedeclaration/topLevelFunctionRedeclaration.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/topLevelFunctionRedeclaration/topLevelFunctionRedeclaration.test @@ -3,6 +3,5 @@ "mainFile": "test/test.kt", "newName": "namedFunB", "withRuntime": "true", - "hint": "Function 'namedFunB' is already declared in package 'test'", - "enabledInK2": "true" + "hint": "Function 'namedFunB' is already declared in package 'test'" } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/refactoring/rename/topLevelPropertyRedeclaration/topLevelPropertyRedeclaration.test b/plugins/kotlin/idea/tests/testData/refactoring/rename/topLevelPropertyRedeclaration/topLevelPropertyRedeclaration.test index 4730f668670a..a9f9eef5fb0c 100644 --- a/plugins/kotlin/idea/tests/testData/refactoring/rename/topLevelPropertyRedeclaration/topLevelPropertyRedeclaration.test +++ b/plugins/kotlin/idea/tests/testData/refactoring/rename/topLevelPropertyRedeclaration/topLevelPropertyRedeclaration.test @@ -3,6 +3,5 @@ "mainFile": "test/test.kt", "newName": "foo", "withRuntime": "true", - "hint": "Property 'foo' is already declared in package 'test'", - "enabledInK2": "true" + "hint": "Property 'foo' is already declared in package 'test'" } \ No newline at end of file diff --git a/plugins/kotlin/intellij.kotlin.plugin.community.main.iml b/plugins/kotlin/intellij.kotlin.plugin.community.main.iml index 7e83a19feea0..8d99f0fb3f57 100644 --- a/plugins/kotlin/intellij.kotlin.plugin.community.main.iml +++ b/plugins/kotlin/intellij.kotlin.plugin.community.main.iml @@ -24,7 +24,6 @@ - @@ -39,8 +38,10 @@ + + @@ -154,7 +155,9 @@ - + + + diff --git a/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/CodeFragmentContextTuner.kt b/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/CodeFragmentContextTuner.kt new file mode 100644 index 000000000000..4ed640bfff80 --- /dev/null +++ b/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/CodeFragmentContextTuner.kt @@ -0,0 +1,159 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. + +package org.jetbrains.kotlin.idea.debugger.core + +import com.intellij.openapi.application.ApplicationManager +import com.intellij.psi.* +import com.intellij.psi.impl.source.tree.LeafPsiElement +import com.intellij.psi.util.PsiTreeUtil +import com.intellij.psi.util.parents +import org.jetbrains.kotlin.asJava.classes.KtLightClass +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.* + +interface CodeFragmentContextTuner { + fun tuneContextElement(element: PsiElement?): PsiElement? + + companion object { + fun getInstance(): CodeFragmentContextTuner { + return ApplicationManager.getApplication().getService(CodeFragmentContextTuner::class.java) + } + } +} + +internal class K2CodeFragmentContextTunerImpl : CodeFragmentContextTuner { + override fun tuneContextElement(element: PsiElement?): PsiElement? { + return when (element) { + null -> return null + is PsiCodeBlock -> tuneContextElement(element.context?.context) + is KtLightClass -> tuneContextElement(element.kotlinOrigin) + else -> { + when (val containingFile = element.containingFile) { + is PsiJavaFile -> element + is KtFile -> tuneKotlinContextElement(getElementSkippingWhitespaces(element), containingFile) + else -> null + } + } + } + } + + private fun tuneKotlinContextElement(element: PsiElement, containingFile: KtFile): PsiElement { + if (element is LeafPsiElement && element.elementType == KtTokens.RBRACE) { + val parent = element.parent + + val containingClass = (parent as? KtClassBody)?.parent as? KtClassOrObject + if (containingClass != null) { + val containingClassOrLiteral = containingClass.parent?.takeIf { it is KtObjectLiteralExpression } + return tuneKotlinContextElement(containingClassOrLiteral ?: containingClass, containingFile) + } + + if (parent is KtBlockExpression) { + // Block scope should be visible on a closing bracket, so we cannot lose the precise context element + return parent + } + } + + val editorTextProvider = KotlinEditorTextProvider.instance + + var result = element.parents(withSelf = true) + .filterIsInstance() + .firstOrNull { editorTextProvider.isAcceptedAsCodeFragmentContext(it) } + + if (result is KtParameterList) { + result = result.ownerFunction ?: result + } + + return result ?: containingFile + } + + private fun getElementSkippingWhitespaces(element: PsiElement): PsiElement { + // elementAt can be PsiWhiteSpace when codeFragment is created from line start offset (in case of first opening EE window) + if (element is PsiWhiteSpace || element is PsiComment) { + val newElement = PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace::class.java, PsiComment::class.java) + if (newElement != null) { + return newElement + } + } + + return element + } +} + +internal class K1CodeFragmentContextTuner : CodeFragmentContextTuner { + override fun tuneContextElement(element: PsiElement?): PsiElement? { + if (element == null) return null + + if (element is PsiCodeBlock) { + return tuneContextElement(element.context?.context) + } + + if (element is KtLightClass) { + return tuneContextElement(element.kotlinOrigin) + } + + val containingFile = element.containingFile + if (containingFile is PsiJavaFile) { + return element + } + + if (containingFile !is KtFile) { + return null + } + + val accurateElement = getAccurateContextElement(element, containingFile) + if (accurateElement != null) { + return accurateElement + } + + return containingFile + } + + private fun getAccurateContextElement(elementAt: PsiElement, containingFile: KtFile): PsiElement? { + // elementAt can be PsiWhiteSpace when codeFragment is created from line start offset (in case of first opening EE window) + val elementAtSkippingWhitespaces = getElementSkippingWhitespaces(elementAt) + + if (elementAtSkippingWhitespaces is LeafPsiElement && elementAtSkippingWhitespaces.elementType == KtTokens.RBRACE) { + val classBody = elementAtSkippingWhitespaces.parent as? KtClassBody + val classOrObject = classBody?.parent as? KtClassOrObject + var declarationParent = classOrObject?.parent + if (declarationParent is KtObjectLiteralExpression) { + declarationParent = declarationParent.parent + } + + if (declarationParent != null) { + return getAccurateContextElement(declarationParent, containingFile) + } + } + + val lineStartOffset = elementAtSkippingWhitespaces.textOffset + + val targetExpression = PsiTreeUtil.findElementOfClassAtOffset(containingFile, lineStartOffset, KtExpression::class.java, false) + + val editorTextProvider = KotlinEditorTextProvider.instance + + if (targetExpression != null) { + if (editorTextProvider.isAcceptedAsCodeFragmentContext(targetExpression)) { + return targetExpression + } + + editorTextProvider.findEvaluationTarget(elementAt, true)?.let { return it } + + targetExpression.parents(withSelf = false) + .firstOrNull { editorTextProvider.isAcceptedAsCodeFragmentContext(it) } + ?.let { return it } + } + + return null + } + + private fun getElementSkippingWhitespaces(elementAt: PsiElement): PsiElement { + if (elementAt is PsiWhiteSpace || elementAt is PsiComment) { + val newElement = PsiTreeUtil.skipSiblingsForward(elementAt, PsiWhiteSpace::class.java, PsiComment::class.java) + if (newElement != null) { + return newElement + } + } + + return elementAt + } +} \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/CodeFragmentContextUtils.kt b/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/CodeFragmentContextUtils.kt deleted file mode 100644 index caa85c469213..000000000000 --- a/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/CodeFragmentContextUtils.kt +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. - -package org.jetbrains.kotlin.idea.debugger.core - -import com.intellij.psi.* -import com.intellij.psi.impl.source.tree.LeafPsiElement -import com.intellij.psi.util.PsiTreeUtil -import org.jetbrains.kotlin.asJava.classes.KtLightClass -import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.parents - -fun getContextElement(elementAt: PsiElement?): PsiElement? { - if (elementAt == null) return null - - if (elementAt is PsiCodeBlock) { - return getContextElement(elementAt.context?.context) - } - - if (elementAt is KtLightClass) { - return getContextElement(elementAt.kotlinOrigin) - } - - val containingFile = elementAt.containingFile - if (containingFile is PsiJavaFile) { - return elementAt - } - - if (containingFile !is KtFile) { - return null - } - - val accurateElement = getAccurateContextElement(elementAt, containingFile) - if (accurateElement != null) { - return accurateElement - } - - return containingFile -} - -private fun getAccurateContextElement(elementAt: PsiElement, containingFile: KtFile): PsiElement? { - // elementAt can be PsiWhiteSpace when codeFragment is created from line start offset (in case of first opening EE window) - val elementAtSkippingWhitespaces = getElementSkippingWhitespaces(elementAt) - - if (elementAtSkippingWhitespaces is LeafPsiElement && elementAtSkippingWhitespaces.elementType == KtTokens.RBRACE) { - val classBody = elementAtSkippingWhitespaces.parent as? KtClassBody - val classOrObject = classBody?.parent as? KtClassOrObject - var declarationParent = classOrObject?.parent - if (declarationParent is KtObjectLiteralExpression) { - declarationParent = declarationParent.parent - } - - if (declarationParent != null) { - return getAccurateContextElement(declarationParent, containingFile) - } - } - - val lineStartOffset = elementAtSkippingWhitespaces.textOffset - - val targetExpression = PsiTreeUtil.findElementOfClassAtOffset(containingFile, lineStartOffset, KtExpression::class.java, false) - - val editorTextProvider = KotlinEditorTextProvider.instance - - if (targetExpression != null) { - if (editorTextProvider.isAcceptedAsCodeFragmentContext(targetExpression)) { - return targetExpression - } - - editorTextProvider.findEvaluationTarget(elementAt, true)?.let { return it } - - targetExpression.parents - .firstOrNull { editorTextProvider.isAcceptedAsCodeFragmentContext(it) } - ?.let { return it } - } - - return null -} - -private fun getElementSkippingWhitespaces(elementAt: PsiElement): PsiElement { - if (elementAt is PsiWhiteSpace || elementAt is PsiComment) { - val newElement = PsiTreeUtil.skipSiblingsForward(elementAt, PsiWhiteSpace::class.java, PsiComment::class.java) - if (newElement != null) { - return newElement - } - } - - return elementAt -} \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/KotlinEditorTextProvider.kt b/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/KotlinEditorTextProvider.kt index 4ec59bec5403..8e230aa46274 100644 --- a/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/KotlinEditorTextProvider.kt +++ b/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/KotlinEditorTextProvider.kt @@ -8,7 +8,7 @@ import com.intellij.debugger.impl.EditorTextProvider import com.intellij.openapi.util.Pair import com.intellij.openapi.util.TextRange import com.intellij.psi.PsiElement -import com.intellij.psi.util.PsiTreeUtil +import com.intellij.psi.util.parents import org.jetbrains.annotations.ApiStatus import org.jetbrains.annotations.TestOnly import org.jetbrains.kotlin.analysis.api.analyze @@ -110,7 +110,7 @@ private object AnalysisApiBasedKotlinEditorTextProvider : KotlinEditorTextProvid private tailrec fun calculateCandidate(originalElement: PsiElement?, allowMethodCalls: Boolean): PsiElement? { val candidate = originalElement?.getParentOfType(strict = false) ?: return null - if (!isAcceptedAsCodeFragmentContext(candidate)) { + if (!isAcceptedAsCandidate(candidate)) { return null } @@ -186,17 +186,31 @@ private object AnalysisApiBasedKotlinEditorTextProvider : KotlinEditorTextProvid !candidate.text.startsWith("\"\"\"") || allowMethodCalls - private val NOT_ACCEPTED_AS_CONTEXT_TYPES = arrayOf( + private val FORBIDDEN_PARENT_TYPES = setOf( KtUserType::class.java, KtImportDirective::class.java, KtPackageDirective::class.java, KtValueArgumentName::class.java, KtTypeAlias::class.java, - KtAnnotationEntry::class.java + KtAnnotationEntry::class.java, + KtDeclarationModifierList::class.java ) + private fun isAcceptedAsCandidate(element: PsiElement): Boolean { + return isAccepted(element, FORBIDDEN_PARENT_TYPES) + } + override fun isAcceptedAsCodeFragmentContext(element: PsiElement): Boolean { - return !NOT_ACCEPTED_AS_CONTEXT_TYPES.contains(element::class.java as Class<*>) - && PsiTreeUtil.getParentOfType(element, *NOT_ACCEPTED_AS_CONTEXT_TYPES) == null + return isAccepted(element, FORBIDDEN_PARENT_TYPES) + } + + private fun isAccepted(element: PsiElement, forbiddenTypes: Set>): Boolean { + for (parent in element.parents(withSelf = true)) { + if (parent::class.java in forbiddenTypes) { + return false + } + } + + return true } } \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/KotlinPositionManager.kt b/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/KotlinPositionManager.kt index fff50887efd4..2ed6de36f02d 100644 --- a/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/KotlinPositionManager.kt +++ b/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/KotlinPositionManager.kt @@ -276,7 +276,7 @@ class KotlinPositionManager(private val debugProcess: DebugProcess) : MultiReque private fun getElementForDeclarationLine(location: Location, file: KtFile, lineNumber: Int): KtElement? { val lineStartOffset = file.getLineStartOffset(lineNumber) ?: return null val elementAt = file.findElementAt(lineStartOffset) - val contextElement = getContextElement(elementAt) + val contextElement = CodeFragmentContextTuner.getInstance().tuneContextElement(elementAt) if (contextElement !is KtClass) return null diff --git a/plugins/kotlin/jvm-debugger/core-fe10/src/org/jetbrains/kotlin/idea/debugger/KotlinSourcePositionProvider.kt b/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/KotlinSourcePositionProvider.kt similarity index 66% rename from plugins/kotlin/jvm-debugger/core-fe10/src/org/jetbrains/kotlin/idea/debugger/KotlinSourcePositionProvider.kt rename to plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/KotlinSourcePositionProvider.kt index 419f1d1b62f0..73eecbdb8033 100644 --- a/plugins/kotlin/jvm-debugger/core-fe10/src/org/jetbrains/kotlin/idea/debugger/KotlinSourcePositionProvider.kt +++ b/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/KotlinSourcePositionProvider.kt @@ -1,6 +1,5 @@ -// 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. - -package org.jetbrains.kotlin.idea.debugger +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.debugger.core import com.intellij.debugger.SourcePosition import com.intellij.debugger.engine.SourcePositionProvider @@ -19,21 +18,17 @@ import com.sun.jdi.AbsentInformationException import com.sun.jdi.ClassNotPreparedException import com.sun.jdi.ClassType import com.sun.jdi.ReferenceType +import org.jetbrains.kotlin.analysis.api.analyze +import org.jetbrains.kotlin.analysis.api.symbols.KtVariableLikeSymbol import org.jetbrains.kotlin.codegen.AsmUtil -import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.debugger.base.util.safeAllInterfaces import org.jetbrains.kotlin.idea.debugger.base.util.safeAllLineLocations -import org.jetbrains.kotlin.idea.debugger.core.GetterDescriptor -import org.jetbrains.kotlin.idea.debugger.core.getContextElement +import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.load.java.possibleGetMethodNames import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType -import org.jetbrains.kotlin.resolve.BindingContextUtils import org.jetbrains.kotlin.resolve.jvm.JvmClassName -import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -import org.jetbrains.kotlin.resolve.source.KotlinSourceElement -import org.jetbrains.kotlin.resolve.source.getPsi class KotlinSourcePositionProvider : SourcePositionProvider() { override fun computeSourcePosition( @@ -44,7 +39,7 @@ class KotlinSourcePositionProvider : SourcePositionProvider() { ): SourcePosition? { if (context.frameProxy == null || DumbService.isDumb(project)) return null - return when(descriptor) { + return when (descriptor) { is FieldDescriptor -> computeSourcePosition(descriptor, context, nearest) is GetterDescriptor -> computeSourcePosition(descriptor, context, nearest) is LocalVariableDescriptor -> computeSourcePosition(descriptor, context, nearest) @@ -60,35 +55,29 @@ class KotlinSourcePositionProvider : SourcePositionProvider() { val place = PositionUtil.getContextElement(context) ?: return null if (place.containingFile !is KtFile) return null - val contextElement = getContextElement(place) ?: return null - + val contextElement = CodeFragmentContextTuner.getInstance().tuneContextElement(place) ?: return null val codeFragment = KtPsiFactory(context.project).createExpressionCodeFragment(descriptor.name, contextElement) - val expression = codeFragment.getContentElement() - if (expression is KtSimpleNameExpression) { - val bindingContext = expression.analyze(BodyResolveMode.PARTIAL) - val declarationDescriptor = BindingContextUtils.extractVariableDescriptorFromReference(bindingContext, expression) - val sourceElement = declarationDescriptor?.source - if (sourceElement is KotlinSourceElement) { - val element = sourceElement.getPsi() ?: return null - if (nearest) { - return DebuggerContextUtil.findNearest(context, element, element.containingFile) + val localReferenceExpression = codeFragment.getContentElement() + if (localReferenceExpression is KtSimpleNameExpression) { + analyze(localReferenceExpression) { + for (symbol in localReferenceExpression.mainReference.resolveToSymbols()) { + if (symbol !is KtVariableLikeSymbol) { + continue + } + + val element = symbol.psi ?: continue + + return when { + nearest -> DebuggerContextUtil.findNearest(context, element, element.containingFile) + else -> SourcePosition.createFromOffset(element.containingFile, element.textOffset) + } } - return SourcePosition.createFromOffset(element.containingFile, element.textOffset) } } return null } - private fun computeSourcePositionForDeclaration( - name: String, - declaringType: ReferenceType, - context: DebuggerContextImpl, - nearest: Boolean - ) = computeSourcePositionForDeclaration(declaringType, context, nearest) { - it.name == name - } - private fun computeSourcePositionForPropertyDeclaration( name: String, declaringType: ReferenceType, @@ -132,30 +121,32 @@ class KotlinSourcePositionProvider : SourcePositionProvider() { return null } - return computeSourcePositionForDeclaration(fieldName, descriptor.field.declaringType(), context, nearest) + return computeSourcePositionForDeclaration(descriptor.field.declaringType(), context, nearest) { + it.name == fieldName + } } private fun computeSourcePosition( descriptor: GetterDescriptor, context: DebuggerContextImpl, nearest: Boolean - ): SourcePosition? { + ): SourcePosition? { val name = descriptor.name val type = descriptor.getter.declaringType() computeSourcePositionForPropertyDeclaration(name, type, context, nearest)?.let { return it } if (type is ClassType) { - val interfaces = type.safeAllInterfaces().distinct() - for (intf in interfaces) { - computeSourcePositionForPropertyDeclaration(name, intf, context, nearest)?.let { return it } + val superInterfaceTypes = type.safeAllInterfaces().distinct() + for (interfaceType in superInterfaceTypes) { + computeSourcePositionForPropertyDeclaration(name, interfaceType, context, nearest)?.let { return it } } } + return null } private fun findClassByType(project: Project, type: ReferenceType, context: DebuggerContextImpl): PsiElement? { - val session = context.debuggerSession - val scope = session?.searchScope ?: GlobalSearchScope.allScope(project) + val scope = context.debuggerSession?.searchScope ?: GlobalSearchScope.allScope(project) val className = JvmClassName.byInternalName(type.name()).fqNameForClassNameWithoutDollars.asString() val myClass = JavaPsiFacade.getInstance(project).findClass(className, scope) @@ -168,22 +159,23 @@ class KotlinSourcePositionProvider : SourcePositionProvider() { return element.getStrictParentOfType() } } + return null } private fun getLastSourcePosition(type: ReferenceType, context: DebuggerContextImpl): SourcePosition? { - val debugProcess = context.debugProcess - if (debugProcess != null) { - try { - val locations = type.safeAllLineLocations() - if (locations.isNotEmpty()) { - val lastLocation = locations[locations.size - 1] - return debugProcess.positionManager.getSourcePosition(lastLocation) - } - } catch (ignored: AbsentInformationException) { - } catch (ignored: ClassNotPreparedException) { + val debugProcess = context.debugProcess ?: return null + + try { + val locations = type.safeAllLineLocations() + if (locations.isNotEmpty()) { + val lastLocation = locations[locations.size - 1] + return debugProcess.positionManager.getSourcePosition(lastLocation) } + } catch (ignored: AbsentInformationException) { + } catch (ignored: ClassNotPreparedException) { } + return null } -} +} \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/breakpoints/KotlinFunctionBreakpointType.kt b/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/breakpoints/KotlinFunctionBreakpointType.kt index e1a42c50e764..a7d29b48bfa4 100644 --- a/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/breakpoints/KotlinFunctionBreakpointType.kt +++ b/plugins/kotlin/jvm-debugger/core/src/org/jetbrains/kotlin/idea/debugger/core/breakpoints/KotlinFunctionBreakpointType.kt @@ -9,12 +9,15 @@ import com.intellij.xdebugger.breakpoints.XBreakpoint import org.jetbrains.annotations.Nls import org.jetbrains.annotations.NotNull import org.jetbrains.java.debugger.breakpoints.properties.JavaMethodBreakpointProperties -import org.jetbrains.kotlin.asJava.LightClassGenerationSupport +import org.jetbrains.kotlin.analysis.api.analyze +import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtTypeAliasSymbol import org.jetbrains.kotlin.idea.base.facet.platform.platform import org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinBreakpointType import org.jetbrains.kotlin.idea.debugger.core.KotlinDebuggerCoreBundle.message import org.jetbrains.kotlin.idea.debugger.core.breakpoints.ApplicabilityResult.Companion.maybe -import org.jetbrains.kotlin.js.descriptorUtils.getKotlinTypeFqName +import org.jetbrains.kotlin.idea.references.mainReference +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.platform.isCommon import org.jetbrains.kotlin.platform.jvm.isJvm import org.jetbrains.kotlin.psi.* @@ -70,14 +73,27 @@ open class KotlinFunctionBreakpointType protected constructor(@NotNull id: Strin } } -private const val COMPOSABLE_FQDN = "androidx.compose.runtime.Composable" +private val COMPOSABLE_CLASS_ID = ClassId.fromString("androidx/compose/runtime/Composable") /** * Don't allow method breakpoints on Composable functions because we can't match their signature. * * This will be handled by the Compose plugin. */ -fun KtFunction.isComposable() = annotationEntries.any { it.getType() == COMPOSABLE_FQDN } +private fun KtFunction.isComposable(): Boolean { + analyze(this) { + for (annotationEntry in annotationEntries) { + val classSymbol = when (val symbol = annotationEntry.typeReference?.mainReference?.resolveToSymbol()) { + is KtTypeAliasSymbol -> symbol.expandedType.expandedClassSymbol + is KtClassOrObjectSymbol -> symbol + else -> null + } -private fun KtAnnotationEntry.getType() = - LightClassGenerationSupport.getInstance(project).analyzeAnnotation(this)?.type?.getKotlinTypeFqName(false) + if (classSymbol != null && classSymbol.classIdIfNonLocal == COMPOSABLE_CLASS_ID) { + return true + } + } + + return false + } +} \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/evaluation/kotlin.jvm-debugger.evaluation.iml b/plugins/kotlin/jvm-debugger/evaluation/kotlin.jvm-debugger.evaluation.iml index a496466e9e31..826d4dc666fe 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/kotlin.jvm-debugger.evaluation.iml +++ b/plugins/kotlin/jvm-debugger/evaluation/kotlin.jvm-debugger.evaluation.iml @@ -14,12 +14,14 @@ + + diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/DebugContextProvider.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/DebugContextProvider.kt new file mode 100644 index 000000000000..89acc6487108 --- /dev/null +++ b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/DebugContextProvider.kt @@ -0,0 +1,29 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.debugger.evaluate + +import com.intellij.debugger.DebuggerManagerEx +import com.intellij.debugger.impl.DebuggerContextImpl +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.Key +import com.intellij.psi.PsiElement +import org.jetbrains.annotations.ApiStatus +import org.jetbrains.annotations.TestOnly +import org.jetbrains.kotlin.idea.util.application.isUnitTestMode + +@ApiStatus.Internal +object DebugContextProvider { + private val DEBUG_CONTEXT_FOR_TEST: Key = Key.create("DEBUG_CONTEXT_FOR_TESTS") + + @TestOnly + fun supplyTestDebugContext(contextElement: PsiElement, context: DebuggerContextImpl) { + contextElement.putCopyableUserData(DEBUG_CONTEXT_FOR_TEST, context) + } + + fun getDebuggerContext(project: Project, context: PsiElement?): DebuggerContextImpl? { + return if (isUnitTestMode()) { + context?.getCopyableUserData(DEBUG_CONTEXT_FOR_TEST) + } else { + DebuggerManagerEx.getInstanceEx(project).context + } + } +} \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/IdeForeignValueProviderService.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/IdeForeignValueProviderService.kt new file mode 100644 index 000000000000..b4a1be4d1ca9 --- /dev/null +++ b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/IdeForeignValueProviderService.kt @@ -0,0 +1,27 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.debugger.evaluate + +import com.intellij.debugger.engine.evaluation.CodeFragmentFactoryContextWrapper +import com.intellij.debugger.impl.DebuggerUtilsImpl +import com.sun.jdi.Value +import org.jetbrains.kotlin.analysis.providers.ForeignValueProviderService +import org.jetbrains.kotlin.psi.KtCodeFragment + +internal class IdeForeignValueProviderService : ForeignValueProviderService { + override fun getForeignValues(codeFragment: KtCodeFragment): Map { + val project = codeFragment.project + val context = codeFragment.context + val debugProcess = DebugContextProvider.getDebuggerContext(project, context)?.debugProcess ?: return emptyMap() + val valueMarkers = DebuggerUtilsImpl.getValueMarkers(debugProcess)?.allMarkers ?: return emptyMap() + + return buildMap { + for ((value, markup) in valueMarkers) { + if (value is Value) { + val valueName = markup.text + CodeFragmentFactoryContextWrapper.DEBUG_LABEL_SUFFIX + val typeDescriptor = value.type().signature() + put(valueName, typeDescriptor) + } + } + } + } +} \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluatorBuilder.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluatorBuilder.kt index c86edd1c8ccb..50205b04f43b 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluatorBuilder.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluatorBuilder.kt @@ -4,6 +4,7 @@ package org.jetbrains.kotlin.idea.debugger.evaluate import com.intellij.debugger.SourcePosition import com.intellij.debugger.engine.DebugProcessImpl +import com.intellij.debugger.engine.evaluation.CodeFragmentFactoryContextWrapper import com.intellij.debugger.engine.evaluation.EvaluateException import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil import com.intellij.debugger.engine.evaluation.EvaluationContextImpl @@ -29,20 +30,35 @@ import org.jetbrains.eval4j.jdi.JDIEval import org.jetbrains.eval4j.jdi.asJdiValue import org.jetbrains.eval4j.jdi.asValue import org.jetbrains.eval4j.jdi.makeInitialFrame +import org.jetbrains.kotlin.analysis.api.analyze +import org.jetbrains.kotlin.analysis.api.compile.CodeFragmentCapturedValue +import org.jetbrains.kotlin.analysis.api.components.KtCompilationResult +import org.jetbrains.kotlin.analysis.api.components.KtCompilerFacility +import org.jetbrains.kotlin.analysis.api.components.KtCompilerTarget +import org.jetbrains.kotlin.analysis.api.components.isClassFile import org.jetbrains.kotlin.caches.resolve.KotlinCacheService +import org.jetbrains.kotlin.codegen.ClassBuilderFactories +import org.jetbrains.kotlin.config.CommonConfigurationKeys +import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.DiagnosticFactory import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Severity import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages +import org.jetbrains.kotlin.idea.base.codeInsight.compiler.KotlinCompilerIdeAllowedErrorFilter +import org.jetbrains.kotlin.idea.base.plugin.isK2Plugin +import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings import org.jetbrains.kotlin.idea.base.util.caching.ConcurrentFactoryCache +import org.jetbrains.kotlin.idea.base.util.module import org.jetbrains.kotlin.idea.debugger.base.util.evaluate.ExecutionContext import org.jetbrains.kotlin.idea.debugger.base.util.safeLocation import org.jetbrains.kotlin.idea.debugger.base.util.safeMethod import org.jetbrains.kotlin.idea.debugger.base.util.safeVisibleVariableByName import org.jetbrains.kotlin.idea.debugger.coroutine.proxy.CoroutineStackFrameProxyImpl +import org.jetbrains.kotlin.idea.debugger.evaluate.classLoading.ClassToLoad import org.jetbrains.kotlin.idea.debugger.evaluate.classLoading.GENERATED_CLASS_NAME +import org.jetbrains.kotlin.idea.debugger.evaluate.classLoading.GENERATED_FUNCTION_NAME import org.jetbrains.kotlin.idea.debugger.evaluate.classLoading.isEvaluationEntryPoint import org.jetbrains.kotlin.idea.debugger.evaluate.compilation.* import org.jetbrains.kotlin.idea.debugger.evaluate.compilingEvaluator.loadClassesSafely @@ -51,6 +67,7 @@ import org.jetbrains.kotlin.idea.debugger.evaluate.variables.VariableFinder import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.util.application.attachmentByPsiFile import org.jetbrains.kotlin.idea.util.application.merge +import org.jetbrains.kotlin.name.NameUtils import org.jetbrains.kotlin.platform.jvm.JvmPlatforms import org.jetbrains.kotlin.psi.KtCodeFragment import org.jetbrains.kotlin.psi.KtFile @@ -176,6 +193,103 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, private val sourcePositi } private fun compileCodeFragment(context: ExecutionContext): CompiledCodeFragmentData { + return if (isK2Plugin()) compiledCodeFragmentDataK2(context) else compiledCodeFragmentDataK1(context) + } + + private fun compiledCodeFragmentDataK2(context: ExecutionContext): CompiledCodeFragmentData = runReadAction { + val module = codeFragment.module + + val compilerConfiguration = CompilerConfiguration().apply { + if (module != null) { + put(CommonConfigurationKeys.MODULE_NAME, module.name) + } + put(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS, codeFragment.languageVersionSettings) + put(KtCompilerFacility.CODE_FRAGMENT_CLASS_NAME, GENERATED_CLASS_NAME) + put(KtCompilerFacility.CODE_FRAGMENT_METHOD_NAME, GENERATED_FUNCTION_NAME) + } + + analyze(codeFragment) { + try { + val compilerTarget = KtCompilerTarget.Jvm(ClassBuilderFactories.BINARIES) + val allowedErrorFilter = KotlinCompilerIdeAllowedErrorFilter.getInstance() + + when (val result = compile(codeFragment, compilerConfiguration, compilerTarget, allowedErrorFilter)) { + is KtCompilationResult.Success -> { + logCompilation(codeFragment) + + val classes: List = result.output + .filter { it.isClassFile && it.isCodeFragmentClassFile } + .map { ClassToLoad(it.internalClassName, it.path, it.content) } + + val fragmentClass = classes.single { it.className == GENERATED_CLASS_NAME } + val methodSignature = getMethodSignature(fragmentClass) + + val parameterInfo = computeCodeFragmentParameterInfo(result) + val ideCompilationResult = CodeFragmentCompiler.CompilationResult(classes, parameterInfo, mapOf(), methodSignature) + createCompiledDataDescriptor(ideCompilationResult) + } + is KtCompilationResult.Failure -> { + val firstError = result.errors.first() + throw EvaluateExceptionUtil.createEvaluateException(firstError.defaultMessage) + } + } + } catch (e: ProcessCanceledException) { + throw e + } catch (e: EvaluateException) { + throw e + } catch (e: Throwable) { + reportErrorWithAttachments(context, codeFragment, CodeFragmentCodegenException(e)) + throw EvaluateExceptionUtil.createEvaluateException(e) + } + } + } + + private fun computeCodeFragmentParameterInfo(result: KtCompilationResult.Success): K2CodeFragmentParameterInfo { + val parameters = ArrayList(result.capturedValues.size) + val crossingBounds = HashSet() + + for (capturedValue in result.capturedValues) { + val parameter = capturedValue.toDumbCodeFragmentParameter() ?: continue + parameters.add(parameter) + + if (capturedValue.isCrossingInlineBounds) { + crossingBounds.add(parameter) + } + } + + return K2CodeFragmentParameterInfo(parameters, crossingBounds) + } + + private fun CodeFragmentCapturedValue.toDumbCodeFragmentParameter(): CodeFragmentParameter.Dumb? { + return when (this) { + is CodeFragmentCapturedValue.Local -> + CodeFragmentParameter.Dumb(CodeFragmentParameter.Kind.ORDINARY, name) + is CodeFragmentCapturedValue.LocalDelegate -> + CodeFragmentParameter.Dumb(CodeFragmentParameter.Kind.DELEGATED, displayText) + is CodeFragmentCapturedValue.ContainingClass -> + CodeFragmentParameter.Dumb(CodeFragmentParameter.Kind.DISPATCH_RECEIVER, "", displayText) + is CodeFragmentCapturedValue.SuperClass -> + CodeFragmentParameter.Dumb(CodeFragmentParameter.Kind.DISPATCH_RECEIVER, "", displayText) + is CodeFragmentCapturedValue.ExtensionReceiver -> + CodeFragmentParameter.Dumb(CodeFragmentParameter.Kind.EXTENSION_RECEIVER, name, displayText) + is CodeFragmentCapturedValue.ContextReceiver -> { + val name = NameUtils.contextReceiverName(index).asString() + CodeFragmentParameter.Dumb(CodeFragmentParameter.Kind.CONTEXT_RECEIVER, name, displayText) + } + is CodeFragmentCapturedValue.ForeignValue -> { + assert(name.endsWith(CodeFragmentFactoryContextWrapper.DEBUG_LABEL_SUFFIX)) + val valueName = name.substringBeforeLast(CodeFragmentFactoryContextWrapper.DEBUG_LABEL_SUFFIX) + CodeFragmentParameter.Dumb(CodeFragmentParameter.Kind.DEBUG_LABEL, valueName, name) + } + is CodeFragmentCapturedValue.BackingField -> + CodeFragmentParameter.Dumb(CodeFragmentParameter.Kind.FIELD_VAR, name, displayText) + is CodeFragmentCapturedValue.CoroutineContext -> + CodeFragmentParameter.Dumb(CodeFragmentParameter.Kind.FAKE_JAVA_OUTER_CLASS, "") + else -> null + } + } + + private fun compiledCodeFragmentDataK1(context: ExecutionContext): CompiledCodeFragmentData { val debugProcess = context.debugProcess var analysisResult = analyze(codeFragment, debugProcess) val codeFragmentWasEdited = KotlinCodeFragmentEditor(codeFragment) @@ -207,9 +321,7 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, private val sourcePositi val result = compilerHandler.compileCodeFragment(codeFragment, analysisResult.moduleDescriptor, analysisResult.bindingContext, context) - if (@Suppress("TestOnlyProblems") LOG_COMPILATIONS) { - LOG.debug("Compile bytecode for ${codeFragment.text}") - } + logCompilation(codeFragment) return createCompiledDataDescriptor(result) } @@ -425,6 +537,12 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, private val sourcePositi @get:ApiStatus.Internal var LOG_COMPILATIONS: Boolean = false + private fun logCompilation(codeFragment: KtCodeFragment) { + if (@Suppress("TestOnlyProblems") LOG_COMPILATIONS) { + LOG.debug("Compile bytecode for ${codeFragment.text}") + } + } + internal val IGNORED_DIAGNOSTICS: Set> = Errors.INVISIBLE_REFERENCE_DIAGNOSTICS + setOf( Errors.OPT_IN_USAGE_ERROR, @@ -502,8 +620,7 @@ fun createCompiledDataDescriptor(result: CodeFragmentCompiler.CompilationResult) val localFunctionSuffixes = result.localFunctionSuffixes val dumbParameters = ArrayList(result.parameterInfo.parameters.size) - for (parameter in result.parameterInfo.parameters) { - val dumb = parameter.dumb + for (dumb in result.parameterInfo.parameters) { if (dumb.kind == CodeFragmentParameter.Kind.LOCAL_FUNCTION) { val suffix = localFunctionSuffixes[dumb] if (suffix != null) { diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinCodeFragmentFactory.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinK1CodeFragmentFactory.kt similarity index 91% rename from plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinCodeFragmentFactory.kt rename to plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinK1CodeFragmentFactory.kt index 44361fcabc0a..09d0622c4ca6 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinCodeFragmentFactory.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinK1CodeFragmentFactory.kt @@ -3,7 +3,6 @@ package org.jetbrains.kotlin.idea.debugger.evaluate import com.intellij.debugger.DebuggerManagerEx -import com.intellij.debugger.engine.DebugProcessImpl import com.intellij.debugger.engine.evaluation.CodeFragmentFactory import com.intellij.debugger.engine.evaluation.TextWithImports import com.intellij.debugger.engine.events.DebuggerCommandImpl @@ -13,7 +12,6 @@ import com.intellij.openapi.application.runReadAction import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.project.Project -import com.intellij.openapi.util.Key import com.intellij.openapi.util.registry.Registry import com.intellij.psi.* import com.intellij.psi.util.PsiTreeUtil @@ -22,13 +20,12 @@ import com.intellij.util.IncorrectOperationException import com.intellij.util.concurrency.Semaphore import com.sun.jdi.AbsentInformationException import com.sun.jdi.InvalidStackFrameException -import org.jetbrains.annotations.TestOnly import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.base.projectStructure.hasKotlinJvmRuntime import org.jetbrains.kotlin.idea.core.syncNonBlockingReadAction import org.jetbrains.kotlin.idea.core.util.CodeFragmentUtils import org.jetbrains.kotlin.idea.debugger.base.util.hopelessAware -import org.jetbrains.kotlin.idea.debugger.core.getContextElement +import org.jetbrains.kotlin.idea.debugger.core.CodeFragmentContextTuner import org.jetbrains.kotlin.idea.debugger.evaluate.compilation.DebugLabelPropertyDescriptorProvider import org.jetbrains.kotlin.idea.j2k.J2kPostProcessor import org.jetbrains.kotlin.idea.j2k.convertToKotlin @@ -41,9 +38,9 @@ import org.jetbrains.kotlin.psi.psiUtil.quoteIfNeeded import org.jetbrains.kotlin.types.KotlinType import java.util.concurrent.atomic.AtomicReference -class KotlinCodeFragmentFactory : CodeFragmentFactory() { +class KotlinK1CodeFragmentFactory : CodeFragmentFactory() { override fun createCodeFragment(item: TextWithImports, context: PsiElement?, project: Project): JavaCodeFragment { - val contextElement = getContextElement(context) + val contextElement = CodeFragmentContextTuner.getInstance().tuneContextElement(context) val codeFragment = KtBlockCodeFragment(project, "fragment.kt", item.text, initImports(item.imports), contextElement) @@ -91,7 +88,7 @@ class KotlinCodeFragmentFactory : CodeFragmentFactory() { return@putCopyableUserData emptyFile } - val frameInfo = getFrameInfo(contextElement, debuggerContext) ?: run { + val frameInfo = getFrameInfo(project, contextElement, debuggerContext) ?: run { val position = "${debuggerContext.sourcePosition?.file?.name}:${debuggerContext.sourcePosition?.line}" LOG.warn("Couldn't get info about 'this' and local variables for $position") return@putCopyableUserData emptyFile @@ -135,20 +132,11 @@ class KotlinCodeFragmentFactory : CodeFragmentFactory() { private fun supplyDebugInformation(codeFragment: KtCodeFragment, context: PsiElement?) { val project = codeFragment.project - val debugProcess = getDebugProcess(project, context) ?: return - + val debugProcess = DebugContextProvider.getDebuggerContext(project, context)?.debugProcess ?: return DebugLabelPropertyDescriptorProvider(codeFragment, debugProcess).supplyDebugLabels() } - private fun getDebugProcess(project: Project, context: PsiElement?): DebugProcessImpl? { - return if (isUnitTestMode()) { - context?.getCopyableUserData(DEBUG_CONTEXT_FOR_TESTS)?.debugProcess - } else { - DebuggerManagerEx.getInstanceEx(project).context.debugProcess - } - } - - private fun getFrameInfo(contextElement: PsiElement?, debuggerContext: DebuggerContextImpl): FrameInfo? { + private fun getFrameInfo(project: Project, contextElement: PsiElement?, debuggerContext: DebuggerContextImpl): FrameInfo? { val semaphore = Semaphore() semaphore.down() @@ -159,7 +147,7 @@ class KotlinCodeFragmentFactory : CodeFragmentFactory() { try { val frameProxy = hopelessAware { if (isUnitTestMode()) { - contextElement?.getCopyableUserData(DEBUG_CONTEXT_FOR_TESTS)?.frameProxy + DebugContextProvider.getDebuggerContext(project, contextElement)?.frameProxy } else { debuggerContext.frameProxy } @@ -285,9 +273,6 @@ class KotlinCodeFragmentFactory : CodeFragmentFactory() { companion object { private val LOG = Logger.getInstance(this::class.java) - @get:TestOnly - val DEBUG_CONTEXT_FOR_TESTS: Key = Key.create("DEBUG_CONTEXT_FOR_TESTS") - const val FAKE_JAVA_CONTEXT_FUNCTION_NAME = "_java_locals_debug_fun_" } diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinK2CodeFragmentFactory.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinK2CodeFragmentFactory.kt new file mode 100644 index 000000000000..06563842dd0d --- /dev/null +++ b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinK2CodeFragmentFactory.kt @@ -0,0 +1,34 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.debugger.evaluate + +import com.intellij.debugger.engine.evaluation.CodeFragmentFactory +import com.intellij.debugger.engine.evaluation.TextWithImports +import com.intellij.openapi.project.Project +import com.intellij.psi.JavaCodeFragment +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.idea.KotlinFileType +import org.jetbrains.kotlin.idea.debugger.core.CodeFragmentContextTuner +import org.jetbrains.kotlin.psi.KtBlockCodeFragment + +class KotlinK2CodeFragmentFactory : CodeFragmentFactory() { + override fun createCodeFragment(item: TextWithImports, context: PsiElement?, project: Project): JavaCodeFragment { + val contextElement = CodeFragmentContextTuner.getInstance().tuneContextElement(context) + return KtBlockCodeFragment(project, "fragment.kt", item.text, item.imports, contextElement) + } + + override fun createPresentationCodeFragment(item: TextWithImports, context: PsiElement?, project: Project): JavaCodeFragment { + return createCodeFragment(item, context, project) + } + + override fun isContextAccepted(contextElement: PsiElement?): Boolean { + return contextElement?.language == KotlinFileType.INSTANCE.language + } + + override fun getFileType(): KotlinFileType { + return KotlinFileType.INSTANCE + } + + override fun getEvaluatorBuilder(): KotlinEvaluatorBuilder { + return KotlinEvaluatorBuilder + } +} \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentCodegenException.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentCodegenException.kt new file mode 100644 index 000000000000..5ece7989d2ee --- /dev/null +++ b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentCodegenException.kt @@ -0,0 +1,53 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.debugger.evaluate.compilation + +import com.intellij.openapi.diagnostic.Attachment +import com.intellij.openapi.diagnostic.RuntimeExceptionWithAttachments +import com.intellij.openapi.vfs.readText +import org.jetbrains.kotlin.idea.debugger.base.util.evaluate.ExecutionContext +import org.jetbrains.kotlin.idea.debugger.evaluate.LOG +import org.jetbrains.kotlin.psi.KtCodeFragment + +class CodeFragmentCodegenException(val reason: Throwable) : Exception() + +internal fun reportErrorWithAttachments( + executionContext: ExecutionContext, + codeFragment: KtCodeFragment, + e: CodeFragmentCodegenException +) { + val evaluationContext = executionContext.evaluationContext + val projectName = evaluationContext.project.name + val suspendContext = evaluationContext.suspendContext + + val file = suspendContext.activeExecutionStack?.topFrame?.sourcePosition?.file + val fileContents = file?.readText() + + val sessionName = suspendContext.debugProcess.session.sessionName + + val debuggerContext = """ + project: $projectName + session: $sessionName + location: ${suspendContext.location} at ${file?.path} + """.trimIndent() + + val suspendStackTrace = suspendContext.thread?.frames()?.joinToString(System.lineSeparator()) { + val location = it.location() + "${location.method()} at line ${location.lineNumber()}" + } + + val attachments = buildList { + add(Attachment("debugger_context.txt", debuggerContext).apply { isIncluded = true }) + add(Attachment("code_fragment.txt", codeFragment.text).apply { isIncluded = true }) + suspendStackTrace?.let { + add(Attachment("suspend_stack_trace.txt", it).apply { isIncluded = true }) + } + fileContents?.let { + add(Attachment("opened_file_contents.txt", it).apply { isIncluded = true }) + } + } + + LOG.error( + "Error when compiling code fragment with IR evaluator. Details in attachments.", + RuntimeExceptionWithAttachments(e.reason, *attachments.toTypedArray()) + ) +} \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentCompiler.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentCompiler.kt index 3eadbf959125..8af85b13580e 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentCompiler.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentCompiler.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.idea.debugger.evaluate.compilation import com.intellij.openapi.application.ReadAction import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.util.registry.Registry +import org.jetbrains.kotlin.analysis.api.components.KtCompiledFile import org.jetbrains.kotlin.backend.common.output.OutputFile import org.jetbrains.kotlin.codegen.ClassBuilderFactories import org.jetbrains.kotlin.codegen.KotlinCodegenFacade @@ -42,8 +43,6 @@ import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.utils.Printer import java.util.concurrent.Callable -class CodeFragmentCodegenException(val reason: Exception) : Exception() - class CodeFragmentCompiler(private val executionContext: ExecutionContext) { companion object { @@ -169,7 +168,7 @@ class CodeFragmentCompiler(private val executionContext: ExecutionContext) { declaration: KtCodeFragment, className: Name, methodName: Name, - parameterInfo: CodeFragmentParameterInfo, + parameterInfo: K1CodeFragmentParameterInfo, returnType: KotlinType, packageFragmentDescriptor: PackageFragmentDescriptor ): Pair { @@ -212,7 +211,7 @@ class CodeFragmentCompiler(private val executionContext: ExecutionContext) { fun erase(type: KotlinType): KotlinType = upperBoundIfTypeParameter(type) ?: eraseTypeArguments(type) - val parameters = parameterInfo.parameters.mapIndexed { index, parameter -> + val parameters = parameterInfo.smartParameters.mapIndexed { index, parameter -> ValueParameterDescriptorImpl( methodDescriptor, null, index, Annotations.EMPTY, Name.identifier("p$index"), erase(parameter.targetType), @@ -337,7 +336,15 @@ private class EvaluatorModuleDescriptor( } internal val OutputFile.internalClassName: String - get() = relativePath.removeSuffix(".class").replace('/', '.') + get() = computeInternalClassName(relativePath) + +internal val KtCompiledFile.internalClassName: String + get() = computeInternalClassName(path) + +private fun computeInternalClassName(path: String): String { + require(path.endsWith(".class", ignoreCase = true)) + return path.dropLast(".class".length).replace('/', '.') +} class CodeFragmentCompilationStats { var analysisTimeMs: Long = -1L diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentCompilingStrategy.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentCompilingStrategy.kt index 52352e1720cc..97439f6441f0 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentCompilingStrategy.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentCompilingStrategy.kt @@ -1,10 +1,7 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.debugger.evaluate.compilation -import com.intellij.openapi.diagnostic.Attachment -import com.intellij.openapi.diagnostic.RuntimeExceptionWithAttachments import com.intellij.openapi.util.registry.Registry -import com.intellij.openapi.vfs.readText import org.jetbrains.kotlin.idea.core.util.analyzeInlinedFunctions import org.jetbrains.kotlin.idea.debugger.base.util.evaluate.ExecutionContext import org.jetbrains.kotlin.idea.debugger.evaluate.* @@ -130,49 +127,6 @@ class IRCodeFragmentCompilingStrategy(codeFragment: KtCodeFragment) : CodeFragme } } - private fun reportErrorWithAttachments( - executionContext: ExecutionContext, - codeFragment: KtCodeFragment, - e: CodeFragmentCodegenException - ) { - val evaluationContext = executionContext.evaluationContext - val projectName = evaluationContext.project.name - val suspendContext = evaluationContext.suspendContext - - val file = suspendContext.activeExecutionStack?.topFrame?.sourcePosition?.file - val fileContents = file?.readText() - - val sessionName = suspendContext.debugProcess.session.sessionName - - val debuggerContext = """ - project: $projectName - session: $sessionName - location: ${suspendContext.location} at ${file?.path} - """.trimIndent() - - val suspendStackTrace = suspendContext.thread?.frames()?.joinToString(System.lineSeparator()) { - val location = it.location() - "${location.method()} at line ${location.lineNumber()}" - } - - val attachments = buildList { - add(Attachment("debugger_context.txt", debuggerContext).apply { isIncluded = true }) - add(Attachment("code_fragment.txt", codeFragment.text).apply { isIncluded = true }) - suspendStackTrace?.let { - add(Attachment("suspend_stack_trace.txt", it).apply { isIncluded = true }) - } - fileContents?.let { - add(Attachment("opened_file_contents.txt", it).apply { isIncluded = true }) - } - } - - LOG.error(basicErrorMessage(), RuntimeExceptionWithAttachments(e.reason, *attachments.toTypedArray())) - } - - private fun basicErrorMessage(): String { - return "Error when compiling code fragment with IR evaluator. Details in attachments." - } - override fun getFallbackStrategy(): CodeFragmentCompilingStrategy? { // It's better not to fall back when testing the IR evaluator -- otherwise regressions might slip through if (isUnitTestMode()) return null diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentParameterAnalyzer.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentParameterAnalyzer.kt index 17a7c7317565..7026db351d8e 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentParameterAnalyzer.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/CodeFragmentParameterAnalyzer.kt @@ -14,7 +14,7 @@ import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor import org.jetbrains.kotlin.idea.base.utils.fqname.fqName import org.jetbrains.kotlin.idea.debugger.base.util.evaluate.ExecutionContext import org.jetbrains.kotlin.idea.debugger.evaluate.* -import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinCodeFragmentFactory.Companion.FAKE_JAVA_CONTEXT_FUNCTION_NAME +import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinK1CodeFragmentFactory.Companion.FAKE_JAVA_CONTEXT_FUNCTION_NAME import org.jetbrains.kotlin.idea.debugger.evaluate.compilation.CodeFragmentParameter.* import org.jetbrains.kotlin.idea.debugger.base.util.safeLocation import org.jetbrains.kotlin.idea.debugger.base.util.safeMethod @@ -35,10 +35,29 @@ import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.expressions.createFunctionType -class CodeFragmentParameterInfo( - val parameters: List, +interface CodeFragmentParameterInfo { + val parameters: List val crossingBounds: Set -) +} + +class K2CodeFragmentParameterInfo( + override val parameters: List, + override val crossingBounds: Set +) : CodeFragmentParameterInfo + +class K1CodeFragmentParameterInfo( + val smartParameters: List, + override val crossingBounds: Set +) : CodeFragmentParameterInfo { + override val parameters: List = object : AbstractList() { + override val size: Int + get() = smartParameters.size + + override fun get(index: Int): Dumb { + return smartParameters[index].dumb + } + } +} /* The purpose of this class is to figure out what parameters the received code fragment captures. @@ -60,7 +79,7 @@ class CodeFragmentParameterAnalyzer( bindingContext[BindingContext.CONSTRUCTOR, constructor] } - fun analyze(): CodeFragmentParameterInfo { + fun analyze(): K1CodeFragmentParameterInfo { onceUsedChecker.trigger() codeFragment.accept(object : KtTreeVisitor() { @@ -198,7 +217,7 @@ class CodeFragmentParameterAnalyzer( } }, Unit) - return CodeFragmentParameterInfo(parameters.values.toList(), crossingBounds) + return K1CodeFragmentParameterInfo(parameters.values.toList(), crossingBounds) } private fun processReceiver(receiver: ImplicitReceiver): Smart? { diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/FragmentCompilerCodegen.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/FragmentCompilerCodegen.kt index 9a0b3fa33bdb..c882c873699e 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/FragmentCompilerCodegen.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/FragmentCompilerCodegen.kt @@ -4,6 +4,7 @@ */ package org.jetbrains.kotlin.idea.debugger.evaluate.compilation +import org.jetbrains.kotlin.analysis.api.components.KtCompiledFile import org.jetbrains.kotlin.backend.common.output.OutputFile import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.config.CompilerConfiguration @@ -16,7 +17,7 @@ import org.jetbrains.kotlin.resolve.BindingContext interface FragmentCompilerCodegen { - fun initCodegen(classDescriptor: ClassDescriptor, methodDescriptor: FunctionDescriptor, parameterInfo: CodeFragmentParameterInfo) + fun initCodegen(classDescriptor: ClassDescriptor, methodDescriptor: FunctionDescriptor, parameterInfo: K1CodeFragmentParameterInfo) fun cleanupCodegen() fun configureCompiler(compilerConfiguration: CompilerConfiguration) @@ -26,25 +27,30 @@ interface FragmentCompilerCodegen { compilerConfiguration: CompilerConfiguration, classDescriptor: ClassDescriptor, methodDescriptor: FunctionDescriptor, - parameterInfo: CodeFragmentParameterInfo + parameterInfo: K1CodeFragmentParameterInfo ) fun computeFragmentParameters( executionContext: ExecutionContext, codeFragment: KtCodeFragment, bindingContext: BindingContext - ): CodeFragmentParameterInfo + ): K1CodeFragmentParameterInfo fun extractResult( - methodDescriptor: FunctionDescriptor, - parameterInfo: CodeFragmentParameterInfo, - generationState: GenerationState + methodDescriptor: FunctionDescriptor, + parameterInfo: K1CodeFragmentParameterInfo, + generationState: GenerationState ): CodeFragmentCompiler.CompilationResult } -fun List.filterCodeFragmentClassFiles(): List { - return filter { classFile -> - val path = classFile.relativePath - path == "$GENERATED_CLASS_NAME.class" || (path.startsWith("$GENERATED_CLASS_NAME\$") && path.endsWith(".class")) - } +private fun isCodeFragmentClassPath(path: String): Boolean { + return path == "$GENERATED_CLASS_NAME.class" + || (path.startsWith("$GENERATED_CLASS_NAME\$") && path.endsWith(".class")) } + +fun List.filterCodeFragmentClassFiles(): List { + return filter { isCodeFragmentClassPath(it.relativePath) } +} + +val KtCompiledFile.isCodeFragmentClassFile: Boolean + get() = isCodeFragmentClassPath(path) \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/IRFragmentCompilerCodegen.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/IRFragmentCompilerCodegen.kt index de8d797e2c41..5fd60a3a45b4 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/IRFragmentCompilerCodegen.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/IRFragmentCompilerCodegen.kt @@ -16,8 +16,8 @@ import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.idea.MainFunctionDetector -import org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldPropertyDescriptor import org.jetbrains.kotlin.idea.debugger.base.util.evaluate.ExecutionContext +import org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldPropertyDescriptor import org.jetbrains.kotlin.idea.debugger.evaluate.classLoading.ClassToLoad import org.jetbrains.kotlin.idea.debugger.evaluate.classLoading.GENERATED_CLASS_NAME import org.jetbrains.kotlin.idea.debugger.evaluate.classLoading.isEvaluationEntryPoint @@ -45,7 +45,7 @@ class IRFragmentCompilerCodegen : FragmentCompilerCodegen { override fun initCodegen( classDescriptor: ClassDescriptor, methodDescriptor: FunctionDescriptor, - parameterInfo: CodeFragmentParameterInfo + parameterInfo: K1CodeFragmentParameterInfo ) { // NO-OP } @@ -67,7 +67,7 @@ class IRFragmentCompilerCodegen : FragmentCompilerCodegen { compilerConfiguration: CompilerConfiguration, classDescriptor: ClassDescriptor, methodDescriptor: FunctionDescriptor, - parameterInfo: CodeFragmentParameterInfo + parameterInfo: K1CodeFragmentParameterInfo ) { builder.isIrBackend(true) builder.codegenFactory( @@ -86,13 +86,13 @@ class IRFragmentCompilerCodegen : FragmentCompilerCodegen { compilerConfiguration: CompilerConfiguration, classDescriptor: ClassDescriptor, methodDescriptor: FunctionDescriptor, - parameterInfo: CodeFragmentParameterInfo + parameterInfo: K1CodeFragmentParameterInfo ): CodegenFactory { val mangler = JvmDescriptorMangler(MainFunctionDetector(bindingContext, compilerConfiguration.languageVersionSettings)) val evaluatorFragmentInfo = EvaluatorFragmentInfo( classDescriptor, methodDescriptor, - parameterInfo.parameters.map { EvaluatorFragmentParameterInfo(it.targetDescriptor, it.isLValue) } + parameterInfo.smartParameters.map { EvaluatorFragmentParameterInfo(it.targetDescriptor, it.isLValue) } ) return JvmIrCodegenFactory( configuration = compilerConfiguration, @@ -159,11 +159,11 @@ class IRFragmentCompilerCodegen : FragmentCompilerCodegen { executionContext: ExecutionContext, codeFragment: KtCodeFragment, bindingContext: BindingContext - ): CodeFragmentParameterInfo { + ): K1CodeFragmentParameterInfo { return CodeFragmentParameterAnalyzer(executionContext, codeFragment, bindingContext).analyze().let { analysis -> // Local functions do not exist as run-time values on the IR backend: they are static functions. - CodeFragmentParameterInfo( - analysis.parameters.filter { it.kind != CodeFragmentParameter.Kind.LOCAL_FUNCTION }, + K1CodeFragmentParameterInfo( + analysis.smartParameters.filter { it.kind != CodeFragmentParameter.Kind.LOCAL_FUNCTION }, analysis.crossingBounds ) } @@ -171,7 +171,7 @@ class IRFragmentCompilerCodegen : FragmentCompilerCodegen { override fun extractResult( methodDescriptor: FunctionDescriptor, - parameterInfo: CodeFragmentParameterInfo, + parameterInfo: K1CodeFragmentParameterInfo, generationState: GenerationState ): CodeFragmentCompiler.CompilationResult { val classes: List = collectGeneratedClasses(generationState) @@ -188,7 +188,7 @@ class IRFragmentCompilerCodegen : FragmentCompilerCodegen { CodeFragmentParameter.Smart(dumb, type, target) } - val processedOldCaptures: List = parameterInfo.parameters.map { + val processedOldCaptures: List = parameterInfo.smartParameters.map { val target = it.targetDescriptor val (newName, newDebugName) = when { target is LocalVariableDescriptor && target.isDelegated -> { @@ -205,7 +205,7 @@ class IRFragmentCompilerCodegen : FragmentCompilerCodegen { } val newParameterInfo = - CodeFragmentParameterInfo( + K1CodeFragmentParameterInfo( processedOldCaptures + newCaptures, parameterInfo.crossingBounds ) @@ -220,30 +220,30 @@ class IRFragmentCompilerCodegen : FragmentCompilerCodegen { ClassToLoad(it.internalClassName, it.relativePath, it.asByteArray()) } } +} - private fun getMethodSignature( - fragmentClass: ClassToLoad, - ): CompiledCodeFragmentData.MethodSignature { - val parameters: MutableList = mutableListOf() - var returnType: Type? = null +fun getMethodSignature( + fragmentClass: ClassToLoad, +): CompiledCodeFragmentData.MethodSignature { + val parameters: MutableList = mutableListOf() + var returnType: Type? = null - ClassReader(fragmentClass.bytes).accept(object : ClassVisitor(Opcodes.ASM7) { - override fun visitMethod( - access: Int, - name: String?, - descriptor: String?, - signature: String?, - exceptions: Array? - ): MethodVisitor? { - if (name != null && isEvaluationEntryPoint(name)) { - Type.getArgumentTypes(descriptor).forEach { parameters.add(it) } - returnType = Type.getReturnType(descriptor) - } - return null + ClassReader(fragmentClass.bytes).accept(object : ClassVisitor(Opcodes.ASM7) { + override fun visitMethod( + access: Int, + name: String?, + descriptor: String?, + signature: String?, + exceptions: Array? + ): MethodVisitor? { + if (name != null && isEvaluationEntryPoint(name)) { + Type.getArgumentTypes(descriptor).forEach { parameters.add(it) } + returnType = Type.getReturnType(descriptor) } - }, SKIP_CODE) + return null + } + }, SKIP_CODE) - return CompiledCodeFragmentData.MethodSignature(parameters, returnType!!) - } + return CompiledCodeFragmentData.MethodSignature(parameters, returnType!!) } diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/OldFragmentCompilerCodegen.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/OldFragmentCompilerCodegen.kt index 2b3b97724718..3b78167b151f 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/OldFragmentCompilerCodegen.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/compilation/OldFragmentCompilerCodegen.kt @@ -28,9 +28,9 @@ class OldFragmentCompilerCodegen( override fun initCodegen( classDescriptor: ClassDescriptor, methodDescriptor: FunctionDescriptor, - parameterInfo: CodeFragmentParameterInfo + parameterInfo: K1CodeFragmentParameterInfo ) { - val codegenInfo = CodeFragmentCodegenInfo(classDescriptor, methodDescriptor, parameterInfo.parameters) + val codegenInfo = CodeFragmentCodegenInfo(classDescriptor, methodDescriptor, parameterInfo.smartParameters) CodeFragmentCodegen.setCodeFragmentInfo(codeFragment, codegenInfo) } @@ -48,7 +48,7 @@ class OldFragmentCompilerCodegen( compilerConfiguration: CompilerConfiguration, classDescriptor: ClassDescriptor, methodDescriptor: FunctionDescriptor, - parameterInfo: CodeFragmentParameterInfo + parameterInfo: K1CodeFragmentParameterInfo ) { // NO-OP } @@ -57,18 +57,18 @@ class OldFragmentCompilerCodegen( executionContext: ExecutionContext, codeFragment: KtCodeFragment, bindingContext: BindingContext - ): CodeFragmentParameterInfo { + ): K1CodeFragmentParameterInfo { return CodeFragmentParameterAnalyzer(executionContext, codeFragment, bindingContext).analyze() } override fun extractResult( methodDescriptor: FunctionDescriptor, - parameterInfo: CodeFragmentParameterInfo, + parameterInfo: K1CodeFragmentParameterInfo, generationState: GenerationState ): CodeFragmentCompiler.CompilationResult { val classes = collectGeneratedClasses(generationState) val methodSignature = getMethodSignature(methodDescriptor, parameterInfo, generationState) - val functionSuffixes = getLocalFunctionSuffixes(parameterInfo.parameters, generationState.typeMapper) + val functionSuffixes = getLocalFunctionSuffixes(parameterInfo.smartParameters, generationState.typeMapper) return CodeFragmentCompiler.CompilationResult(classes, parameterInfo, functionSuffixes, methodSignature) } @@ -92,13 +92,13 @@ class OldFragmentCompilerCodegen( private fun getMethodSignature( methodDescriptor: FunctionDescriptor, - parameterInfo: CodeFragmentParameterInfo, + parameterInfo: K1CodeFragmentParameterInfo, state: GenerationState ): CompiledCodeFragmentData.MethodSignature { val typeMapper = state.typeMapper val asmSignature = typeMapper.mapSignatureSkipGeneric(methodDescriptor) - val asmParameters = parameterInfo.parameters.zip(asmSignature.valueParameters).map { (param, sigParam) -> + val asmParameters = parameterInfo.smartParameters.zip(asmSignature.valueParameters).map { (param, sigParam) -> getSharedTypeIfApplicable(param, typeMapper) ?: sigParam.asmType } diff --git a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/variables/VariableFinder.kt b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/variables/VariableFinder.kt index 9d3307cd6ff8..9ce1b5f1ef22 100644 --- a/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/variables/VariableFinder.kt +++ b/plugins/kotlin/jvm-debugger/evaluation/src/org/jetbrains/kotlin/idea/debugger/evaluate/variables/VariableFinder.kt @@ -29,6 +29,7 @@ import kotlin.coroutines.Continuation import com.sun.jdi.Type as JdiType import org.jetbrains.org.objectweb.asm.Type as AsmType +private const val OLD_CONTEXT_RECEIVER_PREFIX = "_context_receiver" class VariableFinder(val context: ExecutionContext) { private val frameProxy = context.frameProxy @@ -91,7 +92,10 @@ class VariableFinder(val context: ExecutionContext) { class ContextReceiver(asmType: AsmType) : VariableKind(asmType) { override fun capturedNameMatches(name: String) = - name.startsWith(CONTEXT_RECEIVER_PREFIX) || name.startsWith(AsmUtil.CAPTURED_PREFIX + CONTEXT_RECEIVER_PREFIX) + name.startsWith(CONTEXT_RECEIVER_PREFIX) + || name.startsWith(AsmUtil.CAPTURED_PREFIX + CONTEXT_RECEIVER_PREFIX) + || name.startsWith(OLD_CONTEXT_RECEIVER_PREFIX) + || name.startsWith(AsmUtil.CAPTURED_PREFIX + OLD_CONTEXT_RECEIVER_PREFIX) } } diff --git a/plugins/kotlin/jvm-debugger/test/k2/test/org/jetbrains/kotlin/idea/k2/debugger/test/cases/AbstractK2IdeK2CodeKotlinEvaluateExpressionTest.kt b/plugins/kotlin/jvm-debugger/test/k2/test/org/jetbrains/kotlin/idea/k2/debugger/test/cases/AbstractK2IdeK2CodeKotlinEvaluateExpressionTest.kt new file mode 100644 index 000000000000..bee88c4a15d5 --- /dev/null +++ b/plugins/kotlin/jvm-debugger/test/k2/test/org/jetbrains/kotlin/idea/k2/debugger/test/cases/AbstractK2IdeK2CodeKotlinEvaluateExpressionTest.kt @@ -0,0 +1,21 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.k2.debugger.test.cases + +import org.jetbrains.kotlin.config.JvmTarget +import org.jetbrains.kotlin.idea.debugger.test.AbstractK1IdeK2CodeKotlinEvaluateExpressionTest +import org.jetbrains.kotlin.idea.debugger.test.DebuggerTestCompilerFacility +import org.jetbrains.kotlin.idea.debugger.test.TestCompileConfiguration +import org.jetbrains.kotlin.idea.debugger.test.TestFiles +import org.jetbrains.kotlin.idea.k2.debugger.test.K2DebuggerTestCompilerFacility + +abstract class AbstractK2IdeK2CodeKotlinEvaluateExpressionTest : AbstractK1IdeK2CodeKotlinEvaluateExpressionTest() { + override val isK2Plugin = true + + override fun createDebuggerTestCompilerFacility( + testFiles: TestFiles, + jvmTarget: JvmTarget, + compileConfig: TestCompileConfiguration + ): DebuggerTestCompilerFacility { + return K2DebuggerTestCompilerFacility(project, testFiles, jvmTarget, compileConfig) + } +} \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/k2/test/org/jetbrains/kotlin/idea/k2/debugger/test/cases/K2IdeK2CodeKotlinEvaluateExpressionTestGenerated.java b/plugins/kotlin/jvm-debugger/test/k2/test/org/jetbrains/kotlin/idea/k2/debugger/test/cases/K2IdeK2CodeKotlinEvaluateExpressionTestGenerated.java new file mode 100644 index 000000000000..8f75647ded36 --- /dev/null +++ b/plugins/kotlin/jvm-debugger/test/k2/test/org/jetbrains/kotlin/idea/k2/debugger/test/cases/K2IdeK2CodeKotlinEvaluateExpressionTestGenerated.java @@ -0,0 +1,1865 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. + +package org.jetbrains.kotlin.idea.k2.debugger.test.cases; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.idea.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.idea.test.KotlinTestUtils; +import org.jetbrains.kotlin.test.TestMetadata; +import org.jetbrains.kotlin.idea.base.test.TestRoot; +import org.junit.runner.RunWith; +import org.jetbrains.kotlin.test.TargetBackend; + +/** + * This class is generated by {@link org.jetbrains.kotlin.testGenerator.generator.TestGenerator}. + * DO NOT MODIFY MANUALLY. + */ +@SuppressWarnings("all") +@TestRoot("jvm-debugger/test/k2") +@TestDataPath("$CONTENT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public abstract class K2IdeK2CodeKotlinEvaluateExpressionTestGenerated extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint") + public abstract static class SingleBreakpoint extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint/compilingEvaluator") + public abstract static class CompilingEvaluator extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers") + public static class InaccessibleMembers extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doSingleBreakpointTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("inaccessibleMembers.kt") + public void testInaccessibleMembers() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/inaccessibleMembers.kt"); + } + + @TestMetadata("inaccessibleMembersNoReflection.kt") + public void testInaccessibleMembersNoReflection() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/inaccessibleMembersNoReflection.kt"); + } + + @TestMetadata("inaccessibleTypes.kt") + public void testInaccessibleTypes() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/inaccessibleTypes.kt"); + } + + @TestMetadata("javaFields.kt") + public void testJavaFields() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/javaFields.kt"); + } + + @TestMetadata("javaMethods.kt") + public void testJavaMethods() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/javaMethods.kt"); + } + + @TestMetadata("kotlinFields.kt") + public void testKotlinFields() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/kotlinFields.kt"); + } + + @TestMetadata("kotlinMethods.kt") + public void testKotlinMethods() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/kotlinMethods.kt"); + } + + @TestMetadata("membersFromLocalClass.kt") + public void testMembersFromLocalClass() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/membersFromLocalClass.kt"); + } + + @TestMetadata("membersFromLocalClassNoReflection.kt") + public void testMembersFromLocalClassNoReflection() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/membersFromLocalClassNoReflection.kt"); + } + + @TestMetadata("outerMembers.kt") + public void testOuterMembers() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/outerMembers.kt"); + } + + @TestMetadata("outerMembersNoReflection.kt") + public void testOuterMembersNoReflection() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/outerMembersNoReflection.kt"); + } + + @TestMetadata("privateAnnotationCompanionValue.kt") + public void testPrivateAnnotationCompanionValue() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/privateAnnotationCompanionValue.kt"); + } + + @TestMetadata("selfMembers.kt") + public void testSelfMembers() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/selfMembers.kt"); + } + + @TestMetadata("selfMembersNoReflection.kt") + public void testSelfMembersNoReflection() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/selfMembersNoReflection.kt"); + } + + @TestMetadata("superMembers.kt") + public void testSuperMembers() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/superMembers.kt"); + } + + @TestMetadata("superMembersNoReflection.kt") + public void testSuperMembersNoReflection() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/superMembersNoReflection.kt"); + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint/compilingEvaluator") + public static class Uncategorized extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doSingleBreakpointTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("ceAnonymousObject.kt") + public void testCeAnonymousObject() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/ceAnonymousObject.kt"); + } + + @TestMetadata("ceAnonymousObjectCapturedInClosure.kt") + public void testCeAnonymousObjectCapturedInClosure() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/ceAnonymousObjectCapturedInClosure.kt"); + } + + @TestMetadata("ceAnonymousObjectThisAsReceiver.kt") + public void testCeAnonymousObjectThisAsReceiver() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/ceAnonymousObjectThisAsReceiver.kt"); + } + + @TestMetadata("ceLambda.kt") + public void testCeLambda() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/ceLambda.kt"); + } + + @TestMetadata("ceLocalClass.kt") + public void testCeLocalClass() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/ceLocalClass.kt"); + } + + @TestMetadata("ceLocalClassWithSuperClass.kt") + public void testCeLocalClassWithSuperClass() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/ceLocalClassWithSuperClass.kt"); + } + + @TestMetadata("ceObject.kt") + public void testCeObject() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/ceObject.kt"); + } + + @TestMetadata("ceSeveralLambdas.kt") + public void testCeSeveralLambdas() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/compilingEvaluator/ceSeveralLambdas.kt"); + } + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint/contextReceivers") + public static class ContextReceivers extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doSingleBreakpointTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("contextClassAndContextReceiversInMethod.kt") + public void testContextClassAndContextReceiversInMethod() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/contextReceivers/contextClassAndContextReceiversInMethod.kt"); + } + + @TestMetadata("contextClassAndContextReceiversInSuspendMethod.kt") + public void testContextClassAndContextReceiversInSuspendMethod() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/contextReceivers/contextClassAndContextReceiversInSuspendMethod.kt"); + } + + @TestMetadata("contextClassReceiversInMethod.kt") + public void testContextClassReceiversInMethod() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/contextReceivers/contextClassReceiversInMethod.kt"); + } + + @TestMetadata("contextReceiversInFunction.kt") + public void testContextReceiversInFunction() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/contextReceivers/contextReceiversInFunction.kt"); + } + + @TestMetadata("contextReceiversInInlineFunction.kt") + public void testContextReceiversInInlineFunction() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/contextReceivers/contextReceiversInInlineFunction.kt"); + } + + @TestMetadata("contextReceiversInLambdas.kt") + public void testContextReceiversInLambdas() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/contextReceivers/contextReceiversInLambdas.kt"); + } + + @TestMetadata("contextReceiversInSamLambdas.kt") + public void testContextReceiversInSamLambdas() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/contextReceivers/contextReceiversInSamLambdas.kt"); + } + + @TestMetadata("contextReceiversInSuspendFunction.kt") + public void testContextReceiversInSuspendFunction() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/contextReceivers/contextReceiversInSuspendFunction.kt"); + } + + @TestMetadata("functionCallWithImplicitContextClassReceiverCapturing.kt") + public void testFunctionCallWithImplicitContextClassReceiverCapturing() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/contextReceivers/functionCallWithImplicitContextClassReceiverCapturing.kt"); + } + + @TestMetadata("functionCallWithImplicitContextReceiverCapturing.kt") + public void testFunctionCallWithImplicitContextReceiverCapturing() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/contextReceivers/functionCallWithImplicitContextReceiverCapturing.kt"); + } + + @TestMetadata("nestedContextClassReceivers.kt") + public void testNestedContextClassReceivers() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/contextReceivers/nestedContextClassReceivers.kt"); + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint/coroutines") + public static class Coroutines extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doSingleBreakpointTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("accessClassPropertyInSuspendFunction.kt") + public void testAccessClassPropertyInSuspendFunction() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/coroutines/accessClassPropertyInSuspendFunction.kt"); + } + + @TestMetadata("anyUpdateInvokeStatic.kt") + public void testAnyUpdateInvokeStatic() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/coroutines/anyUpdateInvokeStatic.kt"); + } + + @TestMetadata("anyUpdateVariable.kt") + public void testAnyUpdateVariable() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/coroutines/anyUpdateVariable.kt"); + } + + @TestMetadata("capturedReceiverName.kt") + public void testCapturedReceiverName() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/coroutines/capturedReceiverName.kt"); + } + + @TestMetadata("coroutineContextExists.kt") + public void testCoroutineContextExists() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/coroutines/coroutineContextExists.kt"); + } + + @TestMetadata("coroutineScopeReceiver.kt") + public void testCoroutineScopeReceiver() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/coroutines/coroutineScopeReceiver.kt"); + } + + @TestMetadata("functionCallWithSuspendFunctionInside.kt") + public void testFunctionCallWithSuspendFunctionInside() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/coroutines/functionCallWithSuspendFunctionInside.kt"); + } + + @TestMetadata("primitivesCoertion.kt") + public void testPrimitivesCoertion() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/coroutines/primitivesCoertion.kt"); + } + + @TestMetadata("stringUpdateInvokeStatic.kt") + public void testStringUpdateInvokeStatic() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/coroutines/stringUpdateInvokeStatic.kt"); + } + + @TestMetadata("stringUpdateInvokeVirtual.kt") + public void testStringUpdateInvokeVirtual() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/coroutines/stringUpdateInvokeVirtual.kt"); + } + + @TestMetadata("stringUpdatePutField.kt") + public void testStringUpdatePutField() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/coroutines/stringUpdatePutField.kt"); + } + + @TestMetadata("stringUpdateVariable.kt") + public void testStringUpdateVariable() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/coroutines/stringUpdateVariable.kt"); + } + + @TestMetadata("suspendFunctionInClass.kt") + public void testSuspendFunctionInClass() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/coroutines/suspendFunctionInClass.kt"); + } + + @TestMetadata("suspendFunctionWithInlineClass.kt") + public void testSuspendFunctionWithInlineClass() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/coroutines/suspendFunctionWithInlineClass.kt"); + } + + @TestMetadata("suspendFunctionsWithContext.kt") + public void testSuspendFunctionsWithContext() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/coroutines/suspendFunctionsWithContext.kt"); + } + + @TestMetadata("suspendFunctionsWithoutContext.kt") + public void testSuspendFunctionsWithoutContext() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/coroutines/suspendFunctionsWithoutContext.kt"); + } + + @TestMetadata("suspendFunctionsWithoutKotlinxCoroutines.kt") + public void testSuspendFunctionsWithoutKotlinxCoroutines() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/coroutines/suspendFunctionsWithoutKotlinxCoroutines.kt"); + } + + @TestMetadata("uncapturedVariableInSuspendLambda.kt") + public void testUncapturedVariableInSuspendLambda() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/coroutines/uncapturedVariableInSuspendLambda.kt"); + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint/createExpression") + public static class CreateExpression extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doSingleBreakpointTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("createExpressionCastToBuiltIn.kt") + public void testCreateExpressionCastToBuiltIn() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/createExpression/createExpressionCastToBuiltIn.kt"); + } + + @TestMetadata("createExpressionSimple.kt") + public void testCreateExpressionSimple() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/createExpression/createExpressionSimple.kt"); + } + + @TestMetadata("createExpressionWithArray.kt") + public void testCreateExpressionWithArray() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/createExpression/createExpressionWithArray.kt"); + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint/extraVariables") + public static class ExtraVariables extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doSingleBreakpointTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("evBreakpointOnPropertyDeclaration.kt") + public void testEvBreakpointOnPropertyDeclaration() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/extraVariables/evBreakpointOnPropertyDeclaration.kt"); + } + + @TestMetadata("evDelegatedProperty.kt") + public void testEvDelegatedProperty() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/extraVariables/evDelegatedProperty.kt"); + } + + @TestMetadata("evDuplicateItems.kt") + public void testEvDuplicateItems() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/extraVariables/evDuplicateItems.kt"); + } + + @TestMetadata("evFinalProperty.kt") + public void testEvFinalProperty() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/extraVariables/evFinalProperty.kt"); + } + + @TestMetadata("evFunctionDeclaration.kt") + public void testEvFunctionDeclaration() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/extraVariables/evFunctionDeclaration.kt"); + } + + @TestMetadata("evLineRange.kt") + public void testEvLineRange() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/extraVariables/evLineRange.kt"); + } + + @TestMetadata("evProperty.kt") + public void testEvProperty() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/extraVariables/evProperty.kt"); + } + + @TestMetadata("evPropertyRefExpr.kt") + public void testEvPropertyRefExpr() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/extraVariables/evPropertyRefExpr.kt"); + } + + @TestMetadata("evSkipAnonymousObject.kt") + public void testEvSkipAnonymousObject() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/extraVariables/evSkipAnonymousObject.kt"); + } + + @TestMetadata("evSkipLambda.kt") + public void testEvSkipLambda() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/extraVariables/evSkipLambda.kt"); + } + + @TestMetadata("evSkipLocalClass.kt") + public void testEvSkipLocalClass() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/extraVariables/evSkipLocalClass.kt"); + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint/frame") + public static class Frame extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doSingleBreakpointTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("annotationsAreNotShown.kt") + public void testAnnotationsAreNotShown() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/annotationsAreNotShown.kt"); + } + + @TestMetadata("capturedValues1.kt") + public void testCapturedValues1() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/capturedValues1.kt"); + } + + @TestMetadata("capturedValues2.kt") + public void testCapturedValues2() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/capturedValues2.kt"); + } + + @TestMetadata("catchVariable.kt") + public void testCatchVariable() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/catchVariable.kt"); + } + + @TestMetadata("companionObjectGettersAreNotShown.kt") + public void testCompanionObjectGettersAreNotShown() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/companionObjectGettersAreNotShown.kt"); + } + + @TestMetadata("coroutineContextFun.kt") + public void testCoroutineContextFun() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/coroutineContextFun.kt"); + } + + @TestMetadata("coroutineContextLambda.kt") + public void testCoroutineContextLambda() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/coroutineContextLambda.kt"); + } + + @TestMetadata("coroutineContextWithoutSuspend.kt") + public void testCoroutineContextWithoutSuspend() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/coroutineContextWithoutSuspend.kt"); + } + + @TestMetadata("defaultImplsMangling.kt") + public void testDefaultImplsMangling() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/defaultImplsMangling.kt"); + } + + @TestMetadata("delegatedPropertyInClass.kt") + public void testDelegatedPropertyInClass() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/delegatedPropertyInClass.kt"); + } + + @TestMetadata("delegatedPropertyInClassKotlinVariables.kt") + public void testDelegatedPropertyInClassKotlinVariables() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/delegatedPropertyInClassKotlinVariables.kt"); + } + + @TestMetadata("delegatedPropertyInClassWithToString.kt") + public void testDelegatedPropertyInClassWithToString() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/delegatedPropertyInClassWithToString.kt"); + } + + @TestMetadata("delegatedPropertyInClassWoRenderer.kt") + public void testDelegatedPropertyInClassWoRenderer() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/delegatedPropertyInClassWoRenderer.kt"); + } + + @TestMetadata("frameAnonymousObject.kt") + public void testFrameAnonymousObject() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameAnonymousObject.kt"); + } + + @TestMetadata("frameClassObject.kt") + public void testFrameClassObject() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameClassObject.kt"); + } + + @TestMetadata("frameClosingBracket.kt") + public void testFrameClosingBracket() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameClosingBracket.kt"); + } + + @TestMetadata("frameExtFunExtFun.kt") + public void testFrameExtFunExtFun() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameExtFunExtFun.kt"); + } + + @TestMetadata("frameExtensionFun.kt") + public void testFrameExtensionFun() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameExtensionFun.kt"); + } + + @TestMetadata("frameInlineArgument.kt") + public void testFrameInlineArgument() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameInlineArgument.kt"); + } + + @TestMetadata("frameInlineArgumentInsideInlineFun.kt") + public void testFrameInlineArgumentInsideInlineFun() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameInlineArgumentInsideInlineFun.kt"); + } + + @TestMetadata("frameInlineFun.kt") + public void testFrameInlineFun() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameInlineFun.kt"); + } + + @TestMetadata("frameInlineFunCallInsideInlineFun.kt") + public void testFrameInlineFunCallInsideInlineFun() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameInlineFunCallInsideInlineFun.kt"); + } + + @TestMetadata("frameInlineFunCallInsideInlineFunKotlinVariables.kt") + public void testFrameInlineFunCallInsideInlineFunKotlinVariables() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameInlineFunCallInsideInlineFunKotlinVariables.kt"); + } + + @TestMetadata("frameInnerClass.kt") + public void testFrameInnerClass() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameInnerClass.kt"); + } + + @TestMetadata("frameInnerLambda.kt") + public void testFrameInnerLambda() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameInnerLambda.kt"); + } + + @TestMetadata("frameLambda.kt") + public void testFrameLambda() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameLambda.kt"); + } + + @TestMetadata("frameLambdaNotUsed.kt") + public void testFrameLambdaNotUsed() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameLambdaNotUsed.kt"); + } + + @TestMetadata("frameLocalVariable.kt") + public void testFrameLocalVariable() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameLocalVariable.kt"); + } + + @TestMetadata("frameObject.kt") + public void testFrameObject() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameObject.kt"); + } + + @TestMetadata("frameSharedVar.kt") + public void testFrameSharedVar() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameSharedVar.kt"); + } + + @TestMetadata("frameSharedVarLocalVar.kt") + public void testFrameSharedVarLocalVar() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameSharedVarLocalVar.kt"); + } + + @TestMetadata("frameSimple.kt") + public void testFrameSimple() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameSimple.kt"); + } + + @TestMetadata("frameThis0.kt") + public void testFrameThis0() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameThis0.kt"); + } + + @TestMetadata("frameThis0Ext.kt") + public void testFrameThis0Ext() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameThis0Ext.kt"); + } + + @TestMetadata("frameThis0This0.kt") + public void testFrameThis0This0() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/frameThis0This0.kt"); + } + + @TestMetadata("getterOfLateinitVariableIsNotShown.kt") + public void testGetterOfLateinitVariableIsNotShown() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/getterOfLateinitVariableIsNotShown.kt"); + } + + @TestMetadata("gettersAreNotDuplicated.kt") + public void testGettersAreNotDuplicated() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/gettersAreNotDuplicated.kt"); + } + + @TestMetadata("hideContinuationThis.kt") + public void testHideContinuationThis() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/hideContinuationThis.kt"); + } + + @TestMetadata("hideSyntheticThis.kt") + public void testHideSyntheticThis() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/hideSyntheticThis.kt"); + } + + @TestMetadata("inlineFunThisKotlinVariables.kt") + public void testInlineFunThisKotlinVariables() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/inlineFunThisKotlinVariables.kt"); + } + + @TestMetadata("inlinedLambdaInsideSam.kt") + public void testInlinedLambdaInsideSam() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/inlinedLambdaInsideSam.kt"); + } + + @TestMetadata("lambdaAsValueArgument.kt") + public void testLambdaAsValueArgument() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/lambdaAsValueArgument.kt"); + } + + @TestMetadata("lambdaFun1.kt") + public void testLambdaFun1() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/lambdaFun1.kt"); + } + + @TestMetadata("lambdaFun2.kt") + public void testLambdaFun2() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/lambdaFun2.kt"); + } + + @TestMetadata("lambdaFun3.kt") + public void testLambdaFun3() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/lambdaFun3.kt"); + } + + @TestMetadata("lambdaFun4.kt") + public void testLambdaFun4() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/lambdaFun4.kt"); + } + + @TestMetadata("lambdaParameterMangling.kt") + public void testLambdaParameterMangling() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/lambdaParameterMangling.kt"); + } + + @TestMetadata("lambdaThisMangling.kt") + public void testLambdaThisMangling() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/lambdaThisMangling.kt"); + } + + @TestMetadata("localFunctionMangling.kt") + public void testLocalFunctionMangling() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/localFunctionMangling.kt"); + } + + @TestMetadata("nestedInlineFun.kt") + public void testNestedInlineFun() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/nestedInlineFun.kt"); + } + + @TestMetadata("nestedInlineFun2.kt") + public void testNestedInlineFun2() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/nestedInlineFun2.kt"); + } + + @TestMetadata("objectFields.kt") + public void testObjectFields() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/objectFields.kt"); + } + + @TestMetadata("remapThis.kt") + public void testRemapThis() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/remapThis.kt"); + } + + @TestMetadata("showPropertiesFromMethods.kt") + public void testShowPropertiesFromMethods() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/showPropertiesFromMethods.kt"); + } + + @TestMetadata("sourcePositionForGetter.kt") + public void testSourcePositionForGetter() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/sourcePositionForGetter.kt"); + } + + @TestMetadata("sourcePositionForGetterWithDelegatedInterface.kt") + public void testSourcePositionForGetterWithDelegatedInterface() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/sourcePositionForGetterWithDelegatedInterface.kt"); + } + + @TestMetadata("sourcePositionForGetterWithDiamondInterfaces.kt") + public void testSourcePositionForGetterWithDiamondInterfaces() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/sourcePositionForGetterWithDiamondInterfaces.kt"); + } + + @TestMetadata("suspendContinuation.kt") + public void testSuspendContinuation() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/frame/suspendContinuation.kt"); + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint/funWithDefaultParam") + public static class FunWithDefaultParam extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doSingleBreakpointTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("classWithExtensionFun.kt") + public void testClassWithExtensionFun() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/funWithDefaultParam/classWithExtensionFun.kt"); + } + + @TestMetadata("classWithExtensionFun2.kt") + public void testClassWithExtensionFun2() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/funWithDefaultParam/classWithExtensionFun2.kt"); + } + + @TestMetadata("methodInClass.kt") + public void testMethodInClass() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/funWithDefaultParam/methodInClass.kt"); + } + + @TestMetadata("methodInClass2.kt") + public void testMethodInClass2() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/funWithDefaultParam/methodInClass2.kt"); + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint/implicitClassReceiver") + public static class ImplicitClassReceiver extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doSingleBreakpointTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("localClass.kt") + public void testLocalClass() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/implicitClassReceiver/localClass.kt"); + } + + @TestMetadata("localClass2.kt") + public void testLocalClass2() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/implicitClassReceiver/localClass2.kt"); + } + + @TestMetadata("localClass3.kt") + public void testLocalClass3() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/implicitClassReceiver/localClass3.kt"); + } + + @TestMetadata("localObject.kt") + public void testLocalObject() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/implicitClassReceiver/localObject.kt"); + } + + @TestMetadata("localObject2.kt") + public void testLocalObject2() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/implicitClassReceiver/localObject2.kt"); + } + + @TestMetadata("localObject3.kt") + public void testLocalObject3() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/implicitClassReceiver/localObject3.kt"); + } + + @TestMetadata("localObjectInFunArguments.kt") + public void testLocalObjectInFunArguments() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/implicitClassReceiver/localObjectInFunArguments.kt"); + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint/javaContext") + public static class JavaContext extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doSingleBreakpointTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("jcBlock.kt") + public void testJcBlock() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/javaContext/jcBlock.kt"); + } + + @TestMetadata("jcImports.kt") + public void testJcImports() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/javaContext/jcImports.kt"); + } + + @TestMetadata("jcLocalVariable.kt") + public void testJcLocalVariable() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/javaContext/jcLocalVariable.kt"); + } + + @TestMetadata("jcMarkedObject.kt") + public void testJcMarkedObject() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/javaContext/jcMarkedObject.kt"); + } + + @TestMetadata("jcProperty.kt") + public void testJcProperty() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/javaContext/jcProperty.kt"); + } + + @TestMetadata("jcSimple.kt") + public void testJcSimple() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/javaContext/jcSimple.kt"); + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint/labels") + public static class Labels extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doSingleBreakpointTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("lCallOnLabeledObj.kt") + public void testLCallOnLabeledObj() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/labels/lCallOnLabeledObj.kt"); + } + + @TestMetadata("lIdentifier.kt") + public void testLIdentifier() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/labels/lIdentifier.kt"); + } + + @TestMetadata("lSeveralLabels.kt") + public void testLSeveralLabels() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/labels/lSeveralLabels.kt"); + } + + @TestMetadata("lSimple.kt") + public void testLSimple() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/labels/lSimple.kt"); + } + + @TestMetadata("ldifferentTypes.kt") + public void testLdifferentTypes() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/labels/ldifferentTypes.kt"); + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint/lambdas") + public static class Lambdas extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doSingleBreakpointTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("destructuringParam.kt") + public void testDestructuringParam() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/destructuringParam.kt"); + } + + @TestMetadata("inlineFunctionalExpression.kt") + public void testInlineFunctionalExpression() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/inlineFunctionalExpression.kt"); + } + + @TestMetadata("inlineLambda.kt") + public void testInlineLambda() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/inlineLambda.kt"); + } + + @TestMetadata("lambdaOnReturn.kt") + public void testLambdaOnReturn() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/lambdaOnReturn.kt"); + } + + @TestMetadata("lambdaOnSecondLine.kt") + public void testLambdaOnSecondLine() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/lambdaOnSecondLine.kt"); + } + + @TestMetadata("notCapturedClassParameter.kt") + public void testNotCapturedClassParameter() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/notCapturedClassParameter.kt"); + } + + @TestMetadata("notCapturedFunLiteralParameter.kt") + public void testNotCapturedFunLiteralParameter() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/notCapturedFunLiteralParameter.kt"); + } + + @TestMetadata("notCapturedFunParameter.kt") + public void testNotCapturedFunParameter() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/notCapturedFunParameter.kt"); + } + + @TestMetadata("notCapturedFunParameterSecond.kt") + public void testNotCapturedFunParameterSecond() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/notCapturedFunParameterSecond.kt"); + } + + @TestMetadata("notCapturedLambdaParameter.kt") + public void testNotCapturedLambdaParameter() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/notCapturedLambdaParameter.kt"); + } + + @TestMetadata("notCapturedLambdaParameterFourth.kt") + public void testNotCapturedLambdaParameterFourth() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/notCapturedLambdaParameterFourth.kt"); + } + + @TestMetadata("notCapturedLambdaParameterSecond.kt") + public void testNotCapturedLambdaParameterSecond() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/notCapturedLambdaParameterSecond.kt"); + } + + @TestMetadata("notCapturedLambdaParameterThird.kt") + public void testNotCapturedLambdaParameterThird() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/notCapturedLambdaParameterThird.kt"); + } + + @TestMetadata("notCapturedSecondaryConstructorParameter.kt") + public void testNotCapturedSecondaryConstructorParameter() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/notCapturedSecondaryConstructorParameter.kt"); + } + + @TestMetadata("oneLineFunctionalExpression.kt") + public void testOneLineFunctionalExpression() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/oneLineFunctionalExpression.kt"); + } + + @TestMetadata("oneLineLambda.kt") + public void testOneLineLambda() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/oneLineLambda.kt"); + } + + @TestMetadata("twoLambdasOnOneLineFirst.kt") + public void testTwoLambdasOnOneLineFirst() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/twoLambdasOnOneLineFirst.kt"); + } + + @TestMetadata("twoLambdasOnOneLineSecond.kt") + public void testTwoLambdasOnOneLineSecond() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/twoLambdasOnOneLineSecond.kt"); + } + + @TestMetadata("underscoreNames.kt") + public void testUnderscoreNames() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdas/underscoreNames.kt"); + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint/renderer") + public static class Renderer extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doSingleBreakpointTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("collectionRenderer.kt") + public void testCollectionRenderer() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/renderer/collectionRenderer.kt"); + } + + @TestMetadata("mapRenderer.kt") + public void testMapRenderer() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/renderer/mapRenderer.kt"); + } + + @TestMetadata("toStringRenderer.kt") + public void testToStringRenderer() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/renderer/toStringRenderer.kt"); + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint/simpleConstructors") + public static class SimpleConstructors extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doSingleBreakpointTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("property.kt") + public void testProperty() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleConstructors/property.kt"); + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint/simpleLocals") + public static class SimpleLocals extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doSingleBreakpointTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("anonymousObject.kt") + public void testAnonymousObject() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleLocals/anonymousObject.kt"); + } + + @TestMetadata("localClass.kt") + public void testLocalClass() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleLocals/localClass.kt"); + } + + @TestMetadata("localFunction.kt") + public void testLocalFunction() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleLocals/localFunction.kt"); + } + + @TestMetadata("localFunctionCapturedField.kt") + public void testLocalFunctionCapturedField() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleLocals/localFunctionCapturedField.kt"); + } + + @TestMetadata("localFunctionWithArg.kt") + public void testLocalFunctionWithArg() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleLocals/localFunctionWithArg.kt"); + } + + @TestMetadata("localFunctionWithArgAndCapturedLocalVar.kt") + public void testLocalFunctionWithArgAndCapturedLocalVar() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleLocals/localFunctionWithArgAndCapturedLocalVar.kt"); + } + + @TestMetadata("localFunctionWithCapturedLocalVar.kt") + public void testLocalFunctionWithCapturedLocalVar() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleLocals/localFunctionWithCapturedLocalVar.kt"); + } + + @TestMetadata("localFunctionWithCapturedOuterParameter.kt") + public void testLocalFunctionWithCapturedOuterParameter() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleLocals/localFunctionWithCapturedOuterParameter.kt"); + } + + @TestMetadata("twoLocals.kt") + public void testTwoLocals() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleLocals/twoLocals.kt"); + } + + @TestMetadata("variableFinderShouldNotImplementDynamicScoping.kt") + public void testVariableFinderShouldNotImplementDynamicScoping() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleLocals/variableFinderShouldNotImplementDynamicScoping.kt"); + } + + @TestMetadata("variableFinderShouldNotImplementDynamicScoping2.kt") + public void testVariableFinderShouldNotImplementDynamicScoping2() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleLocals/variableFinderShouldNotImplementDynamicScoping2.kt"); + } + + @TestMetadata("variableFinderShouldNotImplementDynamicScoping3.kt") + public void testVariableFinderShouldNotImplementDynamicScoping3() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleLocals/variableFinderShouldNotImplementDynamicScoping3.kt"); + } + + @TestMetadata("variableFinderShouldNotImplementDynamicScoping4.kt") + public void testVariableFinderShouldNotImplementDynamicScoping4() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleLocals/variableFinderShouldNotImplementDynamicScoping4.kt"); + } + + @TestMetadata("variableFinderShouldNotImplementDynamicScoping5.kt") + public void testVariableFinderShouldNotImplementDynamicScoping5() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleLocals/variableFinderShouldNotImplementDynamicScoping5.kt"); + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint/simpleSmartcasts") + public static class SimpleSmartcasts extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doSingleBreakpointTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("downcast.kt") + public void testDowncast() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleSmartcasts/downcast.kt"); + } + + @TestMetadata("downcastFail.kt") + public void testDowncastFail() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleSmartcasts/downcastFail.kt"); + } + + @TestMetadata("downcastFailSplitLines.kt") + public void testDowncastFailSplitLines() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleSmartcasts/downcastFailSplitLines.kt"); + } + + @TestMetadata("downcastSplitLines.kt") + public void testDowncastSplitLines() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleSmartcasts/downcastSplitLines.kt"); + } + + @TestMetadata("notnull.kt") + public void testNotnull() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleSmartcasts/notnull.kt"); + } + + @TestMetadata("notnullFail.kt") + public void testNotnullFail() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simpleSmartcasts/notnullFail.kt"); + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/singleBreakpoint") + public static class Uncategorized extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doSingleBreakpointTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("abstractFunCall.kt") + public void testAbstractFunCall() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/abstractFunCall.kt"); + } + + @TestMetadata("accessToOverridenPropertyWithBackingField.kt") + public void testAccessToOverridenPropertyWithBackingField() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/accessToOverridenPropertyWithBackingField.kt"); + } + + @TestMetadata("annotationValue.kt") + public void testAnnotationValue() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/annotationValue.kt"); + } + + @TestMetadata("anonymousObjects.kt") + public void testAnonymousObjects() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/anonymousObjects.kt"); + } + + @TestMetadata("arrayMethods.kt") + public void testArrayMethods() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/arrayMethods.kt"); + } + + @TestMetadata("arrays.kt") + public void testArrays() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/arrays.kt"); + } + + @TestMetadata("boxParam.kt") + public void testBoxParam() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/boxParam.kt"); + } + + @TestMetadata("boxReturnValue.kt") + public void testBoxReturnValue() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/boxReturnValue.kt"); + } + + @TestMetadata("breakpointInInlineFun.kt") + public void testBreakpointInInlineFun() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/breakpointInInlineFun.kt"); + } + + @TestMetadata("callableBug.kt") + public void testCallableBug() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/callableBug.kt"); + } + + @TestMetadata("capturedVariablesInSamLambda.kt") + public void testCapturedVariablesInSamLambda() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/capturedVariablesInSamLambda.kt"); + } + + @TestMetadata("classFromAnotherPackage.kt") + public void testClassFromAnotherPackage() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/classFromAnotherPackage.kt"); + } + + @TestMetadata("classObjectVal.kt") + public void testClassObjectVal() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/classObjectVal.kt"); + } + + @TestMetadata("collections.kt") + public void testCollections() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/collections.kt"); + } + + @TestMetadata("color.kt") + public void testColor() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/color.kt"); + } + + @TestMetadata("dataClassCopy.kt") + public void testDataClassCopy() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/dataClassCopy.kt"); + } + + @TestMetadata("defaultParameterValues.kt") + public void testDefaultParameterValues() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/defaultParameterValues.kt"); + } + + @TestMetadata("defaultParameterValues2.kt") + public void testDefaultParameterValues2() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/defaultParameterValues2.kt"); + } + + @TestMetadata("delegatedPropertyInOtherFile.kt") + public void testDelegatedPropertyInOtherFile() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/delegatedPropertyInOtherFile.kt"); + } + + @TestMetadata("delegatedVariables.kt") + public void testDelegatedVariables() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/delegatedVariables.kt"); + } + + @TestMetadata("dependentOnFile.kt") + public void testDependentOnFile() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/dependentOnFile.kt"); + } + + @TestMetadata("distinctSequence.kt") + public void testDistinctSequence() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/distinctSequence.kt"); + } + + @TestMetadata("doubles.kt") + public void testDoubles() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/doubles.kt"); + } + + @TestMetadata("enums.kt") + public void testEnums() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/enums.kt"); + } + + @TestMetadata("errors.kt") + public void testErrors() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/errors.kt"); + } + + @TestMetadata("escapedNames.kt") + public void testEscapedNames() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/escapedNames.kt"); + } + + @TestMetadata("experimentalApi.kt") + public void testExperimentalApi() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/experimentalApi.kt"); + } + + @TestMetadata("extractLocalVariables.kt") + public void testExtractLocalVariables() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/extractLocalVariables.kt"); + } + + @TestMetadata("extractThis.kt") + public void testExtractThis() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/extractThis.kt"); + } + + @TestMetadata("extractThisInInterface.kt") + public void testExtractThisInInterface() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/extractThisInInterface.kt"); + } + + @TestMetadata("extractVariablesFromCall.kt") + public void testExtractVariablesFromCall() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/extractVariablesFromCall.kt"); + } + + @TestMetadata("fieldGetters.kt") + public void testFieldGetters() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/fieldGetters.kt"); + } + + @TestMetadata("fileWithError.kt") + public void testFileWithError() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/fileWithError.kt"); + } + + @TestMetadata("funFromSuperClass.kt") + public void testFunFromSuperClass() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/funFromSuperClass.kt"); + } + + @TestMetadata("functionDeclaration.kt") + public void testFunctionDeclaration() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/functionDeclaration.kt"); + } + + @TestMetadata("functionWithBodyExpression.kt") + public void testFunctionWithBodyExpression() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/functionWithBodyExpression.kt"); + } + + @TestMetadata("genericCrossinlineArgument.kt") + public void testGenericCrossinlineArgument() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/genericCrossinlineArgument.kt"); + } + + @TestMetadata("genericWithMultipleUpperBounds.kt") + public void testGenericWithMultipleUpperBounds() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/genericWithMultipleUpperBounds.kt"); + } + + @TestMetadata("imports.kt") + public void testImports() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/imports.kt"); + } + + @TestMetadata("importsLambdaContext.kt") + public void testImportsLambdaContext() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/importsLambdaContext.kt"); + } + + @TestMetadata("inlineFunInMultiFilePackage.kt") + public void testInlineFunInMultiFilePackage() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/inlineFunInMultiFilePackage.kt"); + } + + @TestMetadata("inlineFunInRootPackage.kt") + public void testInlineFunInRootPackage() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/inlineFunInRootPackage.kt"); + } + + @TestMetadata("inlineFunction.kt") + public void testInlineFunction() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/inlineFunction.kt"); + } + + @TestMetadata("inlineFunctionBreakpointAnotherFile.kt") + public void testInlineFunctionBreakpointAnotherFile() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/inlineFunctionBreakpointAnotherFile.kt"); + } + + @TestMetadata("inlineFunctionBreakpointVariants.kt") + public void testInlineFunctionBreakpointVariants() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/inlineFunctionBreakpointVariants.kt"); + } + + @TestMetadata("inlineFunctionClassFileLoading.kt") + public void testInlineFunctionClassFileLoading() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/inlineFunctionClassFileLoading.kt"); + } + + @TestMetadata("inlineFunctionDeepInlining.kt") + public void testInlineFunctionDeepInlining() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/inlineFunctionDeepInlining.kt"); + } + + @TestMetadata("inlineFunctionDeepInliningSameFile.kt") + public void testInlineFunctionDeepInliningSameFile() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/inlineFunctionDeepInliningSameFile.kt"); + } + + @TestMetadata("inlineMethodsInSignature.kt") + public void testInlineMethodsInSignature() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/inlineMethodsInSignature.kt"); + } + + @TestMetadata("innerClass.kt") + public void testInnerClass() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/innerClass.kt"); + } + + @TestMetadata("insertInBlock.kt") + public void testInsertInBlock() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/insertInBlock.kt"); + } + + @TestMetadata("internalFunctionEvaluate.kt") + public void testInternalFunctionEvaluate() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/internalFunctionEvaluate.kt"); + } + + @TestMetadata("internalProperty.kt") + public void testInternalProperty() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/internalProperty.kt"); + } + + @TestMetadata("javaStaticMethods.kt") + public void testJavaStaticMethods() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/javaStaticMethods.kt"); + } + + @TestMetadata("kClass.kt") + public void testKClass() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/kClass.kt"); + } + + @TestMetadata("kt12206BasePropertyWithoutBackingField.kt") + public void testKt12206BasePropertyWithoutBackingField() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/kt12206BasePropertyWithoutBackingField.kt"); + } + + @TestMetadata("kt15259.kt") + public void testKt15259() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/kt15259.kt"); + } + + @TestMetadata("kt17514.kt") + public void testKt17514() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/kt17514.kt"); + } + + @TestMetadata("kt22366.kt") + public void testKt22366() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/kt22366.kt"); + } + + @TestMetadata("kt25220.kt") + public void testKt25220() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/kt25220.kt"); + } + + @TestMetadata("kt25222.kt") + public void testKt25222() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/kt25222.kt"); + } + + @TestMetadata("kt28087.kt") + public void testKt28087() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/kt28087.kt"); + } + + @TestMetadata("kt29179.kt") + public void testKt29179() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/kt29179.kt"); + } + + @TestMetadata("kt31709.kt") + public void testKt31709() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/kt31709.kt"); + } + + @TestMetadata("kt36404.kt") + public void testKt36404() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/kt36404.kt"); + } + + @TestMetadata("kt5554OnlyIntsShouldBeCoerced.kt") + public void testKt5554OnlyIntsShouldBeCoerced() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/kt5554OnlyIntsShouldBeCoerced.kt"); + } + + @TestMetadata("kt7046localVarInInline.kt") + public void testKt7046localVarInInline() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/kt7046localVarInInline.kt"); + } + + @TestMetadata("ktij21907.kt") + public void testKtij21907() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/ktij21907.kt"); + } + + @TestMetadata("ktij21963.kt") + public void testKtij21963() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/ktij21963.kt"); + } + + @TestMetadata("lambdaToString.kt") + public void testLambdaToString() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdaToString.kt"); + } + + @TestMetadata("lambdaWithDestructuring.kt") + public void testLambdaWithDestructuring() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/lambdaWithDestructuring.kt"); + } + + @TestMetadata("localClass.kt") + public void testLocalClass() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/localClass.kt"); + } + + @TestMetadata("localFunctionCapturedLocalVariable.kt") + public void testLocalFunctionCapturedLocalVariable() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.kt"); + } + + @TestMetadata("localFunctionsWithReceivers.kt") + public void testLocalFunctionsWithReceivers() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/localFunctionsWithReceivers.kt"); + } + + @TestMetadata("localVariables.kt") + public void testLocalVariables() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/localVariables.kt"); + } + + @TestMetadata("methodWithBreakpoint.kt") + public void testMethodWithBreakpoint() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/methodWithBreakpoint.kt"); + } + + @TestMetadata("multilineExpressionAtBreakpoint.kt") + public void testMultilineExpressionAtBreakpoint() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/multilineExpressionAtBreakpoint.kt"); + } + + @TestMetadata("nestedInlineArguments.kt") + public void testNestedInlineArguments() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/nestedInlineArguments.kt"); + } + + @TestMetadata("nonAssignmentLValue.kt") + public void testNonAssignmentLValue() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/nonAssignmentLValue.kt"); + } + + @TestMetadata("nothing.kt") + public void testNothing() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/nothing.kt"); + } + + @TestMetadata("onClassHeader.kt") + public void testOnClassHeader() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/onClassHeader.kt"); + } + + @TestMetadata("onGetter.kt") + public void testOnGetter() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/onGetter.kt"); + } + + @TestMetadata("onObjectHeader.kt") + public void testOnObjectHeader() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/onObjectHeader.kt"); + } + + @TestMetadata("package.kt") + public void testPackage() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/package.kt"); + } + + @TestMetadata("parametersOfInlineFun.kt") + public void testParametersOfInlineFun() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/parametersOfInlineFun.kt"); + } + + @TestMetadata("parametersOfInlineFunSeveralOnLine.kt") + public void testParametersOfInlineFunSeveralOnLine() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/parametersOfInlineFunSeveralOnLine.kt"); + } + + @TestMetadata("privateClass.kt") + public void testPrivateClass() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/privateClass.kt"); + } + + @TestMetadata("privateFieldInCompanion.kt") + public void testPrivateFieldInCompanion() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/privateFieldInCompanion.kt"); + } + + @TestMetadata("privateMember.kt") + public void testPrivateMember() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/privateMember.kt"); + } + + @TestMetadata("privatePropertyWithExplicitDefaultGetter.kt") + public void testPrivatePropertyWithExplicitDefaultGetter() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/privatePropertyWithExplicitDefaultGetter.kt"); + } + + @TestMetadata("privatePropertyWithNonDefaultAccessor.kt") + public void testPrivatePropertyWithNonDefaultAccessor() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/privatePropertyWithNonDefaultAccessor.kt"); + } + + @TestMetadata("privateToplevelProperty.kt") + public void testPrivateToplevelProperty() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/privateToplevelProperty.kt"); + } + + @TestMetadata("protectedMember.kt") + public void testProtectedMember() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/protectedMember.kt"); + } + + @TestMetadata("rawTypeskt11831.kt") + public void testRawTypeskt11831() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/rawTypeskt11831.kt"); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/simple.kt"); + } + + @TestMetadata("statements.kt") + public void testStatements() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/statements.kt"); + } + + @TestMetadata("staticField.kt") + public void testStaticField() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/staticField.kt"); + } + + @TestMetadata("stdlib.kt") + public void testStdlib() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/stdlib.kt"); + } + + @TestMetadata("superCallsCaptured.kt") + public void testSuperCallsCaptured() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/superCallsCaptured.kt"); + } + + @TestMetadata("superCallsSimple.kt") + public void testSuperCallsSimple() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/superCallsSimple.kt"); + } + + @TestMetadata("synchronizedBlock.kt") + public void testSynchronizedBlock() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/synchronizedBlock.kt"); + } + + @TestMetadata("typeParameterRef.kt") + public void testTypeParameterRef() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/typeParameterRef.kt"); + } + + @TestMetadata("typedArray.kt") + public void testTypedArray() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/typedArray.kt"); + } + + @TestMetadata("unboxParam.kt") + public void testUnboxParam() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/unboxParam.kt"); + } + + @TestMetadata("unsafeCall.kt") + public void testUnsafeCall() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/unsafeCall.kt"); + } + + @TestMetadata("unusedTransitiveDependencies.kt") + public void testUnusedTransitiveDependencies() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/unusedTransitiveDependencies.kt"); + } + + @TestMetadata("valueParameterName.kt") + public void testValueParameterName() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/valueParameterName.kt"); + } + + @TestMetadata("variableAsFunction.kt") + public void testVariableAsFunction() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/variableAsFunction.kt"); + } + + @TestMetadata("vars.kt") + public void testVars() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/vars.kt"); + } + + @TestMetadata("whenEvaluation.kt") + public void testWhenEvaluation() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/whenEvaluation.kt"); + } + + @TestMetadata(".kt.kt") + public void test_kt() throws Exception { + runTest("../testData/evaluation/singleBreakpoint/.kt.kt"); + } + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/multipleBreakpoints") + public abstract static class MultipleBreakpoints extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/multipleBreakpoints/library") + public static class Library extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doMultipleBreakpointsTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("customLibClassName.kt") + public void testCustomLibClassName() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/library/customLibClassName.kt"); + } + + @TestMetadata("localFunInLibrary.kt") + public void testLocalFunInLibrary() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/library/localFunInLibrary.kt"); + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/evaluation/multipleBreakpoints") + public static class Uncategorized extends AbstractK2IdeK2CodeKotlinEvaluateExpressionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doMultipleBreakpointsTest, this, TargetBackend.JVM_WITH_IR_EVALUATOR, testDataFilePath); + } + + @TestMetadata("clearCache.kt") + public void testClearCache() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/clearCache.kt"); + } + + @TestMetadata("constructors.kt") + public void testConstructors() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/constructors.kt"); + } + + @TestMetadata("exceptions.kt") + public void testExceptions() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/exceptions.kt"); + } + + @TestMetadata("extensionMemberFunction.kt") + public void testExtensionMemberFunction() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/extensionMemberFunction.kt"); + } + + @TestMetadata("extensionMemberFunctionInObject.kt") + public void testExtensionMemberFunctionInObject() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/extensionMemberFunctionInObject.kt"); + } + + @TestMetadata("extensionMemberProperty.kt") + public void testExtensionMemberProperty() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/extensionMemberProperty.kt"); + } + + @TestMetadata("externalReceiverInLambda.kt") + public void testExternalReceiverInLambda() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/externalReceiverInLambda.kt"); + } + + @TestMetadata("fieldVariable.kt") + public void testFieldVariable() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/fieldVariable.kt"); + } + + @TestMetadata("funFromOuterClassInLamdba.kt") + public void testFunFromOuterClassInLamdba() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/funFromOuterClassInLamdba.kt"); + } + + @TestMetadata("initializer.kt") + public void testInitializer() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/initializer.kt"); + } + + @TestMetadata("inlineStackTrace.kt") + public void testInlineStackTrace() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/inlineStackTrace.kt"); + } + + @TestMetadata("inlineStackTraceWithApply.kt") + public void testInlineStackTraceWithApply() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/inlineStackTraceWithApply.kt"); + } + + @TestMetadata("inlineStackTraceWithNestedLambdas.kt") + public void testInlineStackTraceWithNestedLambdas() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/inlineStackTraceWithNestedLambdas.kt"); + } + + @TestMetadata("invisibleDeclarations.kt") + public void testInvisibleDeclarations() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/invisibleDeclarations.kt"); + } + + @TestMetadata("isInsideInlineLambda.kt") + public void testIsInsideInlineLambda() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/isInsideInlineLambda.kt"); + } + + @TestMetadata("lambdaParameters.kt") + public void testLambdaParameters() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/lambdaParameters.kt"); + } + + @TestMetadata("localFun.kt") + public void testLocalFun() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/localFun.kt"); + } + + @TestMetadata("multipleBreakpointsAtLine.kt") + public void testMultipleBreakpointsAtLine() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/multipleBreakpointsAtLine.kt"); + } + + @TestMetadata("mutations.kt") + public void testMutations() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/mutations.kt"); + } + + @TestMetadata("nestedCoroutineContexts.kt") + public void testNestedCoroutineContexts() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/nestedCoroutineContexts.kt"); + } + + @TestMetadata("noReceiverOnStack.kt") + public void testNoReceiverOnStack() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/noReceiverOnStack.kt"); + } + + @TestMetadata("nonCapturedVariables.kt") + public void testNonCapturedVariables() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/nonCapturedVariables.kt"); + } + + @TestMetadata("optimisedVariableEvaluation.kt") + public void testOptimisedVariableEvaluation() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/optimisedVariableEvaluation.kt"); + } + + @TestMetadata("privateMembersPriority.kt") + public void testPrivateMembersPriority() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/privateMembersPriority.kt"); + } + + @TestMetadata("remappedParameterInInline.kt") + public void testRemappedParameterInInline() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/remappedParameterInInline.kt"); + } + + @TestMetadata("smartcasts.kt") + public void testSmartcasts() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/smartcasts.kt"); + } + + @TestMetadata("thisLabels.kt") + public void testThisLabels() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/thisLabels.kt"); + } + + @TestMetadata("typeArguments.kt") + public void testTypeArguments() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/typeArguments.kt"); + } + + @TestMetadata("whenEntry.kt") + public void testWhenEntry() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/whenEntry.kt"); + } + + @TestMetadata("withoutBodyFunctions.kt") + public void testWithoutBodyFunctions() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/withoutBodyFunctions.kt"); + } + + @TestMetadata("withoutBodyProperties.kt") + public void testWithoutBodyProperties() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/withoutBodyProperties.kt"); + } + + @TestMetadata("withoutBodyProperties2.kt") + public void testWithoutBodyProperties2() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/withoutBodyProperties2.kt"); + } + + @TestMetadata("withoutBodyTypeParameters.kt") + public void testWithoutBodyTypeParameters() throws Exception { + runTest("../testData/evaluation/multipleBreakpoints/withoutBodyTypeParameters.kt"); + } + } + } +} diff --git a/plugins/kotlin/jvm-debugger/test/kotlin.jvm-debugger.test.iml b/plugins/kotlin/jvm-debugger/test/kotlin.jvm-debugger.test.iml index 0349ddfe5b80..91fecfd454ff 100644 --- a/plugins/kotlin/jvm-debugger/test/kotlin.jvm-debugger.test.iml +++ b/plugins/kotlin/jvm-debugger/test/kotlin.jvm-debugger.test.iml @@ -20,12 +20,14 @@ + + diff --git a/plugins/kotlin/jvm-debugger/test/test/org/jetbrains/kotlin/idea/debugger/test/AbstractKotlinEvaluateExpressionTest.kt b/plugins/kotlin/jvm-debugger/test/test/org/jetbrains/kotlin/idea/debugger/test/AbstractKotlinEvaluateExpressionTest.kt index ee2d6b505a88..e289a0bd1c69 100644 --- a/plugins/kotlin/jvm-debugger/test/test/org/jetbrains/kotlin/idea/debugger/test/AbstractKotlinEvaluateExpressionTest.kt +++ b/plugins/kotlin/jvm-debugger/test/test/org/jetbrains/kotlin/idea/debugger/test/AbstractKotlinEvaluateExpressionTest.kt @@ -4,6 +4,7 @@ package org.jetbrains.kotlin.idea.debugger.test import com.intellij.debugger.engine.ContextUtil import com.intellij.debugger.engine.SuspendContextImpl +import com.intellij.debugger.engine.evaluation.CodeFragmentFactory import com.intellij.debugger.engine.evaluation.CodeFragmentKind import com.intellij.debugger.engine.evaluation.EvaluateException import com.intellij.debugger.engine.evaluation.TextWithImportsImpl @@ -26,7 +27,8 @@ import org.jetbrains.eval4j.ObjectValue import org.jetbrains.eval4j.Value import org.jetbrains.eval4j.jdi.asValue import org.jetbrains.kotlin.idea.KotlinFileType -import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinCodeFragmentFactory +import org.jetbrains.kotlin.idea.debugger.core.CodeFragmentContextTuner +import org.jetbrains.kotlin.idea.debugger.evaluate.DebugContextProvider import org.jetbrains.kotlin.idea.debugger.test.preference.DebuggerPreferenceKeys import org.jetbrains.kotlin.idea.debugger.test.preference.DebuggerPreferences import org.jetbrains.kotlin.idea.debugger.test.util.FramePrinter @@ -203,15 +205,20 @@ abstract class AbstractKotlinEvaluateExpressionTest : KotlinDescriptorTestCaseWi val debuggerContext = createDebuggerContext(myDebuggerSession, suspendContext, threadProxy, frameProxy) debuggerContext.initCaches() - val contextElement = ContextUtil.getContextElement(debuggerContext)!! + val contextElement = runReadAction { + CodeFragmentContextTuner.getInstance().tuneContextElement(ContextUtil.getContextElement(debuggerContext))!! + } - assert(KotlinCodeFragmentFactory().isContextAccepted(contextElement)) { + val codeFragmentFactory = CodeFragmentFactory.EXTENSION_POINT_NAME.extensions + .first { it.fileType == KotlinFileType.INSTANCE } + + assert(codeFragmentFactory.isContextAccepted(contextElement)) { val text = runReadAction { contextElement.text } "KotlinCodeFragmentFactory should be accepted for context element otherwise default evaluator will be called. " + "ContextElement = $text" } - contextElement.putCopyableUserData(KotlinCodeFragmentFactory.DEBUG_CONTEXT_FOR_TESTS, debuggerContext) + DebugContextProvider.supplyTestDebugContext(contextElement, debuggerContext) suspendContext.runActionInSuspendCommand { try { diff --git a/plugins/kotlin/jvm-debugger/test/test/org/jetbrains/kotlin/idea/debugger/test/AbstractKotlinScriptEvaluateExpressionTest.kt b/plugins/kotlin/jvm-debugger/test/test/org/jetbrains/kotlin/idea/debugger/test/AbstractKotlinScriptEvaluateExpressionTest.kt index 342e914a3925..4b6471a2352b 100644 --- a/plugins/kotlin/jvm-debugger/test/test/org/jetbrains/kotlin/idea/debugger/test/AbstractKotlinScriptEvaluateExpressionTest.kt +++ b/plugins/kotlin/jvm-debugger/test/test/org/jetbrains/kotlin/idea/debugger/test/AbstractKotlinScriptEvaluateExpressionTest.kt @@ -24,7 +24,7 @@ abstract class AbstractKotlinScriptEvaluateExpressionTest : AbstractIrKotlinEval override fun createBreakpoints(className: String?) = super.createBreakpoints(getScriptKtFile()) - override fun analyzeAndFindMainClass(compilerFacility: DebuggerTestCompilerFacility) = K2JVMCompiler::class.qualifiedName!! + override fun getMainClassName(compilerFacility: DebuggerTestCompilerFacility) = K2JVMCompiler::class.qualifiedName!! override fun createJavaParameters(mainClass: String?): JavaParameters { return super.createJavaParameters(mainClass).apply { diff --git a/plugins/kotlin/jvm-debugger/test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinDescriptorTestCase.kt b/plugins/kotlin/jvm-debugger/test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinDescriptorTestCase.kt index f92c1394c08b..b2b04c07dbd2 100644 --- a/plugins/kotlin/jvm-debugger/test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinDescriptorTestCase.kt +++ b/plugins/kotlin/jvm-debugger/test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinDescriptorTestCase.kt @@ -20,6 +20,7 @@ import com.intellij.execution.target.TargetEnvironmentRequest import com.intellij.execution.target.TargetedCommandLineBuilder import com.intellij.openapi.application.invokeAndWaitIfNeeded import com.intellij.openapi.application.runInEdt +import com.intellij.openapi.application.runReadAction import com.intellij.openapi.application.runWriteAction import com.intellij.openapi.roots.LibraryOrderEntry import com.intellij.openapi.roots.ModifiableRootModel @@ -32,9 +33,15 @@ import com.intellij.openapi.vfs.LocalFileSystem import com.intellij.psi.PsiFile import com.intellij.testFramework.runInEdtAndGet import com.intellij.util.ThrowableRunnable +import com.intellij.util.containers.addIfNotNull import com.intellij.xdebugger.XDebugSession +import org.jetbrains.kotlin.analysis.api.analyze import org.jetbrains.kotlin.config.* +import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil +import org.jetbrains.kotlin.idea.base.codeInsight.KotlinMainFunctionDetector +import org.jetbrains.kotlin.idea.base.codeInsight.PsiOnlyKotlinMainFunctionDetector import org.jetbrains.kotlin.idea.base.plugin.artifacts.TestKotlinArtifacts +import org.jetbrains.kotlin.idea.base.psi.classIdIfNonLocal import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerSettings import org.jetbrains.kotlin.idea.compiler.configuration.KotlinPluginLayout @@ -48,6 +55,10 @@ import org.jetbrains.kotlin.idea.test.KotlinBaseTest.TestFile import org.jetbrains.kotlin.idea.test.KotlinTestUtils.* import org.jetbrains.kotlin.idea.test.TestFiles.TestFileFactory import org.jetbrains.kotlin.idea.test.TestFiles.createTestFiles +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.psi.KtNamedFunction +import org.jetbrains.kotlin.psi.KtTreeVisitorVoid +import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.test.TargetBackend import org.jetbrains.kotlin.test.utils.IgnoreTests import org.junit.ComparisonFailure @@ -229,7 +240,7 @@ abstract class KotlinDescriptorTestCase : DescriptorTestCase() { compileLibrariesAndTestSources(preferences, compilerFacility) - val mainClassName = analyzeAndFindMainClass(compilerFacility) + val mainClassName = getMainClassName(compilerFacility) breakpointCreator = BreakpointCreator( project, ::systemLogger, @@ -265,8 +276,47 @@ abstract class KotlinDescriptorTestCase : DescriptorTestCase() { protected open fun compileAdditionalLibraries(compilerFacility: DebuggerTestCompilerFacility) { } - protected open fun analyzeAndFindMainClass(compilerFacility: DebuggerTestCompilerFacility): String { - return compilerFacility.analyzeAndFindMainClass(sourcesKtFiles.jvmKtFiles) + protected open fun getMainClassName(compilerFacility: DebuggerTestCompilerFacility): String { + if (!isK2Plugin) { + // Although the implementation below is frontend-agnostic, K1 tests seem to depend on resolution ordering. + // Some evaluation tests fail if not all files are analyzed at this point. + return compilerFacility.analyzeAndFindMainClass(sourcesKtFiles.jvmKtFiles) + } + + return runReadAction { + val mainFunctionDetector = KotlinMainFunctionDetector.getInstance() + val candidates = mutableListOf() + + for (file in sourcesKtFiles.jvmKtFiles) { + val visitor = object : KtTreeVisitorVoid() { + override fun visitNamedFunction(function: KtNamedFunction) { + if (mainFunctionDetector.isMain(function)) { + val candidate = when (val containingClass = function.containingClassOrObject) { + null -> ClassId.topLevel(JvmFileClassUtil.getFileClassInfoNoResolve(file).facadeClassFqName) + else -> containingClass.classIdIfNonLocal + } + + candidates.addIfNotNull(candidate) + } + } + } + + file.accept(visitor) + } + + when (candidates.size) { + 0 -> error("Cannot find a 'main()' function") + 1 -> { + val candidate = candidates.single() + val packagePrefix = if (candidate.packageFqName.isRoot) "" else candidate.packageFqName.asString() + "." + val relativeNameString = candidate.relativeClassName.asString().replace('.', '$') + packagePrefix + relativeNameString + } + else -> { + error("Multiple main functions found: " + candidates.joinToString()) + } + } + } } override fun createLocalProcess(className: String?) { diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/extensionMemberProperty.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/extensionMemberProperty.kt index effdc748b9ce..c7ce3ebb645c 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/extensionMemberProperty.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/extensionMemberProperty.kt @@ -121,4 +121,6 @@ class MemberClass { class ExtClass { val a = 1 -} \ No newline at end of file +} + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/funFromOuterClassInLamdba.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/funFromOuterClassInLamdba.kt index d46aa60a5fd3..d9650a625bad 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/funFromOuterClassInLamdba.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/funFromOuterClassInLamdba.kt @@ -40,3 +40,5 @@ class Outer { } fun lambda(f: () -> Unit) = f() + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/lambdaParameters.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/lambdaParameters.kt index 417b15557cd1..d46c65f273e3 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/lambdaParameters.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/lambdaParameters.kt @@ -19,4 +19,6 @@ fun main(args: Array) { // RESULT: 3: I // EXPRESSION: f("abc") -// RESULT: Evaluation of 'crossinline' lambdas is not supported \ No newline at end of file +// RESULT: Evaluation of 'crossinline' lambdas is not supported + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/mutations.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/mutations.kt index 55b2ec5f1366..86eb7abf8189 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/mutations.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/mutations.kt @@ -21,4 +21,6 @@ fun main() { // RESULT: VOID_VALUE // EXPRESSION: a + b -// RESULT: 300: I \ No newline at end of file +// RESULT: 300: I + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/nestedCoroutineContexts.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/nestedCoroutineContexts.kt index 0632b40a2535..ee5cec00adaf 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/nestedCoroutineContexts.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/multipleBreakpoints/nestedCoroutineContexts.kt @@ -31,3 +31,5 @@ fun main(args: Array) = runBlocking { } } } + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/annotationValue.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/annotationValue.kt index 302db459b956..c6a0d56d9b84 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/annotationValue.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/annotationValue.kt @@ -13,3 +13,4 @@ fun main(args: Array) { // EXPRESSION: (SomeClass::class.java.annotations[0] as Anno).value // RESULT: "abc": Ljava/lang/String; +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/collections.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/collections.kt index b7e608f64a8d..637ddf714b55 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/collections.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/collections.kt @@ -23,3 +23,5 @@ fun main(args: Array) { // EXPRESSION: arrayListOf(1, 2, 3).drop(1) // RESULT: instance of java.util.ArrayList(id=ID): Ljava/util/ArrayList; + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/inaccessibleMembers.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/inaccessibleMembers.kt index 4a3296b92161..e3bd7dcb09b4 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/inaccessibleMembers.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/inaccessibleMembers.kt @@ -45,4 +45,6 @@ fun main() { // RESULT: 0: J // EXPRESSION: block { Foo.x = 21 } -// RESULT: Method threw 'java.lang.IllegalAccessException' exception. \ No newline at end of file +// RESULT: Method threw 'java.lang.IllegalAccessException' exception. + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/javaMethods.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/javaMethods.kt index 10fde09e4242..2725ee92d929 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/javaMethods.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/javaMethods.kt @@ -42,4 +42,4 @@ fun block(block: () -> T): T { // RESULT: "bar": Ljava/lang/String; // EXPRESSION: block { m.i3('q', "z", false) } -// RESULT: 4: I \ No newline at end of file +// RESULT: 4: I diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/kotlinFields.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/kotlinFields.kt index 19d3df3b1940..4645f40a69fd 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/kotlinFields.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/kotlinFields.kt @@ -68,4 +68,6 @@ fun main() { // RESULT: 6.0: F // EXPRESSION: block { Intf.c } -// RESULT: 1: I \ No newline at end of file +// RESULT: 1: I + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/membersFromLocalClass.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/membersFromLocalClass.kt index 4392cb5b6acf..6904b224dc34 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/membersFromLocalClass.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/membersFromLocalClass.kt @@ -21,4 +21,6 @@ class A { //Breakpoint! val a = 1 } -} \ No newline at end of file +} + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/outerMembers.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/outerMembers.kt index af650b0daa83..d0510ec0b06e 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/outerMembers.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/outerMembers.kt @@ -49,3 +49,5 @@ fun intBlock(block: () -> T): T { // EXPRESSION: intBlock { privateVal } // RESULT: 7: I + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/privateAnnotationCompanionValue.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/privateAnnotationCompanionValue.kt index fd78368d5949..9658b298abaa 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/privateAnnotationCompanionValue.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/privateAnnotationCompanionValue.kt @@ -17,3 +17,5 @@ fun main(args: Array) { // EXPRESSION: Anno.test // RESULT: 4: I + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/selfMembers.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/selfMembers.kt index 1b3ecd7d7820..957f39c2f7c9 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/selfMembers.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/selfMembers.kt @@ -46,4 +46,6 @@ fun block(block: () -> T): T { // RESULT: 6: I // EXPRESSION: block { privateVal } -// RESULT: 7: I \ No newline at end of file +// RESULT: 7: I + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/superMembers.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/superMembers.kt index 197333971dd5..80f7f665ed25 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/superMembers.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/compilingEvaluator/inaccessibleMembers/superMembers.kt @@ -39,3 +39,5 @@ fun main() { // EXPRESSION: block { (d as Base).x } // RESULT: 0: J + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/contextClassAndContextReceiversInMethod.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/contextClassAndContextReceiversInMethod.kt index 1b35eb2b7e4d..6fb9cca61098 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/contextClassAndContextReceiversInMethod.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/contextClassAndContextReceiversInMethod.kt @@ -68,4 +68,5 @@ fun main() { // PRINT_FRAME // SHOW_KOTLIN_VARIABLES -// IGNORE_OLD_BACKEND \ No newline at end of file +// IGNORE_OLD_BACKEND +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/contextClassAndContextReceiversInSuspendMethod.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/contextClassAndContextReceiversInSuspendMethod.kt index 690d96aae680..22401976a677 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/contextClassAndContextReceiversInSuspendMethod.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/contextClassAndContextReceiversInSuspendMethod.kt @@ -70,4 +70,5 @@ fun main() = runBlocking { // PRINT_FRAME // SHOW_KOTLIN_VARIABLES -// IGNORE_OLD_BACKEND \ No newline at end of file +// IGNORE_OLD_BACKEND +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/contextClassReceiversInMethod.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/contextClassReceiversInMethod.kt index 05a3fe820ece..0a6efd151d7e 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/contextClassReceiversInMethod.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/contextClassReceiversInMethod.kt @@ -42,4 +42,5 @@ fun main() { } // PRINT_FRAME -// SHOW_KOTLIN_VARIABLES \ No newline at end of file +// SHOW_KOTLIN_VARIABLES +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/functionCallWithImplicitContextClassReceiverCapturing.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/functionCallWithImplicitContextClassReceiverCapturing.kt index ac22a9d78e19..fbbded00c898 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/functionCallWithImplicitContextClassReceiverCapturing.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/functionCallWithImplicitContextClassReceiverCapturing.kt @@ -51,4 +51,5 @@ fun main() { } } -// IGNORE_OLD_BACKEND \ No newline at end of file +// IGNORE_OLD_BACKEND +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/functionCallWithImplicitContextReceiverCapturing.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/functionCallWithImplicitContextReceiverCapturing.kt index fedb1333383b..7410a1a26049 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/functionCallWithImplicitContextReceiverCapturing.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/functionCallWithImplicitContextReceiverCapturing.kt @@ -34,4 +34,5 @@ fun main() { } } -// IGNORE_OLD_BACKEND \ No newline at end of file +// IGNORE_OLD_BACKEND +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/nestedContextClassReceivers.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/nestedContextClassReceivers.kt index c8f7e79f30e5..c4ac921dfb5d 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/nestedContextClassReceivers.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/contextReceivers/nestedContextClassReceivers.kt @@ -74,4 +74,5 @@ fun main() { // PRINT_FRAME // SHOW_KOTLIN_VARIABLES -// IGNORE_OLD_BACKEND \ No newline at end of file +// IGNORE_OLD_BACKEND +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/coroutineContextExists.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/coroutineContextExists.kt index efb7ad56f65e..8d60b1644529 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/coroutineContextExists.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/coroutineContextExists.kt @@ -11,3 +11,5 @@ fun main() = runBlocking(CoroutineName("NAME")) { //Breakpoint! println("") } + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/coroutineScopeReceiver.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/coroutineScopeReceiver.kt index 69590af52652..531f06376c5e 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/coroutineScopeReceiver.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/coroutineScopeReceiver.kt @@ -17,3 +17,5 @@ fun main(args: Array) = runBlocking { //Breakpoint! println("") } + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/functionCallWithSuspendFunctionInside.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/functionCallWithSuspendFunctionInside.kt index ff2abd3deec7..52a8386e302d 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/functionCallWithSuspendFunctionInside.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/functionCallWithSuspendFunctionInside.kt @@ -12,4 +12,6 @@ suspend fun one(): Int { fun main() { //Breakpoint! println("") -} \ No newline at end of file +} + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionInClass.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionInClass.kt index 6b5f9f47c55b..3b60cb4a5557 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionInClass.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionInClass.kt @@ -25,3 +25,5 @@ fun main() { //Breakpoint! println() } + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionWithInlineClass.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionWithInlineClass.kt index 8ac907ceab14..042d3428ee83 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionWithInlineClass.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionWithInlineClass.kt @@ -12,3 +12,5 @@ fun main() { //Breakpoint! println("") } + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionsWithContext.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionsWithContext.kt index 3f83b59fcf55..7c0a90d451fa 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionsWithContext.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionsWithContext.kt @@ -26,3 +26,5 @@ fun main(args: Array) = runBlocking { //Breakpoint! println("") } + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionsWithoutContext.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionsWithoutContext.kt index 33f07bf78ed4..4c79f255b650 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionsWithoutContext.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionsWithoutContext.kt @@ -25,3 +25,5 @@ fun main(args: Array) { //Breakpoint! println("") } + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionsWithoutKotlinxCoroutines.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionsWithoutKotlinxCoroutines.kt index 6e7d6e89103c..11d56e3abc88 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionsWithoutKotlinxCoroutines.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/coroutines/suspendFunctionsWithoutKotlinxCoroutines.kt @@ -8,3 +8,5 @@ fun main() { //Breakpoint! println("") } + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/errors.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/errors.kt index 32b69b91f70c..d32e84f21e47 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/errors.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/errors.kt @@ -28,4 +28,6 @@ open class Base { // RESULT: Expecting an element; looking at ERROR_ELEMENT '(1,6) in /fragment.kt // EXPRESSION: super.baseFun() -// RESULT: VOID_VALUE \ No newline at end of file +// RESULT: VOID_VALUE + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/fieldGetters.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/fieldGetters.kt index 2f5003b86882..9c2229600664 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/fieldGetters.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/fieldGetters.kt @@ -188,4 +188,6 @@ public class FieldsGetters { public String foo = "c"; public abstract String getFoo(); } -} \ No newline at end of file +} + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/frame/coroutineContextFun.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/frame/coroutineContextFun.kt index 7894a7b2c331..250b8a27450b 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/frame/coroutineContextFun.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/frame/coroutineContextFun.kt @@ -12,4 +12,6 @@ suspend fun main() { private suspend fun foo() {} // EXPRESSION: coroutineContext -// RESULT: instance of kotlin.coroutines.EmptyCoroutineContext(id=ID): Lkotlin/coroutines/EmptyCoroutineContext; \ No newline at end of file +// RESULT: instance of kotlin.coroutines.EmptyCoroutineContext(id=ID): Lkotlin/coroutines/EmptyCoroutineContext; + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/frame/coroutineContextLambda.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/frame/coroutineContextLambda.kt index f23f1a6a4967..8654f54c4d81 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/frame/coroutineContextLambda.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/frame/coroutineContextLambda.kt @@ -16,4 +16,6 @@ private var bar: suspend () -> Unit = { } // EXPRESSION: coroutineContext -// RESULT: instance of kotlin.coroutines.EmptyCoroutineContext(id=ID): Lkotlin/coroutines/EmptyCoroutineContext; \ No newline at end of file +// RESULT: instance of kotlin.coroutines.EmptyCoroutineContext(id=ID): Lkotlin/coroutines/EmptyCoroutineContext; + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/frame/coroutineContextWithoutSuspend.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/frame/coroutineContextWithoutSuspend.kt index 1673225350b7..54eb022c9bcc 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/frame/coroutineContextWithoutSuspend.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/frame/coroutineContextWithoutSuspend.kt @@ -15,4 +15,6 @@ private suspend fun foo() { // PRINT_FRAME // EXPRESSION: coroutineContext -// RESULT: instance of kotlin.coroutines.EmptyCoroutineContext(id=ID): Lkotlin/coroutines/EmptyCoroutineContext; \ No newline at end of file +// RESULT: instance of kotlin.coroutines.EmptyCoroutineContext(id=ID): Lkotlin/coroutines/EmptyCoroutineContext; + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/frame/frameInlineArgumentInsideInlineFun.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/frame/frameInlineArgumentInsideInlineFun.kt index 5820880a0fe2..73afd02a8d03 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/frame/frameInlineArgumentInsideInlineFun.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/frame/frameInlineArgumentInsideInlineFun.kt @@ -36,4 +36,6 @@ fun main(args: Array) { // SHOW_KOTLIN_VARIABLES // EXPRESSION: element -// RESULT: 1: I \ No newline at end of file +// RESULT: 1: I + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/inlineMethodsInSignature.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/inlineMethodsInSignature.kt index cbdb9facd7f5..2e09608db685 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/inlineMethodsInSignature.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/inlineMethodsInSignature.kt @@ -9,4 +9,6 @@ fun main() { } // EXPRESSION: i -// RESULT: "InlineMe(x=1)": Ljava/lang/String; \ No newline at end of file +// RESULT: "InlineMe(x=1)": Ljava/lang/String; + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcBlock.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcBlock.kt index 59df845dddb4..dd97de334efa 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcBlock.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcBlock.kt @@ -33,4 +33,6 @@ public class JavaClass { int elseVal = 1; } } -} \ No newline at end of file +} + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcImports.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcImports.kt index 48a1626866e0..9fb77e948d39 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcImports.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcImports.kt @@ -30,4 +30,6 @@ public class JavaClass { list.add(2); return list; } -} \ No newline at end of file +} + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcLocalVariable.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcLocalVariable.kt index b3cdc3ec9568..d495cf9bf9f4 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcLocalVariable.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcLocalVariable.kt @@ -21,4 +21,6 @@ public class JavaClass { int i = 1; int breakpoint = 1; } -} \ No newline at end of file +} + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcMarkedObject.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcMarkedObject.kt index 136c4299018e..21f28fcdf0ca 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcMarkedObject.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcMarkedObject.kt @@ -26,4 +26,6 @@ public class JavaClass { Integer i = 1; int breakpoint = 1; } -} \ No newline at end of file +} + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcProperty.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcProperty.kt index 7e35ffb8058f..b58d82dc3e16 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcProperty.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcProperty.kt @@ -28,4 +28,6 @@ public class JavaClass { public void property() { int breakpoint = 1; } -} \ No newline at end of file +} + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcSimple.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcSimple.kt index f994953a1f19..050f25609556 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcSimple.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/javaContext/jcSimple.kt @@ -19,4 +19,6 @@ public class JavaClass { public void simple() { int breakpoint = 1; } -} \ No newline at end of file +} + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/kt31709.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/kt31709.kt index becf180fba4a..31fae37ccd05 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/kt31709.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/kt31709.kt @@ -10,4 +10,6 @@ fun main() { } // EXPRESSION: listOf(1, 2, 3, 4, 5).filter { it > a } -// RESULT: instance of java.util.ArrayList(id=ID): Ljava/util/ArrayList; \ No newline at end of file +// RESULT: instance of java.util.ArrayList(id=ID): Ljava/util/ArrayList; + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/labels/ldifferentTypes.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/labels/ldifferentTypes.kt index c512c89b2f60..6b9de0667786 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/labels/ldifferentTypes.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/labels/ldifferentTypes.kt @@ -98,4 +98,6 @@ class A { } fun test() = 1 -} \ No newline at end of file +} + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/nothing.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/nothing.kt index 743e53ff0fe7..c3dc52351bcb 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/nothing.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/nothing.kt @@ -25,4 +25,6 @@ fun block(foo: () -> Unit) { // RESULT: 'Nothing' can't be instantiated // EXPRESSION: fun foo() { Nothing() } -// RESULT: 'Nothing' can't be instantiated \ No newline at end of file +// RESULT: 'Nothing' can't be instantiated + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/privateFieldInCompanion.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/privateFieldInCompanion.kt index 9b717751098e..47d7cfa1a078 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/privateFieldInCompanion.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/privateFieldInCompanion.kt @@ -40,3 +40,5 @@ fun main(args: Array) { // EXPRESSION: PUBLIC_STATIC // RESULT: 6: I + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/privateMember.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/privateMember.kt index 1ced9ae98d6c..6fcef1c77416 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/privateMember.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/privateMember.kt @@ -43,3 +43,5 @@ class Derived: Base() { // EXPRESSION: derivedAsBase.privateFun() // RESULT: 2: I + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/privatePropertyWithExplicitDefaultGetter.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/privatePropertyWithExplicitDefaultGetter.kt index a0501a370d73..7d8481dd67ea 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/privatePropertyWithExplicitDefaultGetter.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/privatePropertyWithExplicitDefaultGetter.kt @@ -16,3 +16,5 @@ class Some { } // EXPRESSION: base.a // RESULT: 1: I + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/privatePropertyWithNonDefaultAccessor.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/privatePropertyWithNonDefaultAccessor.kt index 8ee5d605f2b0..bff99184151f 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/privatePropertyWithNonDefaultAccessor.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/privatePropertyWithNonDefaultAccessor.kt @@ -14,3 +14,5 @@ class Some { // EXPRESSION: base.a // RESULT: 4: I + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/protectedMember.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/protectedMember.kt index 82ad3ec25aef..ed7c5c2ab464 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/protectedMember.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/protectedMember.kt @@ -21,4 +21,6 @@ class MyClass { // RESULT: 1: I // EXPRESSION: MyClass.ProtectedClass().a -// RESULT: 1: I \ No newline at end of file +// RESULT: 1: I + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/simpleLocals/localFunctionWithArg.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/simpleLocals/localFunctionWithArg.kt index da21e058d3db..c9536ef9671f 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/simpleLocals/localFunctionWithArg.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/simpleLocals/localFunctionWithArg.kt @@ -8,4 +8,4 @@ fun main() { } // EXPRESSION: localFunction(8) -// RESULT: 50: I +// RESULT: 50: I \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/simpleLocals/twoLocals.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/simpleLocals/twoLocals.kt index e01b797043ea..8774958120f4 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/simpleLocals/twoLocals.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/simpleLocals/twoLocals.kt @@ -24,4 +24,6 @@ fun main() { // because it's not in the captures of `l2`. // EXPRESSION: l1() -// RESULT: Cannot find local variable 'x' with type int \ No newline at end of file +// RESULT: Cannot find local variable 'x' with type int + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/superCallsCaptured.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/superCallsCaptured.kt index 3ff68e0a8f9a..da4d2c349587 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/superCallsCaptured.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/superCallsCaptured.kt @@ -27,3 +27,5 @@ fun block(block: () -> Unit) { // EXPRESSION: super.foo() // RESULT: 5: I + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/superCallsSimple.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/superCallsSimple.kt index e0b38068a6d1..e7ef21bed6d0 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/superCallsSimple.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/superCallsSimple.kt @@ -19,4 +19,6 @@ class Bar : Foo() { // RESULT: 6: I // EXPRESSION: super.foo() -// RESULT: 5: I \ No newline at end of file +// RESULT: 5: I + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/unboxParam.kt b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/unboxParam.kt index cccc30ae8ff5..0606abc50d07 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/unboxParam.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/evaluation/singleBreakpoint/unboxParam.kt @@ -14,4 +14,6 @@ fun main(args: Array) { fun fooNullableInt(): Int? = 1 -fun fooInt(param: Int) = param \ No newline at end of file +fun fooInt(param: Int) = param + +// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/stepping/custom/simpleConditionalBreakpoint.kt b/plugins/kotlin/jvm-debugger/test/testData/stepping/custom/simpleConditionalBreakpoint.kt index 82111d0ddad5..ae1d5d79fbf2 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/stepping/custom/simpleConditionalBreakpoint.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/stepping/custom/simpleConditionalBreakpoint.kt @@ -6,4 +6,3 @@ fun main(args: Array) { } // RESUME: 1 -// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/stepping/stepIntoAndSmartStepInto/internalInlineMethod.kt b/plugins/kotlin/jvm-debugger/test/testData/stepping/stepIntoAndSmartStepInto/internalInlineMethod.kt index 34e9eb14bf0c..5baeec0b7024 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/stepping/stepIntoAndSmartStepInto/internalInlineMethod.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/stepping/stepIntoAndSmartStepInto/internalInlineMethod.kt @@ -11,5 +11,4 @@ class Clazz() { } // IGNORE_K2_SMART_STEP_INTO -// IGNORE_K2 // Remove after IDEA-326256 fix diff --git a/plugins/kotlin/jvm-debugger/test/testData/stepping/stepIntoAndSmartStepInto/internalMethod.kt b/plugins/kotlin/jvm-debugger/test/testData/stepping/stepIntoAndSmartStepInto/internalMethod.kt index 1a5c86c77d01..d0fb60c1f8f1 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/stepping/stepIntoAndSmartStepInto/internalMethod.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/stepping/stepIntoAndSmartStepInto/internalMethod.kt @@ -15,5 +15,4 @@ class Example { } // IGNORE_K2_SMART_STEP_INTO -// IGNORE_K2 // Remove after IDEA-326256 fix diff --git a/plugins/kotlin/jvm-debugger/test/testData/variables/extractCapturesFromSuspendLambdas.kt b/plugins/kotlin/jvm-debugger/test/testData/variables/extractCapturesFromSuspendLambdas.kt index d92621033c40..a1032136c519 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/variables/extractCapturesFromSuspendLambdas.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/variables/extractCapturesFromSuspendLambdas.kt @@ -80,5 +80,3 @@ suspend fun main() { suspendLambdaWithContext() complex() } - -// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/variables/nestedInlineFunctions.kt b/plugins/kotlin/jvm-debugger/test/testData/variables/nestedInlineFunctions.kt index 6439ca7802c1..cc04e9870467 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/variables/nestedInlineFunctions.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/variables/nestedInlineFunctions.kt @@ -21,5 +21,3 @@ inline fun g(a: Int) { //Breakpoint! println() } - -// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesInNestedFunctions.kt b/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesInNestedFunctions.kt index f9c569420740..0c022331d4e1 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesInNestedFunctions.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesInNestedFunctions.kt @@ -56,4 +56,3 @@ suspend fun suspendUse(value: Any) { } -// IGNORE_K2 diff --git a/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesInSuspendContexts.kt b/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesInSuspendContexts.kt index 182f140348ff..c81a3d09b717 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesInSuspendContexts.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesInSuspendContexts.kt @@ -40,5 +40,3 @@ suspend fun suspendUse(value: Any) { } - -// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesInSuspendInline.kt b/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesInSuspendInline.kt index e43fc99297ca..d4a035354a90 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesInSuspendInline.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesInSuspendInline.kt @@ -28,5 +28,3 @@ suspend fun suspendUse(value: Any) { } inline fun inlineBlock(block: () -> Unit) = block() - -// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesWithLambdas.kt b/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesWithLambdas.kt index 3ec6f99634be..6762c54bbf1c 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesWithLambdas.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesWithLambdas.kt @@ -86,5 +86,3 @@ inline fun noinlineBlock(noinline block: () -> Unit) = block() fun block(block: () -> Unit) = block() suspend fun suspendBlock(block: suspend () -> Unit) = block() - -// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesWithWhen.kt b/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesWithWhen.kt index 0abff9c035bb..3150ec94ed89 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesWithWhen.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/variables/optimisedVariablesWithWhen.kt @@ -90,5 +90,3 @@ suspend fun suspendUse(value: Any) { inline fun inlineBlock(block: () -> Unit) = block() fun block(block: () -> Unit) = block() - -// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-debugger/test/testData/variables/reentrantInlineFunctions.kt b/plugins/kotlin/jvm-debugger/test/testData/variables/reentrantInlineFunctions.kt index fccfc955d2fc..4c4ea043ea70 100644 --- a/plugins/kotlin/jvm-debugger/test/testData/variables/reentrantInlineFunctions.kt +++ b/plugins/kotlin/jvm-debugger/test/testData/variables/reentrantInlineFunctions.kt @@ -24,5 +24,3 @@ inline fun f(b: Boolean, block: (Int) -> Unit) { block(2) } } - -// IGNORE_K2 \ No newline at end of file diff --git a/plugins/kotlin/jvm-decompiler/kotlin.jvm-decompiler.iml b/plugins/kotlin/jvm-decompiler/kotlin.jvm-decompiler.iml index bc51cc5dc647..b41b0e306ce7 100644 --- a/plugins/kotlin/jvm-decompiler/kotlin.jvm-decompiler.iml +++ b/plugins/kotlin/jvm-decompiler/kotlin.jvm-decompiler.iml @@ -12,8 +12,10 @@ + + diff --git a/plugins/kotlin/jvm-decompiler/src/org/jetbrains/kotlin/idea/jvmDecompiler/KotlinBytecodeDecompiler.kt b/plugins/kotlin/jvm-decompiler/src/org/jetbrains/kotlin/idea/jvmDecompiler/KotlinBytecodeDecompiler.kt index b0af464de87d..8f9690f24276 100644 --- a/plugins/kotlin/jvm-decompiler/src/org/jetbrains/kotlin/idea/jvmDecompiler/KotlinBytecodeDecompiler.kt +++ b/plugins/kotlin/jvm-decompiler/src/org/jetbrains/kotlin/idea/jvmDecompiler/KotlinBytecodeDecompiler.kt @@ -4,23 +4,27 @@ package org.jetbrains.kotlin.idea.jvmDecompiler import com.intellij.openapi.application.runReadAction import com.intellij.openapi.fileTypes.StdFileTypes import com.intellij.openapi.util.io.FileUtil -import com.intellij.openapi.util.io.FileUtilRt import com.intellij.openapi.vfs.VirtualFile +import org.jetbrains.annotations.ApiStatus import org.jetbrains.java.decompiler.IdeaLogger import org.jetbrains.java.decompiler.main.decompiler.BaseDecompiler import org.jetbrains.java.decompiler.main.extern.IBytecodeProvider import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences import org.jetbrains.java.decompiler.main.extern.IResultSaver +import org.jetbrains.kotlin.analysis.api.analyze +import org.jetbrains.kotlin.analysis.api.components.KtCompilationResult +import org.jetbrains.kotlin.analysis.api.components.isClassFile import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.languageVersionSettings +import org.jetbrains.kotlin.idea.actions.bytecode.KotlinBytecodeToolWindow import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings import org.jetbrains.kotlin.idea.internal.DecompileFailedException -import org.jetbrains.kotlin.idea.internal.KotlinBytecodeToolWindow import org.jetbrains.kotlin.psi.KtFile import java.io.File import java.util.jar.Manifest -internal object KotlinBytecodeDecompiler { +@ApiStatus.Internal +object KotlinBytecodeDecompiler { fun decompile(file: KtFile): String? { try { val bytecodeMap: Map ByteArray> = runReadAction { @@ -69,13 +73,24 @@ internal object KotlinBytecodeDecompiler { val configuration = CompilerConfiguration().apply { languageVersionSettings = file.languageVersionSettings } - val generationState = KotlinBytecodeToolWindow.compileSingleFile(file, configuration)?.first ?: return emptyMap() - val bytecodeMap = hashMapOf ByteArray>() - generationState.factory.asList().filter { FileUtilRt.extensionEquals(it.relativePath, "class") }.forEach { - bytecodeMap[File("/${it.relativePath}").absoluteFile] = { it.asByteArray() } + analyze(file) { + with(KotlinBytecodeToolWindow.Companion) { + val result = compileSingleFile(file, configuration)?.first ?: return emptyMap() + + return when (result) { + is KtCompilationResult.Success -> buildMap { + for (outputFile in result.output) { + if (outputFile.isClassFile) { + put(File("/" + outputFile.path).absoluteFile) { outputFile.content } + } + } + } + + is KtCompilationResult.Failure -> emptyMap() + } + } } - return bytecodeMap } private class KotlinResultSaver : IResultSaver { diff --git a/plugins/kotlin/jvm-decompiler/src/org/jetbrains/kotlin/idea/jvmDecompiler/KotlinDecompilerAdapter.kt b/plugins/kotlin/jvm-decompiler/src/org/jetbrains/kotlin/idea/jvmDecompiler/KotlinDecompilerAdapter.kt index 0dfc86e51c89..68ebaa5678da 100644 --- a/plugins/kotlin/jvm-decompiler/src/org/jetbrains/kotlin/idea/jvmDecompiler/KotlinDecompilerAdapter.kt +++ b/plugins/kotlin/jvm-decompiler/src/org/jetbrains/kotlin/idea/jvmDecompiler/KotlinDecompilerAdapter.kt @@ -12,10 +12,12 @@ import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.openapi.vfs.ex.dummy.DummyFileSystem +import org.jetbrains.annotations.ApiStatus import org.jetbrains.kotlin.idea.highlighter.isKotlinDecompiledFile import org.jetbrains.kotlin.idea.internal.DecompileFailedException import org.jetbrains.kotlin.psi.KtFile +@ApiStatus.Internal class KotlinBytecodeDecompilerTask(private val file: KtFile) : Task.Backgroundable( file.project, KotlinJvmDecompilerBundle.message("internal.action.text.decompile.kotlin.bytecode") @@ -37,9 +39,8 @@ class KotlinBytecodeDecompilerTask(private val file: KtFile) : Task.Backgroundab val text = decompiledText if (text != null) { - generateDecompiledVirtualFile(text)?.let { - OpenFileDescriptor(file.project, it).navigate(true) - } + val decompiledVirtualFile = generateDecompiledVirtualFile(text) + OpenFileDescriptor(file.project, decompiledVirtualFile).navigate(true) } else { Messages.showErrorDialog( KotlinJvmDecompilerBundle.message("internal.error.text.cannot.decompile", file.name), @@ -48,18 +49,12 @@ class KotlinBytecodeDecompilerTask(private val file: KtFile) : Task.Backgroundab } } - fun generateDecompiledVirtualFile(decompiledText: String? = null): VirtualFile? { - val text = decompiledText ?: try { - KotlinBytecodeDecompiler.decompile(file) - } catch (e: DecompileFailedException) { - null - } ?: return null - + fun generateDecompiledVirtualFile(decompiledText: String): VirtualFile { val virtualFile: VirtualFile = runWriteAction { val root: VirtualFile = getOrCreateDummyRoot() val decompiledFileName = FileUtil.getNameWithoutExtension(file.name) + ".decompiled.java" val result = DummyFileSystem.getInstance().createChildFile(null, root, decompiledFileName) - VfsUtil.saveText(result, text) + VfsUtil.saveText(result, decompiledText) result } diff --git a/plugins/kotlin/jvm/kotlin.jvm.iml b/plugins/kotlin/jvm/kotlin.jvm.iml index af12b87da7ce..541ed4249adf 100644 --- a/plugins/kotlin/jvm/kotlin.jvm.iml +++ b/plugins/kotlin/jvm/kotlin.jvm.iml @@ -11,10 +11,13 @@ + + + @@ -25,7 +28,7 @@ - + diff --git a/plugins/kotlin/jvm/resources/META-INF/jvm-common.xml b/plugins/kotlin/jvm/resources/META-INF/jvm-k1.xml similarity index 97% rename from plugins/kotlin/jvm/resources/META-INF/jvm-common.xml rename to plugins/kotlin/jvm/resources/META-INF/jvm-k1.xml index c3e578ca7bd9..336748596dfa 100644 --- a/plugins/kotlin/jvm/resources/META-INF/jvm-common.xml +++ b/plugins/kotlin/jvm/resources/META-INF/jvm-k1.xml @@ -10,10 +10,6 @@ - - - - @@ -76,6 +72,8 @@ + + @@ -104,6 +102,7 @@ + diff --git a/plugins/kotlin/jvm/resources/META-INF/jvm.xml b/plugins/kotlin/jvm/resources/META-INF/jvm.xml deleted file mode 100644 index b201492c416a..000000000000 --- a/plugins/kotlin/jvm/resources/META-INF/jvm.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/util/InfinitePeriodicalTask.java b/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/actions/bytecode/InfinitePeriodicalTask.java similarity index 75% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/util/InfinitePeriodicalTask.java rename to plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/actions/bytecode/InfinitePeriodicalTask.java index 8e64278d6fa1..8a7fa8087433 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/util/InfinitePeriodicalTask.java +++ b/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/actions/bytecode/InfinitePeriodicalTask.java @@ -1,20 +1,23 @@ -// 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-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package org.jetbrains.kotlin.idea.util; +package org.jetbrains.kotlin.idea.actions.bytecode; import com.intellij.openapi.Disposable; import com.intellij.openapi.util.Computable; import com.intellij.util.Alarm; import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.idea.util.LongRunningReadTask; -public class InfinitePeriodicalTask { +class InfinitePeriodicalTask { private final Alarm myUpdateAlarm; private final long delay; private final Computable taskProvider; private LongRunningReadTask currentTask; - public InfinitePeriodicalTask( - long delay, @NotNull Alarm.ThreadToUse threadToUse, Disposable parentDisposable, + InfinitePeriodicalTask( + long delay, + @NotNull Alarm.ThreadToUse threadToUse, + Disposable parentDisposable, Computable taskProvider ) { myUpdateAlarm = new Alarm(threadToUse, parentDisposable); diff --git a/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/internal/KotlinBytecodeToolWindow.kt b/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/actions/bytecode/KotlinBytecodeToolWindow.kt similarity index 56% rename from plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/internal/KotlinBytecodeToolWindow.kt rename to plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/actions/bytecode/KotlinBytecodeToolWindow.kt index 8ae60599ee4e..a06a9be44bc8 100644 --- a/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/internal/KotlinBytecodeToolWindow.kt +++ b/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/actions/bytecode/KotlinBytecodeToolWindow.kt @@ -1,12 +1,11 @@ -// 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-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package org.jetbrains.kotlin.idea.internal +package org.jetbrains.kotlin.idea.actions.bytecode import com.intellij.ide.highlighter.JavaFileType import com.intellij.openapi.Disposable import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.diagnostic.Logger -import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.EditorFactory import com.intellij.openapi.editor.ScrollType import com.intellij.openapi.fileEditor.FileEditorManager @@ -21,21 +20,27 @@ import com.intellij.openapi.wm.ToolWindow import com.intellij.ui.JBColor import com.intellij.util.Alarm import com.intellij.util.ui.JBUI -import org.jetbrains.kotlin.backend.common.output.OutputFile +import org.jetbrains.annotations.ApiStatus +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.analyze +import org.jetbrains.kotlin.analysis.api.components.* +import org.jetbrains.kotlin.analysis.api.descriptors.components.STUB_UNBOUND_IR_SYMBOLS +import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnosticWithPsi import org.jetbrains.kotlin.codegen.ClassBuilderFactories -import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.config.* -import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages import org.jetbrains.kotlin.idea.KotlinJvmBundle +import org.jetbrains.kotlin.idea.base.codeInsight.compiler.* +import org.jetbrains.kotlin.idea.base.plugin.isK2Plugin import org.jetbrains.kotlin.idea.base.projectStructure.RootKindFilter import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings import org.jetbrains.kotlin.idea.base.projectStructure.matches -import org.jetbrains.kotlin.idea.core.ClassFileOrigins -import org.jetbrains.kotlin.idea.core.KotlinCompilerIde -import org.jetbrains.kotlin.idea.util.InfinitePeriodicalTask +import org.jetbrains.kotlin.idea.base.util.module +import org.jetbrains.kotlin.idea.internal.DecompileFailedException +import org.jetbrains.kotlin.idea.internal.KotlinJvmDecompilerFacade import org.jetbrains.kotlin.idea.util.LongRunningReadTask import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.utils.join +import org.jetbrains.org.objectweb.asm.ClassReader +import org.jetbrains.org.objectweb.asm.util.TraceClassVisitor import java.awt.BorderLayout import java.awt.FlowLayout import java.io.File @@ -45,20 +50,26 @@ import java.util.* import javax.swing.* import kotlin.math.min +@ApiStatus.Internal sealed class BytecodeGenerationResult { data class Bytecode(val text: String) : BytecodeGenerationResult() data class Error(val text: String) : BytecodeGenerationResult() } -class KotlinBytecodeToolWindow(private val myProject: Project, private val toolWindow: ToolWindow) : JPanel(BorderLayout()), Disposable { - @Suppress("JoinDeclarationAndAssignment") - private val myEditor: Editor +@ApiStatus.Internal +class KotlinBytecodeToolWindow( + private val project: Project, + private val toolWindow: ToolWindow +) : JPanel(BorderLayout()), Disposable { + private val document = EditorFactory.getInstance().createDocument("") + private val editor = EditorFactory.getInstance().createEditor(document, project, JavaFileType.INSTANCE, /* isViewer = */ true) + private val enableInline: JCheckBox private val enableOptimization: JCheckBox private val enableAssertions: JCheckBox private val decompile: JButton private val jvmTargets: JComboBox - private val ir: JCheckBox + private val ir: JCheckBox? private inner class UpdateBytecodeToolWindowTask : LongRunningReadTask(this) { override fun prepareRequestInfo(): Location? { @@ -66,7 +77,7 @@ class KotlinBytecodeToolWindow(private val myProject: Project, private val toolW return null } - val location = Location.fromEditor(FileEditorManager.getInstance(myProject).selectedTextEditor, myProject) + val location = Location.fromEditor(FileEditorManager.getInstance(project).selectedTextEditor, project) if (location.getEditor() == null) { return null } @@ -92,20 +103,28 @@ class KotlinBytecodeToolWindow(private val myProject: Project, private val toolW val ktFile = location.kFile!! val configuration = CompilerConfiguration() + + val containingModule = ktFile.module + if (containingModule != null) { + configuration.put(CommonConfigurationKeys.MODULE_NAME, containingModule.name) + } + if (!enableInline.isSelected) { configuration.put(CommonConfigurationKeys.DISABLE_INLINE, true) } + if (!enableAssertions.isSelected) { configuration.put(JVMConfigurationKeys.DISABLE_CALL_ASSERTIONS, true) configuration.put(JVMConfigurationKeys.DISABLE_PARAM_ASSERTIONS, true) } + if (!enableOptimization.isSelected) { configuration.put(JVMConfigurationKeys.DISABLE_OPTIMIZATION, true) } configuration.put(JVMConfigurationKeys.JVM_TARGET, JvmTarget.fromString(jvmTargets.selectedItem as String)!!) - if (ir.isSelected) { + if (isK2Plugin() || ir != null && ir.isSelected) { configuration.put(JVMConfigurationKeys.IR, true) } @@ -115,7 +134,7 @@ class KotlinBytecodeToolWindow(private val myProject: Project, private val toolW } override fun onResultReady(requestInfo: Location, result: BytecodeGenerationResult?) { - val editor = requestInfo.getEditor()!! + val sourceEditor = requestInfo.getEditor()!! if (result == null) { return @@ -133,38 +152,32 @@ class KotlinBytecodeToolWindow(private val myProject: Project, private val toolW val fileStartOffset = requestInfo.getStartOffset() val fileEndOffset = requestInfo.getEndOffset() - val document = editor.document - val startLine = document.getLineNumber(fileStartOffset) - var endLine = document.getLineNumber(fileEndOffset) - if (endLine > startLine && fileEndOffset > 0 && document.charsSequence[fileEndOffset - 1] == '\n') { + val sourceDocument = sourceEditor.document + val startLine = sourceDocument.getLineNumber(fileStartOffset) + var endLine = sourceDocument.getLineNumber(fileEndOffset) + if (endLine > startLine && fileEndOffset > 0 && sourceDocument.charsSequence[fileEndOffset - 1] == '\n') { endLine-- } - val byteCodeDocument = myEditor.document + val linesRange = mapLines(document.text, startLine, endLine) + val endSelectionLineIndex = min(linesRange.second + 1, document.lineCount) - val linesRange = mapLines(byteCodeDocument.text, startLine, endLine) - val endSelectionLineIndex = min(linesRange.second + 1, byteCodeDocument.lineCount) + val startOffset = document.getLineStartOffset(linesRange.first) + val endOffset = min(document.getLineStartOffset(endSelectionLineIndex), document.textLength) - val startOffset = byteCodeDocument.getLineStartOffset(linesRange.first) - val endOffset = min(byteCodeDocument.getLineStartOffset(endSelectionLineIndex), byteCodeDocument.textLength) - - myEditor.caretModel.moveToOffset(endOffset) - myEditor.scrollingModel.scrollToCaret(ScrollType.MAKE_VISIBLE) - myEditor.caretModel.moveToOffset(startOffset) - myEditor.scrollingModel.scrollToCaret(ScrollType.MAKE_VISIBLE) - - myEditor.selectionModel.setSelection(startOffset, endOffset) + editor.caretModel.moveToOffset(endOffset) + editor.scrollingModel.scrollToCaret(ScrollType.MAKE_VISIBLE) + editor.caretModel.moveToOffset(startOffset) + editor.scrollingModel.scrollToCaret(ScrollType.MAKE_VISIBLE) + editor.selectionModel.setSelection(startOffset, endOffset) } } } } init { - myEditor = EditorFactory.getInstance().createEditor( - EditorFactory.getInstance().createDocument(""), myProject, JavaFileType.INSTANCE, true - ) - myEditor.setBorder(null) - add(myEditor.component) + editor.setBorder(null) + add(editor.component) decompile = JButton(KotlinJvmBundle.message("button.text.decompile")) /*TODO: try to extract default parameter from compiler options*/ @@ -172,10 +185,12 @@ class KotlinBytecodeToolWindow(private val myProject: Project, private val toolW enableOptimization = JCheckBox(KotlinJvmBundle.message("checkbox.text.optimization"), true) enableAssertions = JCheckBox(KotlinJvmBundle.message("checkbox.text.assertions"), true) jvmTargets = ComboBox(JvmTarget.supportedValues().map { it.description }.toTypedArray()) + @NlsSafe val description = JvmTarget.DEFAULT.description jvmTargets.selectedItem = description - ir = JCheckBox(KotlinJvmBundle.message("checkbox.text.ir"), false) + + ir = if (!isK2Plugin()) JCheckBox(KotlinJvmBundle.message("checkbox.text.ir"), false) else null setText(DEFAULT_TEXT) initOptionsPanel() @@ -186,33 +201,41 @@ class KotlinBytecodeToolWindow(private val myProject: Project, private val toolW val optionPanel = JPanel(FlowLayout()) add(optionPanel, BorderLayout.NORTH) - val decompilerFacade = KotlinJvmDecompilerFacade.getInstance() - if (decompilerFacade != null) { - optionPanel.add(decompile) - decompile.addActionListener { - decompileBytecode(decompilerFacade) - } - } + with(optionPanel) { + border = JBUI.Borders.customLineBottom(JBColor.border()) - optionPanel.add(enableInline) - optionPanel.add(enableOptimization) - optionPanel.add(enableAssertions) - optionPanel.add(ir) - optionPanel.add(JLabel(KotlinJvmBundle.message("bytecode.toolwindow.label.jvm.target"))) - optionPanel.add(jvmTargets) - optionPanel.border = JBUI.Borders.customLineBottom(JBColor.border()) + val decompilerFacade = KotlinJvmDecompilerFacade.getInstance() + if (decompilerFacade != null) { + add(decompile) + decompile.addActionListener { + decompileBytecode(decompilerFacade) + } + } + + add(enableInline) + add(enableOptimization) + add(enableAssertions) + + if (!isK2Plugin()) { + add(ir) + } + + add(JLabel(KotlinJvmBundle.message("bytecode.toolwindow.label.jvm.target"))) + add(jvmTargets) + } } private fun decompileBytecode(decompilerFacade: KotlinJvmDecompilerFacade) { - val location = Location.fromEditor(FileEditorManager.getInstance(myProject).selectedTextEditor, myProject) - val file = location.kFile - if (file == null) return + val editor = FileEditorManager.getInstance(project).selectedTextEditor ?: return + val location = Location.fromEditor(editor, project) + val file = location.kFile ?: return + try { decompilerFacade.showDecompiledCode(file) } catch (ex: DecompileFailedException) { LOG.info(ex) Messages.showErrorDialog( - myProject, + project, KotlinJvmBundle.message("failed.to.decompile.0.1", file.name, ex), KotlinJvmBundle.message("kotlin.bytecode.decompiler") ) @@ -227,7 +250,7 @@ class KotlinBytecodeToolWindow(private val myProject: Project, private val toolW Computable> { UpdateBytecodeToolWindowTask() } ).start() - listOf(enableInline, enableOptimization, enableAssertions, ir).forEach { checkBox -> + listOfNotNull(enableInline, enableOptimization, enableAssertions, ir).forEach { checkBox -> checkBox.addActionListener { updateToolWindowOnOptionChange() } @@ -246,11 +269,11 @@ class KotlinBytecodeToolWindow(private val myProject: Project, private val toolW } private fun setText(resultText: String) { - ApplicationManager.getApplication().runWriteAction { myEditor.document.setText(StringUtil.convertLineSeparators(resultText)) } + ApplicationManager.getApplication().runWriteAction { editor.document.setText(StringUtil.convertLineSeparators(resultText)) } } override fun dispose() { - EditorFactory.getInstance().releaseEditor(myEditor) + EditorFactory.getInstance().releaseEditor(editor) } companion object { @@ -262,9 +285,8 @@ class KotlinBytecodeToolWindow(private val myProject: Project, private val toolW "No Kotlin source file is opened.\n" + "*/" - // public for tests - fun getBytecodeForFile(ktFile: KtFile, configuration: CompilerConfiguration): BytecodeGenerationResult { - val (state, classFileOrigins) = try { + fun getBytecodeForFile(ktFile: KtFile, configuration: CompilerConfiguration): BytecodeGenerationResult = analyze(ktFile) { + val (result, classFileOrigins) = try { compileSingleFile(ktFile, configuration) ?: return BytecodeGenerationResult.Error(KotlinJvmBundle.message("cannot.compile.0.to.bytecode", ktFile.name)) } catch (e: ProcessCanceledException) { @@ -273,58 +295,97 @@ class KotlinBytecodeToolWindow(private val myProject: Project, private val toolW return BytecodeGenerationResult.Error(printStackTraceToString(e)) } - val answer = StringBuilder() + val writer = StringWriter() - val diagnostics = state.collectedExtraJvmDiagnostics.all() - if (!diagnostics.isEmpty()) { - answer.append("// Backend Errors: \n") - answer.append("// ================\n") - for (diagnostic in diagnostics) { - answer.append("// Error at ") - .append(diagnostic.psiFile.name) - .append(join(diagnostic.textRanges, ",")) - .append(": ") - .append(DefaultErrorMessages.render(diagnostic)) - .append("\n") + when (result) { + is KtCompilationResult.Success -> { + val printWriter = PrintWriter(writer) + + for (outputFile in getRelevantClassFiles(ktFile, result.output, classFileOrigins)) { + writer.append("// ================") + writer.append(outputFile.path) + writer.append(" =================\n") + + val classReader = ClassReader(outputFile.content) + val traceVisitor = TraceClassVisitor(printWriter) + classReader.accept(traceVisitor, 0) + + writer.append("\n\n") + } + } + is KtCompilationResult.Failure -> { + val diagnostics = result.errors + if (diagnostics.isNotEmpty()) { + writer.append("// Backend Errors: \n") + writer.append("// ================\n") + for (error in diagnostics) { + writer.append("// Error") + if (error is KtDiagnosticWithPsi<*>) { + writer.append(" at ") + writer.append(error.psi.containingFile.name) + error.textRanges.joinTo(writer) + } + writer.append(": ") + writer.append(error.defaultMessage) + writer.append("\n") + } + writer.append("// ================\n\n") + } } - answer.append("// ================\n\n") } - for (outputFile in getRelevantOutputFiles(state, classFileOrigins, ktFile)) { - answer.append("// ================") - answer.append(outputFile.relativePath) - answer.append(" =================\n") - answer.append(outputFile.asText()).append("\n\n") - } - - return BytecodeGenerationResult.Bytecode(answer.toString()) + return BytecodeGenerationResult.Bytecode(writer.toString()) } /** - * Returns a list of output files from [state] that should be shown to the user. + * Returns a list of class files from [outputFiles] that should be shown to the user. * - * An [OutputFile] is linked to its source [KtFile] via [OutputFile.sourceFiles]. However, all source files are physical, while a - * [KtFile] might not necessarily be physical. As a fallback for non-physical [KtFile]s, [classFileOrigins] are instead used to map - * the class file name to the original [KtFile]. [classFileOrigins] cannot be used on their own, because some class files are - * generated without an originating PSI file (see the explanation in [ClassFileOrigins]). + * An [KtCompiledFile] is linked to its source [KtFile] via [KtCompiledFile.sourceFiles]. + * However, all source files are physical, while a [KtFile] might not necessarily be physical. + * As a fallback for non-physical [KtFile]s, [classFileOrigins] are instead used to map the class file name to the original [KtFile]. + * [classFileOrigins] cannot be used on their own, because some class files are generated without an originating PSI file + * (see the explanation in [ClassFileOrigins]). * * If this approach for some reason filters out all output files, the full list is returned defensively. */ - private fun getRelevantOutputFiles(state: GenerationState, classFileOrigins: ClassFileOrigins, ktFile: KtFile): List { + private fun getRelevantClassFiles( + ktFile: KtFile, + outputFiles: List, + classFileOrigins: ClassFileOrigins + ): List { + val classFiles = outputFiles.filter { it.isClassFile } val sourceFile = File(ktFile.virtualFile.path) - val outputFiles = state.factory.asList() - return outputFiles.filter { outputFile -> - outputFile.sourceFiles.any { it == sourceFile } || classFileOrigins[outputFile.relativePath]?.contains(ktFile) == true - }.ifEmpty { outputFiles } + + return classFiles + .filter { sourceFile in it.sourceFiles || ktFile in classFileOrigins[it.path].orEmpty() } + .ifEmpty { classFiles } } - fun compileSingleFile(ktFile: KtFile, initialConfiguration: CompilerConfiguration): Pair? = - KotlinCompilerIde( - ktFile, - initialConfiguration, - ClassBuilderFactories.TEST, - shouldStubUnboundIrSymbols = true, - ).compileTracingOrigin() + @ApiStatus.Internal + fun KtAnalysisSession.compileSingleFile( + ktFile: KtFile, + configuration: CompilerConfiguration + ): Pair? { + val effectiveConfiguration = configuration + .copy() + .apply { + put(STUB_UNBOUND_IR_SYMBOLS, true) + } + + val builderFactory = OriginTracingClassBuilderFactory(ClassBuilderFactories.TEST) + val compilerTarget = KtCompilerTarget.Jvm(builderFactory) + val allowedErrorFilter = KotlinCompilerIdeAllowedErrorFilter.getInstance() + + try { + val result = compile(ktFile, effectiveConfiguration, compilerTarget, allowedErrorFilter) + return Pair(result, builderFactory.classFileOrigins) + } catch (e: ProcessCanceledException) { + throw e + } catch (e: Throwable) { + LOG.error(e) + return null + } + } private fun mapLines(text: String, startLine: Int, endLine: Int): Pair { @Suppress("NAME_SHADOWING") diff --git a/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/internal/Location.java b/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/actions/bytecode/Location.java similarity index 90% rename from plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/internal/Location.java rename to plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/actions/bytecode/Location.java index cdbf81d0a0f7..f3246247f223 100644 --- a/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/internal/Location.java +++ b/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/actions/bytecode/Location.java @@ -1,9 +1,8 @@ -// 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-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package org.jetbrains.kotlin.idea.internal; +package org.jetbrains.kotlin.idea.actions.bytecode; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; @@ -13,7 +12,7 @@ import org.jetbrains.kotlin.psi.KtFile; import java.util.Objects; -public class Location { +class Location { @Nullable final Editor editor; diff --git a/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/actions/ShowKotlinBytecodeAction.kt b/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/actions/bytecode/ShowKotlinBytecodeAction.kt similarity index 87% rename from plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/actions/ShowKotlinBytecodeAction.kt rename to plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/actions/bytecode/ShowKotlinBytecodeAction.kt index 6c4bede50a99..0e2a7f35db84 100644 --- a/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/actions/ShowKotlinBytecodeAction.kt +++ b/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/actions/bytecode/ShowKotlinBytecodeAction.kt @@ -1,6 +1,6 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package org.jetbrains.kotlin.idea.actions +package org.jetbrains.kotlin.idea.actions.bytecode import com.intellij.openapi.actionSystem.ActionUpdateThread import com.intellij.openapi.actionSystem.AnAction @@ -11,11 +11,10 @@ import com.intellij.openapi.wm.ToolWindowManager import com.intellij.ui.content.ContentFactory import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.KotlinIcons -import org.jetbrains.kotlin.idea.internal.KotlinBytecodeToolWindow private const val TOOLWINDOW_ID = "Kotlin Bytecode" -class ShowKotlinBytecodeAction : AnAction() { +internal class ShowKotlinBytecodeAction : AnAction() { override fun actionPerformed(e: AnActionEvent) { val project = e.project ?: return val toolWindowManager = ToolWindowManager.getInstance(project) diff --git a/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/scratch/compile/KtScratchExecutionSession.kt b/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/scratch/compile/KtScratchExecutionSession.kt index fa3867b1ea4d..06192559a4a3 100644 --- a/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/scratch/compile/KtScratchExecutionSession.kt +++ b/plugins/kotlin/jvm/src/org/jetbrains/kotlin/idea/scratch/compile/KtScratchExecutionSession.kt @@ -11,6 +11,7 @@ import com.intellij.execution.target.local.LocalTargetEnvironmentRequest import com.intellij.openapi.application.runReadAction import com.intellij.openapi.diagnostic.ControlFlowException import com.intellij.openapi.module.Module +import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.progress.Task import com.intellij.openapi.project.DumbService @@ -18,8 +19,17 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.util.Computable import com.intellij.openapi.util.NlsContexts import com.intellij.openapi.util.io.FileUtil +import org.jetbrains.kotlin.analysis.api.analyze +import org.jetbrains.kotlin.analysis.api.components.KtCompilationResult +import org.jetbrains.kotlin.analysis.api.components.KtCompilerTarget +import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnostic +import org.jetbrains.kotlin.codegen.ClassBuilderFactories +import org.jetbrains.kotlin.config.CommonConfigurationKeys +import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.idea.KotlinJvmBundle -import org.jetbrains.kotlin.idea.core.KotlinCompilerIde +import org.jetbrains.kotlin.idea.base.codeInsight.compiler.compileToDirectory +import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings +import org.jetbrains.kotlin.idea.base.util.module import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager import org.jetbrains.kotlin.idea.scratch.LOG import org.jetbrains.kotlin.idea.scratch.ScratchExpression @@ -145,8 +155,38 @@ class KtScratchExecutionSession( val tmpDir = FileUtil.createTempDirectory("compile", "scratch") LOG.printDebugMessage("Temp output dir: ${tmpDir.path}") - KotlinCompilerIde(psiFile).compileToDirectory(tmpDir) - return tmpDir + val result = analyze(psiFile) { + val configuration = CompilerConfiguration().apply { + val containingModule = psiFile.module + if (containingModule != null) { + put(CommonConfigurationKeys.MODULE_NAME, containingModule.name) + } + + put(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS, psiFile.languageVersionSettings) + } + + try { + val compilerTarget = KtCompilerTarget.Jvm(ClassBuilderFactories.BINARIES) + val allowedErrorFilter: (KtDiagnostic) -> Boolean = { false } + + compileToDirectory(psiFile, configuration, compilerTarget, allowedErrorFilter, tmpDir) + } catch (e: ProcessCanceledException) { + throw e + } catch (e: Throwable) { + LOG.error(e) + return null + } + } + + when (result) { + is KtCompilationResult.Failure -> { + LOG.warn("Errors found on analyzing the scratch file. Compilation aborted") + return null + } + is KtCompilationResult.Success -> { + return tmpDir + } + } } private fun createCommandLine(originalFile: KtFile, module: Module?, mainClassName: String, tempOutDir: String): Pair { diff --git a/plugins/kotlin/k2-fe10-bindings/kotlin.k2.fe10-bindings.iml b/plugins/kotlin/k2-fe10-bindings/kotlin.k2.fe10-bindings.iml index 43edd9aff6f6..19039435dd5e 100644 --- a/plugins/kotlin/k2-fe10-bindings/kotlin.k2.fe10-bindings.iml +++ b/plugins/kotlin/k2-fe10-bindings/kotlin.k2.fe10-bindings.iml @@ -53,6 +53,6 @@ - + \ No newline at end of file diff --git a/plugins/kotlin/kotlin.performanceExtendedPlugin/src/com/intellij/performance/performancePlugin/commands/ClearSourceCaches.java b/plugins/kotlin/kotlin.performanceExtendedPlugin/src/com/intellij/performance/performancePlugin/commands/ClearSourceCaches.java index a4f8e3eb9d91..5c3a5aaa7d3b 100644 --- a/plugins/kotlin/kotlin.performanceExtendedPlugin/src/com/intellij/performance/performancePlugin/commands/ClearSourceCaches.java +++ b/plugins/kotlin/kotlin.performanceExtendedPlugin/src/com/intellij/performance/performancePlugin/commands/ClearSourceCaches.java @@ -11,8 +11,7 @@ import com.jetbrains.performancePlugin.utils.ActionCallbackProfilerStopper; import org.jetbrains.annotations.NotNull; import org.jetbrains.concurrency.Promise; import org.jetbrains.concurrency.Promises; -import org.jetbrains.kotlin.analysis.api.session.KtAnalysisSessionProvider; -import org.jetbrains.kotlin.analysis.providers.KotlinModificationTrackerFactory; +import org.jetbrains.kotlin.analysis.providers.KotlinGlobalModificationService; import org.jetbrains.kotlin.idea.caches.trackers.KotlinIDEModificationTrackerService; public class ClearSourceCaches extends AbstractCommand { @@ -32,8 +31,7 @@ public class ClearSourceCaches extends AbstractCommand { PsiManager.getInstance(project).dropPsiCaches(); KotlinIDEModificationTrackerService.Companion.invalidateCaches(project); if (System.getProperty("idea.kotlin.plugin.use.k2", "false").equals("true")) { - KtAnalysisSessionProvider.Companion.getInstance(project).clearCaches(); - project.getService(KotlinModificationTrackerFactory.class).incrementModificationsCount(false); + KotlinGlobalModificationService.Companion.getInstance(project).publishGlobalSourceModuleStateModification(); } actionCallback.setDone(); }); diff --git a/plugins/kotlin/kotlin.searching/kotlin.searching.k2.iml b/plugins/kotlin/kotlin.searching/kotlin.searching.k2.iml index 68c3c58aeaea..2ecbe5d53ebd 100644 --- a/plugins/kotlin/kotlin.searching/kotlin.searching.k2.iml +++ b/plugins/kotlin/kotlin.searching/kotlin.searching.k2.iml @@ -40,5 +40,6 @@ + \ No newline at end of file diff --git a/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/KotlinK2FindUsagesSupport.kt b/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/KotlinK2FindUsagesSupport.kt index 12a46d544320..e1a8ab0e6e2c 100644 --- a/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/KotlinK2FindUsagesSupport.kt +++ b/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/KotlinK2FindUsagesSupport.kt @@ -13,7 +13,7 @@ import com.intellij.psi.util.PsiFormatUtilBase import com.intellij.util.Processor import org.jetbrains.annotations.Nls import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.analyzeInModalWindow +import org.jetbrains.kotlin.idea.base.analysis.api.utils.analyzeInModalWindow import org.jetbrains.kotlin.analysis.api.calls.* import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.KtRendererAnnotationsFilter import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtDeclarationRenderer diff --git a/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/KotlinK2SearchUsagesSupport.kt b/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/KotlinK2SearchUsagesSupport.kt index 401c7b813d86..05fa346c4dd2 100644 --- a/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/KotlinK2SearchUsagesSupport.kt +++ b/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/KotlinK2SearchUsagesSupport.kt @@ -3,6 +3,7 @@ package org.jetbrains.kotlin.idea.searching.usages import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.application.runReadAction import com.intellij.openapi.module.Module import com.intellij.openapi.progress.ProgressManager import com.intellij.psi.* @@ -123,37 +124,45 @@ internal class KotlinK2SearchUsagesSupport : KotlinSearchUsagesSupport { } } + context(KtAnalysisSession) + private fun containerSymbol(symbol: KtCallableSymbol): KtDeclarationSymbol? { + return symbol.getContainingSymbol() ?: symbol.receiverType?.expandedClassSymbol + } + override fun isUsageInContainingDeclaration(reference: PsiReference, declaration: KtNamedDeclaration): Boolean { - analyze(declaration) { + val container = analyze(declaration) { val symbol = declaration.getSymbol() as? KtCallableSymbol ?: return false - fun container(symbol: KtCallableSymbol): KtDeclarationSymbol? { - return symbol.getContainingSymbol() ?: symbol.receiverType?.expandedClassSymbol + containerSymbol(symbol)?.psi?.originalElement ?: return false + } + return reference.unwrappedTargets.filterIsInstance().any { candidateDeclaration -> + if (candidateDeclaration == declaration) return@any false + if (candidateDeclaration.receiverTypeReference == null && candidateDeclaration.containingFile != container.containingFile) { + return@any false } - val containerSymbol = container(symbol) ?: return false - return reference.unwrappedTargets.filterIsInstance(KtDeclaration::class.java).any { candidateDeclaration -> + analyze(candidateDeclaration) { val candidateSymbol = candidateDeclaration.getSymbol() - candidateSymbol is KtCallableSymbol && candidateSymbol != symbol && container(candidateSymbol) == containerSymbol + candidateSymbol is KtCallableSymbol && candidateDeclaration != declaration && containerSymbol(candidateSymbol)?.psi == container } } } - override fun isExtensionOfDeclarationClassUsage(reference: PsiReference, declaration: KtNamedDeclaration): Boolean { if (declaration !is KtCallableDeclaration) return false - analyze(declaration) { - fun KtClassOrObjectSymbol.isContainerReceiverFor( - candidateSymbol: KtDeclarationSymbol - ): Boolean { - val receiverType = (candidateSymbol as? KtCallableSymbol)?.receiverType ?: return false - val expandedClassSymbol = receiverType.expandedClassSymbol ?: return false - return expandedClassSymbol == this || this.isSubClassOf(expandedClassSymbol) - } + val container = analyze(declaration) { + (declaration.getSymbol().getContainingSymbol() as? KtClassOrObjectSymbol)?.psi?.originalElement as? KtClassOrObject ?: return false + } - val symbol = declaration.getSymbol() - val containerSymbol = symbol.getContainingSymbol() as? KtClassOrObjectSymbol ?: return false - return reference.unwrappedTargets.filterIsInstance(KtDeclaration::class.java).any { candidateDeclaration -> - val candidateSymbol = candidateDeclaration.getSymbol() - candidateSymbol != symbol && containerSymbol.isContainerReceiverFor(candidateSymbol) + return reference.unwrappedTargets.filterIsInstance().any { candidateDeclaration -> + if (candidateDeclaration == declaration) return@any false + if (candidateDeclaration !is KtCallableDeclaration || candidateDeclaration.receiverTypeReference == null) return@any false + analyze(candidateDeclaration) { + if (!container.canBeAnalysed()) return@any false + val containerSymbol = container.getSymbol() as? KtClassOrObjectSymbol ?: return@any false + + val receiverType = (candidateDeclaration.getSymbol() as? KtCallableSymbol)?.receiverType ?: return@any false + val expandedClassSymbol = receiverType.expandedClassSymbol ?: return@any false + + expandedClassSymbol == containerSymbol || containerSymbol.isSubClassOf(expandedClassSymbol) } } } @@ -161,7 +170,7 @@ internal class KotlinK2SearchUsagesSupport : KotlinSearchUsagesSupport { override fun getReceiverTypeSearcherInfo(psiElement: PsiElement, isDestructionDeclarationSearch: Boolean): ReceiverTypeSearcherInfo? { return when (psiElement) { is KtCallableDeclaration -> { - analyzeWithReadAction(psiElement) { + analyze(psiElement) { fun getPsiClassOfKtType(ktType: KtType): PsiClass? { val psi = ktType.asPsiType(psiElement, allowErrorTypes = false, KtTypeMappingMode.DEFAULT, isAnnotationMethod = false) return (psi as? PsiClassReferenceType)?.resolve() @@ -170,22 +179,24 @@ internal class KotlinK2SearchUsagesSupport : KotlinSearchUsagesSupport { is KtValueParameterSymbol -> { // TODO: The following code handles only constructors. Handle other cases e.g., // look for uses of component functions cf [isDestructionDeclarationSearch] - val psiClass = PsiTreeUtil.getParentOfType(psiElement, KtClassOrObject::class.java)?.toLightClass() ?: return@analyzeWithReadAction null + val psiClass = PsiTreeUtil.getParentOfType(psiElement, KtClassOrObject::class.java)?.toLightClass() ?: return@analyze null val classPointer = psiClass.createSmartPointer() ReceiverTypeSearcherInfo(psiClass) { declaration -> - analyzeWithReadAction(declaration) { - fun KtType.containsClassType(clazz: PsiClass?): Boolean { - if (clazz == null) return false - return this is KtNonErrorClassType && (clazz.unwrapped?.isEquivalentTo(classSymbol.psi) == true || ownTypeArguments.any { arg -> - when (arg) { - is KtStarTypeProjection -> false - is KtTypeArgumentWithVariance -> arg.type.containsClassType(clazz) - } - }) - } + runReadAction { + analyze(declaration) { + fun KtType.containsClassType(clazz: PsiClass?): Boolean { + if (clazz == null) return false + return this is KtNonErrorClassType && (clazz.unwrapped?.isEquivalentTo(classSymbol.psi) == true || ownTypeArguments.any { arg -> + when (arg) { + is KtStarTypeProjection -> false + is KtTypeArgumentWithVariance -> arg.type.containsClassType(clazz) + } + }) + } - declaration.getReturnKtType().containsClassType(classPointer.element) + declaration.getReturnKtType().containsClassType(classPointer.element) + } } } } @@ -288,7 +299,7 @@ internal class KotlinK2SearchUsagesSupport : KotlinSearchUsagesSupport { override fun isInheritable(ktClass: KtClass): Boolean { if (ApplicationManager.getApplication().isDispatchThread) { return ProgressManager.getInstance().runProcessWithProgressSynchronously( - Runnable { isOverridableBySymbol(ktClass) }, + Runnable { runReadAction { isOverridableBySymbol(ktClass) } }, KotlinBundle.message("dialog.title.resolving.inheritable.status"), true, ktClass.project @@ -297,12 +308,12 @@ internal class KotlinK2SearchUsagesSupport : KotlinSearchUsagesSupport { return isOverridableBySymbol(ktClass) } - private fun isOverridableBySymbol(declaration: KtDeclaration) = analyzeWithReadAction(declaration) { + private fun isOverridableBySymbol(declaration: KtDeclaration) = analyze(declaration) { var declarationSymbol : KtSymbol? = declaration.getSymbol() if (declarationSymbol is KtValueParameterSymbol) { declarationSymbol = declarationSymbol.generatedPrimaryConstructorProperty } - val symbol = declarationSymbol as? KtSymbolWithModality ?: return@analyzeWithReadAction false + val symbol = declarationSymbol as? KtSymbolWithModality ?: return@analyze false when (symbol.modality) { Modality.OPEN, Modality.SEALED, Modality.ABSTRACT -> true Modality.FINAL -> false diff --git a/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/KotlinK2UsageTypeProvider.kt b/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/KotlinK2UsageTypeProvider.kt index 7d7cfa317b5e..db3baeb1f572 100644 --- a/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/KotlinK2UsageTypeProvider.kt +++ b/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/KotlinK2UsageTypeProvider.kt @@ -3,7 +3,7 @@ package org.jetbrains.kotlin.idea.searching.usages import com.intellij.psi.PsiPackage -import org.jetbrains.kotlin.analysis.api.analyzeWithReadAction +import org.jetbrains.kotlin.analysis.api.analyze import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.idea.base.searching.usages.KotlinUsageTypeProvider import org.jetbrains.kotlin.idea.base.searching.usages.UsageTypeEnum @@ -46,7 +46,7 @@ internal class KotlinK2UsageTypeProvider : KotlinUsageTypeProvider() { } } - return analyzeWithReadAction(refExpr) { + return analyze(refExpr) { when (val targetElement = reference.resolveToSymbol()) { is KtClassifierSymbol -> when (targetElement) { diff --git a/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/findUsagesUtils.kt b/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/findUsagesUtils.kt index 7b4dc9edfcc6..6f3dbbcf86e8 100644 --- a/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/findUsagesUtils.kt +++ b/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/findUsagesUtils.kt @@ -2,7 +2,7 @@ package org.jetbrains.kotlin.idea.searching.usages import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.analyzeWithReadAction +import org.jetbrains.kotlin.analysis.api.analyze import org.jetbrains.kotlin.analysis.api.calls.KtCall import org.jetbrains.kotlin.analysis.api.calls.calls import org.jetbrains.kotlin.idea.base.facet.platform.platform @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.ImportPath internal inline fun withResolvedCall(element: KtElement, crossinline block: KtAnalysisSession.(KtCall) -> R): R? { - return analyzeWithReadAction(element) { + return analyze(element) { element.resolveCall()?.calls?.singleOrNull()?.let { block(it) } } } diff --git a/plugins/kotlin/maven/tests/test/org/jetbrains/kotlin/idea/maven/NavigateToMultiplatformJvmStdlibSourcesTest.kt b/plugins/kotlin/maven/tests/test/org/jetbrains/kotlin/idea/maven/NavigateToMultiplatformJvmStdlibSourcesTest.kt index 11b8d01b153f..c11eb6f067b0 100644 --- a/plugins/kotlin/maven/tests/test/org/jetbrains/kotlin/idea/maven/NavigateToMultiplatformJvmStdlibSourcesTest.kt +++ b/plugins/kotlin/maven/tests/test/org/jetbrains/kotlin/idea/maven/NavigateToMultiplatformJvmStdlibSourcesTest.kt @@ -29,7 +29,7 @@ class NavigateToMultipartJvmStdlibSourcesTest : LightJavaCodeInsightFixtureTestC mapOf("" to "").mapNotNull { } } """.trimIndent()) - assertEquals("", stdlibCommonElement?.moduleInfo?.name.toString()) + assertEquals("", stdlibCommonElement?.moduleInfo?.name.toString()) val stdlibJvmElement = configureAndResolve(""" fun bar() { diff --git a/plugins/kotlin/navigation/src/org/jetbrains/kotlin/idea/navigation/KotlinAnalysisApiBasedDeclarationNavigationPolicyImpl.kt b/plugins/kotlin/navigation/src/org/jetbrains/kotlin/idea/navigation/KotlinAnalysisApiBasedDeclarationNavigationPolicyImpl.kt index 742e12adbaa4..17611e892bd2 100644 --- a/plugins/kotlin/navigation/src/org/jetbrains/kotlin/idea/navigation/KotlinAnalysisApiBasedDeclarationNavigationPolicyImpl.kt +++ b/plugins/kotlin/navigation/src/org/jetbrains/kotlin/idea/navigation/KotlinAnalysisApiBasedDeclarationNavigationPolicyImpl.kt @@ -68,12 +68,20 @@ internal class KotlinAnalysisApiBasedDeclarationNavigationPolicyImpl : KotlinDec correspondingOwner.typeParameters.firstOrNull { it.name == declaration.name } } + is KtEnumEntry -> getCorrespondingEnumEntry(declaration, scope, project) is KtClassLikeDeclaration -> getCorrespondingClassLikeDeclaration(declaration, scope, project) is KtCallableDeclaration -> getCorrespondingCallableDeclaration(declaration, scope, project) else -> null } } + private fun getCorrespondingEnumEntry(declaration: KtEnumEntry, scope: GlobalSearchScope, project: Project): KtEnumEntry? { + val enumClass = declaration.containingClassOrObject ?: return null + val classLikeDeclaration = getCorrespondingClassLikeDeclaration(enumClass, scope, project) as? KtClass ?: return null + val enumEntryName = declaration.name + return classLikeDeclaration.declarations.firstOrNull { it is KtEnumEntry && it.name == enumEntryName } as? KtEnumEntry + } + private fun getCorrespondingClassLikeDeclaration( declaration: KtClassLikeDeclaration, scope: GlobalSearchScope, diff --git a/plugins/kotlin/navigation/tests/test/org/jetbrains/kotlin/idea/k2/navigation/AbstractKotlinNavigationToLibrarySourceTest.kt b/plugins/kotlin/navigation/tests/test/org/jetbrains/kotlin/idea/k2/navigation/AbstractKotlinNavigationToLibrarySourceTest.kt index f45317b4d006..3eaca8b5bbf9 100644 --- a/plugins/kotlin/navigation/tests/test/org/jetbrains/kotlin/idea/k2/navigation/AbstractKotlinNavigationToLibrarySourceTest.kt +++ b/plugins/kotlin/navigation/tests/test/org/jetbrains/kotlin/idea/k2/navigation/AbstractKotlinNavigationToLibrarySourceTest.kt @@ -45,7 +45,7 @@ abstract class AbstractKotlinNavigationToLibrarySourceTest : AbstractReferenceRe } private fun KtNamedDeclaration.signatureText(): String { - val firstElement = children.first { it !is PsiComment && it !is PsiWhiteSpace } + val firstElement = children.firstOrNull { it !is PsiComment && it !is PsiWhiteSpace } ?: return nameAsSafeName.asString() val endOffset = when (this) { is KtNamedFunction -> typeReference ?: valueParameterList?.rightParenthesis is KtProperty -> typeReference ?: equalsToken?.getPrevSiblingIgnoringWhitespace() diff --git a/plugins/kotlin/navigation/tests/test/org/jetbrains/kotlin/idea/k2/navigation/KotlinNavigationToLibrarySourceTestGenerated.java b/plugins/kotlin/navigation/tests/test/org/jetbrains/kotlin/idea/k2/navigation/KotlinNavigationToLibrarySourceTestGenerated.java index 60a725775e1e..a8ffcb402864 100644 --- a/plugins/kotlin/navigation/tests/test/org/jetbrains/kotlin/idea/k2/navigation/KotlinNavigationToLibrarySourceTestGenerated.java +++ b/plugins/kotlin/navigation/tests/test/org/jetbrains/kotlin/idea/k2/navigation/KotlinNavigationToLibrarySourceTestGenerated.java @@ -49,6 +49,11 @@ public abstract class KotlinNavigationToLibrarySourceTestGenerated extends Abstr runTest("testData/navigationToLibrarySourcePolicy/resolveToStdlib/classfiers/class.kt"); } + @TestMetadata("enumEntry.kt") + public void testEnumEntry() throws Exception { + runTest("testData/navigationToLibrarySourcePolicy/resolveToStdlib/classfiers/enumEntry.kt"); + } + @TestMetadata("unnamedCompanion.kt") public void testUnnamedCompanion() throws Exception { runTest("testData/navigationToLibrarySourcePolicy/resolveToStdlib/classfiers/unnamedCompanion.kt"); diff --git a/plugins/kotlin/navigation/tests/testData/navigationToLibrarySourcePolicy/resolveToStdlib/classfiers/enumEntry.kt b/plugins/kotlin/navigation/tests/testData/navigationToLibrarySourcePolicy/resolveToStdlib/classfiers/enumEntry.kt new file mode 100644 index 000000000000..3552083b3020 --- /dev/null +++ b/plugins/kotlin/navigation/tests/testData/navigationToLibrarySourcePolicy/resolveToStdlib/classfiers/enumEntry.kt @@ -0,0 +1,6 @@ +@Deprecated( + "deprecated message", + level = DeprecationLevel.ERROR +) +val p = 0 +// REF: (kotlin.DeprecationLevel.ERROR) ERROR diff --git a/plugins/kotlin/performance-tests/test/org/jetbrains/kotlin/idea/perf/synthetic/PerformanceBasicCompletionHandlerTestGenerated.java b/plugins/kotlin/performance-tests/test/org/jetbrains/kotlin/idea/perf/synthetic/PerformanceBasicCompletionHandlerTestGenerated.java index 9932d2e25db5..6c7f0330abf2 100644 --- a/plugins/kotlin/performance-tests/test/org/jetbrains/kotlin/idea/perf/synthetic/PerformanceBasicCompletionHandlerTestGenerated.java +++ b/plugins/kotlin/performance-tests/test/org/jetbrains/kotlin/idea/perf/synthetic/PerformanceBasicCompletionHandlerTestGenerated.java @@ -153,6 +153,34 @@ public abstract class PerformanceBasicCompletionHandlerTestGenerated extends Abs } } + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../completion/testData/handlers/basic/contextReceivers") + public static class ContextReceivers extends AbstractPerformanceBasicCompletionHandlerTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doPerfTest, this, testDataFilePath); + } + + @TestMetadata("WithoutDeclaration.kt") + public void testWithoutDeclaration() throws Exception { + runTest("../completion/testData/handlers/basic/contextReceivers/WithoutDeclaration.kt"); + } + + @TestMetadata("WithoutDeclarationNestedClass.kt") + public void testWithoutDeclarationNestedClass() throws Exception { + runTest("../completion/testData/handlers/basic/contextReceivers/WithoutDeclarationNestedClass.kt"); + } + + @TestMetadata("WithoutDeclarationNestedClass2.kt") + public void testWithoutDeclarationNestedClass2() throws Exception { + runTest("../completion/testData/handlers/basic/contextReceivers/WithoutDeclarationNestedClass2.kt"); + } + + @TestMetadata("WithoutDeclarationTypeArgument.kt") + public void testWithoutDeclarationTypeArgument() throws Exception { + runTest("../completion/testData/handlers/basic/contextReceivers/WithoutDeclarationTypeArgument.kt"); + } + } + @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("../completion/testData/handlers/basic/defaultImports") public static class DefaultImports extends AbstractPerformanceBasicCompletionHandlerTest { diff --git a/plugins/kotlin/performance-tests/test/org/jetbrains/kotlin/idea/perf/synthetic/PerformanceKeywordCompletionHandlerTestGenerated.java b/plugins/kotlin/performance-tests/test/org/jetbrains/kotlin/idea/perf/synthetic/PerformanceKeywordCompletionHandlerTestGenerated.java index 40db1babb1c9..97109604f2fa 100644 --- a/plugins/kotlin/performance-tests/test/org/jetbrains/kotlin/idea/perf/synthetic/PerformanceKeywordCompletionHandlerTestGenerated.java +++ b/plugins/kotlin/performance-tests/test/org/jetbrains/kotlin/idea/perf/synthetic/PerformanceKeywordCompletionHandlerTestGenerated.java @@ -113,6 +113,16 @@ public class PerformanceKeywordCompletionHandlerTestGenerated extends AbstractPe runTest("../completion/testData/handlers/keywords/ConstructorPrimary.kt"); } + @TestMetadata("Context.kt") + public void testContext() throws Exception { + runTest("../completion/testData/handlers/keywords/Context.kt"); + } + + @TestMetadata("ContextWithoutDeclaration.kt") + public void testContextWithoutDeclaration() throws Exception { + runTest("../completion/testData/handlers/keywords/ContextWithoutDeclaration.kt"); + } + @TestMetadata("Do.kt") public void testDo() throws Exception { runTest("../completion/testData/handlers/keywords/Do.kt"); diff --git a/plugins/kotlin/plugin/common/resources/META-INF/caches.xml b/plugins/kotlin/plugin/common/resources/META-INF/caches.xml index ce5642a73d34..08683a21dadf 100644 --- a/plugins/kotlin/plugin/common/resources/META-INF/caches.xml +++ b/plugins/kotlin/plugin/common/resources/META-INF/caches.xml @@ -25,6 +25,9 @@ + diff --git a/plugins/kotlin/plugin/common/resources/META-INF/jvm-debugger.xml b/plugins/kotlin/plugin/common/resources/META-INF/jvm-debugger.xml index f8c47af5f12b..6550f4119e6d 100644 --- a/plugins/kotlin/plugin/common/resources/META-INF/jvm-debugger.xml +++ b/plugins/kotlin/plugin/common/resources/META-INF/jvm-debugger.xml @@ -47,6 +47,7 @@ + diff --git a/plugins/kotlin/plugin/common/resources/META-INF/jvm.xml b/plugins/kotlin/plugin/common/resources/META-INF/jvm.xml new file mode 100644 index 000000000000..3fcfb4f52f9a --- /dev/null +++ b/plugins/kotlin/plugin/common/resources/META-INF/jvm.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/plugins/kotlin/plugin/common/resources/META-INF/kotlin-core.xml b/plugins/kotlin/plugin/common/resources/META-INF/kotlin-core.xml index 446b908c7980..a50f642f7c71 100644 --- a/plugins/kotlin/plugin/common/resources/META-INF/kotlin-core.xml +++ b/plugins/kotlin/plugin/common/resources/META-INF/kotlin-core.xml @@ -84,6 +84,9 @@ + diff --git a/plugins/kotlin/plugin/k1/kotlin.plugin.k1.iml b/plugins/kotlin/plugin/k1/kotlin.plugin.k1.iml index 8d586e31619c..6a38d2feb3c9 100644 --- a/plugins/kotlin/plugin/k1/kotlin.plugin.k1.iml +++ b/plugins/kotlin/plugin/k1/kotlin.plugin.k1.iml @@ -29,7 +29,8 @@ - + + @@ -45,6 +46,7 @@ + diff --git a/plugins/kotlin/plugin/k1/resources/META-INF/jvm-debugger-fe10.xml b/plugins/kotlin/plugin/k1/resources/META-INF/jvm-debugger-fe10.xml index 41d0a64da2ba..c5fd963eedee 100644 --- a/plugins/kotlin/plugin/k1/resources/META-INF/jvm-debugger-fe10.xml +++ b/plugins/kotlin/plugin/k1/resources/META-INF/jvm-debugger-fe10.xml @@ -5,9 +5,13 @@ serviceInterface="org.jetbrains.kotlin.idea.debugger.core.KotlinDebuggerLegacyFacade" serviceImplementation="org.jetbrains.kotlin.idea.debugger.fe10.core.Fe10KotlinDebuggerLegacyFacade"/> - + + + @@ -17,7 +21,6 @@ - + + - - + diff --git a/plugins/kotlin/plugin/k1/resources/META-INF/kotlin-core-fe10.xml b/plugins/kotlin/plugin/k1/resources/META-INF/kotlin-core-fe10.xml index 38e5d673957e..aac90b1413b9 100644 --- a/plugins/kotlin/plugin/k1/resources/META-INF/kotlin-core-fe10.xml +++ b/plugins/kotlin/plugin/k1/resources/META-INF/kotlin-core-fe10.xml @@ -25,6 +25,9 @@ + - + @@ -72,6 +72,7 @@ + @@ -93,7 +94,7 @@ - + diff --git a/plugins/kotlin/plugin/k2/resources/META-INF/codeInsights.xml b/plugins/kotlin/plugin/k2/resources/META-INF/codeInsights.xml index eaee60db5f82..8cddd4dfaa36 100644 --- a/plugins/kotlin/plugin/k2/resources/META-INF/codeInsights.xml +++ b/plugins/kotlin/plugin/k2/resources/META-INF/codeInsights.xml @@ -4,5 +4,8 @@ + diff --git a/plugins/kotlin/plugin/k2/resources/META-INF/jvm-debugger-k2.xml b/plugins/kotlin/plugin/k2/resources/META-INF/jvm-debugger-k2.xml new file mode 100644 index 000000000000..f4ee9510e846 --- /dev/null +++ b/plugins/kotlin/plugin/k2/resources/META-INF/jvm-debugger-k2.xml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/plugins/kotlin/plugin/k2/resources/META-INF/k2.xml b/plugins/kotlin/plugin/k2/resources/META-INF/k2.xml index 009a9d2b4bd9..17b48e176190 100644 --- a/plugins/kotlin/plugin/k2/resources/META-INF/k2.xml +++ b/plugins/kotlin/plugin/k2/resources/META-INF/k2.xml @@ -27,12 +27,14 @@ + + @@ -208,6 +210,8 @@ + + diff --git a/plugins/kotlin/plugin/k2/resources/META-INF/lowLevelApiFir.xml b/plugins/kotlin/plugin/k2/resources/META-INF/lowLevelApiFir.xml index e6f28d6ec72a..c9d7d5326897 100644 --- a/plugins/kotlin/plugin/k2/resources/META-INF/lowLevelApiFir.xml +++ b/plugins/kotlin/plugin/k2/resources/META-INF/lowLevelApiFir.xml @@ -27,6 +27,7 @@ serviceImplementation="org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization.JvmStubBasedDeserializedSymbolProviderFactory"/> + \ No newline at end of file diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/chooseContainer/chooseContainerUtil.kt b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/chooseContainer/chooseContainerUtil.kt index a1379f954383..bdf04cc2cddc 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/chooseContainer/chooseContainerUtil.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/chooseContainer/chooseContainerUtil.kt @@ -145,9 +145,9 @@ private fun getPsiElementPopup( .presentationProvider(presentationProvider) .builderConsumer { builder -> builder - .setItemChosenCallback { presentation -> + .setItemSelectedCallback() { presentation -> highlighter?.dropHighlight() - val psiElement = (presentation?.item as? SmartPsiElementPointer<*>)?.element ?: return@setItemChosenCallback + val psiElement = (presentation?.item as? SmartPsiElementPointer<*>)?.element ?: return@setItemSelectedCallback highlighter?.highlight(psiElement) } .setItemChosenCallback { diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/rename/handlers/RenameSyntheticDeclarationByReferenceHandler.kt b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/rename/handlers/RenameSyntheticDeclarationByReferenceHandler.kt index 350df0b8698d..82ab0b0a1a87 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/rename/handlers/RenameSyntheticDeclarationByReferenceHandler.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/rename/handlers/RenameSyntheticDeclarationByReferenceHandler.kt @@ -3,6 +3,7 @@ package org.jetbrains.kotlin.idea.refactoring.rename.handlers import com.intellij.openapi.util.NlsContexts.DialogMessage import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin import org.jetbrains.kotlin.idea.base.resources.KotlinBundle @@ -10,7 +11,7 @@ import org.jetbrains.kotlin.idea.base.resources.KotlinBundle internal class RenameSyntheticDeclarationByReferenceHandler : AbstractForbidRenamingSymbolByReferenceHandler() { context(KtAnalysisSession) override fun shouldForbidRenaming(symbol: KtSymbol): Boolean { - return symbol.origin == KtSymbolOrigin.SOURCE_MEMBER_GENERATED + return symbol.origin == KtSymbolOrigin.SOURCE_MEMBER_GENERATED && !(symbol is KtConstructorSymbol && symbol.isPrimary) } override fun getErrorMessage(): @DialogMessage String { diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/introduceVariable/KotlinIntroduceVariableHandler.kt b/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/introduceVariable/KotlinIntroduceVariableHandler.kt index e12e784915ad..261a493c3109 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/introduceVariable/KotlinIntroduceVariableHandler.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/introduceVariable/KotlinIntroduceVariableHandler.kt @@ -21,11 +21,11 @@ import com.intellij.util.SmartList import org.jetbrains.kotlin.analysis.api.KtAllowAnalysisFromWriteAction import org.jetbrains.kotlin.analysis.api.KtAllowAnalysisOnEdt import org.jetbrains.kotlin.analysis.api.analyze -import org.jetbrains.kotlin.analysis.api.analyzeInModalWindow import org.jetbrains.kotlin.analysis.api.lifetime.allowAnalysisFromWriteAction import org.jetbrains.kotlin.analysis.api.lifetime.allowAnalysisOnEdt import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.KtRendererAnnotationsFilter import org.jetbrains.kotlin.analysis.api.renderer.types.impl.KtTypeRendererForSource +import org.jetbrains.kotlin.idea.base.analysis.api.utils.analyzeInModalWindow import org.jetbrains.kotlin.idea.base.analysis.api.utils.shortenReferences import org.jetbrains.kotlin.idea.base.codeInsight.KotlinDeclarationNameValidator import org.jetbrains.kotlin.idea.base.codeInsight.KotlinNameSuggester @@ -35,7 +35,7 @@ import org.jetbrains.kotlin.idea.base.codeInsight.ShortenReferencesFacility import org.jetbrains.kotlin.idea.base.psi.moveInsideParenthesesAndReplaceWith import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.codeinsight.utils.ConvertToBlockBodyUtils -import org.jetbrains.kotlin.idea.codeinsight.utils.getValueArgumentName +import org.jetbrains.kotlin.idea.codeinsight.utils.NamedArgumentUtils import org.jetbrains.kotlin.idea.refactoring.KotlinCommonRefactoringSettings import org.jetbrains.kotlin.idea.refactoring.chooseContainer.chooseContainerElementIfNecessary import org.jetbrains.kotlin.idea.refactoring.introduce.IntroduceRefactoringException @@ -88,7 +88,7 @@ object KotlinIntroduceVariableHandler : RefactoringActionHandler { val functionLiteralArgument = expressionToReplace.getStrictParentOfType()!! val argumentName = analyzeInModalWindow(expressionToReplace, KotlinBundle.message("find.usages.prepare.dialog.progress")) { - functionLiteralArgument.getValueArgumentName() + NamedArgumentUtils.getStableNameFor(functionLiteralArgument) } val newCallExpression = functionLiteralArgument.moveInsideParenthesesAndReplaceWith(replacement, argumentName) newCallExpression.valueArguments.last().getArgumentExpression()!! diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/introduceVariable/KotlinVariableInplaceIntroducer.kt b/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/introduceVariable/KotlinVariableInplaceIntroducer.kt index b12cb6bd7510..53ac220f4e51 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/introduceVariable/KotlinVariableInplaceIntroducer.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/introduceVariable/KotlinVariableInplaceIntroducer.kt @@ -24,7 +24,7 @@ import com.intellij.refactoring.rename.inplace.TemplateInlayUtil.createSettingsP import com.intellij.ui.dsl.builder.actionListener import com.intellij.ui.dsl.builder.panel import com.intellij.ui.dsl.builder.selected -import org.jetbrains.kotlin.analysis.api.analyzeInModalWindow +import org.jetbrains.kotlin.idea.base.analysis.api.utils.analyzeInModalWindow import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.codeinsights.impl.base.CallableReturnTypeUpdaterUtils import org.jetbrains.kotlin.idea.refactoring.KotlinCommonRefactoringSettings diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/introduceVariable/elementSelectionUtils.kt b/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/introduceVariable/elementSelectionUtils.kt index 2444d0e9be1e..6fe3643acbc3 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/introduceVariable/elementSelectionUtils.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/introduceVariable/elementSelectionUtils.kt @@ -10,7 +10,7 @@ import com.intellij.openapi.util.NlsSafe import com.intellij.platform.backend.presentation.TargetPresentation import com.intellij.psi.* import com.intellij.psi.util.PsiTreeUtil -import org.jetbrains.kotlin.analysis.api.analyzeInModalWindow +import org.jetbrains.kotlin.idea.base.analysis.api.utils.analyzeInModalWindow import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.refactoring.introduce.IntroduceRefactoringException import org.jetbrains.kotlin.idea.refactoring.renderTrimmed diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/introduceVariable/introduceVariableUtil.kt b/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/introduceVariable/introduceVariableUtil.kt index b392cf241704..10391b0b3984 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/introduceVariable/introduceVariableUtil.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.introduce.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/introduce/introduceVariable/introduceVariableUtil.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.idea.k2.refactoring.introduce.introduceVariable import com.intellij.openapi.editor.Editor import com.intellij.openapi.ui.popup.JBPopupFactory import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.analyzeInModalWindow +import org.jetbrains.kotlin.idea.base.analysis.api.utils.analyzeInModalWindow import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability import org.jetbrains.kotlin.idea.base.resources.KotlinBundle diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/resources/messages/KotlinK2RefactoringsBundle.properties b/plugins/kotlin/refactorings/kotlin.refactorings.k2/resources/messages/KotlinK2RefactoringsBundle.properties index 4726252653c1..9a614e1fd9c3 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/resources/messages/KotlinK2RefactoringsBundle.properties +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/resources/messages/KotlinK2RefactoringsBundle.properties @@ -1,3 +1,3 @@ override.declaration.x.overrides.y.in.class.list={0} overrides declarations in the following classes/interfaces: {1} Do you want to {2} the base declarations? -resolving.super.methods.progress.title=Resolving super methods\u2026 +resolving.super.methods.progress.title=Resolving Super Methods? safe.delete.implements.conflict.message={0} implements {1}. diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/K2ReferenceMutateService.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/K2ReferenceMutateService.kt index 603c783894f9..c0fe5163bbd8 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/K2ReferenceMutateService.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/K2ReferenceMutateService.kt @@ -73,46 +73,72 @@ internal class K2ReferenceMutateService : KtReferenceMutateServiceBase() { if (targetElement !is KtElement) operationNotSupportedInK2Error() // TODO fix reference shortener for non-Kotlin target elements val expression = simpleNameReference.expression if (fqName.isRoot) return expression + val importDirective = expression.parentOfType(withSelf = false) + if (importDirective != null) return importDirective.replaceWith(fqName) ?: expression return expression.containingKtFile.withOptimizedImports { val anchorElement = expression.parentOfType(withSelf = false) ?: expression.parentOfType(withSelf = false) + ?: expression.parent as? KtCallExpression? ?: expression when (anchorElement) { is KtUserType -> anchorElement.replaceWith(fqName) - is KtSimpleNameExpression -> anchorElement.replaceWith(fqName) is KtDotQualifiedExpression -> anchorElement.replaceWith(fqName) + is KtCallExpression -> anchorElement.replaceWith(fqName) + is KtSimpleNameExpression -> anchorElement.replaceWith(fqName) else -> null } } ?: expression } + private fun KtImportDirective.replaceWith(fqName: FqName): KtExpression? { + val newImportReferenceExpression = KtPsiFactory(project).createExpression(fqName.asString()) + return importedReference?.replaced(newImportReferenceExpression) + } + private fun KtTypeElement.replaceWith(fqName: FqName): KtTypeElement { val newReference = KtPsiFactory(project).createType(fqName.asString()).typeElement ?: error("Could not create type from $fqName") return replaced(newReference) } - private fun KtSimpleNameExpression.replaceWith(fqName: FqName): KtExpression { - val newNameExpression = KtPsiFactory(project).createExpression(fqName.asString()) - return replaced(newNameExpression) - } - private fun KtDotQualifiedExpression.replaceWith(fqName: FqName): KtExpression? { - val psiFactory = KtPsiFactory(project) val selectorExpression = selectorExpression ?: return null val newExpression = when (selectorExpression) { - is KtNameReferenceExpression -> { - psiFactory.createExpression(fqName.asString()) - } - is KtCallExpression -> { - val newName = psiFactory.createSimpleName(fqName.shortName().asString()) - selectorExpression.calleeExpression?.replace(newName) - val packageName = fqName.parent().asString() - psiFactory.createExpression("$packageName.${selectorExpression.text}") - } - else -> return null - } - return replaced(newExpression) + is KtSimpleNameExpression -> selectorExpression.replaceShortName(fqName) + is KtCallExpression -> selectorExpression.replaceShortName(fqName) + else -> null + } ?: return null + return replaceWithQualified(fqName, newExpression) + } + + private fun KtExpression.replaceWithQualified(fqName: FqName, selectorExpression: KtExpression): KtExpression { + val parentFqName = fqName.parent() + if (parentFqName.isRoot) return selectorExpression + val packageName = fqName.parent().asString() + val newQualifiedExpression = KtPsiFactory(project).createExpression("$packageName.${selectorExpression.text}") + return replaced(newQualifiedExpression) + } + + private fun KtCallExpression.replaceWith(fqName: FqName): KtExpression { + val newCall = replaceShortName(fqName) + return newCall.replaceWithQualified(fqName, newCall) + } + + private fun KtCallExpression.replaceShortName(fqName: FqName): KtExpression { + val psiFactory = KtPsiFactory(project) + val newName = psiFactory.createSimpleName(fqName.shortName().asString()) + calleeExpression?.replace(newName) + return this + } + + private fun KtSimpleNameExpression.replaceWith(fqName: FqName): KtExpression { + val newNameExpr = replaceShortName(fqName) + return newNameExpr.replaceWithQualified(fqName, newNameExpr) + } + + private fun KtSimpleNameExpression.replaceShortName(fqName: FqName): KtExpression { + val newNameExpression = KtPsiFactory(project).createSimpleName(fqName.shortName().asString()) + return replaced(newNameExpression) } override fun KtSimpleReference.suggestVariableName( diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/safeDelete/KotlinFirSafeDeleteProcessor.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/safeDelete/KotlinFirSafeDeleteProcessor.kt index 74527c517cc2..dfee5d3afb3f 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/safeDelete/KotlinFirSafeDeleteProcessor.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/safeDelete/KotlinFirSafeDeleteProcessor.kt @@ -18,7 +18,7 @@ import com.intellij.usageView.UsageInfo import com.intellij.util.Processor import com.intellij.util.containers.map2Array import org.jetbrains.kotlin.analysis.api.analyze -import org.jetbrains.kotlin.analysis.api.analyzeInModalWindow +import org.jetbrains.kotlin.idea.base.analysis.api.utils.analyzeInModalWindow import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/utils.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/utils.kt index eb6cf2333410..803ca2ee6942 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/utils.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/utils.kt @@ -8,7 +8,7 @@ import com.intellij.psi.ElementDescriptionUtil import com.intellij.psi.PsiElement import com.intellij.refactoring.util.RefactoringDescriptionLocation import org.jetbrains.annotations.Nls -import org.jetbrains.kotlin.analysis.api.analyzeInModalWindow +import org.jetbrains.kotlin.idea.base.analysis.api.utils.analyzeInModalWindow import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.idea.util.application.isUnitTestMode import org.jetbrains.kotlin.lexer.KtTokens diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/kotlin.refactorings.tests.k2.iml b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/kotlin.refactorings.tests.k2.iml index 25b4ffae4b38..38c18b9300d4 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/kotlin.refactorings.tests.k2.iml +++ b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/kotlin.refactorings.tests.k2.iml @@ -15,5 +15,6 @@ + \ No newline at end of file diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/safeDelete/AbstractK2BindToElementTest.kt b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/safeDelete/AbstractK2BindToElementTest.kt index 568239c4b447..36ea481d3fd2 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/safeDelete/AbstractK2BindToElementTest.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/safeDelete/AbstractK2BindToElementTest.kt @@ -2,7 +2,6 @@ package org.jetbrains.kotlin.idea.k2.refactoring.safeDelete import com.intellij.psi.JavaPsiFacade -import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile import com.intellij.psi.search.GlobalSearchScope @@ -11,8 +10,11 @@ import org.jetbrains.kotlin.analysis.api.KtAllowAnalysisOnEdt import org.jetbrains.kotlin.analysis.api.lifetime.allowAnalysisOnEdt import org.jetbrains.kotlin.asJava.unwrapped import org.jetbrains.kotlin.idea.references.mainReference +import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelFunctionFqnNameIndex +import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelPropertyFqnNameIndex import org.jetbrains.kotlin.idea.test.* import org.jetbrains.kotlin.idea.util.application.executeWriteCommand +import org.jetbrains.kotlin.kdoc.psi.impl.KDocName import org.jetbrains.kotlin.psi.KtSimpleNameExpression abstract class AbstractK2BindToElementTest : KotlinMultiFileLightCodeInsightFixtureTestCase() { @@ -25,23 +27,25 @@ abstract class AbstractK2BindToElementTest : KotlinMultiFileLightCodeInsightFixt val mainFile = files.first() myFixture.configureFromExistingVirtualFile(mainFile.virtualFile) val elem = mainFile.findElementAt(myFixture.caretOffset) ?: error("Couldn't find element at caret") - val nameReference = elem.parentOfType(withSelf = true) + val refElement = elem.parentOfType(withSelf = true) + ?: elem.parentOfType() ?: error("Element at caret isn't of type 'KtSimpleNameExpression'") + val mainReference = refElement.mainReference ?: error("Ref element doesn't have a main reference") val bindTarget = findElementToBind()?.unwrapped ?: error("Could not find element to bind") myFixture.project.executeWriteCommand("bindToElement") { - nameReference.mainReference.bindToElement(bindTarget) + mainReference.bindToElement(bindTarget) } myFixture.checkResultByFile("${dataFile().name}.after") } private fun findElementToBind(): PsiElement? { - val classToBind = InTextDirectivesUtils.findStringWithPrefixes(file.text, BIND_TO) - return classToBind?.let(::findClass) + val nameToBind = InTextDirectivesUtils.findStringWithPrefixes(file.text, BIND_TO) ?: return null + val projectScope = GlobalSearchScope.allScope(myFixture.project) + return JavaPsiFacade.getInstance(myFixture.project).findClass(nameToBind, projectScope) + ?: KotlinTopLevelFunctionFqnNameIndex[nameToBind, myFixture.project, projectScope].firstOrNull() + ?: KotlinTopLevelPropertyFqnNameIndex[nameToBind, myFixture.project, projectScope].firstOrNull() } - private fun findClass(fqn: String): PsiClass? = JavaPsiFacade.getInstance(myFixture.project) - .findClass(fqn, GlobalSearchScope.allScope(myFixture.project)) - private companion object { const val BIND_TO = "BIND_TO" } diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/safeDelete/K2BindToElementTestGenerated.java b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/safeDelete/K2BindToElementTestGenerated.java index d174f305d85c..e9711c3b0058 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/safeDelete/K2BindToElementTestGenerated.java +++ b/plugins/kotlin/refactorings/kotlin.refactorings.tests.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/safeDelete/K2BindToElementTestGenerated.java @@ -17,7 +17,54 @@ import org.junit.runner.RunWith; @TestRoot("refactorings/kotlin.refactorings.tests.k2") @TestDataPath("$CONTENT_ROOT") @RunWith(JUnit3RunnerWithInners.class) +@TestMetadata("../../idea/tests/testData/refactoring/bindToElement") public abstract class K2BindToElementTestGenerated extends AbstractK2BindToElementTest { + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../../idea/tests/testData/refactoring/bindToElement/annotationCall") + public static class AnnotationCall extends AbstractK2BindToElementTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("FullyQualified.kt") + public void testFullyQualified() throws Exception { + runTest("../../idea/tests/testData/refactoring/bindToElement/annotationCall/FullyQualified.kt"); + } + + @TestMetadata("RootPkg.kt") + public void testRootPkg() throws Exception { + runTest("../../idea/tests/testData/refactoring/bindToElement/annotationCall/RootPkg.kt"); + } + + @TestMetadata("UnQualified.kt") + public void testUnQualified() throws Exception { + runTest("../../idea/tests/testData/refactoring/bindToElement/annotationCall/UnQualified.kt"); + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../../idea/tests/testData/refactoring/bindToElement/annotationReference") + public static class AnnotationReference extends AbstractK2BindToElementTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("FullyQualified.kt") + public void testFullyQualified() throws Exception { + runTest("../../idea/tests/testData/refactoring/bindToElement/annotationReference/FullyQualified.kt"); + } + + @TestMetadata("RootPkg.kt") + public void testRootPkg() throws Exception { + runTest("../../idea/tests/testData/refactoring/bindToElement/annotationReference/RootPkg.kt"); + } + + @TestMetadata("UnQualified.kt") + public void testUnQualified() throws Exception { + runTest("../../idea/tests/testData/refactoring/bindToElement/annotationReference/UnQualified.kt"); + } + } + @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("../../idea/tests/testData/refactoring/bindToElement/callableReference") public static class CallableReference extends AbstractK2BindToElementTest { @@ -41,6 +88,19 @@ public abstract class K2BindToElementTestGenerated extends AbstractK2BindToEleme } } + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../../idea/tests/testData/refactoring/bindToElement/changeImport") + public static class ChangeImport extends AbstractK2BindToElementTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("ChangeImport.kt") + public void testChangeImport() throws Exception { + runTest("../../idea/tests/testData/refactoring/bindToElement/changeImport/ChangeImport.kt"); + } + } + @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("../../idea/tests/testData/refactoring/bindToElement/constructorCall") public static class ConstructorCall extends AbstractK2BindToElementTest { @@ -70,48 +130,61 @@ public abstract class K2BindToElementTestGenerated extends AbstractK2BindToEleme } @RunWith(JUnit3RunnerWithInners.class) - @TestMetadata("../../idea/tests/testData/refactoring/bindToElement/superTypeCall") - public static class SuperTypeCall extends AbstractK2BindToElementTest { + @TestMetadata("../../idea/tests/testData/refactoring/bindToElement/delegatedSuperTypeReference") + public static class DelegatedSuperTypeReference extends AbstractK2BindToElementTest { private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); } @TestMetadata("FullyQualified.kt") public void testFullyQualified() throws Exception { - runTest("../../idea/tests/testData/refactoring/bindToElement/superTypeCall/FullyQualified.kt"); + runTest("../../idea/tests/testData/refactoring/bindToElement/delegatedSuperTypeReference/FullyQualified.kt"); } @TestMetadata("RootPkg.kt") public void testRootPkg() throws Exception { - runTest("../../idea/tests/testData/refactoring/bindToElement/superTypeCall/RootPkg.kt"); + runTest("../../idea/tests/testData/refactoring/bindToElement/delegatedSuperTypeReference/RootPkg.kt"); } - @TestMetadata("UnQualified.kt") - public void testUnQualified() throws Exception { - runTest("../../idea/tests/testData/refactoring/bindToElement/superTypeCall/UnQualified.kt"); + @TestMetadata("Unqualified.kt") + public void testUnqualified() throws Exception { + runTest("../../idea/tests/testData/refactoring/bindToElement/delegatedSuperTypeReference/Unqualified.kt"); } } @RunWith(JUnit3RunnerWithInners.class) - @TestMetadata("../../idea/tests/testData/refactoring/bindToElement/annotationCall") - public static class AnnotationCall extends AbstractK2BindToElementTest { + @TestMetadata("../../idea/tests/testData/refactoring/bindToElement/docReference") + public static class DocReference extends AbstractK2BindToElementTest { private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); } @TestMetadata("FullyQualified.kt") public void testFullyQualified() throws Exception { - runTest("../../idea/tests/testData/refactoring/bindToElement/annotationCall/FullyQualified.kt"); + runTest("../../idea/tests/testData/refactoring/bindToElement/docReference/FullyQualified.kt"); } @TestMetadata("RootPkg.kt") public void testRootPkg() throws Exception { - runTest("../../idea/tests/testData/refactoring/bindToElement/annotationCall/RootPkg.kt"); + runTest("../../idea/tests/testData/refactoring/bindToElement/docReference/RootPkg.kt"); } @TestMetadata("UnQualified.kt") public void testUnQualified() throws Exception { - runTest("../../idea/tests/testData/refactoring/bindToElement/annotationCall/UnQualified.kt"); + runTest("../../idea/tests/testData/refactoring/bindToElement/docReference/UnQualified.kt"); + } + } + + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../../idea/tests/testData/refactoring/bindToElement/importReference") + public static class ImportReference extends AbstractK2BindToElementTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("ImportReference.kt") + public void testImportReference() throws Exception { + runTest("../../idea/tests/testData/refactoring/bindToElement/importReference/ImportReference.kt"); } } @@ -161,6 +234,29 @@ public abstract class K2BindToElementTestGenerated extends AbstractK2BindToEleme } } + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../../idea/tests/testData/refactoring/bindToElement/superTypeCall") + public static class SuperTypeCall extends AbstractK2BindToElementTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("FullyQualified.kt") + public void testFullyQualified() throws Exception { + runTest("../../idea/tests/testData/refactoring/bindToElement/superTypeCall/FullyQualified.kt"); + } + + @TestMetadata("RootPkg.kt") + public void testRootPkg() throws Exception { + runTest("../../idea/tests/testData/refactoring/bindToElement/superTypeCall/RootPkg.kt"); + } + + @TestMetadata("UnQualified.kt") + public void testUnQualified() throws Exception { + runTest("../../idea/tests/testData/refactoring/bindToElement/superTypeCall/UnQualified.kt"); + } + } + @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("../../idea/tests/testData/refactoring/bindToElement/superTypeReference") public static class SuperTypeReference extends AbstractK2BindToElementTest { @@ -185,61 +281,48 @@ public abstract class K2BindToElementTestGenerated extends AbstractK2BindToEleme } @RunWith(JUnit3RunnerWithInners.class) - @TestMetadata("../../idea/tests/testData/refactoring/bindToElement/delegatedSuperTypeReference") - public static class DelegatedSuperTypeReference extends AbstractK2BindToElementTest { + @TestMetadata("../../idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall") + public static class TopLevelFunctionCall extends AbstractK2BindToElementTest { private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); } - @TestMetadata("FullyQualified.kt") - public void testFullyQualified() throws Exception { - runTest("../../idea/tests/testData/refactoring/bindToElement/delegatedSuperTypeReference/FullyQualified.kt"); + @TestMetadata("Qualified.kt") + public void testQualified() throws Exception { + runTest("../../idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/Qualified.kt"); } @TestMetadata("RootPkg.kt") public void testRootPkg() throws Exception { - runTest("../../idea/tests/testData/refactoring/bindToElement/delegatedSuperTypeReference/RootPkg.kt"); - } - - @TestMetadata("Unqualified.kt") - public void testUnqualified() throws Exception { - runTest("../../idea/tests/testData/refactoring/bindToElement/delegatedSuperTypeReference/Unqualified.kt"); - } - } - - @RunWith(JUnit3RunnerWithInners.class) - @TestMetadata("../../idea/tests/testData/refactoring/bindToElement/annotationReference") - public static class AnnotationReference extends AbstractK2BindToElementTest { - private void runTest(String testDataFilePath) throws Exception { - KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); - } - - @TestMetadata("FullyQualified.kt") - public void testFullyQualified() throws Exception { - runTest("../../idea/tests/testData/refactoring/bindToElement/annotationReference/FullyQualified.kt"); - } - - @TestMetadata("RootPkg.kt") - public void testRootPkg() throws Exception { - runTest("../../idea/tests/testData/refactoring/bindToElement/annotationReference/RootPkg.kt"); + runTest("../../idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/RootPkg.kt"); } @TestMetadata("UnQualified.kt") public void testUnQualified() throws Exception { - runTest("../../idea/tests/testData/refactoring/bindToElement/annotationReference/UnQualified.kt"); + runTest("../../idea/tests/testData/refactoring/bindToElement/topLevelFunctionCall/UnQualified.kt"); } } @RunWith(JUnit3RunnerWithInners.class) - @TestMetadata("../../idea/tests/testData/refactoring/bindToElement/changeImport") - public static class ChangeImport extends AbstractK2BindToElementTest { + @TestMetadata("../../idea/tests/testData/refactoring/bindToElement/topLevelProperty") + public static class TopLevelProperty extends AbstractK2BindToElementTest { private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); } - @TestMetadata("ChangeImport.kt") - public void testChangeImport() throws Exception { - runTest("../../idea/tests/testData/refactoring/bindToElement/changeImport/ChangeImport.kt"); + @TestMetadata("Qualified.kt") + public void testQualified() throws Exception { + runTest("../../idea/tests/testData/refactoring/bindToElement/topLevelProperty/Qualified.kt"); + } + + @TestMetadata("RootPkg.kt") + public void testRootPkg() throws Exception { + runTest("../../idea/tests/testData/refactoring/bindToElement/topLevelProperty/RootPkg.kt"); + } + + @TestMetadata("UnQualified.kt") + public void testUnQualified() throws Exception { + runTest("../../idea/tests/testData/refactoring/bindToElement/topLevelProperty/UnQualified.kt"); } } } diff --git a/plugins/kotlin/refactorings/rename.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/rename/AbstractFirRenameTest.kt b/plugins/kotlin/refactorings/rename.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/rename/AbstractFirRenameTest.kt index 9e8f5c444bed..0737da5d1254 100644 --- a/plugins/kotlin/refactorings/rename.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/rename/AbstractFirRenameTest.kt +++ b/plugins/kotlin/refactorings/rename.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/rename/AbstractFirRenameTest.kt @@ -20,13 +20,6 @@ import org.jetbrains.kotlin.psi.KtFile abstract class AbstractFirRenameTest : AbstractRenameTest() { - /** - * Rename tests are not 100% stable ATM, so we only run the tests that will definitely pass. - * - * Use this flag locally to find out which tests might be enabled. - */ - private val onlyRunEnabledTests: Boolean = true - override fun isFirPlugin(): Boolean = true override fun tearDown() { @@ -43,14 +36,14 @@ abstract class AbstractFirRenameTest : AbstractRenameTest() { @OptIn(KtAllowAnalysisOnEdt::class) override fun doTest(path: String) { val renameObject = loadTestConfiguration(dataFile()) - val testIsEnabledInK2 = renameObject.get("enabledInK2")?.asBoolean == true + val testIsDisabledInK2 = renameObject.get("enabledInK2")?.asBoolean == false - if (!testIsEnabledInK2 && onlyRunEnabledTests) return + if (testIsDisabledInK2) return val result = allowAnalysisOnEdt { runCatching { super.doTest(path) } } result.fold( - onSuccess = { require(testIsEnabledInK2) { "This test passes and should be enabled!" } }, - onFailure = { exception -> if (testIsEnabledInK2) throw exception } + onSuccess = { require(!testIsDisabledInK2) { "This test passes and should be enabled!" } }, + onFailure = { exception -> if (!testIsDisabledInK2) throw exception } ) } diff --git a/plugins/kotlin/refactorings/rename.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/rename/FirRenameTestGenerated.java b/plugins/kotlin/refactorings/rename.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/rename/FirRenameTestGenerated.java index b68573f36341..0b83bbc0ff10 100644 --- a/plugins/kotlin/refactorings/rename.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/rename/FirRenameTestGenerated.java +++ b/plugins/kotlin/refactorings/rename.k2/test/org/jetbrains/kotlin/idea/k2/refactoring/rename/FirRenameTestGenerated.java @@ -753,6 +753,11 @@ public class FirRenameTestGenerated extends AbstractFirRenameTest { runTest("../../idea/tests/testData/refactoring/rename/renameKotlinClassByConstructorRef/kotlinClass.test"); } + @TestMetadata("renameKotlinClassByImplicitConstructorRef/kotlinClass.test") + public void testRenameKotlinClassByImplicitConstructorRef_KotlinClass() throws Exception { + runTest("../../idea/tests/testData/refactoring/rename/renameKotlinClassByImplicitConstructorRef/kotlinClass.test"); + } + @TestMetadata("renameKotlinClassConstructor/renameKotlinConstructor.test") public void testRenameKotlinClassConstructor_RenameKotlinConstructor() throws Exception { runTest("../../idea/tests/testData/refactoring/rename/renameKotlinClassConstructor/renameKotlinConstructor.test"); diff --git a/plugins/kotlin/run-configurations/jvm/kotlin.run-configurations.jvm.iml b/plugins/kotlin/run-configurations/jvm/kotlin.run-configurations.jvm.iml index 217dc38933bd..a62575df0917 100644 --- a/plugins/kotlin/run-configurations/jvm/kotlin.run-configurations.jvm.iml +++ b/plugins/kotlin/run-configurations/jvm/kotlin.run-configurations.jvm.iml @@ -22,7 +22,7 @@ - + diff --git a/plugins/kotlin/scripting-support/kotlin.scripting-support.iml b/plugins/kotlin/scripting-support/kotlin.scripting-support.iml index 2640f74e9e7a..66ac4023f27f 100644 --- a/plugins/kotlin/scripting-support/kotlin.scripting-support.iml +++ b/plugins/kotlin/scripting-support/kotlin.scripting-support.iml @@ -19,7 +19,7 @@ - + diff --git a/plugins/kotlin/scripting-support/test/org/jetbrains/kotlin/idea/scratch/ScratchLineMarkersTest.kt b/plugins/kotlin/scripting-support/test/org/jetbrains/kotlin/idea/scratch/ScratchLineMarkersTest.kt index 01a244b2d12b..d2cb5d500789 100644 --- a/plugins/kotlin/scripting-support/test/org/jetbrains/kotlin/idea/scratch/ScratchLineMarkersTest.kt +++ b/plugins/kotlin/scripting-support/test/org/jetbrains/kotlin/idea/scratch/ScratchLineMarkersTest.kt @@ -19,7 +19,6 @@ import org.jetbrains.kotlin.idea.codeInsight.AbstractLineMarkersTest import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager import org.jetbrains.kotlin.idea.scratch.AbstractScratchRunActionTest.Companion.configureOptions import org.jetbrains.kotlin.idea.test.runAll -import org.jetbrains.kotlin.psi.KtFile import java.io.File abstract class AbstractScratchLineMarkersTest : FileEditorManagerTestCase() { @@ -54,9 +53,7 @@ abstract class AbstractScratchLineMarkersTest : FileEditorManagerTestCase() { PsiDocumentManager.getInstance(project).commitAllDocuments() - val markers = doAndCheckHighlighting(document, data, File(path)) - - AbstractLineMarkersTest.assertNavigationElements(myFixture.project, myFixture.file as KtFile, myFixture.editor, markers) + doAndCheckHighlighting(document, data, File(path)) } override fun tearDown() { @@ -75,7 +72,7 @@ abstract class AbstractScratchLineMarkersTest : FileEditorManagerTestCase() { ): List> { myFixture.doHighlighting() - return AbstractLineMarkersTest.checkHighlighting(myFixture.file, documentToAnalyze, expectedHighlighting, expectedFile) + return AbstractLineMarkersTest.checkHighlighting(project, myFixture.file, documentToAnalyze, expectedHighlighting, expectedFile) } } diff --git a/plugins/kotlin/test-framework/test/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt b/plugins/kotlin/test-framework/test/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt index 400b58e8b99b..5be0b9140e80 100644 --- a/plugins/kotlin/test-framework/test/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt +++ b/plugins/kotlin/test-framework/test/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt @@ -5,11 +5,13 @@ package org.jetbrains.kotlin.idea.stubs import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase import com.intellij.openapi.Disposable import com.intellij.openapi.application.WriteAction +import com.intellij.openapi.application.runWriteAction import com.intellij.openapi.command.WriteCommandAction import com.intellij.openapi.externalSystem.service.project.ProjectDataManager import com.intellij.openapi.module.Module import com.intellij.openapi.module.ModuleType import com.intellij.openapi.module.StdModuleTypes +import com.intellij.openapi.project.rootManager import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.roots.* import com.intellij.openapi.roots.libraries.PersistentLibraryKind @@ -18,23 +20,27 @@ import com.intellij.openapi.util.Ref import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vfs.LocalFileSystem import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.psi.PsiFile +import com.intellij.psi.PsiManager import com.intellij.testFramework.IdeaTestUtil import com.intellij.testFramework.PsiTestUtil import com.intellij.util.ThrowableRunnable import org.jetbrains.kotlin.config.CompilerSettings import org.jetbrains.kotlin.config.KotlinFacetSettings import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider +import org.jetbrains.kotlin.idea.core.util.toPsiFile import org.jetbrains.kotlin.idea.facet.getOrCreateFacet import org.jetbrains.kotlin.idea.facet.initializeIfNeeded import org.jetbrains.kotlin.idea.test.* import org.jetbrains.kotlin.idea.test.KotlinTestUtils.allowProjectRootAccess import org.jetbrains.kotlin.idea.test.KotlinTestUtils.disposeVfsRootAccess import org.jetbrains.kotlin.idea.test.util.slashedPath +import org.jetbrains.kotlin.idea.util.sourceRoots import org.jetbrains.kotlin.platform.TargetPlatform +import org.jetbrains.kotlin.psi.KtFile import org.junit.Assert import java.io.File -import java.nio.file.Files import java.nio.file.Path import kotlin.io.path.* @@ -99,7 +105,6 @@ abstract class AbstractMultiModuleTest : DaemonAnalyzerTestCase() { protected data class FileWithText(val name: String, val text: String) - override fun tearDown() { runAll( ThrowableRunnable { disposeVfsRootAccess(vfsDisposable) }, @@ -169,6 +174,21 @@ abstract class AbstractMultiModuleTest : DaemonAnalyzerTestCase() { } } + fun Module.addKotlinStdlib() = runWriteAction { + val modifiableModel = rootManager.modifiableModel + KotlinWithJdkAndRuntimeLightProjectDescriptor.JDK_AND_RUNTIME_LIGHT_PROJECT_DESCRIPTOR.configureModule( + this, + modifiableModel, + ) + modifiableModel.commit() + } + + fun Module.findSourceKtFile(fileName: String): KtFile { + val file = "${sourceRoots.first().url}/$fileName" + val virtualFile = VirtualFileManager.getInstance().findFileByUrl(file)!! + return PsiManager.getInstance(myProject).findFile(virtualFile) as KtFile + } + fun Module.enableMultiPlatform(additionalCompilerArguments: String = "") { createFacet() val facetSettings = KotlinFacetSettingsProvider.getInstance(project)?.getInitializedSettings(this) @@ -188,6 +208,20 @@ abstract class AbstractMultiModuleTest : DaemonAnalyzerTestCase() { facetSettings.useProjectSettings = false } + protected fun createKtFileUnderNewContentRoot(fileWithText: FileWithText): KtFile { + val tmpDir = createTempDirectory().toPath() + + // We need to add the script to a module so that it's part of the project's content root. + val containingModule = createModule(tmpDir, moduleType) + PsiTestUtil.addContentRoot(containingModule, getVirtualFile(tmpDir.toFile())) + + val filePath = tmpDir / fileWithText.name + filePath.writeText(fileWithText.text) + + val file = getVirtualFile(filePath.toFile()) + return file.toPsiFile(project)!! as KtFile + } + protected fun checkFiles( findFiles: () -> List, check: () -> Unit diff --git a/plugins/kotlin/test-framework/test/org/jetbrains/kotlin/idea/test/ConfigLibraryUtil.kt b/plugins/kotlin/test-framework/test/org/jetbrains/kotlin/idea/test/ConfigLibraryUtil.kt index 57f0dcfa83c7..7329af302655 100644 --- a/plugins/kotlin/test-framework/test/org/jetbrains/kotlin/idea/test/ConfigLibraryUtil.kt +++ b/plugins/kotlin/test-framework/test/org/jetbrains/kotlin/idea/test/ConfigLibraryUtil.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.idea.test import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.runWriteAction import com.intellij.openapi.module.Module +import com.intellij.openapi.project.Project import com.intellij.openapi.projectRoots.ProjectJdkTable import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.roots.LibraryOrderEntry @@ -13,10 +14,12 @@ import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.roots.impl.libraries.LibraryEx import com.intellij.openapi.roots.libraries.Library +import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar import com.intellij.openapi.roots.libraries.PersistentLibraryKind import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor import com.intellij.openapi.vfs.VfsUtil import com.intellij.util.PathUtil +import com.intellij.util.io.jarFile import org.jetbrains.kotlin.idea.base.platforms.KotlinCommonLibraryKind import org.jetbrains.kotlin.idea.base.platforms.KotlinJavaScriptLibraryKind import org.jetbrains.kotlin.idea.base.plugin.artifacts.TestKotlinArtifacts @@ -107,6 +110,30 @@ object ConfigLibraryUtil { } } + fun addProjectLibrary( + project: Project, + name: String, + init: Library.ModifiableModel.() -> Unit, + ): Library = runWriteAction { + LibraryTablesRegistrar.getInstance().getLibraryTable(project).createLibrary(name).apply { + modifiableModel.init() + } + } + + fun addProjectLibraryWithClassesRoot(project: Project, name: String): Library = runWriteAction { + addProjectLibrary(project, name) { + // Add a unique root to avoid deduplication of library infos in tests (see `LibraryInfoCache`). + addEmptyClassesRoot() + commit() + } + } + + fun removeProjectLibrary(project: Project, library: Library) { + runWriteAction { + LibraryTablesRegistrar.getInstance().getLibraryTable(project).removeLibrary(library) + } + } + fun addLibrary(module: Module, name: String, kind: PersistentLibraryKind<*>? = null, init: Library.ModifiableModel.() -> Unit) { runWriteAction { ModuleRootManager.getInstance(module).modifiableModel.apply { @@ -147,7 +174,6 @@ object ConfigLibraryUtil { return library } - fun removeLibrary(module: Module, libraryName: String): Boolean { return runWriteAction { var removed = false @@ -224,4 +250,9 @@ object ConfigLibraryUtil { fun Library.ModifiableModel.addRoot(file: File, kind: OrderRootType) { addRoot(VfsUtil.getUrlForLibraryRoot(file), kind) -} \ No newline at end of file +} + +fun Library.ModifiableModel.addEmptyClassesRoot() { + val jarFile = jarFile { }.generateInTempDir() + addRoot(jarFile.toFile(), OrderRootType.CLASSES) +} diff --git a/plugins/kotlin/test-framework/test/org/jetbrains/kotlin/idea/test/MockLibraryFacility.kt b/plugins/kotlin/test-framework/test/org/jetbrains/kotlin/idea/test/MockLibraryFacility.kt index a70157338ebd..2ce003b94944 100644 --- a/plugins/kotlin/test-framework/test/org/jetbrains/kotlin/idea/test/MockLibraryFacility.kt +++ b/plugins/kotlin/test-framework/test/org/jetbrains/kotlin/idea/test/MockLibraryFacility.kt @@ -6,19 +6,51 @@ import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.roots.ModifiableRootModel import com.intellij.openapi.roots.OrderRootType import com.intellij.testFramework.IdeaTestUtil +import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.idea.base.platforms.KotlinJavaScriptLibraryKind import org.jetbrains.kotlin.idea.framework.KotlinSdkType import java.io.File -data class MockLibraryFacility( +class MockLibraryFacility( val sources: List, val attachSources: Boolean = true, val platform: KotlinCompilerStandalone.Platform = KotlinCompilerStandalone.Platform.Jvm(), - val options: List = emptyList(), + options: List = emptyList(), val classpath: List = emptyList(), val libraryName: String = MOCK_LIBRARY_NAME, val target: File = KotlinCompilerStandalone.defaultTargetJar(), + val frontend: KotlinCompilerFrontend = KotlinCompilerFrontend.K1, ) { + + private val options: List + + init { + val languageVersionByCompilerOptionsIndex = options.indexOf(LANGUAGE_VERSION_PARAMETER_NAME) + if (languageVersionByCompilerOptionsIndex != -1) { + val languageVersion = LanguageVersion.fromVersionString(options[languageVersionByCompilerOptionsIndex + 1]) + ?: error("Invalid language version provided") + when (frontend) { + KotlinCompilerFrontend.K1 -> { + require(languageVersion < LanguageVersion.KOTLIN_2_0) { + "Cannot use $languageVersion with K1 compiler" + } + } + KotlinCompilerFrontend.K2 -> { + require(languageVersion >= LanguageVersion.KOTLIN_2_0) { + "Cannot use $languageVersion with K2 compiler" + } + } + } + this.options = options + } else { + val languageVersionToUse = when (frontend) { + KotlinCompilerFrontend.K1 -> LanguageVersion.values().last { !it.usesK2 } + KotlinCompilerFrontend.K2 -> maxOf(LanguageVersion.LATEST_STABLE, LanguageVersion.KOTLIN_2_0) + } + this.options = options + listOf(LANGUAGE_VERSION_PARAMETER_NAME, languageVersionToUse.versionString) + } + } + constructor( source: File, attachSources: Boolean = true, @@ -27,7 +59,8 @@ data class MockLibraryFacility( classpath: List = emptyList(), libraryName: String = MOCK_LIBRARY_NAME, target: File = KotlinCompilerStandalone.defaultTargetJar(), - ) : this(listOf(source), attachSources, platform, options, classpath, libraryName, target) + frontend: KotlinCompilerFrontend = KotlinCompilerFrontend.K1, + ) : this(listOf(source), attachSources, platform, options, classpath, libraryName, target, frontend) companion object { const val MOCK_LIBRARY_NAME = "kotlinMockLibrary" @@ -69,4 +102,10 @@ data class MockLibraryFacility( else IdeaTestUtil.getMockJdk18() } + + enum class KotlinCompilerFrontend { + K1, K2 + } } + +private const val LANGUAGE_VERSION_PARAMETER_NAME = "-language-version" diff --git a/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/BaseKotlinUastResolveProviderService.kt b/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/BaseKotlinUastResolveProviderService.kt index e5fb4bdc8459..79370264a5a2 100644 --- a/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/BaseKotlinUastResolveProviderService.kt +++ b/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/BaseKotlinUastResolveProviderService.kt @@ -34,7 +34,44 @@ interface BaseKotlinUastResolveProviderService { fun getArgumentForParameter(ktCallElement: KtCallElement, index: Int, parent: UElement): UExpression? - fun getImplicitReturn(ktLambdaExpression: KtLambdaExpression, parent: UElement): KotlinUImplicitReturnExpression? + fun getImplicitReturn(ktLambdaExpression: KtLambdaExpression, parent: UElement): KotlinUImplicitReturnExpression? { + val lastExpression = ktLambdaExpression.bodyExpression?.statements?.lastOrNull() ?: return null + // Skip _explicit_ return. + if (lastExpression is KtReturnExpression || lastExpression is KtThrowExpression) return null + + /** + * This is not fully correct in the case of lambda with [Unit] return type and non-[Unit] return type of the last statement: + * ```kotlin + * fun foo() { + * 42.apply { + * "str" + * } + * } + * ``` + * Because here [apply] has [Unit] return type, so we shouldn't have the implicit return here, + * but we will create it anyway. + * So effectively, this code will mean: + * ```kotlin + * fun foo() { + * 42.apply { + * return@apply "str" + * } + * } + * ``` + * in terms of UAST what is wrong, but we agree with this behavior because such real type checks are too expensive. + * But it is correct in the case of [Unit] as a return type of the last statement + * ```kotlin + * fun foo() { + * 42.apply { + * return@apply println(this) + * } + * } + * ``` + */ + return KotlinUImplicitReturnExpression(parent).apply { + returnExpression = baseKotlinConverter.convertOrEmpty(lastExpression, this) + } + } fun getImplicitParameters( ktLambdaExpression: KtLambdaExpression, diff --git a/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinStringTemplateUPolyadicExpression.kt b/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinStringTemplateUPolyadicExpression.kt index c4258d15f47f..c4ba1107c5fb 100644 --- a/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinStringTemplateUPolyadicExpression.kt +++ b/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinStringTemplateUPolyadicExpression.kt @@ -41,12 +41,19 @@ class KotlinStringTemplateUPolyadicExpression( val dotQualifiedExpression = uParent.sourcePsi as? KtDotQualifiedExpression if (dotQualifiedExpression != null) { val callExpression = dotQualifiedExpression.selectorExpression as? KtCallExpression ?: return this - val resolvedFunctionName = baseResolveProviderService.resolvedFunctionName(callExpression) - if (resolvedFunctionName == "trimIndent" || resolvedFunctionName == "trimMargin") - return uParent + if (KotlinUFunctionCallExpression.methodNameCanBeOneOf(callExpression, TRIM_METHOD_NAMES)) { + val resolvedFunctionName = baseResolveProviderService.resolvedFunctionName(callExpression) + if (resolvedFunctionName in TRIM_METHOD_NAMES) + return uParent + } } + if (uParent is UPolyadicExpression && uParent.operator == UastBinaryOperator.PLUS) return uParent + return super.getStringRoomExpression() } } + + +private val TRIM_METHOD_NAMES: List = listOf("trimIndent", "trimMargin") diff --git a/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinUCallableReferenceExpression.kt b/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinUCallableReferenceExpression.kt index 00f9404d51f9..bed9920df23d 100644 --- a/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinUCallableReferenceExpression.kt +++ b/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinUCallableReferenceExpression.kt @@ -7,6 +7,8 @@ import com.intellij.psi.PsiNamedElement import com.intellij.psi.ResolveResult import org.jetbrains.annotations.ApiStatus import org.jetbrains.kotlin.psi.KtCallableReferenceExpression +import org.jetbrains.kotlin.psi.KtDotQualifiedExpression +import org.jetbrains.kotlin.psi.KtNameReferenceExpression import org.jetbrains.uast.* import org.jetbrains.uast.kotlin.internal.getResolveResultVariants @@ -23,7 +25,10 @@ class KotlinUCallableReferenceExpression( } override val qualifierType by lz { - baseResolveProviderService.getDoubleColonReceiverType(sourcePsi, this) + if (sourcePsi.receiverExpression !is KtNameReferenceExpression && sourcePsi.receiverExpression !is KtDotQualifiedExpression) { + null + } else + baseResolveProviderService.getDoubleColonReceiverType(sourcePsi, this) } override val callableName: String diff --git a/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinUFunctionCallExpression.kt b/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinUFunctionCallExpression.kt index 1759ceb2017c..d3f3dfa5c38b 100644 --- a/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinUFunctionCallExpression.kt +++ b/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/expressions/KotlinUFunctionCallExpression.kt @@ -217,59 +217,64 @@ class KotlinUFunctionCallExpression( } override fun isMethodNameOneOf(names: Collection): Boolean { - if (methodNameCanBeOneOf(names)) { + if (methodNameCanBeOneOf(sourcePsi, names)) { // canMethodNameBeOneOf can return false-positive results, additional resolve is needed val methodName = methodName ?: return false return methodName in names } + return false } - fun methodNameCanBeOneOf(names: Collection): Boolean { - if (isMethodNameOneOfWithoutConsideringImportAliases(names)) return true - val ktFile = sourcePsi.containingKtFile - val aliasedNames = collectAliasedNamesForName(ktFile, names) - return isMethodNameOneOfWithoutConsideringImportAliases(aliasedNames) - } + companion object { + /** + * Can return false-positive results, additional resolve is needed + */ + internal fun methodNameCanBeOneOf(call: KtCallElement, names: Collection): Boolean { + if (isMethodNameOneOfWithoutConsideringImportAliases(call, names)) return true + val ktFile = call.containingKtFile + val aliasedNames = collectAliasedNamesForName(ktFile, names) + return isMethodNameOneOfWithoutConsideringImportAliases(call, aliasedNames) + } - /** - * For the [actualNames], returns the possible import alias name it might be expanded to - * - * E.g., for the file with imports - * ``` - * import a.b.c as foo - * ``` - * The call `collectAliasedNamesForName(ktFile, listOf("c")` will return `["foo"]` - */ - private fun collectAliasedNamesForName( - ktFile: KtFile, - actualNames: Collection, - ): Set { - if (ktFile.importDirectives.all { it.alias == null }) return emptySet() + /** + * For the [actualNames], returns the possible import alias name it might be expanded to + * + * E.g., for the file with imports + * ``` + * import a.b.c as foo + * ``` + * The call `collectAliasedNamesForName(ktFile, listOf("c")` will return `["foo"]` + */ + private fun collectAliasedNamesForName( + ktFile: KtFile, + actualNames: Collection, + ): Set { + if (ktFile.importDirectives.all { it.alias == null }) return emptySet() - return buildSet { - for (importDirective in ktFile.importDirectives) { - val aliasName = importDirective.aliasName ?: continue - val importedName = importDirective.importedFqName?.pathSegments()?.lastOrNull()?.asString() ?: continue - if (importedName in actualNames) { - add(aliasName) + return buildSet { + for (importDirective in ktFile.importDirectives) { + val aliasName = importDirective.aliasName ?: continue + val importedName = importDirective.importedFqName?.pathSegments()?.lastOrNull()?.asString() ?: continue + if (importedName in actualNames) { + add(aliasName) + } } } } - } - private fun isMethodNameOneOfWithoutConsideringImportAliases(names: Collection): Boolean { - if (names.isEmpty()) return false - if (names.any { it in methodNamesForWhichResolveIsNeeded }) { - // we need an additional resolve to say if the method name is one of expected - return true + private fun isMethodNameOneOfWithoutConsideringImportAliases(call: KtCallElement, names: Collection): Boolean { + if (names.isEmpty()) return false + if (names.any { it in methodNamesForWhichResolveIsNeeded }) { + // we need an additional resolve to say if the method name is one of expected + return true + } + + val referencedName = call.getCallNameExpression()?.getReferencedName() ?: return false + return referencedName in names } - val referencedName = sourcePsi.getCallNameExpression()?.getReferencedName() ?: return false - return referencedName in names - } - companion object { private val methodNamesForWhichResolveIsNeeded = buildSet { /* operator fun Int.invoke() {} diff --git a/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/kotlinConvertParentUtils.kt b/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/kotlinConvertParentUtils.kt index 7ab4a67a64f0..898038751253 100644 --- a/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/kotlinConvertParentUtils.kt +++ b/plugins/kotlin/uast/uast-kotlin-base/src/org/jetbrains/uast/kotlin/kotlinConvertParentUtils.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType +import org.jetbrains.kotlin.psi.psiUtil.isAncestor import org.jetbrains.kotlin.psi.psiUtil.isPropertyParameter import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments @@ -227,17 +228,23 @@ internal fun convertParentImpl( }.expressions.single() } - if (result is KotlinULambdaExpression.Body - && element is UExpression - && element.sourcePsi != null - && result.implicitReturn?.returnExpression?.sourcePsi == element.sourcePsi - ) { - return result.implicitReturn!! + if (result is KotlinULambdaExpression.Body && element is UExpression && element.sourcePsi?.canBeImplicitReturnIn(result) == true) { + result.implicitReturn?.takeIf { it.returnExpression.sourcePsi == element.sourcePsi }?.let { return it } } return result } +private fun PsiElement.canBeImplicitReturnIn(body: KotlinULambdaExpression.Body): Boolean { + val lastStatement = body.sourcePsi.statements.lastOrNull() ?: return false + // It is _explicit_ return so we skip + if (lastStatement is KtReturnExpression) return false + + // We can't be sure that lastStatement after transformations will contain exactly the last statement element, + // so we play safe here + return lastStatement.isAncestor(this, strict = false) +} + private fun isInConditionBranch(element: UElement, result: USwitchClauseExpressionWithBody) = element.psi?.parentsWithSelf?.takeWhile { it !== result.psi }?.any { it is KtWhenCondition } ?: false diff --git a/plugins/kotlin/uast/uast-kotlin-base/tests/test/org/jetbrains/uast/test/common/kotlin/UastResolveApiFixtureTestBase.kt b/plugins/kotlin/uast/uast-kotlin-base/tests/test/org/jetbrains/uast/test/common/kotlin/UastResolveApiFixtureTestBase.kt index eb5e279657ee..d6aab81c6b62 100644 --- a/plugins/kotlin/uast/uast-kotlin-base/tests/test/org/jetbrains/uast/test/common/kotlin/UastResolveApiFixtureTestBase.kt +++ b/plugins/kotlin/uast/uast-kotlin-base/tests/test/org/jetbrains/uast/test/common/kotlin/UastResolveApiFixtureTestBase.kt @@ -1440,7 +1440,7 @@ interface UastResolveApiFixtureTestBase : UastPluginSelection { } TestCase.assertTrue(call is KotlinUFunctionCallExpression) val ktCall = call as KotlinUFunctionCallExpression - TestCase.assertTrue("expected method name to be one of ${names}", ktCall.methodNameCanBeOneOf(names)) + TestCase.assertTrue("expected method name to be one of ${names}", ktCall.isMethodNameOneOf(names)) } fun checkParentOfParameterOfCatchClause(myFixture: JavaCodeInsightTestFixture) { diff --git a/plugins/kotlin/uast/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinUastResolveProviderService.kt b/plugins/kotlin/uast/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinUastResolveProviderService.kt index 6a0fa49b73d4..497ecd82e9c8 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinUastResolveProviderService.kt +++ b/plugins/kotlin/uast/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/FirKotlinUastResolveProviderService.kt @@ -117,22 +117,6 @@ interface FirKotlinUastResolveProviderService : BaseKotlinUastResolveProviderSer } } - override fun getImplicitReturn(ktLambdaExpression: KtLambdaExpression, parent: UElement): KotlinUImplicitReturnExpression? { - val lastExpression = ktLambdaExpression.bodyExpression?.statements?.lastOrNull() ?: return null - // Skip _explicit_ return. - if (lastExpression is KtReturnExpression) return null - analyzeForUast(ktLambdaExpression) { - // TODO: Should check an explicit, expected return type as well - // e.g., val y: () -> Unit = { 1 } // the lambda return type is Int, but we won't add an implicit return here. - val returnType = ktLambdaExpression.functionLiteral.getAnonymousFunctionSymbol().returnType - val returnUnitOrNothing = returnType.isUnit || returnType.isNothing - return if (returnUnitOrNothing) null else - KotlinUImplicitReturnExpression(parent).apply { - returnExpression = baseKotlinConverter.convertOrEmpty(lastExpression, this) - } - } - } - override fun getImplicitParameters( ktLambdaExpression: KtLambdaExpression, parent: UElement, diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/test/org/jetbrains/fir/uast/test/uastTestUtils.kt b/plugins/kotlin/uast/uast-kotlin-fir/tests/test/org/jetbrains/fir/uast/test/uastTestUtils.kt index 6d6ba8faf698..b118dc8e8738 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/test/org/jetbrains/fir/uast/test/uastTestUtils.kt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/test/org/jetbrains/fir/uast/test/uastTestUtils.kt @@ -2,16 +2,17 @@ package org.jetbrains.fir.uast.test +import com.intellij.openapi.application.runWriteAction import com.intellij.openapi.components.service import com.intellij.openapi.project.Project import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals -import org.jetbrains.kotlin.analysis.api.session.KtAnalysisSessionProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirBuiltinsSessionFactory -import org.jetbrains.kotlin.analysis.providers.KotlinModificationTrackerFactory +import org.jetbrains.kotlin.analysis.providers.KotlinGlobalModificationService @OptIn(KtAnalysisApiInternals::class) internal fun Project.invalidateAllCachesForUastTests() { - service().incrementModificationsCount() - service().clearCaches() + runWriteAction { + KotlinGlobalModificationService.getInstance(this).publishGlobalModuleStateModification() + } service().clearForTheNextTest() } \ No newline at end of file diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/build.gradle.kts.log.fe10.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/build.gradle.kts.log.fe10.txt deleted file mode 100644 index 3aeaefb8498d..000000000000 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/build.gradle.kts.log.fe10.txt +++ /dev/null @@ -1,109 +0,0 @@ -UFile (package = ) - UClass (name = Build_gradle) - UMethod (name = Build_gradle) - UParameter (name = args) - UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (plugins)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULambdaExpression - UBlockExpression - UBinaryExpression (operator = ) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (id)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULiteralExpression (value = "com.android.application") - ULiteralExpression (value = "2.3.3") - UBinaryExpression (operator = ) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (id)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULiteralExpression (value = "android") - ULiteralExpression (value = "2.3.3") - UReturnExpression - UBinaryExpression (operator = ) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (kotlin)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULiteralExpression (value = "android") - ULiteralExpression (value = "1.1.51") - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (android)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULambdaExpression - UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (compileSdkVersion)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULiteralExpression (value = 23) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (defaultConfig)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULambdaExpression - UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (minSdkVersion)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULiteralExpression (value = 7) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (targetSdkVersion)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULiteralExpression (value = 23) - UBinaryExpression (operator = =) - USimpleNameReferenceExpression (identifier = applicationId) - ULiteralExpression (value = "com.example.kotlingradle") - UBinaryExpression (operator = =) - USimpleNameReferenceExpression (identifier = versionCode) - ULiteralExpression (value = 1) - UBinaryExpression (operator = =) - USimpleNameReferenceExpression (identifier = versionName) - ULiteralExpression (value = "1.0") - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (buildTypes)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULambdaExpression - UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) - UIdentifier (Identifier (getByName)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULiteralExpression (value = "release") - ULambdaExpression - UBlockExpression - UBinaryExpression (operator = =) - USimpleNameReferenceExpression (identifier = isMinifyEnabled) - ULiteralExpression (value = false) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (proguardFiles)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULiteralExpression (value = "proguard-rules.pro") - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (dependencies)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULambdaExpression - UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (compile)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULiteralExpression (value = "com.android.support:appcompat-v7:23.4.0") - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (compile)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULiteralExpression (value = "com.android.support.constraint:constraint-layout:1.0.0-alpha8") - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (compile)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) - UIdentifier (Identifier (kotlin)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULiteralExpression (value = "stdlib") - ULiteralExpression (value = "1.1.51") - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (repositories)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULambdaExpression - UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) - UIdentifier (Identifier (jcenter)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - UMethod (name = main) - UParameter (name = args) diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/build.gradle.kts.log.fir.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/build.gradle.kts.log.txt similarity index 96% rename from plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/build.gradle.kts.log.fir.txt rename to plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/build.gradle.kts.log.txt index 4b8fc1c11fed..310d446523c3 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/build.gradle.kts.log.fir.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/build.gradle.kts.log.txt @@ -55,9 +55,10 @@ UFile (package = ) UBinaryExpression (operator = =) USimpleNameReferenceExpression (identifier = versionCode) ULiteralExpression (value = 1) - UBinaryExpression (operator = =) - USimpleNameReferenceExpression (identifier = versionName) - ULiteralExpression (value = "1.0") + UReturnExpression + UBinaryExpression (operator = =) + USimpleNameReferenceExpression (identifier = versionName) + ULiteralExpression (value = "1.0") UReturnExpression UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) UIdentifier (Identifier (buildTypes)) @@ -111,4 +112,4 @@ UFile (package = ) UIdentifier (Identifier (jcenter)) USimpleNameReferenceExpression (identifier = , resolvesTo = null) UMethod (name = main) - UParameter (name = args) + UParameter (name = args) \ No newline at end of file diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/build.gradle.kts.render.fe10.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/build.gradle.kts.render.fe10.txt deleted file mode 100644 index 9201cca8f8fe..000000000000 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/build.gradle.kts.render.fe10.txt +++ /dev/null @@ -1,34 +0,0 @@ -public final class Build_gradle { - public fun Build_gradle(args: java.lang.String[]) { - ({ - ("com.android.application") "2.3.3" - ("android") "2.3.3" - return ("android") "1.1.51" - }) - ({ - (23) - ({ - (7) - (23) - applicationId = "com.example.kotlingradle" - versionCode = 1 - versionName = "1.0" - }) - ({ - ("release", { - isMinifyEnabled = false - ("proguard-rules.pro") - }) - }) - }) - ({ - ("com.android.support:appcompat-v7:23.4.0") - ("com.android.support.constraint:constraint-layout:1.0.0-alpha8") - (("stdlib", "1.1.51")) - }) - ({ - () - }) - } - public static final fun main(args: java.lang.String[]) : void = UastEmptyExpression -} diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/build.gradle.kts.render.fir.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/build.gradle.kts.render.txt similarity index 96% rename from plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/build.gradle.kts.render.fir.txt rename to plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/build.gradle.kts.render.txt index e4a8afb4507b..ec19bb8366a8 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/build.gradle.kts.render.fir.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/build.gradle.kts.render.txt @@ -12,7 +12,7 @@ public final class Build_gradle { (23) applicationId = "com.example.kotlingradle" versionCode = 1 - versionName = "1.0" + return versionName = "1.0" }) return ({ return ("release", { @@ -31,4 +31,4 @@ public final class Build_gradle { }) } public static final fun main(args: java.lang.String[]) : void = UastEmptyExpression -} +} \ No newline at end of file diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/commentsOnDataClass.log.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/commentsOnDataClass.log.txt index f85d908ad58b..3a2c70288ba9 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/commentsOnDataClass.log.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/commentsOnDataClass.log.txt @@ -28,10 +28,11 @@ UFile (package = ) UIdentifier (Identifier (append)) USimpleNameReferenceExpression (identifier = append, resolvesTo = null) USimpleNameReferenceExpression (identifier = p2) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (append)) - USimpleNameReferenceExpression (identifier = append, resolvesTo = null) - ULiteralExpression (value = ")") + UReturnExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) + UIdentifier (Identifier (append)) + USimpleNameReferenceExpression (identifier = append, resolvesTo = null) + ULiteralExpression (value = ")") UMethod (name = getP1) UMethod (name = getP2) UMethod (name = Foo) diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/commentsOnDataClass.render.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/commentsOnDataClass.render.txt index f4ece32bf9e0..2e3acca17d19 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/commentsOnDataClass.render.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/commentsOnDataClass.render.txt @@ -7,7 +7,7 @@ public final class Foo { append(p1) append(",") append(p2) - append(")") + return append(")") }) } public final fun getP1() : java.lang.String = UastEmptyExpression diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/returns.log.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/returns.log.txt index b16e2a6632fe..8b82ac1094da 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/returns.log.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/returns.log.txt @@ -32,10 +32,11 @@ UFile (package = ) ULiteralExpression (value = 2) ULiteralExpression (value = 0) UReturnExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (print)) - USimpleNameReferenceExpression (identifier = print, resolvesTo = null) - USimpleNameReferenceExpression (identifier = it) + UReturnExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) + UIdentifier (Identifier (print)) + USimpleNameReferenceExpression (identifier = print, resolvesTo = null) + USimpleNameReferenceExpression (identifier = it) UMethod (name = implicitLabel) UBlockExpression UQualifiedReferenceExpression @@ -59,10 +60,11 @@ UFile (package = ) ULiteralExpression (value = 2) ULiteralExpression (value = 0) UReturnExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (print)) - USimpleNameReferenceExpression (identifier = print, resolvesTo = null) - USimpleNameReferenceExpression (identifier = it) + UReturnExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) + UIdentifier (Identifier (print)) + USimpleNameReferenceExpression (identifier = print, resolvesTo = null) + USimpleNameReferenceExpression (identifier = it) UMethod (name = simulateBreak) UBlockExpression UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) @@ -71,26 +73,28 @@ UFile (package = ) ULabeledExpression (label = loop) ULambdaExpression UBlockExpression - UQualifiedReferenceExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 4)) - UIdentifier (Identifier (listOf)) - USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) - ULiteralExpression (value = 1) - ULiteralExpression (value = 2) - ULiteralExpression (value = 3) - ULiteralExpression (value = 4) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (forEach)) - USimpleNameReferenceExpression (identifier = forEach, resolvesTo = null) - ULambdaExpression - UParameter (name = it) - UBlockExpression - UIfExpression - UBinaryExpression (operator = ==) - USimpleNameReferenceExpression (identifier = it) - ULiteralExpression (value = 3) + UReturnExpression + UQualifiedReferenceExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 4)) + UIdentifier (Identifier (listOf)) + USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) + ULiteralExpression (value = 1) + ULiteralExpression (value = 2) + ULiteralExpression (value = 3) + ULiteralExpression (value = 4) + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) + UIdentifier (Identifier (forEach)) + USimpleNameReferenceExpression (identifier = forEach, resolvesTo = null) + ULambdaExpression + UParameter (name = it) + UBlockExpression + UIfExpression + UBinaryExpression (operator = ==) + USimpleNameReferenceExpression (identifier = it) + ULiteralExpression (value = 3) + UReturnExpression UReturnExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (print)) - USimpleNameReferenceExpression (identifier = print, resolvesTo = null) - USimpleNameReferenceExpression (identifier = it) \ No newline at end of file + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) + UIdentifier (Identifier (print)) + USimpleNameReferenceExpression (identifier = print, resolvesTo = null) + USimpleNameReferenceExpression (identifier = it) diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/returns.render.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/returns.render.txt index 932c01ae0acb..2ba2d6b698e9 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/returns.render.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/declaration/returns.render.txt @@ -8,23 +8,23 @@ public final class ReturnsKt { listOf(1, 2, 3, 4).forEach(l@ { var it: int -> if (it % 2 == 0) return - print(it) + return print(it) }) } public static final fun implicitLabel() : void { listOf(1, 2, 3, 4).forEach({ var it: int -> if (it % 2 == 0) return - print(it) + return print(it) }) } public static final fun simulateBreak() : void { run(loop@ { - listOf(1, 2, 3, 4).forEach({ var it: int -> + return listOf(1, 2, 3, 4).forEach({ var it: int -> if (it == 3) return - print(it) + return print(it) }) }) } -} \ No newline at end of file +} diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Anonymous.log.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Anonymous.log.txt index d8610e40cedb..b58691bdc839 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Anonymous.log.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Anonymous.log.txt @@ -23,9 +23,10 @@ UFile (package = ) USimpleNameReferenceExpression (identifier = Runnable, resolvesTo = PsiClass: Runnable) ULambdaExpression UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) - UIdentifier (Identifier (println)) - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) + UReturnExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + UIdentifier (Identifier (println)) + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) UQualifiedReferenceExpression USimpleNameReferenceExpression (identifier = runnable2) UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) @@ -60,4 +61,4 @@ UFile (package = ) UDeclarationsExpression ULocalVariable (name = runnable) UObjectLiteralExpression - UClass (name = ) \ No newline at end of file + UClass (name = ) diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Anonymous.render.fe10.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Anonymous.render.fe10.txt index bb2e36e3b696..21d24745979a 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Anonymous.render.fe10.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Anonymous.render.fe10.txt @@ -6,7 +6,7 @@ public final class AnonymousKt { var runnable: = anonymous object : Runnable { override fun run() {} } runnable.run() var runnable2: java.lang.Runnable = Runnable({ - println() + return println() }) runnable2.run() var closeableRunnable: = anonymous object : Runnable, Closeable { override fun close() {} override fun run() {} } diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Anonymous.render.fir.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Anonymous.render.fir.txt index a564376deae1..13100572ed7e 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Anonymous.render.fir.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Anonymous.render.fir.txt @@ -6,7 +6,7 @@ public final class AnonymousKt { var runnable: java.lang.Runnable = anonymous object : Runnable { override fun run() {} } runnable.run() var runnable2: java.lang.Runnable = Runnable({ - println() + return println() }) runnable2.run() var closeableRunnable: java.lang.Object = anonymous object : Runnable, Closeable { override fun close() {} override fun run() {} } diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaParameters.log.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaParameters.log.txt index f36a71921310..44c2ad8b4d27 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaParameters.log.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaParameters.log.txt @@ -7,10 +7,11 @@ UFile (package = ) USimpleNameReferenceExpression (identifier = buildString, resolvesTo = null) ULambdaExpression UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (append)) - USimpleNameReferenceExpression (identifier = append, resolvesTo = null) - ULiteralExpression (value = "a") + UReturnExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) + UIdentifier (Identifier (append)) + USimpleNameReferenceExpression (identifier = append, resolvesTo = null) + ULiteralExpression (value = "a") UMethod (name = itParameter) UBlockExpression UQualifiedReferenceExpression @@ -22,4 +23,4 @@ UFile (package = ) UParameter (name = it) UBlockExpression UReturnExpression - USimpleNameReferenceExpression (identifier = it) \ No newline at end of file + USimpleNameReferenceExpression (identifier = it) diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaParameters.render.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaParameters.render.txt index cde604497ecc..1344201a5fcc 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaParameters.render.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaParameters.render.txt @@ -1,7 +1,7 @@ public final class LambdaParametersKt { public static final fun lambdaWithRecivier() : void { buildString({ - append("a") + return append("a") }) } public static final fun itParameter() : void { @@ -10,4 +10,4 @@ public final class LambdaParametersKt { return it }) } -} \ No newline at end of file +} diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaReturn.log.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaReturn.log.txt index 9eeccbf7e338..2b08b1ad101f 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaReturn.log.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaReturn.log.txt @@ -101,36 +101,38 @@ UFile (package = org.jetbrains.uast.kotlin) ULocalVariable (name = x) ULambdaExpression UBlockExpression - UDeclarationsExpression - ULocalVariable (name = vardbcd0724) - UAnnotation (fqName = org.jetbrains.annotations.NotNull) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) - UIdentifier (Identifier (listOf)) - USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) - ULiteralExpression (value = 1) - ULiteralExpression (value = 2) - ULocalVariable (name = a) - UAnnotation (fqName = org.jetbrains.annotations.NotNull) - UQualifiedReferenceExpression - USimpleNameReferenceExpression (identifier = vardbcd0724) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) - UIdentifier (Identifier (component1)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULocalVariable (name = b) - UAnnotation (fqName = org.jetbrains.annotations.NotNull) - UQualifiedReferenceExpression - USimpleNameReferenceExpression (identifier = vardbcd0724) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) - UIdentifier (Identifier (component2)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) + UReturnExpression + UDeclarationsExpression + ULocalVariable (name = vardbcd0724) + UAnnotation (fqName = org.jetbrains.annotations.NotNull) + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) + UIdentifier (Identifier (listOf)) + USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) + ULiteralExpression (value = 1) + ULiteralExpression (value = 2) + ULocalVariable (name = a) + UAnnotation (fqName = org.jetbrains.annotations.NotNull) + UQualifiedReferenceExpression + USimpleNameReferenceExpression (identifier = vardbcd0724) + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + UIdentifier (Identifier (component1)) + USimpleNameReferenceExpression (identifier = , resolvesTo = null) + ULocalVariable (name = b) + UAnnotation (fqName = org.jetbrains.annotations.NotNull) + UQualifiedReferenceExpression + USimpleNameReferenceExpression (identifier = vardbcd0724) + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + UIdentifier (Identifier (component2)) + USimpleNameReferenceExpression (identifier = , resolvesTo = null) UDeclarationsExpression ULocalVariable (name = y) ULambdaExpression UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (listOf)) - USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) - ULiteralExpression (value = 1) + UReturnExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) + UIdentifier (Identifier (listOf)) + USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) + ULiteralExpression (value = 1) UMethod (name = bar) UParameter (name = lmbd) UAnnotation (fqName = org.jetbrains.annotations.NotNull) @@ -138,4 +140,4 @@ UFile (package = org.jetbrains.uast.kotlin) UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) UIdentifier (Identifier (lmbd)) USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) - ULiteralExpression (value = 1) \ No newline at end of file + ULiteralExpression (value = 1) diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaReturn.render.fe10.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaReturn.render.fe10.txt index 7bab5caf59be..c86ccda8006b 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaReturn.render.fe10.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaReturn.render.fe10.txt @@ -31,12 +31,12 @@ public final class LambdaReturnKt { return it + b }) var x: kotlin.jvm.functions.Function0 = { - @org.jetbrains.annotations.NotNull var vardbcd0724: = listOf(1, 2) + return @org.jetbrains.annotations.NotNull var vardbcd0724: = listOf(1, 2) @org.jetbrains.annotations.NotNull var a: int = vardbcd0724.() @org.jetbrains.annotations.NotNull var b: int = vardbcd0724.() } var y: kotlin.jvm.functions.Function0 = { - listOf(1) + return listOf(1) } } private static final fun bar(@org.jetbrains.annotations.NotNull lmbd: kotlin.jvm.functions.Function1) : void { diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaReturn.render.fir.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaReturn.render.fir.txt index 8f584bc87858..c6e7329b3b70 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaReturn.render.fir.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/LambdaReturn.render.fir.txt @@ -31,12 +31,12 @@ public final class LambdaReturnKt { return it + b }) var x: kotlin.jvm.functions.Function0 = { - @org.jetbrains.annotations.NotNull var vardbcd0724: java.util.List = listOf(1, 2) + return @org.jetbrains.annotations.NotNull var vardbcd0724: java.util.List = listOf(1, 2) @org.jetbrains.annotations.NotNull var a: int = vardbcd0724.() @org.jetbrains.annotations.NotNull var b: int = vardbcd0724.() } var y: kotlin.jvm.functions.Function0 = { - listOf(1) + return listOf(1) } } private static final fun bar(@org.jetbrains.annotations.NotNull lmbd: kotlin.jvm.functions.Function1) : void { diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/NonTrivialIdentifiers.log.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/NonTrivialIdentifiers.log.txt index 495ad931ba96..0f9217932608 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/NonTrivialIdentifiers.log.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/NonTrivialIdentifiers.log.txt @@ -17,14 +17,16 @@ UFile (package = ) USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) ULambdaExpression UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (p)) - USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) - ULambdaExpression - UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) - UIdentifier (Identifier (()) - USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) + UReturnExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) + UIdentifier (Identifier (p)) + USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) + ULambdaExpression + UBlockExpression + UReturnExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + UIdentifier (Identifier (()) + USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) UClass (name = A) UMethod (name = invoke) UBlockExpression diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/NonTrivialIdentifiers.render.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/NonTrivialIdentifiers.render.txt index b86e5d287929..126a378ddd30 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/NonTrivialIdentifiers.render.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/NonTrivialIdentifiers.render.txt @@ -3,8 +3,8 @@ public final class NonTrivialIdentifiersKt { invoke() var p: A = () invoke({ - invoke({ - invoke() + return invoke({ + return invoke() }) }) } @@ -17,4 +17,4 @@ public final class A { public final fun invoke(@org.jetbrains.annotations.NotNull f: kotlin.jvm.functions.Function0) : void { } public fun A() = UastEmptyExpression -} \ No newline at end of file +} diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/ParametersDisorder.log.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/ParametersDisorder.log.txt index 3ff64942066a..053f71ba6c6e 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/ParametersDisorder.log.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/ParametersDisorder.log.txt @@ -131,13 +131,14 @@ UFile (package = ) USimpleNameReferenceExpression (identifier = , resolvesTo = PsiClass: A) ULambdaExpression UBlockExpression - UQualifiedReferenceExpression - ULiteralExpression (value = "def") - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) - UIdentifier (Identifier (with2Receivers)) - USimpleNameReferenceExpression (identifier = with2Receivers, resolvesTo = null) - ULiteralExpression (value = 8) - ULiteralExpression (value = 7.0) + UReturnExpression + UQualifiedReferenceExpression + ULiteralExpression (value = "def") + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) + UIdentifier (Identifier (with2Receivers)) + USimpleNameReferenceExpression (identifier = with2Receivers, resolvesTo = null) + ULiteralExpression (value = 8) + ULiteralExpression (value = 7.0) UMethod (name = objectLiteral) UBlockExpression UObjectLiteralExpression @@ -166,4 +167,4 @@ UFile (package = ) UParameter (name = a) UAnnotation (fqName = org.jetbrains.annotations.NotNull) UParameter (name = b) - UAnnotation (fqName = org.jetbrains.annotations.NotNull) \ No newline at end of file + UAnnotation (fqName = org.jetbrains.annotations.NotNull) diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/ParametersDisorder.render.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/ParametersDisorder.render.txt index 5e784cd832d2..4076b88d6cfa 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/ParametersDisorder.render.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/ParametersDisorder.render.txt @@ -16,7 +16,7 @@ public final class ParametersDisorderKt { java.lang.String.format("%i %i %i", arrayOf(1, 2, 3), arrayOf(4, 5, 6)) java.lang.String.format("%i %i %i", "".chunked(2).toTypedArray()) with((), { - "def".with2Receivers(8, 7.0) + return "def".with2Receivers(8, 7.0) }) } public static final fun objectLiteral() : void { @@ -32,4 +32,4 @@ public final class A { public class Parent { public fun Parent(@org.jetbrains.annotations.NotNull a: java.lang.String, @org.jetbrains.annotations.NotNull b: int) = UastEmptyExpression -} \ No newline at end of file +} diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Resolve.log.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Resolve.log.txt index f88219b46a8f..cb3e3f09b90e 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Resolve.log.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Resolve.log.txt @@ -29,10 +29,11 @@ UFile (package = ) ULambdaExpression UParameter (name = it) UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (println)) - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) - USimpleNameReferenceExpression (identifier = it) + UReturnExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) + UIdentifier (Identifier (println)) + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) + USimpleNameReferenceExpression (identifier = it) UQualifiedReferenceExpression UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) UIdentifier (Identifier (listOf)) @@ -144,4 +145,4 @@ UFile (package = ) UBlockExpression UMethod (name = inlineFoo) UBlockExpression - UMethod (name = A) \ No newline at end of file + UMethod (name = A) diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Resolve.render.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Resolve.render.txt index b39dd9597510..45ece02c605c 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Resolve.render.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/Resolve.render.txt @@ -4,7 +4,7 @@ public final class ResolveKt { ().inlineFoo() listOf(()).forEach({ var it: A -> - println(it) + return println(it) }) listOf("").joinToString() listOf("").size @@ -34,4 +34,4 @@ public class A { public final fun inlineFoo() : void { } public fun A() = UastEmptyExpression -} \ No newline at end of file +} diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/SAM.log.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/SAM.log.txt index 529952e66a28..c5a588ec72b2 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/SAM.log.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/SAM.log.txt @@ -85,10 +85,11 @@ UFile (package = ) USimpleNameReferenceExpression (identifier = , resolvesTo = PsiClass: Thread) ULambdaExpression UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (println)) - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) - ULiteralExpression (value = "hello1") + UReturnExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) + UIdentifier (Identifier (println)) + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) + ULiteralExpression (value = "hello1") UMethod (name = test2) UBlockExpression UDeclarationsExpression @@ -101,10 +102,11 @@ UFile (package = ) USimpleNameReferenceExpression (identifier = Runnable, resolvesTo = PsiClass: Runnable) ULambdaExpression UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (println)) - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) - ULiteralExpression (value = "hello2") + UReturnExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) + UIdentifier (Identifier (println)) + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) + ULiteralExpression (value = "hello2") UMethod (name = test3) UBlockExpression UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/SAM.render.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/SAM.render.txt index 5a994034074c..dbc71924af3b 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/SAM.render.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyRenderLog/SAM.render.txt @@ -44,12 +44,12 @@ public final class SAMKt { } public static final fun test1() : void { var thread1: java.lang.Thread = ({ - println("hello1") + return println("hello1") }) } public static final fun test2() : void { var thread2: java.lang.Thread = (Runnable({ - println("hello2") + return println("hello2") })) } public static final fun test3() : void { diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/NonTrivialIdentifiers.resolved.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/NonTrivialIdentifiers.resolved.txt index e45388789d9b..6cde2fc58b27 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/NonTrivialIdentifiers.resolved.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/NonTrivialIdentifiers.resolved.txt @@ -40,7 +40,7 @@ UTypeReferenceExpression (name = A) -> USimpleNameReferenceExpression (identifie UPostfixExpression (operator = !!) -> USimpleNameReferenceExpression (identifier = a) -> Kotlin_Light_Value_Parameter: a UPostfixExpression (operator = !!) -> USimpleNameReferenceExpression (identifier = !!) -> null: null UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))(resolves to Kotlin_Light_Method) -> USimpleNameReferenceExpression (identifier = p) -> Kotlin_Light_Variable: p - UBlockExpression -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) -> Kotlin_Light_Method: + UReturnExpression -> UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) -> Kotlin_Light_Method: UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0))(resolves to Kotlin_Light_Method) -> USimpleNameReferenceExpression (identifier = A) -> Kotlin_Light_Class:class A { operator fun invoke(){ @@ -51,4 +51,4 @@ UTypeReferenceExpression (name = A) -> USimpleNameReferenceExpression (identifie } -}: A \ No newline at end of file +}: A diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/ParametersDisorder.resolved.fe10.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/ParametersDisorder.resolved.fe10.txt index 84eab8946aac..35c2844c1004 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/ParametersDisorder.resolved.fe10.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/ParametersDisorder.resolved.fe10.txt @@ -57,7 +57,7 @@ UTypeReferenceExpression (name = float) -> USimpleNameReferenceExpression (ident fun String.with2Receivers(a: Int, b: Float) {} }: A - UBlockExpression -> UQualifiedReferenceExpression -> Kotlin_Light_Method: with2Receivers + UReturnExpression -> UQualifiedReferenceExpression -> Kotlin_Light_Method: with2Receivers UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2))(resolves to Kotlin_Light_Method) -> USimpleNameReferenceExpression (identifier = with2Receivers) -> Kotlin_Light_Method: with2Receivers UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> Decompiled_Class: String UTypeReferenceExpression (name = int) -> USimpleNameReferenceExpression (identifier = Int) -> Decompiled_Class: Integer diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/ParametersDisorder.resolved.fir.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/ParametersDisorder.resolved.fir.txt index cd43ae1b4723..abf58cb3a1cd 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/ParametersDisorder.resolved.fir.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/ParametersDisorder.resolved.fir.txt @@ -57,7 +57,7 @@ UTypeReferenceExpression (name = float) -> USimpleNameReferenceExpression (ident fun String.with2Receivers(a: Int, b: Float) {} }: A - UBlockExpression -> UQualifiedReferenceExpression -> Kotlin_Light_Method: with2Receivers + UReturnExpression -> UQualifiedReferenceExpression -> Kotlin_Light_Method: with2Receivers UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2))(resolves to Kotlin_Light_Method) -> USimpleNameReferenceExpression (identifier = with2Receivers) -> Kotlin_Light_Method: with2Receivers UTypeReferenceExpression (name = java.lang.String) -> USimpleNameReferenceExpression (identifier = String) -> Decompiled_Class: String UTypeReferenceExpression (name = int) -> USimpleNameReferenceExpression (identifier = Int) -> Decompiled_Class: Integer diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/Reified.resolved.fir.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/Reified.resolved.fir.txt deleted file mode 100644 index c48904db2d35..000000000000 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/Reified.resolved.fir.txt +++ /dev/null @@ -1,27 +0,0 @@ -null -> UQualifiedReferenceExpression -> PsiPackage:test.pkg: pkg -UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = test) -> PsiPackage:test: test -UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = pkg) -> PsiPackage:test.pkg: pkg -UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))(resolves to null) -> USimpleNameReferenceExpression (identifier = getSystemService) -> null: null -UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))(resolves to null) -> UQualifiedReferenceExpression -> Decompiled_Method: getJavaClass -UClassLiteralExpression -> USimpleNameReferenceExpression (identifier = T) -> null: null -UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = java) -> Decompiled_Method: getJavaClass -UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))(resolves to null) -> USimpleNameReferenceExpression (identifier = getSystemService) -> null: null -UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))(resolves to null) -> UQualifiedReferenceExpression -> Decompiled_Method: getJavaClass -UClassLiteralExpression -> USimpleNameReferenceExpression (identifier = String) -> Decompiled_Class: String -UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = java) -> Decompiled_Method: getJavaClass -UTypeReferenceExpression (name = test.pkg.Context) -> USimpleNameReferenceExpression (identifier = Context) -> Kotlin_Light_Class:class Context { - inline fun ownSystemService1() = getSystemService(T::class.java) - inline fun ownSystemService2() = getSystemService(String::class.java) -}: Context -UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))(resolves to null) -> USimpleNameReferenceExpression (identifier = getSystemService) -> null: null -UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))(resolves to null) -> UQualifiedReferenceExpression -> Decompiled_Method: getJavaClass -UClassLiteralExpression -> USimpleNameReferenceExpression (identifier = T) -> null: null -UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = java) -> Decompiled_Method: getJavaClass -UTypeReferenceExpression (name = test.pkg.Context) -> USimpleNameReferenceExpression (identifier = Context) -> Kotlin_Light_Class:class Context { - inline fun ownSystemService1() = getSystemService(T::class.java) - inline fun ownSystemService2() = getSystemService(String::class.java) -}: Context -UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))(resolves to null) -> USimpleNameReferenceExpression (identifier = getSystemService) -> null: null -UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1))(resolves to null) -> UQualifiedReferenceExpression -> Decompiled_Method: getJavaClass -UClassLiteralExpression -> USimpleNameReferenceExpression (identifier = String) -> Decompiled_Class: String -UQualifiedReferenceExpression -> USimpleNameReferenceExpression (identifier = java) -> Decompiled_Method: getJavaClass diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/Reified.resolved.fe10.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/Reified.resolved.txt similarity index 100% rename from plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/Reified.resolved.fe10.txt rename to plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyResolved/Reified.resolved.txt diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/Anonymous.types.fe10.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/Anonymous.types.fe10.txt index aee90bec2219..56a2e86f1837 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/Anonymous.types.fe10.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/Anonymous.types.fe10.txt @@ -23,9 +23,10 @@ UFile (package = ) [import java.io.Closeable...] USimpleNameReferenceExpression (identifier = Runnable, resolvesTo = PsiClass: Runnable) [Runnable] : PsiType:Runnable ULambdaExpression [{ ...}] : PsiType:Function0 UBlockExpression [{...}] - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [println()] : PsiType:Unit - UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] : PsiType:Unit + UReturnExpression [return println()] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [println()] : PsiType:Unit + UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] : PsiType:Unit UQualifiedReferenceExpression [runnable2.run()] : PsiType:Unit USimpleNameReferenceExpression (identifier = runnable2) [runnable2] : PsiType:Runnable UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [run()] : PsiType:Unit diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/Anonymous.types.fir.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/Anonymous.types.fir.txt index 38874e8f0195..86a1e1052fba 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/Anonymous.types.fir.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/Anonymous.types.fir.txt @@ -23,9 +23,10 @@ UFile (package = ) [import java.io.Closeable...] USimpleNameReferenceExpression (identifier = Runnable, resolvesTo = PsiClass: Runnable) [Runnable] : PsiType:Runnable ULambdaExpression [{ ...}] : PsiType:Function0 UBlockExpression [{...}] : PsiType:Unit - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [println()] : PsiType:Unit - UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] : PsiType:Unit + UReturnExpression [return println()] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [println()] : PsiType:Unit + UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] : PsiType:Unit UQualifiedReferenceExpression [runnable2.run()] : PsiType:Unit USimpleNameReferenceExpression (identifier = runnable2) [runnable2] : PsiType:Runnable UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [run()] : PsiType:Unit diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/LambdaParameters.types.fe10.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/LambdaParameters.types.fe10.txt index e3d148b416f5..80a770af8912 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/LambdaParameters.types.fe10.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/LambdaParameters.types.fe10.txt @@ -7,10 +7,11 @@ UFile (package = ) [public final class LambdaParametersKt {...] USimpleNameReferenceExpression (identifier = buildString, resolvesTo = null) [buildString] : PsiType:String ULambdaExpression [{ ...}] : PsiType:Function1 UBlockExpression [{...}] - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [append("a")] : PsiType:StringBuilder - UIdentifier (Identifier (append)) [UIdentifier (Identifier (append))] - USimpleNameReferenceExpression (identifier = append, resolvesTo = null) [append] : PsiType:StringBuilder - ULiteralExpression (value = "a") ["a"] : PsiType:String + UReturnExpression [return append("a")] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [append("a")] : PsiType:StringBuilder + UIdentifier (Identifier (append)) [UIdentifier (Identifier (append))] + USimpleNameReferenceExpression (identifier = append, resolvesTo = null) [append] : PsiType:StringBuilder + ULiteralExpression (value = "a") ["a"] : PsiType:String UMethod (name = itParameter) [public static final fun itParameter() : void {...}] UBlockExpression [{...}] : PsiType:int UQualifiedReferenceExpression [10.let({ var it: int ->...})] : PsiType:int diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/LambdaParameters.types.fir.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/LambdaParameters.types.fir.txt index a3845fcb10d4..b34a11a23c97 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/LambdaParameters.types.fir.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/LambdaParameters.types.fir.txt @@ -7,10 +7,11 @@ UFile (package = ) [public final class LambdaParametersKt {...] USimpleNameReferenceExpression (identifier = buildString, resolvesTo = null) [buildString] : PsiType:String ULambdaExpression [{ ...}] : PsiType:Function1 UBlockExpression [{...}] : PsiType:Unit - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [append("a")] : PsiType:StringBuilder - UIdentifier (Identifier (append)) [UIdentifier (Identifier (append))] - USimpleNameReferenceExpression (identifier = append, resolvesTo = null) [append] : PsiType:StringBuilder - ULiteralExpression (value = "a") ["a"] : PsiType:String + UReturnExpression [return append("a")] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [append("a")] : PsiType:StringBuilder + UIdentifier (Identifier (append)) [UIdentifier (Identifier (append))] + USimpleNameReferenceExpression (identifier = append, resolvesTo = null) [append] : PsiType:StringBuilder + ULiteralExpression (value = "a") ["a"] : PsiType:String UMethod (name = itParameter) [public static final fun itParameter() : void {...}] UBlockExpression [{...}] : PsiType:int UQualifiedReferenceExpression [10.let({ var it: int ->...})] : PsiType:int diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/LambdaReturn.types.fe10.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/LambdaReturn.types.fe10.txt index e160185d089b..9a89ce5f342e 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/LambdaReturn.types.fe10.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/LambdaReturn.types.fe10.txt @@ -101,36 +101,38 @@ UFile (package = org.jetbrains.uast.kotlin) [package org.jetbrains.uast.kotlin.. ULocalVariable (name = x) [var x: kotlin.jvm.functions.Function0 = { ...}] ULambdaExpression [{ ...}] : PsiType:Function0 UBlockExpression [{...}] - UDeclarationsExpression [@org.jetbrains.annotations.NotNull var vardbcd0724: = listOf(1, 2)...@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] - ULocalVariable (name = vardbcd0724) [@org.jetbrains.annotations.NotNull var vardbcd0724: = listOf(1, 2)] - UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [listOf(1, 2)] : PsiType:List - UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] - USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) [listOf] : PsiType:List - ULiteralExpression (value = 1) [1] : PsiType:int - ULiteralExpression (value = 2) [2] : PsiType:int - ULocalVariable (name = a) [@org.jetbrains.annotations.NotNull var a: int = vardbcd0724.()] - UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] - UQualifiedReferenceExpression [vardbcd0724.()] - USimpleNameReferenceExpression (identifier = vardbcd0724) [vardbcd0724] - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [()] - UIdentifier (Identifier (component1)) [UIdentifier (Identifier (component1))] - USimpleNameReferenceExpression (identifier = , resolvesTo = null) [] - ULocalVariable (name = b) [@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] - UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] - UQualifiedReferenceExpression [vardbcd0724.()] - USimpleNameReferenceExpression (identifier = vardbcd0724) [vardbcd0724] - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [()] - UIdentifier (Identifier (component2)) [UIdentifier (Identifier (component2))] - USimpleNameReferenceExpression (identifier = , resolvesTo = null) [] + UReturnExpression [return @org.jetbrains.annotations.NotNull var vardbcd0724: = listOf(1, 2)...@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] + UDeclarationsExpression [@org.jetbrains.annotations.NotNull var vardbcd0724: = listOf(1, 2)...@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] + ULocalVariable (name = vardbcd0724) [@org.jetbrains.annotations.NotNull var vardbcd0724: = listOf(1, 2)] + UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [listOf(1, 2)] : PsiType:List + UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] + USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) [listOf] : PsiType:List + ULiteralExpression (value = 1) [1] : PsiType:int + ULiteralExpression (value = 2) [2] : PsiType:int + ULocalVariable (name = a) [@org.jetbrains.annotations.NotNull var a: int = vardbcd0724.()] + UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] + UQualifiedReferenceExpression [vardbcd0724.()] + USimpleNameReferenceExpression (identifier = vardbcd0724) [vardbcd0724] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [()] + UIdentifier (Identifier (component1)) [UIdentifier (Identifier (component1))] + USimpleNameReferenceExpression (identifier = , resolvesTo = null) [] + ULocalVariable (name = b) [@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] + UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] + UQualifiedReferenceExpression [vardbcd0724.()] + USimpleNameReferenceExpression (identifier = vardbcd0724) [vardbcd0724] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [()] + UIdentifier (Identifier (component2)) [UIdentifier (Identifier (component2))] + USimpleNameReferenceExpression (identifier = , resolvesTo = null) [] UDeclarationsExpression [var y: kotlin.jvm.functions.Function0 = { ...}] ULocalVariable (name = y) [var y: kotlin.jvm.functions.Function0 = { ...}] ULambdaExpression [{ ...}] : PsiType:Function0 UBlockExpression [{...}] - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [listOf(1)] : PsiType:List - UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] - USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) [listOf] : PsiType:List - ULiteralExpression (value = 1) [1] : PsiType:int + UReturnExpression [return listOf(1)] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [listOf(1)] : PsiType:List + UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] + USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) [listOf] : PsiType:List + ULiteralExpression (value = 1) [1] : PsiType:int UMethod (name = bar) [private static final fun bar(@org.jetbrains.annotations.NotNull lmbd: kotlin.jvm.functions.Function1) : void {...}] UParameter (name = lmbd) [@org.jetbrains.annotations.NotNull var lmbd: kotlin.jvm.functions.Function1] UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/LambdaReturn.types.fir.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/LambdaReturn.types.fir.txt index 89b481690af3..8c62f99ae92a 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/LambdaReturn.types.fir.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/LambdaReturn.types.fir.txt @@ -101,36 +101,38 @@ UFile (package = org.jetbrains.uast.kotlin) [package org.jetbrains.uast.kotlin.. ULocalVariable (name = x) [var x: kotlin.jvm.functions.Function0 = { ...}] ULambdaExpression [{ ...}] : PsiType:Function0 UBlockExpression [{...}] : PsiType:Unit - UDeclarationsExpression [@org.jetbrains.annotations.NotNull var vardbcd0724: java.util.List = listOf(1, 2)...@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] - ULocalVariable (name = vardbcd0724) [@org.jetbrains.annotations.NotNull var vardbcd0724: java.util.List = listOf(1, 2)] - UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [listOf(1, 2)] : PsiType:List - UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] - USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) [listOf] : PsiType:List - ULiteralExpression (value = 1) [1] : PsiType:int - ULiteralExpression (value = 2) [2] : PsiType:int - ULocalVariable (name = a) [@org.jetbrains.annotations.NotNull var a: int = vardbcd0724.()] - UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] - UQualifiedReferenceExpression [vardbcd0724.()] : PsiType: - USimpleNameReferenceExpression (identifier = vardbcd0724) [vardbcd0724] : PsiType: - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [()] : PsiType: - UIdentifier (Identifier (component1)) [UIdentifier (Identifier (component1))] - USimpleNameReferenceExpression (identifier = , resolvesTo = null) [] : PsiType: - ULocalVariable (name = b) [@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] - UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] - UQualifiedReferenceExpression [vardbcd0724.()] : PsiType: - USimpleNameReferenceExpression (identifier = vardbcd0724) [vardbcd0724] : PsiType: - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [()] : PsiType: - UIdentifier (Identifier (component2)) [UIdentifier (Identifier (component2))] - USimpleNameReferenceExpression (identifier = , resolvesTo = null) [] : PsiType: + UReturnExpression [return @org.jetbrains.annotations.NotNull var vardbcd0724: java.util.List = listOf(1, 2)...@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] + UDeclarationsExpression [@org.jetbrains.annotations.NotNull var vardbcd0724: java.util.List = listOf(1, 2)...@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] + ULocalVariable (name = vardbcd0724) [@org.jetbrains.annotations.NotNull var vardbcd0724: java.util.List = listOf(1, 2)] + UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [listOf(1, 2)] : PsiType:List + UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] + USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) [listOf] : PsiType:List + ULiteralExpression (value = 1) [1] : PsiType:int + ULiteralExpression (value = 2) [2] : PsiType:int + ULocalVariable (name = a) [@org.jetbrains.annotations.NotNull var a: int = vardbcd0724.()] + UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] + UQualifiedReferenceExpression [vardbcd0724.()] : PsiType: + USimpleNameReferenceExpression (identifier = vardbcd0724) [vardbcd0724] : PsiType: + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [()] : PsiType: + UIdentifier (Identifier (component1)) [UIdentifier (Identifier (component1))] + USimpleNameReferenceExpression (identifier = , resolvesTo = null) [] : PsiType: + ULocalVariable (name = b) [@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] + UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] + UQualifiedReferenceExpression [vardbcd0724.()] : PsiType: + USimpleNameReferenceExpression (identifier = vardbcd0724) [vardbcd0724] : PsiType: + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [()] : PsiType: + UIdentifier (Identifier (component2)) [UIdentifier (Identifier (component2))] + USimpleNameReferenceExpression (identifier = , resolvesTo = null) [] : PsiType: UDeclarationsExpression [var y: kotlin.jvm.functions.Function0 = { ...}] ULocalVariable (name = y) [var y: kotlin.jvm.functions.Function0 = { ...}] ULambdaExpression [{ ...}] : PsiType:Function0 UBlockExpression [{...}] : PsiType:Unit - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [listOf(1)] : PsiType:List - UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] - USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) [listOf] : PsiType:List - ULiteralExpression (value = 1) [1] : PsiType:int + UReturnExpression [return listOf(1)] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [listOf(1)] : PsiType:List + UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] + USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) [listOf] : PsiType:List + ULiteralExpression (value = 1) [1] : PsiType:int UMethod (name = bar) [private static final fun bar(@org.jetbrains.annotations.NotNull lmbd: kotlin.jvm.functions.Function1) : void {...}] UParameter (name = lmbd) [@org.jetbrains.annotations.NotNull var lmbd: kotlin.jvm.functions.Function1] UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/NonTrivialIdentifiers.types.fe10.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/NonTrivialIdentifiers.types.fe10.txt index b5d32b8c93a2..a41d7ab6ff36 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/NonTrivialIdentifiers.types.fe10.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/NonTrivialIdentifiers.types.fe10.txt @@ -17,14 +17,16 @@ UFile (package = ) [public final class NonTrivialIdentifiersKt {...] USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) [invoke] : PsiType:Unit ULambdaExpression [{ ...}] : PsiType:Function0 UBlockExpression [{...}] - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [invoke({ ...})] : PsiType:Unit - UIdentifier (Identifier (p)) [UIdentifier (Identifier (p))] - USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) [invoke] : PsiType:Unit - ULambdaExpression [{ ...}] : PsiType:Function0 - UBlockExpression [{...}] - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [invoke()] : PsiType:Unit - UIdentifier (Identifier (()) [UIdentifier (Identifier (())] - USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) [invoke] : PsiType:Unit + UReturnExpression [return invoke({ ...})] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [invoke({ ...})] : PsiType:Unit + UIdentifier (Identifier (p)) [UIdentifier (Identifier (p))] + USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) [invoke] : PsiType:Unit + ULambdaExpression [{ ...}] : PsiType:Function0 + UBlockExpression [{...}] + UReturnExpression [return invoke()] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [invoke()] : PsiType:Unit + UIdentifier (Identifier (()) [UIdentifier (Identifier (())] + USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) [invoke] : PsiType:Unit UClass (name = A) [public final class A {...}] UMethod (name = invoke) [public final fun invoke() : void {...}] UBlockExpression [{...}] : PsiType:void diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/NonTrivialIdentifiers.types.fir.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/NonTrivialIdentifiers.types.fir.txt index 503370048841..e50fe025e01c 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/NonTrivialIdentifiers.types.fir.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/NonTrivialIdentifiers.types.fir.txt @@ -17,14 +17,16 @@ UFile (package = ) [public final class NonTrivialIdentifiersKt {...] USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) [invoke] : PsiType:Unit ULambdaExpression [{ ...}] : PsiType:Function0 UBlockExpression [{...}] : PsiType:Unit - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [invoke({ ...})] : PsiType:Unit - UIdentifier (Identifier (p)) [UIdentifier (Identifier (p))] - USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) [invoke] : PsiType:Unit - ULambdaExpression [{ ...}] : PsiType:Function0 - UBlockExpression [{...}] : PsiType:Unit - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [invoke()] : PsiType:Unit - UIdentifier (Identifier (()) [UIdentifier (Identifier (())] - USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) [invoke] : PsiType:Unit + UReturnExpression [return invoke({ ...})] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [invoke({ ...})] : PsiType:Unit + UIdentifier (Identifier (p)) [UIdentifier (Identifier (p))] + USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) [invoke] : PsiType:Unit + ULambdaExpression [{ ...}] : PsiType:Function0 + UBlockExpression [{...}] : PsiType:Unit + UReturnExpression [return invoke()] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [invoke()] : PsiType:Unit + UIdentifier (Identifier (()) [UIdentifier (Identifier (())] + USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) [invoke] : PsiType:Unit UClass (name = A) [public final class A {...}] UMethod (name = invoke) [public final fun invoke() : void {...}] UBlockExpression [{...}] : PsiType:void diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/ParametersDisorder.types.fe10.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/ParametersDisorder.types.fe10.txt index e1cc64f51a6a..27db8c63e9de 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/ParametersDisorder.types.fe10.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/ParametersDisorder.types.fe10.txt @@ -131,13 +131,14 @@ UFile (package = ) [public final class ParametersDisorderKt {...] USimpleNameReferenceExpression (identifier = , resolvesTo = PsiClass: A) [] : PsiType:A ULambdaExpression [{ ...}] : PsiType:Function1 UBlockExpression [{...}] - UQualifiedReferenceExpression ["def".with2Receivers(8, 7.0)] : PsiType:Unit - ULiteralExpression (value = "def") ["def"] : PsiType:String - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [with2Receivers(8, 7.0)] : PsiType:Unit - UIdentifier (Identifier (with2Receivers)) [UIdentifier (Identifier (with2Receivers))] - USimpleNameReferenceExpression (identifier = with2Receivers, resolvesTo = null) [with2Receivers] : PsiType:Unit - ULiteralExpression (value = 8) [8] : PsiType:int - ULiteralExpression (value = 7.0) [7.0] : PsiType:float + UReturnExpression [return "def".with2Receivers(8, 7.0)] + UQualifiedReferenceExpression ["def".with2Receivers(8, 7.0)] : PsiType:Unit + ULiteralExpression (value = "def") ["def"] : PsiType:String + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [with2Receivers(8, 7.0)] : PsiType:Unit + UIdentifier (Identifier (with2Receivers)) [UIdentifier (Identifier (with2Receivers))] + USimpleNameReferenceExpression (identifier = with2Receivers, resolvesTo = null) [with2Receivers] : PsiType:Unit + ULiteralExpression (value = 8) [8] : PsiType:int + ULiteralExpression (value = 7.0) [7.0] : PsiType:float UMethod (name = objectLiteral) [public static final fun objectLiteral() : void {...}] UBlockExpression [{...}] : PsiType: UObjectLiteralExpression [anonymous object : Parent(b = 1, a = "foo") { }] : PsiType:Parent diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/ParametersDisorder.types.fir.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/ParametersDisorder.types.fir.txt index 61436d7e3149..72269282b92b 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/ParametersDisorder.types.fir.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/ParametersDisorder.types.fir.txt @@ -131,13 +131,14 @@ UFile (package = ) [public final class ParametersDisorderKt {...] USimpleNameReferenceExpression (identifier = , resolvesTo = PsiClass: A) [] : PsiType:A ULambdaExpression [{ ...}] : PsiType:Function1 UBlockExpression [{...}] : PsiType:Unit - UQualifiedReferenceExpression ["def".with2Receivers(8, 7.0)] : PsiType:Unit - ULiteralExpression (value = "def") ["def"] : PsiType:String - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [with2Receivers(8, 7.0)] : PsiType:Unit - UIdentifier (Identifier (with2Receivers)) [UIdentifier (Identifier (with2Receivers))] - USimpleNameReferenceExpression (identifier = with2Receivers, resolvesTo = null) [with2Receivers] : PsiType:Unit - ULiteralExpression (value = 8) [8] : PsiType:int - ULiteralExpression (value = 7.0) [7.0] : PsiType:float + UReturnExpression [return "def".with2Receivers(8, 7.0)] + UQualifiedReferenceExpression ["def".with2Receivers(8, 7.0)] : PsiType:Unit + ULiteralExpression (value = "def") ["def"] : PsiType:String + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [with2Receivers(8, 7.0)] : PsiType:Unit + UIdentifier (Identifier (with2Receivers)) [UIdentifier (Identifier (with2Receivers))] + USimpleNameReferenceExpression (identifier = with2Receivers, resolvesTo = null) [with2Receivers] : PsiType:Unit + ULiteralExpression (value = 8) [8] : PsiType:int + ULiteralExpression (value = 7.0) [7.0] : PsiType:float UMethod (name = objectLiteral) [public static final fun objectLiteral() : void {...}] UBlockExpression [{...}] : PsiType:Parent UObjectLiteralExpression [anonymous object : Parent(b = 1, a = "foo") { }] : PsiType:Parent diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/Resolve.types.fe10.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/Resolve.types.fe10.txt index c19bd5ccd6b0..d1a07f88a14e 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/Resolve.types.fe10.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/Resolve.types.fe10.txt @@ -29,10 +29,11 @@ UFile (package = ) [public final class ResolveKt {...] ULambdaExpression [{ var it: A ->...}] : PsiType:Function1 UParameter (name = it) [var it: A] UBlockExpression [{...}] - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [println(it)] : PsiType:Unit - UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] : PsiType:Unit - USimpleNameReferenceExpression (identifier = it) [it] : PsiType:A + UReturnExpression [return println(it)] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [println(it)] : PsiType:Unit + UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] : PsiType:Unit + USimpleNameReferenceExpression (identifier = it) [it] : PsiType:A UQualifiedReferenceExpression [listOf("").joinToString()] : PsiType:String UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [listOf("")] : PsiType:List UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/Resolve.types.fir.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/Resolve.types.fir.txt index 733236e266c0..d462c59fc2a2 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/Resolve.types.fir.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/Resolve.types.fir.txt @@ -29,10 +29,11 @@ UFile (package = ) [public final class ResolveKt {...] ULambdaExpression [{ var it: A ->...}] : PsiType:Function1 UParameter (name = it) [var it: A] UBlockExpression [{...}] : PsiType:Unit - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [println(it)] : PsiType:Unit - UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] : PsiType:Unit - USimpleNameReferenceExpression (identifier = it) [it] : PsiType:A + UReturnExpression [return println(it)] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [println(it)] : PsiType:Unit + UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] : PsiType:Unit + USimpleNameReferenceExpression (identifier = it) [it] : PsiType:A UQualifiedReferenceExpression [listOf("").joinToString()] : PsiType:String UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [listOf("")] : PsiType:List UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/SAM.types.fe10.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/SAM.types.fe10.txt index 5fdb48dcbe3f..29ed01d85ddf 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/SAM.types.fe10.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/SAM.types.fe10.txt @@ -85,10 +85,11 @@ UFile (package = ) [import java.lang.Thread...] USimpleNameReferenceExpression (identifier = , resolvesTo = PsiClass: Thread) [] : PsiType:Thread ULambdaExpression [{ ...}] : PsiType:Function0 UBlockExpression [{...}] - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [println("hello1")] : PsiType:Unit - UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] : PsiType:Unit - ULiteralExpression (value = "hello1") ["hello1"] : PsiType:String + UReturnExpression [return println("hello1")] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [println("hello1")] : PsiType:Unit + UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] : PsiType:Unit + ULiteralExpression (value = "hello1") ["hello1"] : PsiType:String UMethod (name = test2) [public static final fun test2() : void {...}] UBlockExpression [{...}] : PsiType:void UDeclarationsExpression [var thread2: java.lang.Thread = (Runnable({ ...}))] @@ -101,10 +102,11 @@ UFile (package = ) [import java.lang.Thread...] USimpleNameReferenceExpression (identifier = Runnable, resolvesTo = PsiClass: Runnable) [Runnable] : PsiType:Runnable ULambdaExpression [{ ...}] : PsiType:Function0 UBlockExpression [{...}] - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [println("hello2")] : PsiType:Unit - UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] : PsiType:Unit - ULiteralExpression (value = "hello2") ["hello2"] : PsiType:String + UReturnExpression [return println("hello2")] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [println("hello2")] : PsiType:Unit + UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] : PsiType:Unit + ULiteralExpression (value = "hello2") ["hello2"] : PsiType:String UMethod (name = test3) [public static final fun test3() : void {...}] UBlockExpression [{...}] : PsiType:String UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [ambiguousSamAcceptor(Supplier({ ...}))] : PsiType:String diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/SAM.types.fir.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/SAM.types.fir.txt index 0b20e07be357..389cf9e10478 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/SAM.types.fir.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyTypes/SAM.types.fir.txt @@ -85,10 +85,11 @@ UFile (package = ) [import java.lang.Thread...] USimpleNameReferenceExpression (identifier = , resolvesTo = PsiClass: Thread) [] : PsiType:Thread ULambdaExpression [{ ...}] : PsiType:Function0 UBlockExpression [{...}] : PsiType:Unit - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [println("hello1")] : PsiType:Unit - UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] : PsiType:Unit - ULiteralExpression (value = "hello1") ["hello1"] : PsiType:String + UReturnExpression [return println("hello1")] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [println("hello1")] : PsiType:Unit + UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] : PsiType:Unit + ULiteralExpression (value = "hello1") ["hello1"] : PsiType:String UMethod (name = test2) [public static final fun test2() : void {...}] UBlockExpression [{...}] : PsiType:void UDeclarationsExpression [var thread2: java.lang.Thread = (Runnable({ ...}))] @@ -101,10 +102,11 @@ UFile (package = ) [import java.lang.Thread...] USimpleNameReferenceExpression (identifier = Runnable, resolvesTo = PsiClass: Runnable) [Runnable] : PsiType:Runnable ULambdaExpression [{ ...}] : PsiType:Function0 UBlockExpression [{...}] : PsiType:Unit - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [println("hello2")] : PsiType:Unit - UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] : PsiType:Unit - ULiteralExpression (value = "hello2") ["hello2"] : PsiType:String + UReturnExpression [return println("hello2")] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [println("hello2")] : PsiType:Unit + UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] : PsiType:Unit + ULiteralExpression (value = "hello2") ["hello2"] : PsiType:String UMethod (name = test3) [public static final fun test3() : void {...}] UBlockExpression [{...}] : PsiType:String UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [ambiguousSamAcceptor(Supplier({ ...}))] : PsiType:String diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/Anonymous.values.fe10.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/Anonymous.values.fe10.txt index 1d14c35a82cc..2a7e31d49ad0 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/Anonymous.values.fe10.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/Anonymous.values.fe10.txt @@ -19,20 +19,21 @@ UFile (package = ) [import java.io.Closeable...] UDeclarationsExpression [var runnable2: java.lang.Runnable = Runnable({ ...})] = Undetermined ULocalVariable (name = runnable2) [var runnable2: java.lang.Runnable = Runnable({ ...})] UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) [Runnable({ ...})] = external Runnable({ - println() + return println() })(Undetermined) UIdentifier (Identifier (Runnable)) [UIdentifier (Identifier (Runnable))] USimpleNameReferenceExpression (identifier = Runnable, resolvesTo = PsiClass: Runnable) [Runnable] = external Runnable({ - println() + return println() })(Undetermined) ULambdaExpression [{ ...}] = Undetermined - UBlockExpression [{...}] = external println()() - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [println()] = external println()() - UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] = external println()() + UBlockExpression [{...}] = Nothing + UReturnExpression [return println()] = Nothing + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [println()] = external println()() + UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] = external println()() UQualifiedReferenceExpression [runnable2.run()] = external run()() USimpleNameReferenceExpression (identifier = runnable2) [runnable2] = (var runnable2 = external Runnable({ - println() + return println() })(Undetermined)) UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [run()] = external run()() UIdentifier (Identifier (run)) [UIdentifier (Identifier (run))] diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/Anonymous.values.fir.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/Anonymous.values.fir.txt index 7f23cf724302..91d64a74a850 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/Anonymous.values.fir.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/Anonymous.values.fir.txt @@ -19,20 +19,21 @@ UFile (package = ) [import java.io.Closeable...] UDeclarationsExpression [var runnable2: java.lang.Runnable = Runnable({ ...})] = Undetermined ULocalVariable (name = runnable2) [var runnable2: java.lang.Runnable = Runnable({ ...})] UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) [Runnable({ ...})] = external Runnable({ - println() + return println() })(Undetermined) UIdentifier (Identifier (Runnable)) [UIdentifier (Identifier (Runnable))] USimpleNameReferenceExpression (identifier = Runnable, resolvesTo = PsiClass: Runnable) [Runnable] = external Runnable({ - println() + return println() })(Undetermined) ULambdaExpression [{ ...}] = Undetermined - UBlockExpression [{...}] = external println()() - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [println()] = external println()() - UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] = external println()() + UBlockExpression [{...}] = Nothing + UReturnExpression [return println()] = Nothing + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [println()] = external println()() + UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] = external println()() UQualifiedReferenceExpression [runnable2.run()] = external run()() USimpleNameReferenceExpression (identifier = runnable2) [runnable2] = (var runnable2 = external Runnable({ - println() + return println() })(Undetermined)) UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [run()] = external run()() UIdentifier (Identifier (run)) [UIdentifier (Identifier (run))] diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/LambdaParameters.values.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/LambdaParameters.values.txt index 872bf6ca08b1..9aaa47afc9f5 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/LambdaParameters.values.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/LambdaParameters.values.txt @@ -2,21 +2,22 @@ UFile (package = ) [public final class LambdaParametersKt {...] UClass (name = LambdaParametersKt) [public final class LambdaParametersKt {...}] UMethod (name = lambdaWithRecivier) [public static final fun lambdaWithRecivier() : void {...}] UBlockExpression [{...}] = external buildString({ - append("a") + return append("a") })(Undetermined) UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [buildString({ ...})] = external buildString({ - append("a") + return append("a") })(Undetermined) UIdentifier (Identifier (buildString)) [UIdentifier (Identifier (buildString))] USimpleNameReferenceExpression (identifier = buildString, resolvesTo = null) [buildString] = external buildString({ - append("a") + return append("a") })(Undetermined) ULambdaExpression [{ ...}] = Undetermined - UBlockExpression [{...}] = external append("a")("a") - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [append("a")] = external append("a")("a") - UIdentifier (Identifier (append)) [UIdentifier (Identifier (append))] - USimpleNameReferenceExpression (identifier = append, resolvesTo = null) [append] = external append("a")("a") - ULiteralExpression (value = "a") ["a"] = "a" + UBlockExpression [{...}] = Nothing + UReturnExpression [return append("a")] = Nothing + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [append("a")] = external append("a")("a") + UIdentifier (Identifier (append)) [UIdentifier (Identifier (append))] + USimpleNameReferenceExpression (identifier = append, resolvesTo = null) [append] = external append("a")("a") + ULiteralExpression (value = "a") ["a"] = "a" UMethod (name = itParameter) [public static final fun itParameter() : void {...}] UBlockExpression [{...}] = external let({ var it: int -> @@ -40,4 +41,4 @@ UFile (package = ) [public final class LambdaParametersKt {...] UParameter (name = it) [var it: int] UBlockExpression [{...}] = Nothing UReturnExpression [return it] = Nothing - USimpleNameReferenceExpression (identifier = it) [it] = external it() \ No newline at end of file + USimpleNameReferenceExpression (identifier = it) [it] = external it() diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/LambdaReturn.values.fe10.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/LambdaReturn.values.fe10.txt index 36f469e9495c..600308bb82e4 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/LambdaReturn.values.fe10.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/LambdaReturn.values.fe10.txt @@ -110,37 +110,39 @@ UFile (package = org.jetbrains.uast.kotlin) [package org.jetbrains.uast.kotlin.. UDeclarationsExpression [var x: kotlin.jvm.functions.Function0 = { ...}] = Undetermined ULocalVariable (name = x) [var x: kotlin.jvm.functions.Function0 = { ...}] ULambdaExpression [{ ...}] = Undetermined - UBlockExpression [{...}] = Undetermined - UDeclarationsExpression [@org.jetbrains.annotations.NotNull var vardbcd0724: = listOf(1, 2)...@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] = Undetermined - ULocalVariable (name = vardbcd0724) [@org.jetbrains.annotations.NotNull var vardbcd0724: = listOf(1, 2)] - UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [listOf(1, 2)] = external listOf(1, 2)(1, 2) - UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] - USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) [listOf] = external listOf(1, 2)(1, 2) - ULiteralExpression (value = 1) [1] = 1 - ULiteralExpression (value = 2) [2] = 2 - ULocalVariable (name = a) [@org.jetbrains.annotations.NotNull var a: int = vardbcd0724.()] - UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] - UQualifiedReferenceExpression [vardbcd0724.()] = external ()() - USimpleNameReferenceExpression (identifier = vardbcd0724) [vardbcd0724] = external vardbcd0724() - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [()] = external ()() - UIdentifier (Identifier (component1)) [UIdentifier (Identifier (component1))] - USimpleNameReferenceExpression (identifier = , resolvesTo = null) [] = external ()() - ULocalVariable (name = b) [@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] - UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] - UQualifiedReferenceExpression [vardbcd0724.()] = external ()() - USimpleNameReferenceExpression (identifier = vardbcd0724) [vardbcd0724] = external vardbcd0724() - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [()] = external ()() - UIdentifier (Identifier (component2)) [UIdentifier (Identifier (component2))] - USimpleNameReferenceExpression (identifier = , resolvesTo = null) [] = external ()() + UBlockExpression [{...}] = Nothing + UReturnExpression [return @org.jetbrains.annotations.NotNull var vardbcd0724: = listOf(1, 2)...@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] = Nothing + UDeclarationsExpression [@org.jetbrains.annotations.NotNull var vardbcd0724: = listOf(1, 2)...@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] = Undetermined + ULocalVariable (name = vardbcd0724) [@org.jetbrains.annotations.NotNull var vardbcd0724: = listOf(1, 2)] + UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [listOf(1, 2)] = external listOf(1, 2)(1, 2) + UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] + USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) [listOf] = external listOf(1, 2)(1, 2) + ULiteralExpression (value = 1) [1] = 1 + ULiteralExpression (value = 2) [2] = 2 + ULocalVariable (name = a) [@org.jetbrains.annotations.NotNull var a: int = vardbcd0724.()] + UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] + UQualifiedReferenceExpression [vardbcd0724.()] = external ()() + USimpleNameReferenceExpression (identifier = vardbcd0724) [vardbcd0724] = external vardbcd0724() + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [()] = external ()() + UIdentifier (Identifier (component1)) [UIdentifier (Identifier (component1))] + USimpleNameReferenceExpression (identifier = , resolvesTo = null) [] = external ()() + ULocalVariable (name = b) [@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] + UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] + UQualifiedReferenceExpression [vardbcd0724.()] = external ()() + USimpleNameReferenceExpression (identifier = vardbcd0724) [vardbcd0724] = external vardbcd0724() + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [()] = external ()() + UIdentifier (Identifier (component2)) [UIdentifier (Identifier (component2))] + USimpleNameReferenceExpression (identifier = , resolvesTo = null) [] = external ()() UDeclarationsExpression [var y: kotlin.jvm.functions.Function0 = { ...}] = Undetermined ULocalVariable (name = y) [var y: kotlin.jvm.functions.Function0 = { ...}] ULambdaExpression [{ ...}] = Undetermined - UBlockExpression [{...}] = external listOf(1)(1) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [listOf(1)] = external listOf(1)(1) - UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] - USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) [listOf] = external listOf(1)(1) - ULiteralExpression (value = 1) [1] = 1 + UBlockExpression [{...}] = Nothing + UReturnExpression [return listOf(1)] = Nothing + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [listOf(1)] = external listOf(1)(1) + UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] + USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) [listOf] = external listOf(1)(1) + ULiteralExpression (value = 1) [1] = 1 UMethod (name = bar) [private static final fun bar(@org.jetbrains.annotations.NotNull lmbd: kotlin.jvm.functions.Function1) : void {...}] UParameter (name = lmbd) [@org.jetbrains.annotations.NotNull var lmbd: kotlin.jvm.functions.Function1] UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/LambdaReturn.values.fir.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/LambdaReturn.values.fir.txt index 2c14c171e10e..6bc1bb814c7f 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/LambdaReturn.values.fir.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/LambdaReturn.values.fir.txt @@ -110,37 +110,39 @@ UFile (package = org.jetbrains.uast.kotlin) [package org.jetbrains.uast.kotlin.. UDeclarationsExpression [var x: kotlin.jvm.functions.Function0 = { ...}] = Undetermined ULocalVariable (name = x) [var x: kotlin.jvm.functions.Function0 = { ...}] ULambdaExpression [{ ...}] = Undetermined - UBlockExpression [{...}] = Undetermined - UDeclarationsExpression [@org.jetbrains.annotations.NotNull var vardbcd0724: java.util.List = listOf(1, 2)...@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] = Undetermined - ULocalVariable (name = vardbcd0724) [@org.jetbrains.annotations.NotNull var vardbcd0724: java.util.List = listOf(1, 2)] - UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [listOf(1, 2)] = external listOf(1, 2)(1, 2) - UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] - USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) [listOf] = external listOf(1, 2)(1, 2) - ULiteralExpression (value = 1) [1] = 1 - ULiteralExpression (value = 2) [2] = 2 - ULocalVariable (name = a) [@org.jetbrains.annotations.NotNull var a: int = vardbcd0724.()] - UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] - UQualifiedReferenceExpression [vardbcd0724.()] = external ()() - USimpleNameReferenceExpression (identifier = vardbcd0724) [vardbcd0724] = external vardbcd0724() - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [()] = external ()() - UIdentifier (Identifier (component1)) [UIdentifier (Identifier (component1))] - USimpleNameReferenceExpression (identifier = , resolvesTo = null) [] = external ()() - ULocalVariable (name = b) [@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] - UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] - UQualifiedReferenceExpression [vardbcd0724.()] = external ()() - USimpleNameReferenceExpression (identifier = vardbcd0724) [vardbcd0724] = external vardbcd0724() - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [()] = external ()() - UIdentifier (Identifier (component2)) [UIdentifier (Identifier (component2))] - USimpleNameReferenceExpression (identifier = , resolvesTo = null) [] = external ()() + UBlockExpression [{...}] = Nothing + UReturnExpression [return @org.jetbrains.annotations.NotNull var vardbcd0724: java.util.List = listOf(1, 2)...@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] = Nothing + UDeclarationsExpression [@org.jetbrains.annotations.NotNull var vardbcd0724: java.util.List = listOf(1, 2)...@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] = Undetermined + ULocalVariable (name = vardbcd0724) [@org.jetbrains.annotations.NotNull var vardbcd0724: java.util.List = listOf(1, 2)] + UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [listOf(1, 2)] = external listOf(1, 2)(1, 2) + UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] + USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) [listOf] = external listOf(1, 2)(1, 2) + ULiteralExpression (value = 1) [1] = 1 + ULiteralExpression (value = 2) [2] = 2 + ULocalVariable (name = a) [@org.jetbrains.annotations.NotNull var a: int = vardbcd0724.()] + UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] + UQualifiedReferenceExpression [vardbcd0724.()] = external ()() + USimpleNameReferenceExpression (identifier = vardbcd0724) [vardbcd0724] = external vardbcd0724() + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [()] = external ()() + UIdentifier (Identifier (component1)) [UIdentifier (Identifier (component1))] + USimpleNameReferenceExpression (identifier = , resolvesTo = null) [] = external ()() + ULocalVariable (name = b) [@org.jetbrains.annotations.NotNull var b: int = vardbcd0724.()] + UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] + UQualifiedReferenceExpression [vardbcd0724.()] = external ()() + USimpleNameReferenceExpression (identifier = vardbcd0724) [vardbcd0724] = external vardbcd0724() + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [()] = external ()() + UIdentifier (Identifier (component2)) [UIdentifier (Identifier (component2))] + USimpleNameReferenceExpression (identifier = , resolvesTo = null) [] = external ()() UDeclarationsExpression [var y: kotlin.jvm.functions.Function0 = { ...}] = Undetermined ULocalVariable (name = y) [var y: kotlin.jvm.functions.Function0 = { ...}] ULambdaExpression [{ ...}] = Undetermined - UBlockExpression [{...}] = external listOf(1)(1) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [listOf(1)] = external listOf(1)(1) - UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] - USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) [listOf] = external listOf(1)(1) - ULiteralExpression (value = 1) [1] = 1 + UBlockExpression [{...}] = Nothing + UReturnExpression [return listOf(1)] = Nothing + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [listOf(1)] = external listOf(1)(1) + UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] + USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) [listOf] = external listOf(1)(1) + ULiteralExpression (value = 1) [1] = 1 UMethod (name = bar) [private static final fun bar(@org.jetbrains.annotations.NotNull lmbd: kotlin.jvm.functions.Function1) : void {...}] UParameter (name = lmbd) [@org.jetbrains.annotations.NotNull var lmbd: kotlin.jvm.functions.Function1] UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/NonTrivialIdentifiers.values.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/NonTrivialIdentifiers.values.txt index 98538a79bfa9..fcac7b58fa4c 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/NonTrivialIdentifiers.values.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/NonTrivialIdentifiers.values.txt @@ -4,8 +4,8 @@ UFile (package = ) [public final class NonTrivialIdentifiersKt {...] UParameter (name = a) [@org.jetbrains.annotations.Nullable var a: A] UAnnotation (fqName = org.jetbrains.annotations.Nullable) [@org.jetbrains.annotations.Nullable] UBlockExpression [{...}] = external invoke({ - invoke({ - invoke() + return invoke({ + return invoke() }) })(Undetermined) UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [invoke()] = external invoke()() @@ -17,32 +17,32 @@ UFile (package = ) [public final class NonTrivialIdentifiersKt {...] UIdentifier (Identifier (A)) [UIdentifier (Identifier (A))] USimpleNameReferenceExpression (identifier = , resolvesTo = PsiClass: A) [] = external ()() UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [invoke({ ...})] = external invoke({ - invoke({ - invoke() + return invoke({ + return invoke() }) })(Undetermined) UIdentifier (Identifier ({)) [UIdentifier (Identifier ({))] USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) [invoke] = external invoke({ - invoke({ - invoke() + return invoke({ + return invoke() }) })(Undetermined) ULambdaExpression [{ ...}] = Undetermined - UBlockExpression [{...}] = external invoke({ - invoke() + UBlockExpression [{...}] = Nothing + UReturnExpression [return invoke({ ...})] = Nothing + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [invoke({ ...})] = external invoke({ + return invoke() })(Undetermined) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [invoke({ ...})] = external invoke({ - invoke() + UIdentifier (Identifier (p)) [UIdentifier (Identifier (p))] + USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) [invoke] = external invoke({ + return invoke() })(Undetermined) - UIdentifier (Identifier (p)) [UIdentifier (Identifier (p))] - USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) [invoke] = external invoke({ - invoke() -})(Undetermined) - ULambdaExpression [{ ...}] = Undetermined - UBlockExpression [{...}] = external invoke()() - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [invoke()] = external invoke()() - UIdentifier (Identifier (()) [UIdentifier (Identifier (())] - USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) [invoke] = external invoke()() + ULambdaExpression [{ ...}] = Undetermined + UBlockExpression [{...}] = Nothing + UReturnExpression [return invoke()] = Nothing + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [invoke()] = external invoke()() + UIdentifier (Identifier (()) [UIdentifier (Identifier (())] + USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) [invoke] = external invoke()() UClass (name = A) [public final class A {...}] UMethod (name = invoke) [public final fun invoke() : void {...}] UBlockExpression [{...}] = external invoke()() @@ -53,4 +53,4 @@ UFile (package = ) [public final class NonTrivialIdentifiersKt {...] UParameter (name = f) [@org.jetbrains.annotations.NotNull var f: kotlin.jvm.functions.Function0] UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] UBlockExpression [{...}] = Undetermined - UMethod (name = A) [public fun A() = UastEmptyExpression] \ No newline at end of file + UMethod (name = A) [public fun A() = UastEmptyExpression] diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/ParametersDisorder.values.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/ParametersDisorder.values.txt index 58a458acfe28..d8b7727a3915 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/ParametersDisorder.values.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/ParametersDisorder.values.txt @@ -24,7 +24,7 @@ UFile (package = ) [public final class ParametersDisorderKt {...] UBlockExpression [{...}] = Undetermined UMethod (name = call) [public static final fun call() : void {...}] UBlockExpression [{...}] = external with((), { - "def".with2Receivers(8, 7.0) + return "def".with2Receivers(8, 7.0) })(external ()(), Undetermined) UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [global(2.2, 2)] = external global(2.2, 2)((float)2.200000047683716, 2) UIdentifier (Identifier (global)) [UIdentifier (Identifier (global))] @@ -126,24 +126,25 @@ UFile (package = ) [public final class ParametersDisorderKt {...] UIdentifier (Identifier (toTypedArray)) [UIdentifier (Identifier (toTypedArray))] USimpleNameReferenceExpression (identifier = toTypedArray, resolvesTo = null) [toTypedArray] = external toTypedArray()() UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [with((), { ...})] = external with((), { - "def".with2Receivers(8, 7.0) + return "def".with2Receivers(8, 7.0) })(external ()(), Undetermined) UIdentifier (Identifier (with)) [UIdentifier (Identifier (with))] USimpleNameReferenceExpression (identifier = with, resolvesTo = null) [with] = external with((), { - "def".with2Receivers(8, 7.0) + return "def".with2Receivers(8, 7.0) })(external ()(), Undetermined) UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [()] = external ()() UIdentifier (Identifier (A)) [UIdentifier (Identifier (A))] USimpleNameReferenceExpression (identifier = , resolvesTo = PsiClass: A) [] = external ()() ULambdaExpression [{ ...}] = Undetermined - UBlockExpression [{...}] = external with2Receivers(8, 7.0)(8, (float)7.0) - UQualifiedReferenceExpression ["def".with2Receivers(8, 7.0)] = external with2Receivers(8, 7.0)(8, (float)7.0) - ULiteralExpression (value = "def") ["def"] = "def" - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [with2Receivers(8, 7.0)] = external with2Receivers(8, 7.0)(8, (float)7.0) - UIdentifier (Identifier (with2Receivers)) [UIdentifier (Identifier (with2Receivers))] - USimpleNameReferenceExpression (identifier = with2Receivers, resolvesTo = null) [with2Receivers] = external with2Receivers(8, 7.0)(8, (float)7.0) - ULiteralExpression (value = 8) [8] = 8 - ULiteralExpression (value = 7.0) [7.0] = (float)7.0 + UBlockExpression [{...}] = Nothing + UReturnExpression [return "def".with2Receivers(8, 7.0)] = Nothing + UQualifiedReferenceExpression ["def".with2Receivers(8, 7.0)] = external with2Receivers(8, 7.0)(8, (float)7.0) + ULiteralExpression (value = "def") ["def"] = "def" + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [with2Receivers(8, 7.0)] = external with2Receivers(8, 7.0)(8, (float)7.0) + UIdentifier (Identifier (with2Receivers)) [UIdentifier (Identifier (with2Receivers))] + USimpleNameReferenceExpression (identifier = with2Receivers, resolvesTo = null) [with2Receivers] = external with2Receivers(8, 7.0)(8, (float)7.0) + ULiteralExpression (value = 8) [8] = 8 + ULiteralExpression (value = 7.0) [7.0] = (float)7.0 UMethod (name = objectLiteral) [public static final fun objectLiteral() : void {...}] UBlockExpression [{...}] = Undetermined UObjectLiteralExpression [anonymous object : Parent(b = 1, a = "foo") { }] = Undetermined @@ -172,4 +173,4 @@ UFile (package = ) [public final class ParametersDisorderKt {...] UParameter (name = a) [@org.jetbrains.annotations.NotNull var a: java.lang.String] UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] UParameter (name = b) [@org.jetbrains.annotations.NotNull var b: int] - UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] \ No newline at end of file + UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull] diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/Resolve.values.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/Resolve.values.txt index a15c2c3c006a..ec3fedca8d90 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/Resolve.values.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/Resolve.values.txt @@ -18,7 +18,7 @@ UFile (package = ) [public final class ResolveKt {...] USimpleNameReferenceExpression (identifier = inlineFoo, resolvesTo = null) [inlineFoo] = external inlineFoo()() UQualifiedReferenceExpression [listOf(()).forEach({ var it: A ->...})] = external forEach({ var it: A -> - println(it) + return println(it) })(Undetermined) UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [listOf(())] = external listOf(())(external ()()) UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] @@ -28,20 +28,21 @@ UFile (package = ) [public final class ResolveKt {...] USimpleNameReferenceExpression (identifier = , resolvesTo = PsiClass: A) [] = external ()() UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [forEach({ var it: A ->...})] = external forEach({ var it: A -> - println(it) + return println(it) })(Undetermined) UIdentifier (Identifier (forEach)) [UIdentifier (Identifier (forEach))] USimpleNameReferenceExpression (identifier = forEach, resolvesTo = null) [forEach] = external forEach({ var it: A -> - println(it) + return println(it) })(Undetermined) ULambdaExpression [{ var it: A ->...}] = Undetermined UParameter (name = it) [var it: A] - UBlockExpression [{...}] = external println(it)(external it()) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [println(it)] = external println(it)(external it()) - UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] = external println(it)(external it()) - USimpleNameReferenceExpression (identifier = it) [it] = external it() + UBlockExpression [{...}] = Nothing + UReturnExpression [return println(it)] = Nothing + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [println(it)] = external println(it)(external it()) + UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] = external println(it)(external it()) + USimpleNameReferenceExpression (identifier = it) [it] = external it() UQualifiedReferenceExpression [listOf("").joinToString()] = external joinToString()() UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [listOf("")] = external listOf("")("") UIdentifier (Identifier (listOf)) [UIdentifier (Identifier (listOf))] @@ -153,4 +154,4 @@ UFile (package = ) [public final class ResolveKt {...] UBlockExpression [{...}] = Undetermined UMethod (name = inlineFoo) [public final fun inlineFoo() : void {...}] UBlockExpression [{...}] = Undetermined - UMethod (name = A) [public fun A() = UastEmptyExpression] \ No newline at end of file + UMethod (name = A) [public fun A() = UastEmptyExpression] diff --git a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/SAM.values.txt b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/SAM.values.txt index 260aba938f0b..bc00d8abe951 100644 --- a/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/SAM.values.txt +++ b/plugins/kotlin/uast/uast-kotlin-fir/tests/testData/legacyValues/SAM.values.txt @@ -99,46 +99,48 @@ UFile (package = ) [import java.lang.Thread...] UDeclarationsExpression [var thread1: java.lang.Thread = ({ ...})] = Undetermined ULocalVariable (name = thread1) [var thread1: java.lang.Thread = ({ ...})] UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) [({ ...})] = external ({ - println("hello1") + return println("hello1") })(Undetermined) UIdentifier (Identifier (Thread)) [UIdentifier (Identifier (Thread))] USimpleNameReferenceExpression (identifier = , resolvesTo = PsiClass: Thread) [] = external ({ - println("hello1") + return println("hello1") })(Undetermined) ULambdaExpression [{ ...}] = Undetermined - UBlockExpression [{...}] = external println("hello1")("hello1") - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [println("hello1")] = external println("hello1")("hello1") - UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] = external println("hello1")("hello1") - ULiteralExpression (value = "hello1") ["hello1"] = "hello1" + UBlockExpression [{...}] = Nothing + UReturnExpression [return println("hello1")] = Nothing + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [println("hello1")] = external println("hello1")("hello1") + UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] = external println("hello1")("hello1") + ULiteralExpression (value = "hello1") ["hello1"] = "hello1" UMethod (name = test2) [public static final fun test2() : void {...}] UBlockExpression [{...}] = Undetermined UDeclarationsExpression [var thread2: java.lang.Thread = (Runnable({ ...}))] = Undetermined ULocalVariable (name = thread2) [var thread2: java.lang.Thread = (Runnable({ ...}))] UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) [(Runnable({ ...}))] = external (Runnable({ - println("hello2") + return println("hello2") }))(external Runnable({ - println("hello2") + return println("hello2") })(Undetermined)) UIdentifier (Identifier (Thread)) [UIdentifier (Identifier (Thread))] USimpleNameReferenceExpression (identifier = , resolvesTo = PsiClass: Thread) [] = external (Runnable({ - println("hello2") + return println("hello2") }))(external Runnable({ - println("hello2") + return println("hello2") })(Undetermined)) UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) [Runnable({ ...})] = external Runnable({ - println("hello2") + return println("hello2") })(Undetermined) UIdentifier (Identifier (Runnable)) [UIdentifier (Identifier (Runnable))] USimpleNameReferenceExpression (identifier = Runnable, resolvesTo = PsiClass: Runnable) [Runnable] = external Runnable({ - println("hello2") + return println("hello2") })(Undetermined) ULambdaExpression [{ ...}] = Undetermined - UBlockExpression [{...}] = external println("hello2")("hello2") - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [println("hello2")] = external println("hello2")("hello2") - UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] = external println("hello2")("hello2") - ULiteralExpression (value = "hello2") ["hello2"] = "hello2" + UBlockExpression [{...}] = Nothing + UReturnExpression [return println("hello2")] = Nothing + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [println("hello2")] = external println("hello2")("hello2") + UIdentifier (Identifier (println)) [UIdentifier (Identifier (println))] + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) [println] = external println("hello2")("hello2") + ULiteralExpression (value = "hello2") ["hello2"] = "hello2" UMethod (name = test3) [public static final fun test3() : void {...}] UBlockExpression [{...}] = external ambiguousSamAcceptor(Callable({ return "Callable" diff --git a/plugins/kotlin/uast/uast-kotlin-idea/tests/test/org/jetbrains/uast/test/kotlin/KotlinUastGenerationTest.kt b/plugins/kotlin/uast/uast-kotlin-idea/tests/test/org/jetbrains/uast/test/kotlin/KotlinUastGenerationTest.kt index 86bbeae27e22..2f6d870455f1 100644 --- a/plugins/kotlin/uast/uast-kotlin-idea/tests/test/org/jetbrains/uast/test/kotlin/KotlinUastGenerationTest.kt +++ b/plugins/kotlin/uast/uast-kotlin-idea/tests/test/org/jetbrains/uast/test/kotlin/KotlinUastGenerationTest.kt @@ -99,13 +99,14 @@ class KotlinUastGenerationTest : AbstractKotlinUastGenerationTest() { UParameter (name = b) UAnnotation (fqName = org.jetbrains.annotations.NotNull) UBlockExpression - UQualifiedReferenceExpression + UReturnExpression UQualifiedReferenceExpression - USimpleNameReferenceExpression (identifier = System) - USimpleNameReferenceExpression (identifier = out) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) - UIdentifier (Identifier (println)) - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) + UQualifiedReferenceExpression + USimpleNameReferenceExpression (identifier = System) + USimpleNameReferenceExpression (identifier = out) + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + UIdentifier (Identifier (println)) + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) """.trimIndent(), lambda.putIntoFunctionBody().asRecursiveLogString().trim()) } @@ -149,13 +150,14 @@ class KotlinUastGenerationTest : AbstractKotlinUastGenerationTest() { UParameter (name = b) UAnnotation (fqName = org.jetbrains.annotations.NotNull) UBlockExpression - UQualifiedReferenceExpression + UReturnExpression UQualifiedReferenceExpression - USimpleNameReferenceExpression (identifier = System) - USimpleNameReferenceExpression (identifier = out) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) - UIdentifier (Identifier (println)) - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) + UQualifiedReferenceExpression + USimpleNameReferenceExpression (identifier = System) + USimpleNameReferenceExpression (identifier = out) + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + UIdentifier (Identifier (println)) + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) """.trimIndent(), lambda.putIntoFunctionBody().asRecursiveLogString().trim()) } diff --git a/plugins/kotlin/uast/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastResolveProviderService.kt b/plugins/kotlin/uast/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastResolveProviderService.kt index 10ffd6ffbcd3..2d120861e7e3 100644 --- a/plugins/kotlin/uast/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastResolveProviderService.kt +++ b/plugins/kotlin/uast/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastResolveProviderService.kt @@ -136,17 +136,6 @@ interface KotlinUastResolveProviderService : BaseKotlinUastResolveProviderServic return baseKotlinConverter.createVarargsHolder(arguments, parent) } - override fun getImplicitReturn(ktLambdaExpression: KtLambdaExpression, parent: UElement): KotlinUImplicitReturnExpression? { - val lastExpression = ktLambdaExpression.bodyExpression?.statements?.lastOrNull() ?: return null - val context = lastExpression.analyze() - if (context[BindingContext.USED_AS_RESULT_OF_LAMBDA, lastExpression] == true) { - return KotlinUImplicitReturnExpression(parent).apply { - returnExpression = baseKotlinConverter.convertOrEmpty(lastExpression, this) - } - } - return null - } - override fun getImplicitParameters( ktLambdaExpression: KtLambdaExpression, parent: UElement, diff --git a/plugins/kotlin/uast/uast-kotlin/tests/testData/Anonymous.log-ide.txt b/plugins/kotlin/uast/uast-kotlin/tests/testData/Anonymous.log-ide.txt index e6aa5eb5f3be..b58691bdc839 100644 --- a/plugins/kotlin/uast/uast-kotlin/tests/testData/Anonymous.log-ide.txt +++ b/plugins/kotlin/uast/uast-kotlin/tests/testData/Anonymous.log-ide.txt @@ -23,9 +23,10 @@ UFile (package = ) USimpleNameReferenceExpression (identifier = Runnable, resolvesTo = PsiClass: Runnable) ULambdaExpression UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) - UIdentifier (Identifier (println)) - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) + UReturnExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + UIdentifier (Identifier (println)) + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) UQualifiedReferenceExpression USimpleNameReferenceExpression (identifier = runnable2) UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) diff --git a/plugins/kotlin/uast/uast-kotlin/tests/testData/Anonymous.log.txt b/plugins/kotlin/uast/uast-kotlin/tests/testData/Anonymous.log.txt index e6aa5eb5f3be..b58691bdc839 100644 --- a/plugins/kotlin/uast/uast-kotlin/tests/testData/Anonymous.log.txt +++ b/plugins/kotlin/uast/uast-kotlin/tests/testData/Anonymous.log.txt @@ -23,9 +23,10 @@ UFile (package = ) USimpleNameReferenceExpression (identifier = Runnable, resolvesTo = PsiClass: Runnable) ULambdaExpression UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) - UIdentifier (Identifier (println)) - USimpleNameReferenceExpression (identifier = println, resolvesTo = null) + UReturnExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + UIdentifier (Identifier (println)) + USimpleNameReferenceExpression (identifier = println, resolvesTo = null) UQualifiedReferenceExpression USimpleNameReferenceExpression (identifier = runnable2) UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) diff --git a/plugins/kotlin/uast/uast-kotlin/tests/testData/Anonymous.missed.txt b/plugins/kotlin/uast/uast-kotlin/tests/testData/Anonymous.missed.txt index f08bb8875ffd..1e4c32318b1c 100644 --- a/plugins/kotlin/uast/uast-kotlin/tests/testData/Anonymous.missed.txt +++ b/plugins/kotlin/uast/uast-kotlin/tests/testData/Anonymous.missed.txt @@ -30,7 +30,7 @@ com.intellij.psi.impl.source.tree.LeafPsiElement: UIdentifier (Identifier (runna org.jetbrains.kotlin.psi.KtNameReferenceExpression: USimpleNameReferenceExpression (identifier = Runnable) <- UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) <- ULocalVariable (name = runnable2) <- UDeclarationsExpression <- UBlockExpression org.jetbrains.kotlin.psi.KtLambdaArgument: ULambdaExpression <- UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) <- ULocalVariable (name = runnable2) <- UDeclarationsExpression <- UBlockExpression org.jetbrains.kotlin.psi.KtFunctionLiteral: ULambdaExpression <- UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) <- ULocalVariable (name = runnable2) <- UDeclarationsExpression <- UBlockExpression -org.jetbrains.kotlin.psi.KtNameReferenceExpression: USimpleNameReferenceExpression (identifier = println) <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) <- UBlockExpression <- ULambdaExpression <- UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) +org.jetbrains.kotlin.psi.KtNameReferenceExpression: USimpleNameReferenceExpression (identifier = println) <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) <- UReturnExpression <- UBlockExpression <- ULambdaExpression com.intellij.psi.impl.source.tree.LeafPsiElement: UIdentifier (Identifier (runnable2)) <- USimpleNameReferenceExpression (identifier = runnable2) <- UQualifiedReferenceExpression <- UBlockExpression <- UMethod (name = foo) org.jetbrains.kotlin.psi.KtNameReferenceExpression: USimpleNameReferenceExpression (identifier = run) <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) <- UQualifiedReferenceExpression <- UBlockExpression <- UMethod (name = foo) com.intellij.psi.impl.source.tree.LeafPsiElement: UIdentifier (Identifier (closeableRunnable)) <- ULocalVariable (name = closeableRunnable) <- UDeclarationsExpression <- UBlockExpression <- UMethod (name = foo) diff --git a/plugins/kotlin/uast/uast-kotlin/tests/testData/Anonymous.render.txt b/plugins/kotlin/uast/uast-kotlin/tests/testData/Anonymous.render.txt index bb2e36e3b696..21d24745979a 100644 --- a/plugins/kotlin/uast/uast-kotlin/tests/testData/Anonymous.render.txt +++ b/plugins/kotlin/uast/uast-kotlin/tests/testData/Anonymous.render.txt @@ -6,7 +6,7 @@ public final class AnonymousKt { var runnable: = anonymous object : Runnable { override fun run() {} } runnable.run() var runnable2: java.lang.Runnable = Runnable({ - println() + return println() }) runnable2.run() var closeableRunnable: = anonymous object : Runnable, Closeable { override fun close() {} override fun run() {} } diff --git a/plugins/kotlin/uast/uast-kotlin/tests/testData/LambdaReturn.log.txt b/plugins/kotlin/uast/uast-kotlin/tests/testData/LambdaReturn.log.txt index 41227bdcfe3f..2b08b1ad101f 100644 --- a/plugins/kotlin/uast/uast-kotlin/tests/testData/LambdaReturn.log.txt +++ b/plugins/kotlin/uast/uast-kotlin/tests/testData/LambdaReturn.log.txt @@ -101,36 +101,38 @@ UFile (package = org.jetbrains.uast.kotlin) ULocalVariable (name = x) ULambdaExpression UBlockExpression - UDeclarationsExpression - ULocalVariable (name = vardbcd0724) - UAnnotation (fqName = org.jetbrains.annotations.NotNull) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) - UIdentifier (Identifier (listOf)) - USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) - ULiteralExpression (value = 1) - ULiteralExpression (value = 2) - ULocalVariable (name = a) - UAnnotation (fqName = org.jetbrains.annotations.NotNull) - UQualifiedReferenceExpression - USimpleNameReferenceExpression (identifier = vardbcd0724) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) - UIdentifier (Identifier (component1)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) - ULocalVariable (name = b) - UAnnotation (fqName = org.jetbrains.annotations.NotNull) - UQualifiedReferenceExpression - USimpleNameReferenceExpression (identifier = vardbcd0724) - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) - UIdentifier (Identifier (component2)) - USimpleNameReferenceExpression (identifier = , resolvesTo = null) + UReturnExpression + UDeclarationsExpression + ULocalVariable (name = vardbcd0724) + UAnnotation (fqName = org.jetbrains.annotations.NotNull) + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) + UIdentifier (Identifier (listOf)) + USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) + ULiteralExpression (value = 1) + ULiteralExpression (value = 2) + ULocalVariable (name = a) + UAnnotation (fqName = org.jetbrains.annotations.NotNull) + UQualifiedReferenceExpression + USimpleNameReferenceExpression (identifier = vardbcd0724) + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + UIdentifier (Identifier (component1)) + USimpleNameReferenceExpression (identifier = , resolvesTo = null) + ULocalVariable (name = b) + UAnnotation (fqName = org.jetbrains.annotations.NotNull) + UQualifiedReferenceExpression + USimpleNameReferenceExpression (identifier = vardbcd0724) + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + UIdentifier (Identifier (component2)) + USimpleNameReferenceExpression (identifier = , resolvesTo = null) UDeclarationsExpression ULocalVariable (name = y) ULambdaExpression UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (listOf)) - USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) - ULiteralExpression (value = 1) + UReturnExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) + UIdentifier (Identifier (listOf)) + USimpleNameReferenceExpression (identifier = listOf, resolvesTo = null) + ULiteralExpression (value = 1) UMethod (name = bar) UParameter (name = lmbd) UAnnotation (fqName = org.jetbrains.annotations.NotNull) diff --git a/plugins/kotlin/uast/uast-kotlin/tests/testData/LambdaReturn.render.txt b/plugins/kotlin/uast/uast-kotlin/tests/testData/LambdaReturn.render.txt index 7bab5caf59be..c86ccda8006b 100644 --- a/plugins/kotlin/uast/uast-kotlin/tests/testData/LambdaReturn.render.txt +++ b/plugins/kotlin/uast/uast-kotlin/tests/testData/LambdaReturn.render.txt @@ -31,12 +31,12 @@ public final class LambdaReturnKt { return it + b }) var x: kotlin.jvm.functions.Function0 = { - @org.jetbrains.annotations.NotNull var vardbcd0724: = listOf(1, 2) + return @org.jetbrains.annotations.NotNull var vardbcd0724: = listOf(1, 2) @org.jetbrains.annotations.NotNull var a: int = vardbcd0724.() @org.jetbrains.annotations.NotNull var b: int = vardbcd0724.() } var y: kotlin.jvm.functions.Function0 = { - listOf(1) + return listOf(1) } } private static final fun bar(@org.jetbrains.annotations.NotNull lmbd: kotlin.jvm.functions.Function1) : void { diff --git a/plugins/kotlin/uast/uast-kotlin/tests/testData/NonTrivialIdentifiers.log.txt b/plugins/kotlin/uast/uast-kotlin/tests/testData/NonTrivialIdentifiers.log.txt index 97180a870454..1709a1a60496 100644 --- a/plugins/kotlin/uast/uast-kotlin/tests/testData/NonTrivialIdentifiers.log.txt +++ b/plugins/kotlin/uast/uast-kotlin/tests/testData/NonTrivialIdentifiers.log.txt @@ -17,14 +17,16 @@ UFile (package = ) USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) ULambdaExpression UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) - UIdentifier (Identifier (p)) - USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) - ULambdaExpression - UBlockExpression - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) - UIdentifier (Identifier (()) - USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) + UReturnExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) + UIdentifier (Identifier (p)) + USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) + ULambdaExpression + UBlockExpression + UReturnExpression + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) + UIdentifier (Identifier (()) + USimpleNameReferenceExpression (identifier = invoke, resolvesTo = null) UClass (name = A) UMethod (name = invoke) UBlockExpression diff --git a/plugins/kotlin/uast/uast-kotlin/tests/testData/NonTrivialIdentifiers.missed.txt b/plugins/kotlin/uast/uast-kotlin/tests/testData/NonTrivialIdentifiers.missed.txt index 7aebba6cf2b0..308b9cc08055 100644 --- a/plugins/kotlin/uast/uast-kotlin/tests/testData/NonTrivialIdentifiers.missed.txt +++ b/plugins/kotlin/uast/uast-kotlin/tests/testData/NonTrivialIdentifiers.missed.txt @@ -33,9 +33,9 @@ org.jetbrains.kotlin.psi.KtOperationReferenceExpression: USimpleNameReferenceExp com.intellij.psi.impl.source.tree.LeafPsiElement: UIdentifier (Identifier (!!)) <- USimpleNameReferenceExpression (identifier = !!) <- UPostfixExpression (operator = !!) <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) <- UBlockExpression org.jetbrains.kotlin.psi.KtLambdaArgument: ULambdaExpression <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) <- UBlockExpression <- UMethod (name = main) <- UClass (name = NonTrivialIdentifiersKt) org.jetbrains.kotlin.psi.KtFunctionLiteral: ULambdaExpression <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) <- UBlockExpression <- UMethod (name = main) <- UClass (name = NonTrivialIdentifiersKt) -org.jetbrains.kotlin.psi.KtNameReferenceExpression: USimpleNameReferenceExpression (identifier = p) <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) <- UBlockExpression <- ULambdaExpression <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) -org.jetbrains.kotlin.psi.KtLambdaArgument: ULambdaExpression <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) <- UBlockExpression <- ULambdaExpression <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) -org.jetbrains.kotlin.psi.KtFunctionLiteral: ULambdaExpression <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) <- UBlockExpression <- ULambdaExpression <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) -org.jetbrains.kotlin.psi.KtCallExpression: UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) <- UBlockExpression <- ULambdaExpression <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) -org.jetbrains.kotlin.psi.KtNameReferenceExpression: USimpleNameReferenceExpression (identifier = A) <- UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) <- UBlockExpression <- ULambdaExpression -com.intellij.psi.impl.source.tree.LeafPsiElement: UIdentifier (Identifier (A)) <- UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) <- UBlockExpression <- ULambdaExpression +org.jetbrains.kotlin.psi.KtNameReferenceExpression: USimpleNameReferenceExpression (identifier = p) <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) <- UReturnExpression <- UBlockExpression <- ULambdaExpression +org.jetbrains.kotlin.psi.KtLambdaArgument: ULambdaExpression <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) <- UReturnExpression <- UBlockExpression <- ULambdaExpression +org.jetbrains.kotlin.psi.KtFunctionLiteral: ULambdaExpression <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) <- UReturnExpression <- UBlockExpression <- ULambdaExpression +org.jetbrains.kotlin.psi.KtCallExpression: UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) <- UReturnExpression <- UBlockExpression <- ULambdaExpression +org.jetbrains.kotlin.psi.KtNameReferenceExpression: USimpleNameReferenceExpression (identifier = A) <- UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) <- UReturnExpression <- UBlockExpression +com.intellij.psi.impl.source.tree.LeafPsiElement: UIdentifier (Identifier (A)) <- UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) <- UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) <- UReturnExpression <- UBlockExpression diff --git a/plugins/kotlin/uast/uast-kotlin/tests/testData/NonTrivialIdentifiers.render.txt b/plugins/kotlin/uast/uast-kotlin/tests/testData/NonTrivialIdentifiers.render.txt index c87a219431a9..126a378ddd30 100644 --- a/plugins/kotlin/uast/uast-kotlin/tests/testData/NonTrivialIdentifiers.render.txt +++ b/plugins/kotlin/uast/uast-kotlin/tests/testData/NonTrivialIdentifiers.render.txt @@ -2,9 +2,9 @@ public final class NonTrivialIdentifiersKt { public static final fun main(@org.jetbrains.annotations.Nullable a: A) : void { invoke() var p: A = () - invoke({ - invoke({ - invoke() + invoke({ + return invoke({ + return invoke() }) }) } diff --git a/plugins/kotlin/uast/uast-kotlin/tests/testData/ParametersDisorder.log-ide.txt b/plugins/kotlin/uast/uast-kotlin/tests/testData/ParametersDisorder.log-ide.txt index c2b1a2cab446..053f71ba6c6e 100644 --- a/plugins/kotlin/uast/uast-kotlin/tests/testData/ParametersDisorder.log-ide.txt +++ b/plugins/kotlin/uast/uast-kotlin/tests/testData/ParametersDisorder.log-ide.txt @@ -131,13 +131,14 @@ UFile (package = ) USimpleNameReferenceExpression (identifier = , resolvesTo = PsiClass: A) ULambdaExpression UBlockExpression - UQualifiedReferenceExpression - ULiteralExpression (value = "def") - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) - UIdentifier (Identifier (with2Receivers)) - USimpleNameReferenceExpression (identifier = with2Receivers, resolvesTo = null) - ULiteralExpression (value = 8) - ULiteralExpression (value = 7.0) + UReturnExpression + UQualifiedReferenceExpression + ULiteralExpression (value = "def") + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) + UIdentifier (Identifier (with2Receivers)) + USimpleNameReferenceExpression (identifier = with2Receivers, resolvesTo = null) + ULiteralExpression (value = 8) + ULiteralExpression (value = 7.0) UMethod (name = objectLiteral) UBlockExpression UObjectLiteralExpression diff --git a/plugins/kotlin/uast/uast-kotlin/tests/testData/ParametersDisorder.log.txt b/plugins/kotlin/uast/uast-kotlin/tests/testData/ParametersDisorder.log.txt index c2b1a2cab446..053f71ba6c6e 100644 --- a/plugins/kotlin/uast/uast-kotlin/tests/testData/ParametersDisorder.log.txt +++ b/plugins/kotlin/uast/uast-kotlin/tests/testData/ParametersDisorder.log.txt @@ -131,13 +131,14 @@ UFile (package = ) USimpleNameReferenceExpression (identifier = , resolvesTo = PsiClass: A) ULambdaExpression UBlockExpression - UQualifiedReferenceExpression - ULiteralExpression (value = "def") - UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) - UIdentifier (Identifier (with2Receivers)) - USimpleNameReferenceExpression (identifier = with2Receivers, resolvesTo = null) - ULiteralExpression (value = 8) - ULiteralExpression (value = 7.0) + UReturnExpression + UQualifiedReferenceExpression + ULiteralExpression (value = "def") + UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) + UIdentifier (Identifier (with2Receivers)) + USimpleNameReferenceExpression (identifier = with2Receivers, resolvesTo = null) + ULiteralExpression (value = 8) + ULiteralExpression (value = 7.0) UMethod (name = objectLiteral) UBlockExpression UObjectLiteralExpression diff --git a/plugins/kotlin/uast/uast-kotlin/tests/testData/ParametersDisorder.render.txt b/plugins/kotlin/uast/uast-kotlin/tests/testData/ParametersDisorder.render.txt index dde115c8decf..4076b88d6cfa 100644 --- a/plugins/kotlin/uast/uast-kotlin/tests/testData/ParametersDisorder.render.txt +++ b/plugins/kotlin/uast/uast-kotlin/tests/testData/ParametersDisorder.render.txt @@ -16,7 +16,7 @@ public final class ParametersDisorderKt { java.lang.String.format("%i %i %i", arrayOf(1, 2, 3), arrayOf(4, 5, 6)) java.lang.String.format("%i %i %i", "".chunked(2).toTypedArray()) with((), { - "def".with2Receivers(8, 7.0) + return "def".with2Receivers(8, 7.0) }) } public static final fun objectLiteral() : void { diff --git a/plugins/kotlin/util/project-model-updater/resources/model.properties b/plugins/kotlin/util/project-model-updater/resources/model.properties index e1c9c6389b23..15c67106ce63 100644 --- a/plugins/kotlin/util/project-model-updater/resources/model.properties +++ b/plugins/kotlin/util/project-model-updater/resources/model.properties @@ -1,4 +1,4 @@ -kotlincVersion=1.9.20-dev-8143 +kotlincVersion=1.9.30-dev-222 kotlincArtifactsMode=MAVEN jpsPluginVersion=1.9.0-release-358 diff --git a/plugins/kotlin/util/project-model-updater/src/org/jetbrains/tools/model/updater/kotlincLibraries.kt b/plugins/kotlin/util/project-model-updater/src/org/jetbrains/tools/model/updater/kotlincLibraries.kt index 54f5356e0f46..f6ae814e5f01 100644 --- a/plugins/kotlin/util/project-model-updater/src/org/jetbrains/tools/model/updater/kotlincLibraries.kt +++ b/plugins/kotlin/util/project-model-updater/src/org/jetbrains/tools/model/updater/kotlincLibraries.kt @@ -88,10 +88,7 @@ internal fun generateKotlincLibraries(preferences: GeneratorPreferences, isCommu run { val mavenIds = listOf( - MavenId.parse("$ktGroup:kotlin-stdlib-jdk8:${kotlincCoordinates.version}"), MavenId.parse("$ktGroup:kotlin-stdlib:${kotlincCoordinates.version}"), - MavenId.parse("$ktGroup:kotlin-stdlib-common:${kotlincCoordinates.version}"), - MavenId.parse("$ktGroup:kotlin-stdlib-jdk7:${kotlincCoordinates.version}") ) val annotationLibrary = JpsLibrary( diff --git a/plugins/kotlin/util/test-generator-fe10/test/org/jetbrains/kotlin/fe10/testGenerator/Fe10GenerateTests.kt b/plugins/kotlin/util/test-generator-fe10/test/org/jetbrains/kotlin/fe10/testGenerator/Fe10GenerateTests.kt index 2307ea473ff1..42d391b44374 100644 --- a/plugins/kotlin/util/test-generator-fe10/test/org/jetbrains/kotlin/fe10/testGenerator/Fe10GenerateTests.kt +++ b/plugins/kotlin/util/test-generator-fe10/test/org/jetbrains/kotlin/fe10/testGenerator/Fe10GenerateTests.kt @@ -1155,12 +1155,12 @@ private fun assembleWorkspace(): TWorkspace = workspace { model("weighers/smart", pattern = KT_OR_KTS_WITHOUT_DOTS) } - testClass { + testClass { model("basic/common", pattern = KT_WITHOUT_FIR_PREFIX) model("basic/js", pattern = KT_WITHOUT_FIR_PREFIX) } - testClass { + testClass { model("basic/common", pattern = KT_WITHOUT_FIR_PREFIX) model("basic/java", pattern = KT_WITHOUT_FIR_PREFIX) } @@ -1205,7 +1205,7 @@ private fun assembleWorkspace(): TWorkspace = workspace { model("smartMultiFile", pattern = DIRECTORY, isRecursive = false) } - testClass("org.jetbrains.kotlin.idea.completion.test.KDocCompletionTestGenerated") { + testClass("org.jetbrains.kotlin.idea.completion.test.K1KDocCompletionTestGenerated") { model("kdoc", pattern = KT_WITHOUT_DOT_AND_FIR_PREFIX) } diff --git a/plugins/kotlin/util/test-generator-fir/kotlin.util.test-generator-fir.iml b/plugins/kotlin/util/test-generator-fir/kotlin.util.test-generator-fir.iml index 85be85f195ce..90d293692518 100644 --- a/plugins/kotlin/util/test-generator-fir/kotlin.util.test-generator-fir.iml +++ b/plugins/kotlin/util/test-generator-fir/kotlin.util.test-generator-fir.iml @@ -66,11 +66,12 @@ - + + \ No newline at end of file diff --git a/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/FirGenerateTests.kt b/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/FirGenerateTests.kt index 324a05ed0371..6376590b8d46 100644 --- a/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/FirGenerateTests.kt +++ b/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/FirGenerateTests.kt @@ -3,9 +3,12 @@ package org.jetbrains.kotlin.fir.testGenerator import org.jetbrains.fir.uast.test.* +import org.jetbrains.kotlin.copyright.AbstractFirUpdateKotlinCopyrightTest import org.jetbrains.kotlin.fir.testGenerator.codeinsight.generateK2CodeInsightTests import org.jetbrains.kotlin.idea.fir.actions.AbstractK2AddImportActionTest +import org.jetbrains.kotlin.idea.fir.actions.AbstractK2BytecodeToolWindowTest import org.jetbrains.kotlin.idea.fir.analysis.providers.AbstractIdeKotlinAnnotationsResolverTest +import org.jetbrains.kotlin.idea.fir.analysis.providers.dependents.AbstractModuleDependentsTest import org.jetbrains.kotlin.idea.fir.analysis.providers.sessions.AbstractSessionsInvalidationTest import org.jetbrains.kotlin.idea.fir.analysis.providers.trackers.AbstractProjectWideOutOfBlockKotlinModificationTrackerTest import org.jetbrains.kotlin.idea.fir.codeInsight.AbstractK2MultiModuleLineMarkerTest @@ -80,6 +83,10 @@ private fun assembleWorkspace(): TWorkspace = workspace { testClass { model("annotationsResolver", pattern = KT_WITHOUT_DOTS) } + + testClass { + model("moduleDependents", pattern = DIRECTORY, isRecursive = false) + } } testGroup("compiler-plugins/parcelize/tests/k2", testDataPath = "../testData") { @@ -204,16 +211,20 @@ private fun assembleWorkspace(): TWorkspace = workspace { model("editor/optimizeImports/jvm", pattern = KT_WITHOUT_DOTS) model("editor/optimizeImports/common", pattern = KT_WITHOUT_DOTS) } + + testClass { + model("internal/toolWindow", isRecursive = false, pattern = DIRECTORY, testMethodName = "doTestWithIr") + } } testGroup("fir", testDataPath = "../completion/testData") { - testClass { + testClass { model("basic/common", pattern = KT_WITHOUT_FIR_PREFIX) model("basic/java", pattern = KT_WITHOUT_FIR_PREFIX) model("../../idea-fir/testData/completion/basic/common", testClassName = "CommonFir") } - testClass("org.jetbrains.kotlin.idea.fir.completion.HighLevelKDocCompletionTestGenerated") { + testClass("org.jetbrains.kotlin.idea.fir.completion.K2KDocCompletionTestGenerated") { model("kdoc", pattern = KT_WITHOUT_FIR_PREFIX) } @@ -365,4 +376,10 @@ private fun assembleWorkspace(): TWorkspace = workspace { model("") } } + + testGroup("copyright/fir-tests", testDataPath = "../../copyright/tests/testData") { + testClass { + model("update", pattern = KT_OR_KTS, testMethodName = "doTest") + } + } } diff --git a/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/GenerateK2DebuggerTests.kt b/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/GenerateK2DebuggerTests.kt index 7bea34f5489e..7f9aa448ba0f 100644 --- a/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/GenerateK2DebuggerTests.kt +++ b/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/GenerateK2DebuggerTests.kt @@ -2,6 +2,7 @@ package org.jetbrains.kotlin.fir.testGenerator import org.jetbrains.kotlin.idea.k2.debugger.test.cases.* +import org.jetbrains.kotlin.test.TargetBackend import org.jetbrains.kotlin.testGenerator.model.* internal fun MutableTWorkspace.generateK2DebuggerTests() { @@ -22,6 +23,10 @@ internal fun MutableTWorkspace.generateK2DebuggerTests() { model("stepping/custom", pattern = Patterns.KT_WITHOUT_DOTS, testMethodName = "doCustomTest") } } + testClass { + model("evaluation/singleBreakpoint", testMethodName = "doSingleBreakpointTest", targetBackend = TargetBackend.JVM_WITH_IR_EVALUATOR) + model("evaluation/multipleBreakpoints", testMethodName = "doMultipleBreakpointsTest", targetBackend = TargetBackend.JVM_WITH_IR_EVALUATOR) + } // //testClass { // model("evaluation/singleBreakpoint", testMethodName = "doSingleBreakpointTest", targetBackend = TargetBackend.JVM_WITH_OLD_EVALUATOR) diff --git a/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/GenerateK2HighlighterTests.kt b/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/GenerateK2HighlighterTests.kt index d5a72977373b..3b44a605c25a 100644 --- a/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/GenerateK2HighlighterTests.kt +++ b/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/GenerateK2HighlighterTests.kt @@ -9,7 +9,7 @@ import org.jetbrains.kotlin.idea.k2.highlighting.AbstractOutsiderHighlightingTes import org.jetbrains.kotlin.testGenerator.model.* internal fun MutableTWorkspace.generateK2HighlighterTests() { - testGroup("highlighting", testDataPath = "../idea/tests/testData") { + testGroup("highlighting/highlighting-k2", testDataPath = "../../idea/tests/testData") { testClass { model("highlighterMetaInfo") } @@ -27,7 +27,7 @@ internal fun MutableTWorkspace.generateK2HighlighterTests() { } } - testGroup("highlighting") { + testGroup("highlighting/highlighting-k2", testDataPath = "testData") { testClass { model("outsider", pattern = Patterns.DIRECTORY, isRecursive = false, passTestDataPath = false) } diff --git a/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/GenerateK2RefactoringsTests.kt b/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/GenerateK2RefactoringsTests.kt index d72eb848c31a..f6c3029f6151 100644 --- a/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/GenerateK2RefactoringsTests.kt +++ b/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/GenerateK2RefactoringsTests.kt @@ -32,16 +32,7 @@ internal fun MutableTWorkspace.generateK2RefactoringsTests() { model("refactoring/safeDelete/deleteValueParameter/javaParameterWithKotlin", pattern = Patterns.JAVA, testMethodName = "doJavaParameterTest") } testClass { - model("refactoring/bindToElement/callableReference") - model("refactoring/bindToElement/constructorCall") - model("refactoring/bindToElement/superTypeCall") - model("refactoring/bindToElement/annotationCall") - model("refactoring/bindToElement/propertyTypeReference") - model("refactoring/bindToElement/returnTypeReference") - model("refactoring/bindToElement/superTypeReference") - model("refactoring/bindToElement/delegatedSuperTypeReference") - model("refactoring/bindToElement/annotationReference") - model("refactoring/bindToElement/changeImport") + model("refactoring/bindToElement") } } diff --git a/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/codeinsight/GenerateK2LineMarkerTests.kt b/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/codeinsight/GenerateK2LineMarkerTests.kt index 890040153172..712911cb85ed 100644 --- a/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/codeinsight/GenerateK2LineMarkerTests.kt +++ b/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/codeinsight/GenerateK2LineMarkerTests.kt @@ -1,16 +1,20 @@ // Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.fir.testGenerator.codeinsight -import org.jetbrains.kotlin.idea.k2.codeInsight.lineMarkers.test.AbstractLineMarkerTest +import org.jetbrains.kotlin.idea.k2.codeInsight.lineMarkers.test.AbstractLineMarkersK2Test import org.jetbrains.kotlin.testGenerator.model.* internal fun MutableTWorkspace.generateK2LineMarkerTests() { testGroup("code-insight/line-markers") { - testClass { - model("recursive", pattern = Patterns.KT_WITHOUT_DOTS, passTestDataPath = false) - model("suspend", pattern = Patterns.KT_WITHOUT_DOTS, passTestDataPath = false) - model("../../../idea/tests/testData/codeInsight/lineMarker/overrideImplement", pattern = Patterns.KT_WITHOUT_DOTS, passTestDataPath = false) - model("../../../idea/tests/testData/codeInsight/lineMarker/dslMarker", pattern = Patterns.KT_WITHOUT_DOTS, passTestDataPath = false) + testClass { + model("recursive", pattern = Patterns.KT_WITHOUT_DOTS) + model("suspend", pattern = Patterns.KT_WITHOUT_DOTS) + model("../../../idea/tests/testData/codeInsight/lineMarker/overrideImplement", pattern = Patterns.KT_WITHOUT_DOTS) + model("../../../idea/tests/testData/codeInsight/lineMarker/dslMarker", pattern = Patterns.KT_WITHOUT_DOTS) + model("../../../idea/tests/testData/codeInsight/lineMarker/main", pattern = Patterns.KT_WITHOUT_DOTS) + model("../../../idea/tests/testData/codeInsight/lineMarker/runMarkers", pattern = Patterns.KT_WITHOUT_DOTS) + model("../../../idea/tests/testData/codeInsight/lineMarker/methodSeparators", pattern = Patterns.KT_WITHOUT_DOTS) + } } } \ No newline at end of file