mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
jps bazel 12
GitOrigin-RevId: f88bca362f38ae3fa66a7ddc69801399f4c68019
This commit is contained in:
committed by
intellij-monorepo-bot
parent
3e470a2767
commit
79ef984541
Generated
+5
-5
@@ -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>
|
||||
@@ -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(
|
||||
|
||||
@@ -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": [
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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>
|
||||
+17
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user