jps bazel 12

GitOrigin-RevId: f88bca362f38ae3fa66a7ddc69801399f4c68019
This commit is contained in:
Vladimir Krivosheev
2025-02-03 18:28:40 +00:00
committed by intellij-monorepo-bot
parent 3e470a2767
commit 79ef984541
29 changed files with 632 additions and 508 deletions
+5 -5
View File
@@ -1,18 +1,18 @@
<component name="libraryTable">
<library name="kotlin-metadata" type="repository">
<properties include-transitive-deps="false" maven-id="org.jetbrains.kotlin:kotlin-metadata-jvm:2.1.20-Beta1">
<properties include-transitive-deps="false" maven-id="org.jetbrains.kotlin:kotlin-metadata-jvm:2.1.20-Beta2">
<verification>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-metadata-jvm/2.1.20-Beta1/kotlin-metadata-jvm-2.1.20-Beta1.jar">
<sha256sum>243ac56352ce7e1ca7f294a53b1a1b3040ca12b95725449f0c04bbee6d43d84c</sha256sum>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-metadata-jvm/2.1.20-Beta2/kotlin-metadata-jvm-2.1.20-Beta2.jar">
<sha256sum>a4d99e5b88eff9972c117b577436aa587e83f78e60cf005cd614065f59ead7a9</sha256sum>
</artifact>
</verification>
</properties>
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-metadata-jvm/2.1.20-Beta1/kotlin-metadata-jvm-2.1.20-Beta1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-metadata-jvm/2.1.20-Beta2/kotlin-metadata-jvm-2.1.20-Beta2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-metadata-jvm/2.1.20-Beta1/kotlin-metadata-jvm-2.1.20-Beta1-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-metadata-jvm/2.1.20-Beta2/kotlin-metadata-jvm-2.1.20-Beta2-sources.jar!/" />
</SOURCES>
</library>
</component>
+54 -54
View File
@@ -18,8 +18,8 @@ local_path_override(
http_archive(
name = "kotlinc",
url = "https://github.com/JetBrains/kotlin/releases/download/v2.1.20-Beta1/kotlin-compiler-2.1.20-Beta1.zip",
sha256 = "a4e655eb8370c6dde9deaf1271836dc6d1d0a667fb00efb2e99021d91e2cf8a4",
url = "https://github.com/JetBrains/kotlin/releases/download/v2.1.20-Beta2/kotlin-compiler-2.1.20-Beta2.zip",
sha256 = "2d24cfb0fd736d86f6aa52fb7bd117b00f5df73d8d99d030f35413ba06db490a",
build_file = "//:BUILD.kotlinc.bazel",
strip_prefix = "kotlinc",
)
@@ -79,119 +79,119 @@ http_file(
http_file(
name = "kotlin-build-tools-api",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-build-tools-api/2.1.20-Beta1/kotlin-build-tools-api-2.1.20-Beta1.jar",
sha256 = "09ddebb845f30310395d91c084f65d2133484080dfac1977502776b77345f3d7",
downloaded_file_path = "kotlin-build-tools-api-2.1.20-Beta1.jar",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-build-tools-api/2.1.20-Beta2/kotlin-build-tools-api-2.1.20-Beta2.jar",
sha256 = "d2155dea5f3a6262fa7f68400c858c2982d937863ec142cc13b142e915b324e3",
downloaded_file_path = "kotlin-build-tools-api-2.1.20-Beta2.jar",
)
http_file(
name = "kotlin-build-tools-api-sources",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-build-tools-api/2.1.20-Beta1/kotlin-build-tools-api-2.1.20-Beta1-sources.jar",
sha256 = "236ff9971b05fdbef35fafd390f39546c6b61467d4991474111a4823d359324b",
downloaded_file_path = "kotlin-build-tools-api-2.1.20-Beta1-sources.jar",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-build-tools-api/2.1.20-Beta2/kotlin-build-tools-api-2.1.20-Beta2-sources.jar",
sha256 = "fe86558db8dc6b7712ef376b92de40f3573dd844f2529424fb8162309b97d7f6",
downloaded_file_path = "kotlin-build-tools-api-2.1.20-Beta2-sources.jar",
)
http_file(
name = "kotlin-util-klib",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-util-klib/2.1.20-Beta1/kotlin-util-klib-2.1.20-Beta1.jar",
sha256 = "f48b6323092cb30f860cb5c880d6107982d82941166073871a36349dfd3f7909",
downloaded_file_path = "kotlin-util-klib-2.1.20-Beta1.jar",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-util-klib/2.1.20-Beta2/kotlin-util-klib-2.1.20-Beta2.jar",
sha256 = "3323354cff5c1e10e5ce3a57a0eb9475b20868264689543b7bc80cf4797423ca",
downloaded_file_path = "kotlin-util-klib-2.1.20-Beta2.jar",
)
http_file(
name = "kotlin-util-klib-sources",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-util-klib/2.1.20-Beta1/kotlin-util-klib-2.1.20-Beta1-sources.jar",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-util-klib/2.1.20-Beta2/kotlin-util-klib-2.1.20-Beta2-sources.jar",
sha256 = "4aa4da6df01507c0fe9b48ff4f3d2a5eb5edf5f894850169c90efc89330a9d8b",
downloaded_file_path = "kotlin-util-klib-2.1.20-Beta1-sources.jar",
downloaded_file_path = "kotlin-util-klib-2.1.20-Beta2-sources.jar",
)
http_file(
name = "kotlin-util-klib-metadata",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-util-klib-metadata/2.1.20-Beta1/kotlin-util-klib-metadata-2.1.20-Beta1.jar",
sha256 = "1b59ec74876c8d13242d04aeefc22e10444ed082f38ad52fc95bc64a6896c7fd",
downloaded_file_path = "kotlin-util-klib-metadata-2.1.20-Beta1.jar",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-util-klib-metadata/2.1.20-Beta2/kotlin-util-klib-metadata-2.1.20-Beta2.jar",
sha256 = "98261bc30acd236aadd09de17b8a375a5a3181af72e293b4d5e41e08a2e2f691",
downloaded_file_path = "kotlin-util-klib-metadata-2.1.20-Beta2.jar",
)
http_file(
name = "kotlin-util-klib-metadata-sources",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-util-klib-metadata/2.1.20-Beta1/kotlin-util-klib-metadata-2.1.20-Beta1-sources.jar",
sha256 = "7d4d0fcd74aa62a12add77e9738a29562086dd23fd095e40f8e5308e8335b5bf",
downloaded_file_path = "kotlin-util-klib-metadata-2.1.20-Beta1-sources.jar",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-util-klib-metadata/2.1.20-Beta2/kotlin-util-klib-metadata-2.1.20-Beta2-sources.jar",
sha256 = "8c09123a01414e2e8b7b691aecb3e96b36d993f0101de8566f62f5ff6a1e8d3f",
downloaded_file_path = "kotlin-util-klib-metadata-2.1.20-Beta2-sources.jar",
)
http_file(
name = "kotlin-build-tools-impl",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-build-tools-impl/2.1.20-Beta1/kotlin-build-tools-impl-2.1.20-Beta1.jar",
sha256 = "7e1e4d96ca0d29fc5890b9eadca97f64917e1d67f8385b91cc28cee9215b70b3",
downloaded_file_path = "kotlin-build-tools-impl-2.1.20-Beta1.jar",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-build-tools-impl/2.1.20-Beta2/kotlin-build-tools-impl-2.1.20-Beta2.jar",
sha256 = "fef93d25defc9c63fc2d8a85914282ccf18bd4fdf4a757d00417e82c4fe30d75",
downloaded_file_path = "kotlin-build-tools-impl-2.1.20-Beta2.jar",
)
http_file(
name = "kotlin-build-tools-impl-sources",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-build-tools-impl/2.1.20-Beta1/kotlin-build-tools-impl-2.1.20-Beta1-sources.jar",
sha256 = "8f7fe21cd6773f9b4d842cc8eb282e72004b300b6f23b6a32d27346de7336533",
downloaded_file_path = "kotlin-build-tools-impl-2.1.20-Beta1-sources.jar",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-build-tools-impl/2.1.20-Beta2/kotlin-build-tools-impl-2.1.20-Beta2-sources.jar",
sha256 = "8f8f11d1078d1a4ee7c5c3a61c3df74e0b3c1820e97a95b9e3a81ea4f70f6101",
downloaded_file_path = "kotlin-build-tools-impl-2.1.20-Beta2-sources.jar",
)
http_file(
name = "kotlin-compiler",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-compiler/2.1.20-Beta1/kotlin-compiler-2.1.20-Beta1.jar",
sha256 = "7bc01138d15bc1b7657480ce9fabbbb704626f92287edc05745341b11d8795b4",
downloaded_file_path = "kotlin-compiler-2.1.20-Beta1.jar",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-compiler/2.1.20-Beta2/kotlin-compiler-2.1.20-Beta2.jar",
sha256 = "367c4d9e0ba8c4e1f5ee52552bb4c63ca1422fc8543333378480031eda5010eb",
downloaded_file_path = "kotlin-compiler-2.1.20-Beta2.jar",
)
http_file(
name = "kotlin-compiler-sources",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-compiler/2.1.20-Beta1/kotlin-compiler-2.1.20-Beta1-sources.jar",
sha256 = "8a670f50a7e506cb859a4b4122a7c6d5dfd0fb180a5efd3448ab551dbfc85589",
downloaded_file_path = "kotlin-compiler-2.1.20-Beta1-sources.jar",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-compiler/2.1.20-Beta2/kotlin-compiler-2.1.20-Beta2-sources.jar",
sha256 = "84652229286b1136776b0d739993c48d5a963343a9dbd240a7a41da99c68556d",
downloaded_file_path = "kotlin-compiler-2.1.20-Beta2-sources.jar",
)
http_file(
name = "kotlin-metadata-jvm",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-metadata-jvm/2.1.20-Beta1/kotlin-metadata-jvm-2.1.20-Beta1.jar",
sha256 = "243ac56352ce7e1ca7f294a53b1a1b3040ca12b95725449f0c04bbee6d43d84c",
downloaded_file_path = "kotlin-metadata-jvm-2.1.20-Beta1.jar",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-metadata-jvm/2.1.20-Beta2/kotlin-metadata-jvm-2.1.20-Beta2.jar",
sha256 = "a4d99e5b88eff9972c117b577436aa587e83f78e60cf005cd614065f59ead7a9",
downloaded_file_path = "kotlin-metadata-jvm-2.1.20-Beta2.jar",
)
http_file(
name = "kotlin-metadata-jvm-sources",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-metadata-jvm/2.1.20-Beta1/kotlin-metadata-jvm-2.1.20-Beta1-sources.jar",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-metadata-jvm/2.1.20-Beta2/kotlin-metadata-jvm-2.1.20-Beta2-sources.jar",
sha256 = "3f5468b5c409702c7cac30067208b7218ab9e3f7209e686966c6c2de2134dd18",
downloaded_file_path = "kotlin-metadata-jvm-2.1.20-Beta1-sources.jar",
downloaded_file_path = "kotlin-metadata-jvm-2.1.20-Beta2-sources.jar",
)
http_file(
name = "kotlin-jps-plugin",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-jps-plugin/2.1.20-Beta1/kotlin-jps-plugin-2.1.20-Beta1.jar",
sha256 = "0f60c6f49e74ee938605890553df1ba1ce219ebd8a8ff8d93dab82a202293ae8",
downloaded_file_path = "kotlin-jps-plugin-2.1.20-Beta1.jar",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-jps-plugin/2.1.20-Beta2/kotlin-jps-plugin-2.1.20-Beta2.jar",
sha256 = "479f83fbaff22361ac3c1c2de410043901afe71e06fa6ab599b0037059b53788",
downloaded_file_path = "kotlin-jps-plugin-2.1.20-Beta2.jar",
)
http_file(
name = "kotlin-jps-plugin-sources",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-jps-plugin/2.1.20-Beta1/kotlin-jps-plugin-2.1.20-Beta1-sources.jar",
sha256 = "5a337df793923ff69a55e52d386e17205570686bab85a4967fb58bbb6aee340a",
downloaded_file_path = "kotlin-jps-plugin-2.1.20-Beta1-sources.jar",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-jps-plugin/2.1.20-Beta2/kotlin-jps-plugin-2.1.20-Beta2-sources.jar",
sha256 = "9050fd365fa139a4aa0c5c1383d177474eacf151495b577987ffc86bc78cecbc",
downloaded_file_path = "kotlin-jps-plugin-2.1.20-Beta2-sources.jar",
)
http_file(
name = "kotlin-serialization-compiler-plugin",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-serialization-compiler-plugin/2.1.20-Beta1/kotlin-serialization-compiler-plugin-2.1.20-Beta1.jar",
sha256 = "6c84d19e34509173b9e9f7ea7cbd96e1a1c8314b603f691a328012dd1e0b8f9e",
downloaded_file_path = "kotlin-serialization-compiler-plugin-2.1.20-Beta1.jar",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-serialization-compiler-plugin/2.1.20-Beta2/kotlin-serialization-compiler-plugin-2.1.20-Beta2.jar",
sha256 = "deabc2903e4c1aab9d5e3e4be29736c0873a961b7b2f9db02051d5fd1675ceb8",
downloaded_file_path = "kotlin-serialization-compiler-plugin-2.1.20-Beta2.jar",
)
http_file(
name = "kotlin-serialization-compiler-plugin-sources",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-serialization-compiler-plugin/2.1.20-Beta1/kotlin-serialization-compiler-plugin-2.1.20-Beta1-sources.jar",
sha256 = "09037197de2c7b4a022c1bb9be4ed3d13d38dd63ca7c08465765e98501378306",
downloaded_file_path = "kotlin-serialization-compiler-plugin-2.1.20-Beta1-sources.jar",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-serialization-compiler-plugin/2.1.20-Beta2/kotlin-serialization-compiler-plugin-2.1.20-Beta2-sources.jar",
sha256 = "941b3bf2b6b366f6b6d066b8d17daf4ec974ec9a419888aa3448716b15fde8e9",
downloaded_file_path = "kotlin-serialization-compiler-plugin-2.1.20-Beta2-sources.jar",
)
http_file(
name = "kotlin-compose-compiler-plugin",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-compose-compiler-plugin/2.1.20-Beta1/kotlin-compose-compiler-plugin-2.1.20-Beta1.jar",
sha256 = "a8b056165e5f0f294b52b61721bfbf776d17e6a270a33f8e6e5d8bf405ece4a4",
downloaded_file_path = "kotlin-compose-compiler-plugin-2.1.20-Beta1.jar",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-compose-compiler-plugin/2.1.20-Beta2/kotlin-compose-compiler-plugin-2.1.20-Beta2.jar",
sha256 = "516e93281f577203335d0aaafcd63a5ffa23082d674c3d78159d5000b1c40f61",
downloaded_file_path = "kotlin-compose-compiler-plugin-2.1.20-Beta2.jar",
)
http_file(
name = "kotlin-compose-compiler-plugin-sources",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-compose-compiler-plugin/2.1.20-Beta1/kotlin-compose-compiler-plugin-2.1.20-Beta1-sources.jar",
sha256 = "320128e59ff599f6016addcc6aabea8bd2715609586502430647b4820fbe9836",
downloaded_file_path = "kotlin-compose-compiler-plugin-2.1.20-Beta1-sources.jar",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-compose-compiler-plugin/2.1.20-Beta2/kotlin-compose-compiler-plugin-2.1.20-Beta2-sources.jar",
sha256 = "bfb26a777eb4338852c072adb735c7903306e7c45ea57a59e6a023f2986af628",
downloaded_file_path = "kotlin-compose-compiler-plugin-2.1.20-Beta2-sources.jar",
)
http_file(
+25 -25
View File
@@ -43,40 +43,40 @@
"abfef148779957f34430c14e9b9a98872ea8064336bc82998d53668a0ded7d2a",
"d1fd0853979b6670f073fb95f83794c5792706e179a686a6471ee3a6450bf716"
],
"org.jetbrains.kotlin:kotlin-build-tools-api:2.1.20-Beta1": [
"09ddebb845f30310395d91c084f65d2133484080dfac1977502776b77345f3d7",
"236ff9971b05fdbef35fafd390f39546c6b61467d4991474111a4823d359324b"
"org.jetbrains.kotlin:kotlin-build-tools-api:2.1.20-Beta2": [
"d2155dea5f3a6262fa7f68400c858c2982d937863ec142cc13b142e915b324e3",
"fe86558db8dc6b7712ef376b92de40f3573dd844f2529424fb8162309b97d7f6"
],
"org.jetbrains.kotlin:kotlin-build-tools-impl:2.1.20-Beta1": [
"7e1e4d96ca0d29fc5890b9eadca97f64917e1d67f8385b91cc28cee9215b70b3",
"8f7fe21cd6773f9b4d842cc8eb282e72004b300b6f23b6a32d27346de7336533"
"org.jetbrains.kotlin:kotlin-build-tools-impl:2.1.20-Beta2": [
"fef93d25defc9c63fc2d8a85914282ccf18bd4fdf4a757d00417e82c4fe30d75",
"8f8f11d1078d1a4ee7c5c3a61c3df74e0b3c1820e97a95b9e3a81ea4f70f6101"
],
"org.jetbrains.kotlin:kotlin-compiler:2.1.20-Beta1": [
"7bc01138d15bc1b7657480ce9fabbbb704626f92287edc05745341b11d8795b4",
"8a670f50a7e506cb859a4b4122a7c6d5dfd0fb180a5efd3448ab551dbfc85589"
"org.jetbrains.kotlin:kotlin-compiler:2.1.20-Beta2": [
"367c4d9e0ba8c4e1f5ee52552bb4c63ca1422fc8543333378480031eda5010eb",
"84652229286b1136776b0d739993c48d5a963343a9dbd240a7a41da99c68556d"
],
"org.jetbrains.kotlin:kotlin-compose-compiler-plugin:2.1.20-Beta1": [
"a8b056165e5f0f294b52b61721bfbf776d17e6a270a33f8e6e5d8bf405ece4a4",
"320128e59ff599f6016addcc6aabea8bd2715609586502430647b4820fbe9836"
"org.jetbrains.kotlin:kotlin-compose-compiler-plugin:2.1.20-Beta2": [
"516e93281f577203335d0aaafcd63a5ffa23082d674c3d78159d5000b1c40f61",
"bfb26a777eb4338852c072adb735c7903306e7c45ea57a59e6a023f2986af628"
],
"org.jetbrains.kotlin:kotlin-jps-plugin:2.1.20-Beta1": [
"0f60c6f49e74ee938605890553df1ba1ce219ebd8a8ff8d93dab82a202293ae8",
"5a337df793923ff69a55e52d386e17205570686bab85a4967fb58bbb6aee340a"
"org.jetbrains.kotlin:kotlin-jps-plugin:2.1.20-Beta2": [
"479f83fbaff22361ac3c1c2de410043901afe71e06fa6ab599b0037059b53788",
"9050fd365fa139a4aa0c5c1383d177474eacf151495b577987ffc86bc78cecbc"
],
"org.jetbrains.kotlin:kotlin-metadata-jvm:2.1.20-Beta1": [
"243ac56352ce7e1ca7f294a53b1a1b3040ca12b95725449f0c04bbee6d43d84c",
"org.jetbrains.kotlin:kotlin-metadata-jvm:2.1.20-Beta2": [
"a4d99e5b88eff9972c117b577436aa587e83f78e60cf005cd614065f59ead7a9",
"3f5468b5c409702c7cac30067208b7218ab9e3f7209e686966c6c2de2134dd18"
],
"org.jetbrains.kotlin:kotlin-serialization-compiler-plugin:2.1.20-Beta1": [
"6c84d19e34509173b9e9f7ea7cbd96e1a1c8314b603f691a328012dd1e0b8f9e",
"09037197de2c7b4a022c1bb9be4ed3d13d38dd63ca7c08465765e98501378306"
"org.jetbrains.kotlin:kotlin-serialization-compiler-plugin:2.1.20-Beta2": [
"deabc2903e4c1aab9d5e3e4be29736c0873a961b7b2f9db02051d5fd1675ceb8",
"941b3bf2b6b366f6b6d066b8d17daf4ec974ec9a419888aa3448716b15fde8e9"
],
"org.jetbrains.kotlin:kotlin-util-klib-metadata:2.1.20-Beta1": [
"1b59ec74876c8d13242d04aeefc22e10444ed082f38ad52fc95bc64a6896c7fd",
"7d4d0fcd74aa62a12add77e9738a29562086dd23fd095e40f8e5308e8335b5bf"
"org.jetbrains.kotlin:kotlin-util-klib-metadata:2.1.20-Beta2": [
"98261bc30acd236aadd09de17b8a375a5a3181af72e293b4d5e41e08a2e2f691",
"8c09123a01414e2e8b7b691aecb3e96b36d993f0101de8566f62f5ff6a1e8d3f"
],
"org.jetbrains.kotlin:kotlin-util-klib:2.1.20-Beta1": [
"f48b6323092cb30f860cb5c880d6107982d82941166073871a36349dfd3f7909",
"org.jetbrains.kotlin:kotlin-util-klib:2.1.20-Beta2": [
"3323354cff5c1e10e5ce3a57a0eb9475b20868264689543b7bc80cf4797423ca",
"4aa4da6df01507c0fe9b48ff4f3d2a5eb5edf5f894850169c90efc89330a9d8b"
],
"org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.1": [
+9 -9
View File
@@ -5,28 +5,28 @@
version: 4.29.3
# kotlin JPS plugin
- id: org.jetbrains.kotlin:kotlin-build-tools-api
version: 2.1.20-Beta1
version: 2.1.20-Beta2
- id: org.jetbrains.kotlin:kotlin-util-klib
version: 2.1.20-Beta1
version: 2.1.20-Beta2
- id: org.jetbrains.kotlin:kotlin-util-klib-metadata
version: 2.1.20-Beta1
version: 2.1.20-Beta2
# kotlin compiler
- id: org.jetbrains.kotlin:kotlin-build-tools-impl
version: 2.1.20-Beta1
version: 2.1.20-Beta2
- id: org.jetbrains.kotlin:kotlin-compiler
version: 2.1.20-Beta1
version: 2.1.20-Beta2
runtimeDeps:
- "@lib//:jetbrains-annotations"
- ":kotlinx-coroutines-core"
- id: org.jetbrains.kotlin:kotlin-metadata-jvm
version: 2.1.20-Beta1
version: 2.1.20-Beta2
- id: org.jetbrains.kotlin:kotlin-jps-plugin
version: 2.1.20-Beta1
version: 2.1.20-Beta2
# kotlin compiler plugins
- id: org.jetbrains.kotlin:kotlin-serialization-compiler-plugin
version: 2.1.20-Beta1
version: 2.1.20-Beta2
- id: org.jetbrains.kotlin:kotlin-compose-compiler-plugin
version: 2.1.20-Beta1
version: 2.1.20-Beta2
- id: dev.drewhamilton.poko:poko-compiler-plugin
version: 0.18.2
# other libs
@@ -35,8 +35,6 @@ internal class JavaAbiClassVisitor(
}
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String?, interfaces: Array<String>?) {
//isApiClass = (access and (Opcodes.ACC_PUBLIC or Opcodes.ACC_PROTECTED)) != 0
// we have a lot of violations for now - allow any, even package-local class
isApiClass = (access and (Opcodes.ACC_PUBLIC or Opcodes.ACC_PROTECTED)) != 0
if (isApiClass) {
classVisitor.visit(version, access, name, signature, superName, interfaces)
+107 -131
View File
@@ -1,15 +1,17 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
@file:Suppress("ReplaceGetOrSet")
package org.jetbrains.bazel.jvm.abi
import org.jetbrains.org.objectweb.asm.AnnotationVisitor
import org.jetbrains.org.objectweb.asm.Attribute
import org.jetbrains.org.objectweb.asm.ClassReader
import org.jetbrains.org.objectweb.asm.ClassVisitor
import org.jetbrains.org.objectweb.asm.ClassWriter
import org.jetbrains.org.objectweb.asm.FieldVisitor
import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.ModuleVisitor
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.RecordComponentVisitor
import org.jetbrains.org.objectweb.asm.TypePath
import org.jetbrains.org.objectweb.asm.tree.AnnotationNode
import org.jetbrains.org.objectweb.asm.commons.ClassRemapper
import org.jetbrains.org.objectweb.asm.commons.Remapper
import org.jetbrains.org.objectweb.asm.tree.FieldNode
import org.jetbrains.org.objectweb.asm.tree.MethodNode
import kotlin.metadata.KmClass
@@ -29,51 +31,56 @@ import kotlin.metadata.jvm.localDelegatedProperties
import kotlin.metadata.jvm.signature
import kotlin.metadata.visibility
internal class KotlinAbiClassVisitor(
private val classVisitor: ClassVisitor,
internal fun createAbForKotlin(classesToBeDeleted: HashSet<String>, item: JarContentToProcess): ByteArray? {
val classWriter = ClassWriter(0)
val innerClassesToKeep = HashSet<String>()
val remapper = ClassRemapper(classWriter, object : Remapper() {
override fun map(internalName: String): String {
innerClassesToKeep.add(internalName)
return internalName
}
override fun mapInnerClassName(name: String, ownerName: String?, innerName: String?): String? = innerName
})
val abiClassVisitor = KotlinAbiClassVisitor(
classesToBeDeleted = classesToBeDeleted,
treatInternalAsPrivate = false,
remapper = remapper,
innerClassesToKeep = innerClassesToKeep,
)
ClassReader(item.data).accept(abiClassVisitor, ClassReader.SKIP_FRAMES)
if (abiClassVisitor.isApiClass) {
return classWriter.toByteArray()
}
return null
}
private class InnerClassInfo(
@JvmField val name: String,
@JvmField val outerName: String?,
@JvmField val innerName: String?,
@JvmField val access: Int,
)
// inspired by JvmAbiOutputExtension
private class KotlinAbiClassVisitor(
private val classesToBeDeleted: MutableSet<String>,
private val treatInternalAsPrivate: Boolean,
) : ClassVisitor(Opcodes.API_VERSION) {
remapper: ClassRemapper,
private val innerClassesToKeep: MutableSet<String>,
) : ClassVisitor(Opcodes.API_VERSION, remapper) {
private val innerClassToInfo = mutableMapOf<String, InnerClassInfo>()
// tracks if this class has any public API members
var isApiClass: Boolean = true
private set
private val visibleAnnotations = ArrayList<AnnotationNode>()
private val invisibleAnnotations = ArrayList<AnnotationNode>()
private val fields = mutableListOf<FieldNode>()
private val methods = mutableListOf<MethodNode>()
private var kotlinMetadata: Pair<String, KotlinClassMetadata>? = null
override fun visitAnnotation(descriptor: String, visible: Boolean): AnnotationVisitor? {
// parse @Metadata for Kotlin-specific visibility information
@Suppress("SpellCheckingInspection")
if (descriptor == "Lkotlin/Metadata;") {
return KotlinAnnotationVisitor {
kotlinMetadata = descriptor to KotlinClassMetadata.readStrict(it)
}
}
else {
val annotationNode = AnnotationNode(api, descriptor)
(if (visible) visibleAnnotations else invisibleAnnotations).add(annotationNode)
return annotationNode
}
}
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String?, interfaces: Array<String>?) {
isApiClass = (access and (Opcodes.ACC_PUBLIC or Opcodes.ACC_PROTECTED)) != 0
if (isApiClass) {
val visibility = (kotlinMetadata?.second as? KotlinClassMetadata.Class)?.kmClass?.visibility
if (visibility == null || !isPrivateVisibility(visibility, treatInternalAsPrivate)) {
classVisitor.visit(version, access, name, signature, superName, interfaces)
return
}
else {
isApiClass = false
}
}
classesToBeDeleted.add(name)
override fun visitSource(source: String?, debug: String?) {
// debug not important
}
override fun visitField(
@@ -113,20 +120,61 @@ internal class KotlinAbiClassVisitor(
val method = MethodNode(Opcodes.API_VERSION, access, name, descriptor, signature, exceptions)
methods.add(method)
if (access and (Opcodes.ACC_NATIVE or Opcodes.ACC_ABSTRACT) != 0) {
return method
}
val functions = kotlinMetadata?.second?.let { getFunctions(it) }
val isInlineMethod = functions != null && functions.any { it.isInline && it.name == method.name }
if (isInlineMethod) {
return method
}
else {
return ReplaceWithEmptyBody(method)
return BodyStrippingMethodVisitor(method)
}
}
override fun visitEnd() {
visibleAnnotations.sortBy { it.desc }
invisibleAnnotations.sortBy { it.desc }
override fun visitInnerClass(name: String, outerName: String?, innerName: String?, access: Int) {
// `visitInnerClass` is called before `visitField`/`visitMethod`, so we don't know
// which types are referenced by kept methods yet.
innerClassToInfo[name] = InnerClassInfo(name, outerName, innerName, access)
}
override fun visitAnnotation(descriptor: String, visible: Boolean): AnnotationVisitor? {
// parse @Metadata for Kotlin-specific visibility information
@Suppress("SpellCheckingInspection")
when (descriptor) {
"Lkotlin/Metadata;" -> {
return KotlinAnnotationVisitor {
kotlinMetadata = descriptor to KotlinClassMetadata.readStrict(it)
}
}
"Lkotlin/jvm/internal/SourceDebugExtension;" -> {
return null
}
else -> {
return super.visitAnnotation(descriptor, visible)
}
}
}
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String?, interfaces: Array<String>?) {
isApiClass = (access and (Opcodes.ACC_PUBLIC or Opcodes.ACC_PROTECTED)) != 0
if (isApiClass) {
val visibility = (kotlinMetadata?.second as? KotlinClassMetadata.Class)?.kmClass?.visibility
if (visibility == null || !isPrivateVisibility(visibility, treatInternalAsPrivate)) {
cv.visit(version, access, name, signature, superName, interfaces)
return
}
else {
isApiClass = false
}
}
classesToBeDeleted.add(name)
}
override fun visitEnd() {
fields.sortBy { it.name }
methods.sortBy { it.name }
@@ -134,85 +182,27 @@ internal class KotlinAbiClassVisitor(
transformAndWriteKotlinMetadata(
metadata = header,
descriptor = descriptor,
classVisitor = classVisitor,
classVisitor = cv,
classesToBeDeleted = classesToBeDeleted,
treatInternalAsPrivate = treatInternalAsPrivate,
)
}
for (annotation in visibleAnnotations) {
annotation.accept(classVisitor.visitAnnotation(annotation.desc, true))
}
for (annotation in invisibleAnnotations) {
annotation.accept(classVisitor.visitAnnotation(annotation.desc, false))
}
for (field in fields) {
field.accept(classVisitor)
field.accept(cv)
}
//val km = kotlinMetadata?.second
//val functions = getFunctions(km)
for (method in methods) {
//if (isInlineMethod || !isKotlin) {
method.accept(classVisitor)
//}
//else {
// val methodVisitor = cv.visitMethod(method.access, method.name, method.desc, method.signature, method.exceptions?.toTypedArray())
// methodVisitor.visitCode()
// methodVisitor.visitInsn(Opcodes.RETURN)
// methodVisitor.visitMaxs(0, 0)
// methodVisitor.visitEnd()
//}
val methodVisitor = cv.visitMethod(method.access, method.name, method.desc, method.signature, method.exceptions?.toTypedArray())
method.accept(methodVisitor)
}
classVisitor.visitEnd()
}
override fun visitSource(source: String?, debug: String?) {
classVisitor.visitSource(source, debug)
}
override fun visitModule(name: String?, access: Int, version: String?): ModuleVisitor? {
return classVisitor.visitModule(name, access, version)
}
override fun visitAttribute(attribute: Attribute?) {
classVisitor.visitAttribute(attribute)
}
override fun visitOuterClass(owner: String?, name: String?, descriptor: String?) {
classVisitor.visitOuterClass(owner, name, descriptor)
}
override fun visitRecordComponent(name: String?, descriptor: String?, signature: String?): RecordComponentVisitor? {
return classVisitor.visitRecordComponent(name, descriptor, signature)
}
override fun visitTypeAnnotation(typeRef: Int, typePath: TypePath?, descriptor: String?, visible: Boolean): AnnotationVisitor? {
return classVisitor.visitTypeAnnotation(typeRef, typePath, descriptor, visible)
}
override fun visitNestMember(nestMember: String?) {
if (nestMember == null || !classesToBeDeleted.contains(nestMember)) {
classVisitor.visitNestMember(nestMember)
for (name in innerClassesToKeep.sorted()) {
val innerClassInfo = innerClassToInfo.get(name) ?: continue
cv.visitInnerClass(innerClassInfo.name, innerClassInfo.outerName, innerClassInfo.innerName, innerClassInfo.access)
}
}
override fun visitPermittedSubclass(permittedSubclass: String?) {
if (permittedSubclass == null || !classesToBeDeleted.contains(permittedSubclass)) {
classVisitor.visitPermittedSubclass(permittedSubclass)
}
}
override fun visitInnerClass(name: String?, outerName: String?, innerName: String?, access: Int) {
if (innerName == null || !classesToBeDeleted.contains(name)) {
classVisitor.visitInnerClass(name, outerName, innerName, access)
}
}
override fun visitNestHost(nestHost: String?) {
classVisitor.visitNestHost(nestHost)
cv.visitEnd()
}
private fun isMethodKotlinInternal(methodName: String?): Boolean {
@@ -373,27 +363,13 @@ private fun removePrivateDeclarationsForDeclarationContainer(
}
}
private class ReplaceWithEmptyBody(
private val targetWriter: MethodVisitor,
) : MethodVisitor(Opcodes.API_VERSION) {
private class BodyStrippingMethodVisitor(visitor: MethodVisitor) : MethodVisitor(Opcodes.API_VERSION, visitor) {
override fun visitCode() {
targetWriter.visitCode()
targetWriter.visitInsn(Opcodes.RETURN)
}
override fun visitParameter(name: String?, access: Int) {
targetWriter.visitParameter(name, access)
}
override fun visitParameterAnnotation(parameter: Int, descriptor: String?, visible: Boolean): AnnotationVisitor? {
return targetWriter.visitParameterAnnotation(parameter, descriptor, visible)
}
override fun visitAnnotation(descriptor: String?, visible: Boolean): AnnotationVisitor? {
return targetWriter.visitAnnotation(descriptor, visible)
}
override fun visitEnd() {
targetWriter.visitEnd()
mv.visitCode()
mv.visitInsn(Opcodes.ACONST_NULL)
mv.visitInsn(Opcodes.ATHROW)
mv.visitMaxs(0, 0)
mv.visitEnd()
mv = null
}
}
+9 -9
View File
@@ -13,16 +13,16 @@ internal object TestAbiGenerator {
try {
//val className = "com.intellij.codeInsight.folding.impl.FoldingUtil"
val className = "com.intellij.ui.AppUIUtilKt"
val classReader = ClassReader(zip.getInputStream(zip.getEntry(className.replace('.', '/') + ".class")))
val zipName = className.replace('.', '/') + ".class"
val data = zip.getInputStream(zip.getEntry(zipName)).use { it.readAllBytes() }
val classesToBeDeleted = HashSet<String>()
val classWriter = ClassWriter(classReader, 0)
val abiVisitor = KotlinAbiClassVisitor(
classVisitor = classWriter,
classesToBeDeleted = classesToBeDeleted,
treatInternalAsPrivate = false,
)
classReader.accept(abiVisitor, ClassReader.SKIP_CODE or ClassReader.SKIP_FRAMES)
val bytes = classWriter.toByteArray()
val bytes = createAbForKotlin(HashSet(), JarContentToProcess(
name = zipName.toByteArray(),
data = data,
isKotlinModuleMetadata = false,
isKotlin = true,
))
//val classNode = ClassNode()
//ClassReader(bytes).accept(classNode, 0)
}
+4 -9
View File
@@ -40,16 +40,11 @@ suspend fun writeAbi(abiJar: Path, classChannel: Channel<JarContentToProcess>) {
private fun createAbi(item: JarContentToProcess, classesToBeDeleted: HashSet<String>): ByteArray? {
if (item.isKotlin) {
val classWriter = ClassWriter(ClassWriter.COMPUTE_MAXS)
val abiClassVisitor = KotlinAbiClassVisitor(
classVisitor = classWriter,
classesToBeDeleted = classesToBeDeleted,
treatInternalAsPrivate = false,
)
ClassReader(item.data).accept(abiClassVisitor, ClassReader.SKIP_FRAMES)
if (abiClassVisitor.isApiClass) {
return classWriter.toByteArray()
// check that Java ABI works
if (true) {
return item.data
}
return createAbForKotlin(classesToBeDeleted, item)
}
else {
val classWriter = ClassWriter(0)
+4 -3
View File
@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.bazel.jvm.kotlin
import java.util.*
@@ -30,7 +30,7 @@ class ArgMap<T : Enum<T>> internal constructor(private val map: EnumMap<T, Mutab
}
}
fun mandatory(key: T): List<String> = requireNotNull(map[key]) { "$key is not optional"}
fun mandatory(key: T): List<String> = requireNotNull(map[key]) { "$key is not optional" }
fun optional(key: T): List<String>? = map[key]
@@ -68,7 +68,8 @@ fun <T : Enum<T>> createArgMap(
if (it.startsWith("--")) {
mergeCurrent()
currentKey = java.lang.Enum.valueOf(enumClass, it.substring(2).uppercase().replace('-', '_'))
} else {
}
else {
currentValue.add(it)
}
}
+11 -15
View File
@@ -14,7 +14,6 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap
import kotlinx.coroutines.*
import org.apache.arrow.memory.RootAllocator
import org.jetbrains.annotations.VisibleForTesting
import org.jetbrains.bazel.jvm.WorkRequest
import org.jetbrains.bazel.jvm.WorkRequestExecutor
import org.jetbrains.bazel.jvm.jps.impl.*
import org.jetbrains.bazel.jvm.jps.state.LoadStateResult
@@ -28,7 +27,6 @@ import org.jetbrains.bazel.jvm.kotlin.JvmBuilderFlags
import org.jetbrains.bazel.jvm.kotlin.parseArgs
import org.jetbrains.bazel.jvm.processRequests
import org.jetbrains.bazel.jvm.use
import org.jetbrains.jps.api.CanceledStatus
import org.jetbrains.jps.api.GlobalOptions
import org.jetbrains.jps.backwardRefs.JavaBackwardReferenceIndexBuilder
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType
@@ -77,7 +75,7 @@ fun configureGlobalJps(tracer: Tracer, scope: CoroutineScope) {
configureKotlincHome()
}
internal class JpsBuildWorker private constructor(private val allocator: RootAllocator) : WorkRequestExecutor {
internal class JpsBuildWorker private constructor(private val allocator: RootAllocator) : WorkRequestExecutor<WorkRequestWithDigests> {
companion object {
@JvmStatic
fun main(startupArgs: Array<String>) {
@@ -86,14 +84,15 @@ internal class JpsBuildWorker private constructor(private val allocator: RootAll
startupArgs = startupArgs,
executor = JpsBuildWorker(allocator),
setup = { tracer, scope -> configureGlobalJps(tracer = tracer, scope = scope) },
serviceName = "jps-builder"
reader = WorkRequestWithDigestReader(System.`in`),
serviceName = "jps-builder",
)
}
}
}
@OptIn(ExperimentalStdlibApi::class)
override suspend fun execute(request: WorkRequest, writer: Writer, baseDir: Path, tracingContext: Context, tracer: Tracer): Int {
override suspend fun execute(request: WorkRequestWithDigests, writer: Writer, baseDir: Path, tracingContext: Context, tracer: Tracer): Int {
val dependencyFileToDigest = hashMap<Path, ByteArray>()
val sourceFileToDigest = hashMap<Path, ByteArray>(request.inputPaths.size)
val sources = ArrayList<Path>()
@@ -101,7 +100,7 @@ internal class JpsBuildWorker private constructor(private val allocator: RootAll
val sourceFileToDigestDebugString = if (isDebugEnabled) StringBuilder() else null
val dependencyFileToDigestDebugString = if (isDebugEnabled) StringBuilder() else null
for ((index, input) in request.inputPaths.withIndex()) {
val digest = request.inputDigests[index]
val digest = request.inputDigests.get(index)
if (input.endsWith(".kt") || input.endsWith(".java")) {
val file = baseDir.resolve(input).normalize()
sources.add(file)
@@ -347,11 +346,11 @@ private suspend fun initAndBuild(
val storageInitializer = StorageInitializer(dataDir = dataDir, classOutDir = classOutDir)
val storageManager = tracer.spanBuilder("init storage").setParent(tracingContext).use { span ->
if (isRebuild) {
storageInitializer.clearAndInit(span)
}
else {
storageInitializer.init(span)
}
storageInitializer.clearAndInit(span)
}
else {
storageInitializer.init(span)
}
}
try {
val projectDescriptor = storageInitializer.createProjectDescriptor(
@@ -376,10 +375,7 @@ private suspend fun initAndBuild(
projectDescriptor,
messageHandler,
emptyMap(),
object : CanceledStatus {
override fun isCanceled(): Boolean = !coroutineContext.isActive
},
)
) { !coroutineContext.isActive }
val exitCode = tracer.spanBuilder("compile")
.setParent(tracingContext)
@@ -0,0 +1,72 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.bazel.jvm.jps
import org.jetbrains.bazel.jvm.WorkRequest
import org.jetbrains.bazel.jvm.WorkRequestReader
import org.jetbrains.bazel.jvm.doReadWorkRequestFromStream
import java.io.InputStream
internal class WorkRequestWithDigests(
arguments: Array<String>,
inputPaths: Array<String>,
requestId: Int,
cancel: Boolean,
verbosity: Int,
sandboxDir: String?,
@JvmField val inputDigests: Array<ByteArray>,
) : WorkRequest(
arguments = arguments,
inputPaths = inputPaths,
requestId = requestId,
cancel = cancel,
verbosity = verbosity,
sandboxDir = sandboxDir,
)
internal open class WorkRequestWithDigestReader(
//private val allocator: BufferAllocator,
private val input: InputStream,
) : WorkRequestReader<WorkRequestWithDigests> {
private val inputPathsToReuse = ArrayList<String>()
private val inputDigestToReuse = ArrayList<ByteArray>()
private val argListToReuse = ArrayList<String>()
override fun readWorkRequestFromStream(): WorkRequestWithDigests? {
//val digests = VarBinaryVector("digests", allocator)
//var counter = 0
//try {
// digests.allocateNew()
val inputDigestToReuse = inputDigestToReuse
inputDigestToReuse.clear()
val result = doReadWorkRequestFromStream(
input = input,
inputPathsToReuse = inputPathsToReuse,
argListToReuse = argListToReuse,
readDigest = { codedInputStream, tag ->
val digest = codedInputStream.readByteArray()
//inputDigestToReuse.setSafe(counter++, digest)
inputDigestToReuse.add(digest)
},
requestCreator = { argListToReuse, inputPathsToReuse, requestId, cancel, verbosity, sandboxDir ->
//digests.setValueCount(counter)
//counter = -1
WorkRequestWithDigests(
arguments = argListToReuse,
inputPaths = inputPathsToReuse,
requestId = requestId,
cancel = cancel,
verbosity = verbosity,
sandboxDir = sandboxDir,
inputDigests = inputDigestToReuse.toTypedArray(),
)
},
)
return result
//}
//finally {
// if (counter != -1) {
// digests.close()
// }
}
}
@@ -1,19 +1,20 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.bazel.jvm.kotlin
import io.opentelemetry.api.trace.Tracer
import io.opentelemetry.context.Context
import org.jetbrains.bazel.jvm.WorkRequest
import org.jetbrains.bazel.jvm.WorkRequestExecutor
import org.jetbrains.bazel.jvm.WorkRequestReaderWithoutDigest
import org.jetbrains.bazel.jvm.processRequests
import java.io.Writer
import java.nio.file.Path
object KotlinBuildWorker : WorkRequestExecutor {
object KotlinBuildWorker : WorkRequestExecutor<WorkRequest> {
@JvmStatic
fun main(startupArgs: Array<String>) {
org.jetbrains.kotlin.cli.jvm.compiler.CompileEnvironmentUtil
processRequests(startupArgs = startupArgs, executor = this, serviceName = "kotlin-builder")
processRequests(startupArgs = startupArgs, executor = this, reader = WorkRequestReaderWithoutDigest(System.`in`), serviceName = "kotlin-builder")
}
override suspend fun execute(request: WorkRequest, writer: Writer, baseDir: Path, tracingContext: Context, tracer: Tracer): Int {
@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.bazel.jvm.kotlin
import com.google.devtools.build.lib.view.proto.Deps
@@ -11,18 +11,24 @@ import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
import org.jetbrains.kotlin.cli.common.messages.*
import org.jetbrains.kotlin.cli.common.moduleChunk
import org.jetbrains.kotlin.cli.common.modules.ModuleBuilder
import org.jetbrains.kotlin.cli.common.modules.ModuleChunk
import org.jetbrains.kotlin.cli.common.setupCommonArguments
import org.jetbrains.kotlin.cli.jvm.compiler.BazelJvmCliPipeline
import org.jetbrains.kotlin.cli.jvm.compiler.BazelJvmConfigurationPipelinePhase
import org.jetbrains.kotlin.cli.jvm.compiler.configTemplate
import org.jetbrains.kotlin.cli.jvm.compiler.configurePlugins
import org.jetbrains.kotlin.cli.jvm.compiler.k2jvm
import org.jetbrains.kotlin.cli.jvm.compiler.loadPlugins
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
import org.jetbrains.kotlin.cli.jvm.config.JvmModulePathRoot
import org.jetbrains.kotlin.cli.jvm.config.addJavaSourceRoot
import org.jetbrains.kotlin.cli.jvm.setupJvmSpecificArguments
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.config.messageCollector
import org.jetbrains.kotlin.config.moduleName
import org.jetbrains.kotlin.config.modules
import org.jetbrains.kotlin.metadata.deserialization.MetadataVersion
import org.jetbrains.kotlin.modules.JavaRootPath
import java.io.BufferedInputStream
@@ -68,7 +74,7 @@ internal suspend fun compileKotlinForJvm(
kotlinArgs.freeArgs = sources.map { it.toString() }
val messageCollector = WriterBackedMessageCollector(verbose = context.isTracing)
val config = org.jetbrains.kotlin.cli.jvm.compiler.configTemplate.copy()
val config = configTemplate.copy()
config.put(CLIConfigurationKeys.ORIGINAL_MESSAGE_COLLECTOR_KEY, messageCollector)
val collector = GroupingMessageCollector(messageCollector, kotlinArgs.allWarningsAsErrors, kotlinArgs.reportAllWarnings).also {
config.messageCollector = it
@@ -88,7 +94,7 @@ internal suspend fun compileKotlinForJvm(
loadPlugins(configuration = config, pluginConfigurations = pluginConfigurations)
val moduleName = info.moduleName
config.put(CommonConfigurationKeys.MODULE_NAME, moduleName)
config.moduleName = moduleName
val module = ModuleBuilder(moduleName, outFilePath, "java-production")
@@ -128,14 +134,21 @@ internal suspend fun compileKotlinForJvm(
config.add(CLIConfigurationKeys.CONTENT_ROOTS, JvmClasspathRoot(ioFile))
}
config.addAll(JVMConfigurationKeys.MODULES, listOf(module))
val modules = listOf(module)
config.modules = modules
config.moduleChunk = ModuleChunk(modules)
k2jvm(
config = config,
rootDisposable = rootDisposable,
module = module,
messageCollector = messageCollector,
).code
val pipeline = BazelJvmCliPipeline(BazelJvmConfigurationPipelinePhase(config))
//val groupingMessageCollector = GroupingMessageCollector(messageCollector, false, false)
//val argumentsInput = ArgumentsPipelineArtifact(
// kotlinArgs,
// Services.EMPTY,
// rootDisposable,
// groupingMessageCollector,
// pipeline.defaultPerformanceManager,
//)
pipeline.execute(kotlinArgs, Services.EMPTY, messageCollector).code
}
finally {
Disposer.dispose(rootDisposable)
@@ -1,3 +1,4 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.bazel.jvm.kotlin
import kotlinx.coroutines.Dispatchers
@@ -15,7 +16,7 @@ internal object TestKotlinBuildWorker {
val testPaths = getTestWorkerPaths()
val baseDir = testPaths.baseDir
runBlocking(Dispatchers.Default) {
val testModule = TestModules.PLATFORM_BOOTSTRAP
val testModule = TestModules.XML_DOM
val sources = collectSources(sourceDirPath = testModule.sourcePath, paths = testPaths)
val testParams = testModule.getParams(baseDir)
@@ -1,10 +1,9 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
@file:Suppress("PackageDirectoryMismatch")
package org.jetbrains.kotlin.cli.jvm.compiler
import org.jetbrains.bazel.jvm.kotlin.createJar
import org.jetbrains.intellij.build.io.ZipIndexWriter
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.modules.ModuleChunk
@@ -1,40 +1,44 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.cli.jvm.compiler
import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.backend.jvm.jvmLoweringPhases
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.backend.common.phaser.then
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.createPhaseConfig
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.modules.ModuleBuilder
import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.compileModulesUsingFrontendIrAndLightTree
import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.createProjectEnvironment
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.K2JVMCompilerPerformanceManager
import org.jetbrains.kotlin.cli.jvm.config.configureJdkClasspathRoots
import org.jetbrains.kotlin.cli.jvm.configureAdvancedJvmOptions
import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser.RegisteredPluginInfo
import org.jetbrains.kotlin.cli.pipeline.AbstractCliPipeline
import org.jetbrains.kotlin.cli.pipeline.AbstractConfigurationPhase
import org.jetbrains.kotlin.cli.pipeline.ArgumentsPipelineArtifact
import org.jetbrains.kotlin.cli.pipeline.CheckCompilationErrors
import org.jetbrains.kotlin.cli.pipeline.ConfigurationPipelineArtifact
import org.jetbrains.kotlin.cli.pipeline.PipelineContext
import org.jetbrains.kotlin.cli.pipeline.jvm.JvmBackendPipelinePhase
import org.jetbrains.kotlin.cli.pipeline.jvm.JvmBinaryPipelineArtifact
import org.jetbrains.kotlin.cli.pipeline.jvm.JvmFir2IrPipelinePhase
import org.jetbrains.kotlin.cli.pipeline.jvm.JvmFrontendPipelinePhase
import org.jetbrains.kotlin.cli.plugins.processCompilerPluginOptions
import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi
import org.jetbrains.kotlin.compiler.plugin.PluginProcessingException
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.messageCollector
import org.jetbrains.kotlin.config.phaseConfig
import org.jetbrains.kotlin.config.phaser.CompilerPhase
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.metadata.deserialization.MetadataVersion
import org.jetbrains.kotlin.util.ServiceLoaderLite
import java.io.File
import java.net.URLClassLoader
private fun createCompilerConfigurationTemplate(): CompilerConfiguration {
val config = CompilerConfiguration()
config.put(CLIConfigurationKeys.FLEXIBLE_PHASE_CONFIG, createPhaseConfig(
compoundPhase = jvmLoweringPhases,
arguments = CommonCompilerArguments.DummyImpl(),
messageCollector = MessageCollector.NONE,
))
config.phaseConfig = createPhaseConfig(arguments = CommonCompilerArguments.DummyImpl())
config.put(JVMConfigurationKeys.JDK_HOME, File(System.getProperty("java.home") ?: error("No java.home system property")))
config.put(JVMConfigurationKeys.DISABLE_STANDARD_SCRIPT_DEFINITION, true)
@@ -50,56 +54,84 @@ private fun createCompilerConfigurationTemplate(): CompilerConfiguration {
internal val configTemplate = createCompilerConfigurationTemplate()
internal fun k2jvm(
config: CompilerConfiguration,
rootDisposable: Disposable,
module: ModuleBuilder,
messageCollector: MessageCollector,
): ExitCode {
val moduleBuilders = listOf(module)
internal class BazelJvmCliPipeline(
private val configPhase: BazelJvmConfigurationPipelinePhase,
) : AbstractCliPipeline<K2JVMCompilerArguments>() {
override val defaultPerformanceManager: K2JVMCompilerPerformanceManager = K2JVMCompilerPerformanceManager()
val modularJdkRoot = module.modularJdkRoot
if (modularJdkRoot != null) {
// We use the SDK of the first module in the chunk, which is not always correct because some other module in the chunk
// might depend on a different SDK
config.put(JVMConfigurationKeys.JDK_HOME, File(modularJdkRoot))
override fun createCompoundPhase(arguments: K2JVMCompilerArguments): CompilerPhase<PipelineContext, ArgumentsPipelineArtifact<K2JVMCompilerArguments>, *> {
return createRegularPipeline()
}
require(config.getBoolean(CommonConfigurationKeys.USE_LIGHT_TREE))
require(config.getBoolean(CommonConfigurationKeys.USE_FIR))
if (messageCollector.hasErrors()) {
return ExitCode.COMPILATION_ERROR
private fun createRegularPipeline(): CompilerPhase<PipelineContext, ArgumentsPipelineArtifact<K2JVMCompilerArguments>, JvmBinaryPipelineArtifact> {
// instead of JvmConfigurationPipelinePhase, we use our own BazelJvmConfigurationPipelinePhase
return configPhase then
JvmFrontendPipelinePhase then
JvmFir2IrPipelinePhase then
JvmBackendPipelinePhase
}
val projectEnvironment = createProjectEnvironment(
configuration = config,
parentDisposable = rootDisposable,
configFiles = EnvironmentConfigFiles.JVM_CONFIG_FILES,
messageCollector = messageCollector,
)
if (messageCollector.hasErrors()) {
return ExitCode.COMPILATION_ERROR
}
if (!FirKotlinToJvmBytecodeCompiler.checkNotSupportedPlugins(config, messageCollector)) {
return ExitCode.COMPILATION_ERROR
}
if (compileModulesUsingFrontendIrAndLightTree(
projectEnvironment = projectEnvironment,
compilerConfiguration = config,
messageCollector = messageCollector,
buildFile = null,
chunk = moduleBuilders,
targetDescription = module.getModuleName() + "-" + module.getModuleType(),
checkSourceFiles = false,
isPrintingVersion = false,
)) {
return ExitCode.OK
}
return ExitCode.COMPILATION_ERROR
}
internal class BazelJvmConfigurationPipelinePhase(
private val config: CompilerConfiguration,
) : AbstractConfigurationPhase<K2JVMCompilerArguments>(
name = "JvmConfigurationPipelinePhase",
postActions = setOf(CheckCompilationErrors.CheckMessageCollector),
configurationUpdaters = emptyList()
) {
override fun executePhase(input: ArgumentsPipelineArtifact<K2JVMCompilerArguments>): ConfigurationPipelineArtifact? {
return ConfigurationPipelineArtifact(config, input.diagnosticCollector, input.rootDisposable)
}
override fun createMetadataVersion(versionArray: IntArray): BinaryVersion = MetadataVersion(*versionArray)
}
//internal fun k2jvm(
// config: CompilerConfiguration,
// rootDisposable: Disposable,
// module: ModuleBuilder,
// messageCollector: MessageCollector,
//): ExitCode {
// val moduleBuilders = listOf(module)
//
// val modularJdkRoot = module.modularJdkRoot
// if (modularJdkRoot != null) {
// // We use the SDK of the first module in the chunk, which is not always correct because some other module in the chunk
// // might depend on a different SDK
// config.put(JVMConfigurationKeys.JDK_HOME, File(modularJdkRoot))
// }
//
// require(config.getBoolean(CommonConfigurationKeys.USE_LIGHT_TREE))
// require(config.getBoolean(CommonConfigurationKeys.USE_FIR))
// if (messageCollector.hasErrors()) {
// return ExitCode.COMPILATION_ERROR
// }
//
// val projectEnvironment = createCoreEnvironment(
// configuration = config,
// rootDisposable = rootDisposable,
// configFiles = EnvironmentConfigFiles.JVM_CONFIG_FILES,
// messageCollector = messageCollector,
// )
// if (messageCollector.hasErrors()) {
// return ExitCode.COMPILATION_ERROR
// }
//
// if (compileModulesUsingFrontendIrAndLightTree(
// projectEnvironment = projectEnvironment,
// compilerConfiguration = config,
// messageCollector = messageCollector,
// buildFile = null,
// chunk = moduleBuilders,
// targetDescription = module.getModuleName() + "-" + module.getModuleType(),
// checkSourceFiles = false,
// isPrintingVersion = false,
// )) {
// return ExitCode.OK
// }
// return ExitCode.COMPILATION_ERROR
//}
@OptIn(ExperimentalCompilerApi::class)
internal fun loadPlugins(
configuration: CompilerConfiguration,
@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.cli.jvm.compiler
import org.jetbrains.bazel.jvm.kotlin.TraceHelper
@@ -46,6 +46,10 @@ private class WorkerKotlinLogger(private val out: Writer, override val isDebugEn
}
}
override fun warn(msg: String, throwable: Throwable?) {
out.append("WARN: ").appendLine(msg + " " + throwable?.stackTraceToString())
}
override fun warn(msg: String) {
out.append("WARN: ").appendLine(msg)
}
@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.jvm.abi
@@ -199,8 +199,8 @@ internal class JvmAbiOutputExtension(
av.visitEnd()
}
innerClassesToKeep.addInnerClasses(innerClassInfos, internalName)
innerClassesToKeep.addOuterClasses(innerClassInfos)
addInnerClasses(innerClassesToKeep, innerClassInfos, internalName)
addOuterClasses(innerClassesToKeep, innerClassInfos)
for (name in innerClassesToKeep.sorted()) {
innerClassInfos[name]?.let { cv.visitInnerClass(it.name, it.outerName, it.innerName, it.access) }
}
@@ -219,12 +219,12 @@ internal class JvmAbiOutputExtension(
// Outer class infos for a class and all classes transitively nested in it (that are public ABI)
// should be kept in its own class file even if the classes are otherwise unused.
private fun MutableSet<String>.addInnerClasses(innerClassInfos: Map<String, InnerClassInfo>, internalName: String) {
private fun addInnerClasses(names: MutableSet<String>, innerClassInfos: Map<String, InnerClassInfo>, internalName: String) {
val innerClassesByOuterName = innerClassInfos.values.groupBy { it.outerName }
val stack = mutableListOf(internalName)
while (stack.isNotEmpty()) {
val next = stack.removeLast()
add(next)
names.add(next)
// Classes form a tree by nesting, so none of the children have been visited yet.
innerClassesByOuterName[next]?.mapNotNullTo(stack) { info ->
info.name.takeUnless { abiClassInfos[it] == AbiClassInfo.Deleted }
@@ -233,11 +233,11 @@ internal class JvmAbiOutputExtension(
}
// For every class A.B, if its outer class info is kept then so should be A's.
private fun MutableSet<String>.addOuterClasses(innerClassInfos: Map<String, InnerClassInfo>) {
for (name in toList()) {
private fun addOuterClasses(names: MutableSet<String>, innerClassInfos: Map<String, InnerClassInfo>) {
for (name in names.toTypedArray()) {
var info = innerClassInfos[name]
while (info != null) {
info = info.outerName?.takeIf(::add)?.let(innerClassInfos::get)
info = info.outerName?.takeIf { names.add(it) }?.let(innerClassInfos::get)
}
}
}
@@ -1,10 +1,11 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package io.bazel.kotlin.plugin.jdeps
import com.google.devtools.build.lib.view.proto.Deps
import org.jetbrains.bazel.jvm.kotlin.JarOwner
import org.jetbrains.bazel.jvm.kotlin.JarOwner.Companion.INJECTING_RULE_KIND
import org.jetbrains.bazel.jvm.kotlin.JarOwner.Companion.TARGET_LABEL
import org.jetbrains.intellij.build.io.writeFileUsingTempFile
import org.jetbrains.kotlin.codegen.ClassFileFactory
import org.jetbrains.kotlin.codegen.extensions.ClassFileFactoryFinalizerExtension
import org.jetbrains.kotlin.config.CompilerConfiguration
@@ -105,8 +106,11 @@ private fun doWriteJdeps(
deps.sortBy { it.path }
rootBuilder.addAllDependency(deps)
// build and write out deps.proto
val jdepsOutput = configuration.getNotNull(JdepsGenConfigurationKeys.OUTPUT_JDEPS)
Files.write(Path.of(jdepsOutput), rootBuilder.build().toByteArray())
val jdepsOutput = Path.of(configuration.getNotNull(JdepsGenConfigurationKeys.OUTPUT_JDEPS))
val data = rootBuilder.build().toByteArray()
writeFileUsingTempFile(jdepsOutput) {
Files.write(it, data)
}
}
private fun doStrictDeps(
+3 -3
View File
@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.bazel.jvm
import io.opentelemetry.api.trace.Tracer
@@ -11,10 +11,10 @@ import java.io.Writer
import java.nio.channels.FileChannel
import java.nio.file.Path
object JvmWorker : WorkRequestExecutor {
object JvmWorker : WorkRequestExecutor<WorkRequest> {
@JvmStatic
fun main(startupArgs: Array<String>) {
processRequests(startupArgs = startupArgs, executor = this, serviceName = "jvm-worker")
processRequests(startupArgs = startupArgs, executor = this, reader = WorkRequestReaderWithoutDigest(System.`in`), serviceName = "jvm-worker")
}
override suspend fun execute(request: WorkRequest, writer: Writer, baseDir: Path, tracingContext: Context, tracer: Tracer): Int {
@@ -17,6 +17,7 @@ kt_jvm_library(
"//:opentelemetry-exporter-logging-otlp",
"//:kotlinx-coroutines-core",
"//:protobuf-java",
"@lib//:netty-buffer",
"@lib//:jetbrains-annotations",
],
runtime_deps = [
@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
@file:Suppress("ReplaceGetOrSet")
package org.jetbrains.bazel.jvm
@@ -32,8 +32,8 @@ import kotlin.coroutines.cancellation.CancellationException
import kotlin.coroutines.coroutineContext
import kotlin.system.exitProcess
fun interface WorkRequestExecutor {
suspend fun execute(request: WorkRequest, writer: Writer, baseDir: Path, tracingContext: Context, tracer: Tracer): Int
fun interface WorkRequestExecutor<T : WorkRequest> {
suspend fun execute(request: T, writer: Writer, baseDir: Path, tracingContext: Context, tracer: Tracer): Int
}
fun configureOpenTelemetry(out: OutputStream, serviceName: String): OpenTelemetrySdk {
@@ -51,10 +51,9 @@ fun configureOpenTelemetry(out: OutputStream, serviceName: String): OpenTelemetr
val tracerProvider = SdkTracerProvider.builder()
.setResource(resource)
.setSampler(Sampler.alwaysOn())
.addSpanProcessor(batchSpanProcessor) // For batch exporting (preferred in production)
.addSpanProcessor(batchSpanProcessor)
.build()
// Build and set the OpenTelemetry SDK
val openTelemetrySdk = OpenTelemetrySdk.builder()
.setTracerProvider(tracerProvider)
.build()
@@ -63,10 +62,11 @@ fun configureOpenTelemetry(out: OutputStream, serviceName: String): OpenTelemetr
private val noopTracer = OpenTelemetry.noop().getTracer("noop")
fun processRequests(
fun <T : WorkRequest> processRequests(
startupArgs: Array<String>,
executor: WorkRequestExecutor,
executor: WorkRequestExecutor<T>,
serviceName: String?,
reader: WorkRequestReader<T>,
setup: (Tracer, CoroutineScope) -> Unit = { _, _ -> },
) {
if (!startupArgs.contains("--persistent_worker")) {
@@ -84,8 +84,8 @@ fun processRequests(
runBlocking(Dispatchers.Default) {
tracer.spanBuilder("process requests").use { span ->
setup(tracer, this@runBlocking)
WorkRequestHandler(requestExecutor = executor, input = System.`in`, out = System.out, tracer = tracer)
.processRequests(Context.current().with(span))
WorkRequestHandler(requestExecutor = executor, out = System.out, tracer = tracer)
.processRequests(reader, Context.current().with(span))
}
exitProcess(0)
@@ -97,8 +97,8 @@ fun processRequests(
}
}
private class RequestState(@JvmField val request: WorkRequest) {
@JvmField val state = AtomicReference<WorkRequestState>(NOT_STARTED)
private class RequestState<T : WorkRequest>(@JvmField val request: T) {
@JvmField val state = AtomicReference(NOT_STARTED)
}
@VisibleForTesting
@@ -110,13 +110,12 @@ internal enum class WorkRequestState {
* A helper class that handles [WorkRequests](https://bazel.build/docs/persistent-workers), including
* [multiplex workers](https://bazel.build/docs/multiplex-worker).
*/
internal class WorkRequestHandler internal constructor(
internal class WorkRequestHandler<T : WorkRequest> internal constructor(
/**
* The function to be called after each [WorkRequest] is read.
*/
private val requestExecutor: WorkRequestExecutor,
private val requestExecutor: WorkRequestExecutor<T>,
private val input: InputStream,
private val out: OutputStream,
/**
@@ -130,11 +129,11 @@ internal class WorkRequestHandler internal constructor(
/**
* Requests that are currently being processed.
*/
private val activeRequests = ConcurrentHashMap<Int, RequestState>()
private val activeRequests = ConcurrentHashMap<Int, RequestState<T>>()
@OptIn(DelicateCoroutinesApi::class)
internal suspend fun processRequests(tracingContext: Context) {
val requestChannel = Channel<RequestState>(Channel.UNLIMITED)
internal suspend fun processRequests(reader: WorkRequestReader<T>, tracingContext: Context) {
val requestChannel = Channel<RequestState<T>>(Channel.UNLIMITED)
try {
coroutineScope {
tracer.spanBuilder("process requests").setParent(tracingContext).use { span ->
@@ -142,7 +141,7 @@ internal class WorkRequestHandler internal constructor(
}
tracer.spanBuilder("read requests").setParent(tracingContext).use { span ->
readRequests(requestChannel, span)
readRequests(requestChannel, reader, span)
}
}
}
@@ -167,14 +166,11 @@ internal class WorkRequestHandler internal constructor(
}
}
private suspend fun readRequests(requestChannel: Channel<RequestState>, span: Span) {
val inputPathsToReuse = ArrayList<String>()
val inputDigestsToReuse = ArrayList<ByteArray>()
val argListToReuse = ArrayList<String>()
private suspend fun readRequests(requestChannel: Channel<RequestState<T>>, reader: WorkRequestReader<T>, span: Span) {
while (coroutineContext.isActive) {
val request = try {
runInterruptible(Dispatchers.IO) {
readWorkRequestFromStream(input, inputPathsToReuse, inputDigestsToReuse, argListToReuse)
reader.readWorkRequestFromStream()
}
}
catch (e: InterruptedIOException) {
@@ -227,7 +223,7 @@ internal class WorkRequestHandler internal constructor(
}
}
private fun CoroutineScope.startTaskProcessing(requestChannel: Channel<RequestState>, tracingContext: Context) {
private fun CoroutineScope.startTaskProcessing(requestChannel: Channel<RequestState<T>>, tracingContext: Context) {
repeat(Runtime.getRuntime().availableProcessors().coerceAtLeast(2)) {
launch {
for (item in requestChannel) {
@@ -241,7 +237,7 @@ internal class WorkRequestHandler internal constructor(
AttributeKey.stringArrayKey("arguments"), request.arguments.toList(),
//AttributeKey.stringArrayKey("inputs"), request.inputs.map { it.path },
AttributeKey.longKey("id"), request.requestId.toLong(),
AttributeKey.stringKey("sandboxDir"), request.sandboxDir?.toString() ?: "",
AttributeKey.stringKey("sandboxDir"), request.sandboxDir ?: "",
))
.setParent(tracingContext)
.startSpan()
@@ -317,7 +313,7 @@ internal class WorkRequestHandler internal constructor(
}
}
private suspend fun cancelRequestOnShutdown(item: RequestState, span: Span) {
private suspend fun cancelRequestOnShutdown(item: RequestState<T>, span: Span) {
val stateRef = item.state
val requestId = item.request.requestId
if (stateRef.compareAndSet(NOT_STARTED, FINISHED) || stateRef.compareAndSet(STARTED, FINISHED)) {
@@ -336,7 +332,7 @@ internal class WorkRequestHandler internal constructor(
}
internal suspend fun handleRequest(
request: WorkRequest,
request: T,
requestState: AtomicReference<WorkRequestState>,
tracingContext: Context?,
parentSpan: Span?,
@@ -40,9 +40,9 @@ class WorkRequestHandlerTest {
@Timeout(value = 10, unit = TimeUnit.SECONDS)
fun normalWorkRequest() {
val out = ByteArrayOutputStream()
val handler = WorkRequestHandler(
val handler = WorkRequestHandler<WorkRequest>(
requestExecutor = { args, err, _, _, _ -> 1 },
input = ByteArrayInputStream(ByteArray(0)),
//input = ByteArrayInputStream(ByteArray(0)),
out = out,
tracer = OpenTelemetry.noop().getTracer("noop"),
)
@@ -50,7 +50,6 @@ class WorkRequestHandlerTest {
val request = WorkRequest(
arguments = arrayOf("--sources", "A.java"),
inputPaths = emptyArray(),
inputDigests = emptyArray(),
requestId = 0,
cancel = false,
verbosity = 0,
@@ -70,9 +69,9 @@ class WorkRequestHandlerTest {
@Timeout(value = 10, unit = TimeUnit.SECONDS)
fun multiplexWorkRequest() {
val out = ByteArrayOutputStream()
val handler = WorkRequestHandler(
val handler = WorkRequestHandler<WorkRequest>(
requestExecutor = { args, err, _, _, _ -> 0 },
input = ByteArray(0).inputStream(),
//input = ByteArray(0).inputStream(),
out,
tracer = OpenTelemetry.noop().getTracer("noop"),
)
@@ -96,7 +95,7 @@ class WorkRequestHandlerTest {
// work request threads release this when they have started
val started = Semaphore(0)
val workerThreads = AtomicInteger()
val handler = WorkRequestHandler(
val handler = WorkRequestHandler<WorkRequest>(
requestExecutor = { args, err, _, _, _ ->
// each call to this, runs in its own thread
workerThreads.incrementAndGet()
@@ -112,12 +111,11 @@ class WorkRequestHandlerTest {
}
0
},
input = PipedInputStream(src),
out = OutputStream.nullOutputStream(),
tracer = OpenTelemetry.noop().getTracer("noop"),
)
useHandler(handler = handler, waitForProcessing = true, errorFilter = { it.message != "Intentional death!" }) {
useHandler(handler = handler, input = PipedInputStream(src), waitForProcessing = true, errorFilter = { it.message != "Intentional death!" }) {
val args = listOf("--sources", "A.java")
WorkerProtocol.WorkRequest.newBuilder().addAllArguments(args).setRequestId(42).build().writeDelimitedTo(src)
WorkerProtocol.WorkRequest.newBuilder().addAllArguments(args).setRequestId(43).build().writeDelimitedTo(src)
@@ -131,12 +129,12 @@ class WorkRequestHandlerTest {
@Timeout(value = 10, unit = TimeUnit.SECONDS)
fun testOutput() {
val out = ByteArrayOutputStream()
val handler = WorkRequestHandler(
val handler = WorkRequestHandler<WorkRequest>(
requestExecutor = { args, err, _, _, _ ->
err.appendLine("Failed!")
1
},
input = ByteArray(0).inputStream(),
//input = ByteArray(0).inputStream(),
out,
tracer = OpenTelemetry.noop().getTracer("noop"),
)
@@ -157,11 +155,11 @@ class WorkRequestHandlerTest {
@Timeout(value = 10, unit = TimeUnit.SECONDS)
fun testException() {
val out = ByteArrayOutputStream()
val handler = WorkRequestHandler(
val handler = WorkRequestHandler<WorkRequest>(
requestExecutor = { args, err, _, _, _ ->
throw RuntimeException("Exploded!")
},
input = ByteArray(0).inputStream(),
//input = ByteArray(0).inputStream(),
out,
tracer = OpenTelemetry.noop().getTracer("noop"),
)
@@ -186,13 +184,13 @@ class WorkRequestHandlerTest {
val src = PipedOutputStream()
val dest = PipedInputStream()
val handler = WorkRequestHandler(
val input = PipedInputStream(src)
val handler = WorkRequestHandler<WorkRequest>(
requestExecutor = { args, err, _, _, _ ->
handlerCalled = true
err.appendLine("Such work! Much progress! Wow!")
1
},
input = PipedInputStream(src),
out = PipedOutputStream(dest),
tracer = OpenTelemetry.noop().getTracer("noop"),
cancelHandler = {
@@ -200,7 +198,7 @@ class WorkRequestHandlerTest {
},
)
useHandler(handler) {
useHandler(handler, input) {
WorkerProtocol.WorkRequest.newBuilder().setRequestId(42).build().writeDelimitedTo(src)
WorkerProtocol.WorkRequest.newBuilder().setRequestId(42).setCancel(true).build().writeDelimitedTo(src)
@@ -235,7 +233,7 @@ class WorkRequestHandlerTest {
val failures = ConcurrentLinkedQueue<String>()
// we force the regular handling to not finish until after we have read the cancel response, to avoid flakiness
val handler = WorkRequestHandler(
val handler = WorkRequestHandler<WorkRequest>(
requestExecutor = { args, err, _, _, _ ->
// this handler waits until the main thread has sent a cancel request
handlerCalled.release()
@@ -248,14 +246,13 @@ class WorkRequestHandlerTest {
}
0
},
input = PipedInputStream(src),
out = PipedOutputStream(dest),
tracer = OpenTelemetry.noop().getTracer("noop"),
cancelHandler = { i -> cancelCalled.incrementAndGet() }
)
// this thread just makes sure the WorkRequestHandler does work asynchronously
useHandler(handler, failures, waitForProcessing = true) {
useHandler(handler, PipedInputStream(src), failures, waitForProcessing = true) {
WorkerProtocol.WorkRequest.newBuilder().setRequestId(42).build().writeDelimitedTo(src)
// make sure the handler is called before sending the cancel request, or we might process the cancellation entirely before that
handlerCalled.acquire()
@@ -285,7 +282,7 @@ class WorkRequestHandlerTest {
// we force the regular handling to not finish until after we have read the cancel response, to avoid flakiness
val inputStream = PipedInputStream(src)
val handler = WorkRequestHandler(
val handler = WorkRequestHandler<WorkRequest>(
requestExecutor = { args, err, _, _, _ ->
try {
waitForCancel.acquire()
@@ -296,7 +293,6 @@ class WorkRequestHandlerTest {
}
0
},
input = inputStream,
out = PipedOutputStream(dest),
tracer = OpenTelemetry.noop().getTracer("noop"),
cancelHandler = {
@@ -304,7 +300,7 @@ class WorkRequestHandlerTest {
},
)
useHandler(handler, failures, waitForProcessing = true) {
useHandler(handler, inputStream, failures, waitForProcessing = true) {
WorkerProtocol.WorkRequest.newBuilder().setRequestId(42).build().writeDelimitedTo(src)
WorkerProtocol.WorkRequest.newBuilder().setRequestId(42).setCancel(true).build().writeDelimitedTo(src)
WorkerProtocol.WorkRequest.newBuilder().setRequestId(42).setCancel(true).build().writeDelimitedTo(src)
@@ -332,19 +328,18 @@ class WorkRequestHandlerTest {
val dest = PipedInputStream()
// we force the cancel request to not happen until after we have read the normal response, to avoid flakiness
val handler = WorkRequestHandler(
val handler = WorkRequestHandler<WorkRequest>(
requestExecutor = { args, err, _, _, _ ->
handlerCalled.release()
err.appendLine("Such work! Much progress! Wow!")
2
},
input = PipedInputStream(src),
out = PipedOutputStream(dest),
tracer = OpenTelemetry.noop().getTracer("noop"),
)
var r: WorkResponse? = null
useHandler(handler, waitForProcessing = true) {
useHandler(handler, PipedInputStream(src), waitForProcessing = true) {
WorkerProtocol.WorkRequest.newBuilder().setRequestId(42).build().writeDelimitedTo(src)
r = WorkResponse.parseDelimitedFrom(dest)
WorkerProtocol.WorkRequest.newBuilder().setRequestId(42).setCancel(true).build().writeDelimitedTo(src)
@@ -367,9 +362,9 @@ class WorkRequestHandlerTest {
@Timeout(value = 10, unit = TimeUnit.SECONDS)
fun workRequestHandlerWithWorkRequestCallback() {
val out = ByteArrayOutputStream()
val handler = WorkRequestHandler(
val handler = WorkRequestHandler<WorkRequest>(
requestExecutor = { request, err, _, _, _ -> request.arguments.size },
ByteArrayInputStream(ByteArray(0)),
//ByteArrayInputStream(ByteArray(0)),
out,
tracer = OpenTelemetry.noop().getTracer("noop"),
)
@@ -392,7 +387,7 @@ private fun newWorkRequest(args: List<String>, requestId: Int = 42): WorkRequest
arguments = args.toTypedArray(),
requestId = requestId,
inputPaths = emptyArray(),
inputDigests = emptyArray(),
//inputDigests = emptyArray(),
cancel = false,
verbosity = 0,
sandboxDir = null
@@ -401,7 +396,8 @@ private fun newWorkRequest(args: List<String>, requestId: Int = 42): WorkRequest
@OptIn(DelicateCoroutinesApi::class, ExperimentalCoroutinesApi::class)
private inline fun useHandler(
handler: WorkRequestHandler,
handler: WorkRequestHandler<WorkRequest>,
input: InputStream,
failures: ConcurrentLinkedQueue<String> = ConcurrentLinkedQueue<String>(),
waitForProcessing: Boolean = false,
crossinline errorFilter: (Throwable) -> Boolean = { true },
@@ -409,7 +405,7 @@ private inline fun useHandler(
) {
val processor = GlobalScope.async(Dispatchers.Default) {
try {
handler.processRequests(Context.current())
handler.processRequests(WorkRequestReaderWithoutDigest(input), Context.current())
}
catch (_: CancellationException) {
}
+109 -89
View File
@@ -1,27 +1,54 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.bazel.jvm
import com.google.protobuf.CodedInputStream
import jdk.internal.util.xml.impl.Input
import java.io.FilterInputStream
import io.netty.buffer.PooledByteBufAllocator
import java.io.InputStream
import kotlin.math.min
class WorkRequest(
open class WorkRequest(
@JvmField val arguments: Array<String>,
@JvmField val inputPaths: Array<String>,
@JvmField val inputDigests: Array<ByteArray>,
@JvmField val requestId: Int,
@JvmField val cancel: Boolean,
@JvmField val verbosity: Int,
@JvmField val sandboxDir: String?
)
internal fun readWorkRequestFromStream(
interface WorkRequestReader<T : WorkRequest> {
fun readWorkRequestFromStream(): T?
}
class WorkRequestReaderWithoutDigest(private val input: InputStream) : WorkRequestReader<WorkRequest> {
private val inputPathsToReuse = ArrayList<String>()
private val argListToReuse = ArrayList<String>()
override fun readWorkRequestFromStream(): WorkRequest? {
return doReadWorkRequestFromStream(
input = input,
inputPathsToReuse = inputPathsToReuse,
argListToReuse = argListToReuse,
readDigest = { codedInputStream, tag -> codedInputStream.skipField(tag) },
requestCreator = { argListToReuse, inputPathsToReuse, requestId, cancel, verbosity, sandboxDir ->
WorkRequest(
arguments = argListToReuse,
inputPaths = inputPathsToReuse,
requestId = requestId,
cancel = cancel,
verbosity = verbosity,
sandboxDir = sandboxDir
)
},
)
}
}
inline fun <T : WorkRequest> doReadWorkRequestFromStream(
input: InputStream,
inputPathsToReuse: MutableList<String>,
inputDigestsToReuse: MutableList<ByteArray>,
argListToReuse: MutableList<String>
): WorkRequest? {
argListToReuse: MutableList<String>,
readDigest: (CodedInputStream, Int) -> Unit,
requestCreator: RequestCreator<T>,
): T? {
// read the length-prefixed WorkRequest
val firstByte = input.read()
if (firstByte == -1) {
@@ -29,16 +56,69 @@ internal fun readWorkRequestFromStream(
}
val size = CodedInputStream.readRawVarint32(firstByte, input)
val buffer = PooledByteBufAllocator.DEFAULT.heapBuffer(size, size)
try {
var toRead = size
while (toRead > 0) {
val n = buffer.writeBytes(input, toRead)
if (n < 0) {
throw IllegalStateException("Unexpected EOF")
}
toRead -= n
}
assert(buffer.readableBytes() == size)
var requestId = 0
var cancel = false
var verbosity = 0
var sandboxDir: String? = null
var requestId = 0
var cancel = false
var verbosity = 0
var sandboxDir: String? = null
val codedInputStream = CodedInputStream.newInstance(LimitedInputStream(input, size))
argListToReuse.clear()
inputPathsToReuse.clear()
inputDigestsToReuse.clear()
val codedInputStream = CodedInputStream.newInstance(buffer.array(), buffer.arrayOffset() + buffer.readerIndex(), buffer.readableBytes())
argListToReuse.clear()
inputPathsToReuse.clear()
while (true) {
val tag = codedInputStream.readTag()
if (tag == 0) {
break
}
when (tag.shr(3)) {
1 -> argListToReuse.add(codedInputStream.readString())
2 -> {
val messageSize = codedInputStream.readRawVarint32()
val limit = codedInputStream.pushLimit(messageSize)
readInput(codedInputStream, inputPathsToReuse, readDigest)
codedInputStream.popLimit(limit)
}
3 -> requestId = codedInputStream.readInt32()
4 -> cancel = codedInputStream.readBool()
5 -> verbosity = codedInputStream.readInt32()
6 -> sandboxDir = codedInputStream.readString()
else -> codedInputStream.skipField(tag)
}
}
return requestCreator(
(argListToReuse as java.util.ArrayList).toArray(emptyStringArray),
(inputPathsToReuse as java.util.ArrayList).toArray(emptyStringArray),
requestId,
cancel,
verbosity,
sandboxDir,
)
}
finally {
buffer.release()
}
}
@PublishedApi
internal inline fun readInput(
codedInputStream: CodedInputStream,
inputPathsToReuse: MutableList<String>,
readDigest: (CodedInputStream, Int) -> Unit
) {
while (true) {
val tag = codedInputStream.readTag()
if (tag == 0) {
@@ -46,81 +126,21 @@ internal fun readWorkRequestFromStream(
}
when (tag.shr(3)) {
1 -> argListToReuse.add(codedInputStream.readString())
2 -> {
var path = ""
var digest: ByteArray? = null
val messageSize = codedInputStream.readRawVarint32()
val limit = codedInputStream.pushLimit(messageSize)
while (true) {
val tag = codedInputStream.readTag()
if (tag == 0) {
break
}
when (tag.shr(3)) {
1 -> path = codedInputStream.readString()
2 -> digest = codedInputStream.readByteArray()
else -> codedInputStream.skipField(tag)
}
}
codedInputStream.popLimit(limit)
inputPathsToReuse.add(path)
inputDigestsToReuse.add(digest!!)
}
3 -> requestId = codedInputStream.readInt32()
4 -> cancel = codedInputStream.readBool()
5 -> verbosity = codedInputStream.readInt32()
6 -> sandboxDir = codedInputStream.readString()
1 -> inputPathsToReuse.add(codedInputStream.readString())
2 -> readDigest(codedInputStream, tag)
else -> codedInputStream.skipField(tag)
}
}
return WorkRequest(
arguments = argListToReuse.toTypedArray(),
inputPaths = inputPathsToReuse.toTypedArray(),
inputDigests = inputDigestsToReuse.toTypedArray(),
requestId = requestId,
cancel = cancel,
verbosity = verbosity,
sandboxDir = sandboxDir
)
}
private class LimitedInputStream(input: InputStream, private var limit: Int) : FilterInputStream(input) {
override fun available(): Int = min(super.available(), limit)
@PublishedApi
internal val emptyStringArray = emptyArray<String>()
override fun read(): Int {
if (limit <= 0) {
return -1
}
val result = super.read()
if (result >= 0) {
--limit
}
return result
}
override fun read(b: ByteArray?, off: Int, len: Int): Int {
var len = len
if (limit <= 0) {
return -1
}
len = min(len, limit)
val result = super.read(b, off, len)
if (result >= 0) {
limit -= result
}
return result
}
override fun skip(n: Long): Long {
val result = super.skip(min(n, limit.toLong())).toInt()
if (result >= 0) {
limit -= result
}
return result.toLong()
}
}
typealias RequestCreator<T> = (
argListToReuse: Array<String>,
inputPathsToReuse: Array<String>,
requestId: Int,
cancel: Boolean,
verbosity: Int,
sandboxDir: String?
) -> T
@@ -14,6 +14,7 @@ import kotlin.io.path.walk
import kotlin.system.exitProcess
enum class TestModules(@JvmField val sourcePath: String, private val paramsPath: String) {
XML_DOM("platform/util/xmlDom/src", "platform/util/xmlDom/xmlDom.jar-0.params"),
PLATFORM_IMPL("platform/platform-impl/src", "platform/platform-impl/ide-impl.jar-0.params"),
LANG_IMPL("platform/lang-impl/src", "platform/lang-impl/lang-impl.jar-0.params"),
PLATFORM_BOOTSTRAP("platform/platform-impl/bootstrap/src", "platform/platform-impl/bootstrap/ide-bootstrap-kt.jar-0.params");
@@ -32,7 +33,7 @@ data class TestWorkerPaths(
fun getTestWorkerPaths(): TestWorkerPaths {
val userHomeDir = Path.of(System.getProperty("user.home"))
val ideaProjectDirName = if (Runtime.getRuntime().availableProcessors() >= 20) "idea-push" else "idea"
val ideaProjectDirName = "idea"
val projectDir = userHomeDir.resolve("projects/$ideaProjectDirName")
val communityDir = projectDir.resolve("community")
val baseDir = getBazelExecRoot(projectDir)
+2 -2
View File
@@ -3323,8 +3323,8 @@ kt_jvm_import(
kt_jvm_import(
name = "kotlin-metadata",
jar = "@kotlin-metadata-jvm-2_1_20-Beta1_http//file",
srcjar = "@kotlin-metadata-jvm-2_1_20-Beta1-sources_http//file",
jar = "@kotlin-metadata-jvm-2_1_20-Beta2_http//file",
srcjar = "@kotlin-metadata-jvm-2_1_20-Beta2-sources_http//file",
visibility = ["//visibility:public"]
)
+7 -7
View File
@@ -4585,17 +4585,17 @@ http_file(
)
http_file(
name = "kotlin-metadata-jvm-2_1_20-Beta1_http",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-metadata-jvm/2.1.20-Beta1/kotlin-metadata-jvm-2.1.20-Beta1.jar",
sha256 = "243ac56352ce7e1ca7f294a53b1a1b3040ca12b95725449f0c04bbee6d43d84c",
downloaded_file_path = "kotlin-metadata-jvm-2.1.20-Beta1.jar"
name = "kotlin-metadata-jvm-2_1_20-Beta2_http",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-metadata-jvm/2.1.20-Beta2/kotlin-metadata-jvm-2.1.20-Beta2.jar",
sha256 = "a4d99e5b88eff9972c117b577436aa587e83f78e60cf005cd614065f59ead7a9",
downloaded_file_path = "kotlin-metadata-jvm-2.1.20-Beta2.jar"
)
http_file(
name = "kotlin-metadata-jvm-2_1_20-Beta1-sources_http",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-metadata-jvm/2.1.20-Beta1/kotlin-metadata-jvm-2.1.20-Beta1-sources.jar",
name = "kotlin-metadata-jvm-2_1_20-Beta2-sources_http",
url = "https://cache-redirector.jetbrains.com/repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-metadata-jvm/2.1.20-Beta2/kotlin-metadata-jvm-2.1.20-Beta2-sources.jar",
sha256 = "3f5468b5c409702c7cac30067208b7218ab9e3f7209e686966c6c2de2134dd18",
downloaded_file_path = "kotlin-metadata-jvm-2.1.20-Beta1-sources.jar"
downloaded_file_path = "kotlin-metadata-jvm-2.1.20-Beta2-sources.jar"
)
http_file(
@@ -43,5 +43,6 @@
<orderEntry type="library" name="kaml" level="project" />
<orderEntry type="library" name="hash4j" level="project" />
<orderEntry type="module" module-name="intellij.idea.community.build.zip" />
<orderEntry type="library" scope="RUNTIME" name="okhttp" level="project" />
</component>
</module>
@@ -15,6 +15,8 @@ import org.jetbrains.kotlin.jps.model.JpsKotlinFacetModuleExtension
import java.nio.file.Files
import java.nio.file.Path
import java.util.*
import kotlin.io.path.ExperimentalPathApi
import kotlin.io.path.deleteRecursively
import kotlin.io.path.invariantSeparatorsPathString
internal class ModuleList(
@@ -517,6 +519,7 @@ private fun computeResources(module: JpsModule, contentRoots: List<Path>, bazelB
.toList()
}
@OptIn(ExperimentalPathApi::class)
private fun extraResourceTarget(
module: JpsModule,
contentRoots: List<Path>,
@@ -532,6 +535,20 @@ private fun extraResourceTarget(
return@mapNotNull null
}
val isEmptyDir = Files.newDirectoryStream(metaInf).use { stream ->
val iterator = stream.iterator()
while (iterator.hasNext()) {
if (!iterator.next().toString().startsWith('.')) {
return@use false
}
}
true
}
if (isEmptyDir) {
metaInf.deleteRecursively()
return@mapNotNull null
}
val metaInfRelative = resolveRelativeToBazelBuildFileDirectory(childDir = metaInf, contentRoots = contentRoots, bazelBuildDir = bazelBuildDir, module = module)
.invariantSeparatorsPathString