diff --git a/build/jvm-rules/.gitignore b/build/jvm-rules/.gitignore index 5891abc28309..8cbab2ef802b 100644 --- a/build/jvm-rules/.gitignore +++ b/build/jvm-rules/.gitignore @@ -1,3 +1,4 @@ .idea bazel-* -.bazelbsp/ \ No newline at end of file +.bazelbsp/ +src/jps-builder/jps-build-standalone* \ No newline at end of file diff --git a/build/jvm-rules/BUILD.bazel b/build/jvm-rules/BUILD.bazel index b0c5e43496c3..5980ce6c8a82 100644 --- a/build/jvm-rules/BUILD.bazel +++ b/build/jvm-rules/BUILD.bazel @@ -35,6 +35,27 @@ jvm_import( visibility = ["//visibility:public"], ) +jvm_import( + name = "kotlin-build-tools-api", + jar = "@kotlin-build-tools-api//file", + source_jar = "@kotlin-build-tools-api-sources//file", + visibility = ["//visibility:public"], +) + +jvm_import( + name = "kotlin-util-klib", + jar = "@kotlin-util-klib//file", + source_jar = "@kotlin-util-klib-sources//file", + visibility = ["//visibility:public"], +) + +jvm_import( + name = "kotlin-util-klib-metadata", + jar = "@kotlin-util-klib-metadata//file", + source_jar = "@kotlin-util-klib-metadata-sources//file", + visibility = ["//visibility:public"], +) + jvm_import( name = "kotlin-build-tools-impl", jar = "@kotlin-build-tools-impl//file", @@ -49,7 +70,7 @@ jvm_import( visibility = ["//visibility:public"], runtime_deps = [ "@lib//:jetbrains-annotations", - ":kotlinx-coroutines-core", + ":kotlinx-coroutines-core" ], ) @@ -60,6 +81,13 @@ jvm_import( visibility = ["//visibility:public"], ) +jvm_import( + name = "kotlin-jps-plugin", + jar = "@kotlin-jps-plugin//file", + source_jar = "@kotlin-jps-plugin-sources//file", + visibility = ["//visibility:public"], +) + jvm_import( name = "kotlin-serialization-compiler-plugin", jar = "@kotlin-serialization-compiler-plugin//file", diff --git a/build/jvm-rules/BUILD.kotlinc.bazel b/build/jvm-rules/BUILD.kotlinc.bazel new file mode 100644 index 000000000000..643b297ce2bd --- /dev/null +++ b/build/jvm-rules/BUILD.kotlinc.bazel @@ -0,0 +1,5 @@ +filegroup( + name = "kotlinc_dist", + srcs = ["build.txt"], + visibility = ["//visibility:public"], +) diff --git a/build/jvm-rules/MODULE.bazel b/build/jvm-rules/MODULE.bazel index 281bdc817af9..b317f81f7db4 100644 --- a/build/jvm-rules/MODULE.bazel +++ b/build/jvm-rules/MODULE.bazel @@ -11,12 +11,21 @@ bazel_dep(name = "protobuf", version = "29.2") bazel_dep(name = "contrib_rules_jvm", version = "0.27.0") http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") +http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") local_path_override( module_name = "lib", path = "../../lib", ) +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", + build_file = "//:BUILD.kotlinc.bazel", + strip_prefix = "kotlinc", +) + # GraalVM git_override( module_name = "rules_graalvm", @@ -63,6 +72,45 @@ http_file( downloaded_file_path = "protobuf-java-4.29.2-sources.jar", ) +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", +) +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", +) + +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", +) +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", + sha256 = "4aa4da6df01507c0fe9b48ff4f3d2a5eb5edf5f894850169c90efc89330a9d8b", + downloaded_file_path = "kotlin-util-klib-2.1.20-Beta1-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", +) +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", +) + 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", @@ -102,6 +150,19 @@ http_file( downloaded_file_path = "kotlin-metadata-jvm-2.1.20-Beta1-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", +) +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", +) + 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", diff --git a/build/jvm-rules/libs.lock.json b/build/jvm-rules/libs.lock.json index e9620d2e5663..8cf29d2fcae1 100644 --- a/build/jvm-rules/libs.lock.json +++ b/build/jvm-rules/libs.lock.json @@ -7,6 +7,10 @@ "4def45d16f7b077c8f4fa31f46f940bff14ecb985408fd74ac26c7910576cf00", "e33785f02bafc11751914ff1892c0a302a6408edb0ca6076436a71150b201e55" ], + "org.jetbrains.kotlin:kotlin-build-tools-api:2.1.20-Beta1": [ + "09ddebb845f30310395d91c084f65d2133484080dfac1977502776b77345f3d7", + "236ff9971b05fdbef35fafd390f39546c6b61467d4991474111a4823d359324b" + ], "org.jetbrains.kotlin:kotlin-build-tools-impl:2.1.20-Beta1": [ "7e1e4d96ca0d29fc5890b9eadca97f64917e1d67f8385b91cc28cee9215b70b3", "8f7fe21cd6773f9b4d842cc8eb282e72004b300b6f23b6a32d27346de7336533" @@ -19,6 +23,10 @@ "a8b056165e5f0f294b52b61721bfbf776d17e6a270a33f8e6e5d8bf405ece4a4", "320128e59ff599f6016addcc6aabea8bd2715609586502430647b4820fbe9836" ], + "org.jetbrains.kotlin:kotlin-jps-plugin:2.1.20-Beta1": [ + "0f60c6f49e74ee938605890553df1ba1ce219ebd8a8ff8d93dab82a202293ae8", + "5a337df793923ff69a55e52d386e17205570686bab85a4967fb58bbb6aee340a" + ], "org.jetbrains.kotlin:kotlin-metadata-jvm:2.1.20-Beta1": [ "243ac56352ce7e1ca7f294a53b1a1b3040ca12b95725449f0c04bbee6d43d84c", "3f5468b5c409702c7cac30067208b7218ab9e3f7209e686966c6c2de2134dd18" @@ -27,6 +35,14 @@ "6c84d19e34509173b9e9f7ea7cbd96e1a1c8314b603f691a328012dd1e0b8f9e", "09037197de2c7b4a022c1bb9be4ed3d13d38dd63ca7c08465765e98501378306" ], + "org.jetbrains.kotlin:kotlin-util-klib-metadata:2.1.20-Beta1": [ + "1b59ec74876c8d13242d04aeefc22e10444ed082f38ad52fc95bc64a6896c7fd", + "7d4d0fcd74aa62a12add77e9738a29562086dd23fd095e40f8e5308e8335b5bf" + ], + "org.jetbrains.kotlin:kotlin-util-klib:2.1.20-Beta1": [ + "f48b6323092cb30f860cb5c880d6107982d82941166073871a36349dfd3f7909", + "4aa4da6df01507c0fe9b48ff4f3d2a5eb5edf5f894850169c90efc89330a9d8b" + ], "org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.9.0": [ "ad89c2892235e670f222d819cb3d81188143cb19a05b59df9889ae4269f5c70a", "01e0f26a274d8f2f2ae702b161bc0980cea817bfcaf66ca4944434ea7b601771" diff --git a/build/jvm-rules/libs.yaml b/build/jvm-rules/libs.yaml index c1ee4f12d1a3..b59401145b35 100644 --- a/build/jvm-rules/libs.yaml +++ b/build/jvm-rules/libs.yaml @@ -3,6 +3,13 @@ # protobuf - id: com.google.protobuf:protobuf-java version: 4.29.2 + # kotlin JPS plugin + - id: org.jetbrains.kotlin:kotlin-build-tools-api + version: 2.1.20-Beta1 + - id: org.jetbrains.kotlin:kotlin-util-klib + version: 2.1.20-Beta1 + - id: org.jetbrains.kotlin:kotlin-util-klib-metadata + version: 2.1.20-Beta1 # kotlin compiler - id: org.jetbrains.kotlin:kotlin-build-tools-impl version: 2.1.20-Beta1 @@ -13,6 +20,8 @@ - ":kotlinx-coroutines-core" - id: org.jetbrains.kotlin:kotlin-metadata-jvm version: 2.1.20-Beta1 + - id: org.jetbrains.kotlin:kotlin-jps-plugin + version: 2.1.20-Beta1 # kotlin compiler plugins - id: org.jetbrains.kotlin:kotlin-serialization-compiler-plugin version: 2.1.20-Beta1 diff --git a/build/jvm-rules/rules/common-attrs.bzl b/build/jvm-rules/rules/common-attrs.bzl index fd09fc8ae0c2..e33eb133e7ad 100644 --- a/build/jvm-rules/rules/common-attrs.bzl +++ b/build/jvm-rules/rules/common-attrs.bzl @@ -125,6 +125,13 @@ common_attr = add_dicts( allow_files = True, cfg = "exec", ), + "_jps_builder": attr.label( + default = "//src/jps-builder:worker-jvm", + executable = True, + allow_files = True, + cfg = "exec", + ), + "_reduced_classpath": attr.bool(default = False), "_trace": attr.label(default = "//:kt_trace"), }, ) diff --git a/build/jvm-rules/rules/impl/compile.bzl b/build/jvm-rules/rules/impl/compile.bzl index cc98542352c9..81dd8f4fee98 100644 --- a/build/jvm-rules/rules/impl/compile.bzl +++ b/build/jvm-rules/rules/impl/compile.bzl @@ -88,7 +88,7 @@ def _compute_transitive_jars(dep_infos, prune_transitive_deps): transitive_compile_time_jars = [d.transitive_compile_time_jars for d in dep_infos] return compile_jars + transitive_compile_time_jars -def _jvm_deps(ctx, toolchains, associated_targets, deps, runtime_deps = []): +def _jvm_deps(ctx, associated_targets, deps, runtime_deps): """Encapsulates jvm dependency metadata.""" if not len(associated_targets) == 0: deps_dict = {it.label: True for it in deps} @@ -195,6 +195,7 @@ def _new_plugins_from(targets): def _new_plugin_from(plugin_id_to_configuration, plugins_for_phase): classpath = {} + # data = [] options = {} for p in plugins_for_phase: @@ -272,7 +273,9 @@ def _run_merge_jdeps_action(ctx, report_unused_deps, jdeps, output, deps): empty_depset = depset() -def _run_kt_builder_action( +def _run_jvm_builder_action( + mnemonic, + executable, ctx, rule_kind, toolchains, @@ -283,12 +286,11 @@ def _run_kt_builder_action( annotation_processors, transitive_runtime_jars, plugins, + args, outputs): """Creates a KotlinBuilder action invocation.""" kotlinc_options = ctx.attr.kotlinc_opts[KotlincOptions] - args = init_builder_args(ctx, rule_kind, associates.module_name) - for f, path in outputs.items(): args.add("--" + f, path) @@ -296,11 +298,12 @@ def _run_kt_builder_action( args.add_all("--opt_in", kotlinc_options.opt_in) - args.add_all("--direct_dependencies", _java_infos_to_compile_jars(compile_deps.deps)) args.add_all("--classpath", compile_deps.compile_jars) - # if not toolchains.kt.experimental_reduce_classpath_mode == "NONE": - # args.add("--reduced_classpath_mode", "true") + if ctx.attr._reduced_classpath: + args.add("--reduced-classpath-mode", "true") + args.add_all("--direct-dependencies", _java_infos_to_compile_jars(compile_deps.deps)) + deps_artifacts = _deps_artifacts(ctx.attr.deps + associates.targets) if kotlinc_options.report_unused_deps else empty_depset if kotlinc_options.report_unused_deps: args.add_all("--deps_artifacts", deps_artifacts) @@ -321,7 +324,7 @@ def _run_kt_builder_action( progress_message = "Compile %%{label} { kt: %d, java: %d }" % (len(srcs.kt), len(srcs.java)) ctx.actions.run( - mnemonic = "KotlinCompile", + mnemonic = mnemonic, inputs = depset( srcs.all_srcs + generated_src_jars, transitive = [ @@ -362,9 +365,8 @@ def kt_jvm_produce_jar_actions(ctx, rule_kind): srcs = _partitioned_srcs(ctx.files.srcs) associates = get_associates(ctx) compile_deps = _jvm_deps( - ctx, - toolchains, - associates.targets, + ctx = ctx, + associated_targets = associates.targets, deps = ctx.attr.deps, runtime_deps = ctx.attr.runtime_deps, ) @@ -376,19 +378,35 @@ def kt_jvm_produce_jar_actions(ctx, rule_kind): # merge outputs into final runtime jar output_jar = ctx.actions.declare_file(ctx.label.name + ".jar") - outputs_struct = _run_kt_java_builder_actions( - ctx = ctx, - output_jar = output_jar, - rule_kind = rule_kind, - toolchains = toolchains, - srcs = srcs, - generated_ksp_src_jars = [], - associates = associates, - compile_deps = compile_deps, - annotation_processors = [], - transitive_runtime_jars = transitive_runtime_jars, - plugins = plugins, - ) + outputs_struct = None + kotlinc_options = ctx.attr.kotlinc_opts[KotlincOptions] + if kotlinc_options.jps_threshold != -1 and len(srcs.kt) >= kotlinc_options.jps_threshold: + outputs_struct = _run_jps_builder( + ctx = ctx, + output_jar = output_jar, + rule_kind = rule_kind, + toolchains = toolchains, + srcs = srcs, + generated_ksp_src_jars = [], + associates = associates, + compile_deps = compile_deps, + transitive_runtime_jars = transitive_runtime_jars, + plugins = plugins, + ) + else: + outputs_struct = _run_kt_java_builder_actions( + ctx = ctx, + output_jar = output_jar, + rule_kind = rule_kind, + toolchains = toolchains, + srcs = srcs, + generated_ksp_src_jars = [], + associates = associates, + compile_deps = compile_deps, + annotation_processors = [], + transitive_runtime_jars = transitive_runtime_jars, + plugins = plugins, + ) compile_jar = outputs_struct.compile_jar generated_src_jars = outputs_struct.generated_src_jars @@ -537,7 +555,7 @@ def _run_kt_java_builder_actions( kt_output_jar = None has_java_sources = srcs.java or srcs.src_jars or generated_ksp_src_jars - jvm_emit_jdeps = kotlinc_options.jvm_emit_jdeps + emit_jdeps = kotlinc_options.emit_jdeps # build Kotlin if has_kt_sources: @@ -555,11 +573,14 @@ def _run_kt_java_builder_actions( } kt_jdeps = None - if jvm_emit_jdeps: + if emit_jdeps: kt_jdeps = ctx.actions.declare_file(ctx.label.name + "-kt.jdeps") outputs["kotlin_output_jdeps"] = kt_jdeps - _run_kt_builder_action( + _run_jvm_builder_action( + mnemonic = "KotlinCompile", + executable = ctx.attr._kotlin_builder.files_to_run.executable, + args = init_builder_args(ctx, rule_kind, associates.module_name), ctx = ctx, rule_kind = rule_kind, toolchains = toolchains, @@ -653,7 +674,93 @@ def _run_kt_java_builder_actions( compile_jar = compile_jar, generated_src_jars = generated_ksp_src_jars, annotation_processing = annotation_processing, - output_jdeps = _get_or_create_single_jdeps_output(kotlinc_options.report_unused_deps, java_infos, ctx, compile_deps) if jvm_emit_jdeps else None, + output_jdeps = _get_or_create_single_jdeps_output(kotlinc_options.report_unused_deps, java_infos, ctx, compile_deps) if emit_jdeps else None, + ) + +def _run_jps_builder( + ctx, + output_jar, + rule_kind, + toolchains, + srcs, + generated_ksp_src_jars, + associates, + compile_deps, + transitive_runtime_jars, + plugins): + """Runs the necessary JpsBuilder actions to compile a jar + + Returns: + A struct containing the a list of output_jars and a struct annotation_processing jars + """ + outputs = None + kt_compile_jar = None + + kotlinc_options = ctx.attr.kotlinc_opts[KotlincOptions] + + # todo JDEPS for JVM + emit_jdeps = False + # emit_jdeps = kotlinc_options.emit_jdeps + + kt_output_jar = output_jar + + # todo ABI for JPS + if False: + kt_compile_jar = ctx.actions.declare_file(ctx.label.name + ".abi.jar") + outputs = { + "output": kt_output_jar, + "abi_jar": kt_compile_jar, + } + else: + kt_compile_jar = kt_output_jar + outputs = { + "output": kt_output_jar, + } + + kt_jdeps = None + if emit_jdeps: + kt_jdeps = ctx.actions.declare_file(ctx.label.name + "-kt.jdeps") + outputs["kotlin_output_jdeps"] = kt_jdeps + + args = init_builder_args(ctx, rule_kind, associates.module_name) + javac_opts = ctx.attr.javac_opts[JavacOptions] if ctx.attr.javac_opts else None + if javac_opts and javac_opts.add_exports: + args.add_all("--add-export", javac_opts.add_exports) + + _run_jvm_builder_action( + mnemonic = "JpsCompile", + executable = ctx.attr._jps_builder.files_to_run.executable, + args = args, + ctx = ctx, + rule_kind = rule_kind, + toolchains = toolchains, + srcs = srcs, + generated_src_jars = generated_ksp_src_jars, + associates = associates, + compile_deps = compile_deps, + annotation_processors = [], + transitive_runtime_jars = transitive_runtime_jars, + plugins = plugins, + outputs = outputs, + ) + + java_infos = [ + JavaInfo( + output_jar = kt_output_jar, + compile_jar = kt_compile_jar, + jdeps = kt_jdeps, + deps = compile_deps.deps, + runtime_deps = [d[JavaInfo] for d in ctx.attr.runtime_deps], + exports = [d[JavaInfo] for d in getattr(ctx.attr, "exports", [])], + neverlink = getattr(ctx.attr, "neverlink", False), + ), + ] + + return struct( + compile_jar = kt_compile_jar, + generated_src_jars = generated_ksp_src_jars, + annotation_processing = None, + output_jdeps = _get_or_create_single_jdeps_output(kotlinc_options.report_unused_deps, java_infos, ctx, compile_deps) if emit_jdeps else None, ) def _create_annotation_processing(annotation_processors, ap_class_jar, ap_source_jar): diff --git a/build/jvm-rules/rules/impl/kotlinc-options.bzl b/build/jvm-rules/rules/impl/kotlinc-options.bzl index ea42909ad007..3bd96f269e7d 100644 --- a/build/jvm-rules/rules/impl/kotlinc-options.bzl +++ b/build/jvm-rules/rules/impl/kotlinc-options.bzl @@ -8,30 +8,6 @@ _KOPTS = { type = attr.string, flag_name = "warn", ), - # "include_stdlibs": struct( - # args = dict( - # default = "all", - # doc = "Don't automatically include the Kotlin standard libraries into the classpath (stdlib and reflect).", - # values = ["all", "stdlib", "none"], - # ), - # type = attr.string, - # value_to_flag = { - # "all": None, - # "stdlib": ["-no-reflect"], - # "none": ["-no-stdlib"], - # }, - # ), - # "x_skip_prerelease_check": struct( - # flag = "-Xskip-prerelease-check", - # args = dict( - # default = False, - # doc = "Suppress errors thrown when using pre-release classes.", - # ), - # type = attr.bool, - # value_to_flag = { - # True: ["-Xskip-prerelease-check"], - # }, - # ), "context_receivers": struct( args = dict( default = False, @@ -40,17 +16,6 @@ _KOPTS = { type = attr.bool, flag_name = "context-receivers", ), - # "x_suppress_version_warnings": struct( - # flag = "-Xsuppress-version-warnings", - # args = dict( - # default = False, - # doc = "Suppress warnings about outdated, inconsistent, or experimental language or API versions.", - # ), - # type = attr.bool, - # value_to_flag = { - # True: ["-Xsuppress-version-warnings"], - # }, - # ), "x_inline_classes": struct( args = dict( default = False, @@ -59,17 +24,6 @@ _KOPTS = { type = attr.bool, flag_name = "inline-classes", ), - # "x_allow_result_return_type": struct( - # flag = "-Xallow-result-return-type", - # args = dict( - # default = False, - # doc = "Enable kotlin.Result as a return type", - # ), - # type = attr.bool, - # value_to_flag = { - # True: ["-Xallow-result-return-type"], - # }, - # ), "jvm_default": struct( args = dict( default = "", @@ -79,98 +33,6 @@ _KOPTS = { type = attr.string, flag_name = "jvm-default", ), - # "x_no_call_assertions": struct( - # flag = "-Xno-call-assertions", - # args = dict( - # default = False, - # doc = "Don't generate not-null assertions for arguments of platform types", - # ), - # type = attr.bool, - # value_to_flag = { - # True: ["-Xno-call-assertions"], - # }, - # ), - # "x_no_param_assertions": struct( - # flag = "-Xno-param-assertions", - # args = dict( - # default = False, - # doc = "Don't generate not-null assertions on parameters of methods accessible from Java", - # ), - # type = attr.bool, - # value_to_flag = { - # True: ["-Xno-param-assertions"], - # }, - # ), - # "x_no_receiver_assertions": struct( - # flag = "-Xno-receiver-assertions", - # args = dict( - # default = False, - # doc = "Don't generate not-null assertion for extension receiver arguments of platform types", - # ), - # type = attr.bool, - # value_to_flag = { - # True: ["-Xno-receiver-assertions"], - # }, - # ), - # "x_no_optimized_callable_references": struct( - # flag = "-Xno-optimized-callable-references", - # args = dict( - # default = False, - # doc = "Do not use optimized callable reference superclasses. Available from 1.4.", - # ), - # type = attr.bool, - # value_to_flag = { - # True: ["-Xno-optimized-callable-references"], - # }, - # ), - # "x_explicit_api_mode": struct( - # flag = "-Xexplicit-api", - # args = dict( - # default = "off", - # doc = "Enable explicit API mode for Kotlin libraries.", - # values = ["off", "warning", "strict"], - # ), - # type = attr.string, - # value_to_flag = { - # "off": None, - # "warning": ["-Xexplicit-api=warning"], - # "strict": ["-Xexplicit-api=strict"], - # }, - # ), - # "java_parameters": struct( - # args = dict( - # default = False, - # doc = "Generate metadata for Java 1.8+ reflection on method parameters.", - # ), - # type = attr.bool, - # value_to_flag = { - # True: ["-java-parameters"], - # }, - # ), - # "x_multi_platform": struct( - # flag = "-Xmulti-platform", - # args = dict( - # default = False, - # doc = "Enable experimental language support for multi-platform projects", - # ), - # type = attr.bool, - # value_to_flag = { - # True: ["-Xmulti-platform"], - # }, - # ), - # "x_sam_conversions": struct( - # flag = "-Xsam-conversions", - # args = dict( - # default = "class", - # doc = "Change codegen behavior of SAM/functional interfaces", - # values = ["class", "indy"], - # ), - # type = attr.string, - # value_to_flag = { - # "class": ["-Xsam-conversions=class"], - # "indy": ["-Xsam-conversions=indy"], - # }, - # ), "x_lambdas": struct( flag = "-Xlambdas", args = dict( @@ -181,17 +43,6 @@ _KOPTS = { type = attr.string, flag_name = "lambdas", ), - # "x_emit_jvm_type_annotations": struct( - # flag = "-Xemit-jvm-type-annotations", - # args = dict( - # default = False, - # doc = "Basic support for type annotations in JVM bytecode.", - # ), - # type = attr.bool, - # value_to_flag = { - # True: ["-Xemit-jvm-type-annotations"], - # }, - # ), "opt_in": struct( args = dict( default = [], @@ -199,83 +50,6 @@ _KOPTS = { ), type = attr.string_list, ), - # "x_use_fir": struct( - # # 1.6 - # flag = "-Xuse-fir", - # args = dict( - # default = False, - # doc = "Compile using the experimental Kotlin Front-end IR. Available from 1.6.", - # ), - # type = attr.bool, - # value_to_flag = { - # True: ["-Xuse-fir"], - # }, - # ), - # "x_use_k2": struct( - # # 1.7 - # flag = "-Xuse-k2", - # args = dict( - # default = False, - # doc = "Compile using experimental K2. K2 is a new compiler pipeline, no compatibility guarantees are yet provided", - # ), - # type = attr.bool, - # value_to_flag = { - # True: ["-Xuse-k2"], - # }, - # ), - # "x_no_optimize": struct( - # flag = "-Xno-optimize", - # args = dict( - # default = False, - # doc = "Disable optimizations", - # ), - # type = attr.bool, - # value_to_flag = { - # True: ["-Xno-optimize"], - # }, - # ), - # "x_backend_threads": struct( - # # 1.6.20, 1.7 - # flag = "-Xbackend-threads", - # args = dict( - # default = 1, - # doc = "When using the IR backend, run lowerings by file in N parallel threads. 0 means use a thread per processor core. Default value is 1.", - # ), - # type = attr.int, - # value_to_flag = None, - # map_value_to_flag = _map_backend_threads_to_flag, - # ), - # "x_enable_incremental_compilation": struct( - # args = dict( - # default = False, - # doc = "Enable incremental compilation", - # ), - # type = attr.bool, - # value_to_flag = { - # True: ["-Xenable-incremental-compilation"], - # }, - # ), - # "x_report_perf": struct( - # flag = "-Xreport-perf", - # args = dict( - # default = False, - # doc = "Report detailed performance statistics", - # ), - # type = attr.bool, - # value_to_flag = { - # True: ["-Xreport-perf"], - # }, - # ), - # "x_use_fir_lt": struct( - # args = dict( - # default = False, - # doc = "Compile using LightTree parser with Front-end IR. Warning: this feature is far from being production-ready", - # ), - # type = attr.bool, - # value_to_flag = { - # True: ["-Xuse-fir-lt"], - # }, - # ), "allow_kotlin_package": struct( args = dict( default = False, @@ -284,54 +58,6 @@ _KOPTS = { type = attr.bool, flag_name = "allow-kotlin-package", ), - # "x_no_source_debug_extension": struct( - # args = dict( - # default = False, - # doc = "Do not generate @kotlin.jvm.internal.SourceDebugExtension annotation on a class with the copy of SMAP", - # ), - # type = attr.bool, - # value_to_flag = { - # True: ["-Xno-source-debug-extension"], - # }, - # ), - # "x_type_enhancement_improvements_strict_mode": struct( - # args = dict( - # default = False, - # doc = "Enables strict mode for type enhancement improvements, enforcing stricter type checking and enhancements.", - # ), - # type = attr.bool, - # value_to_flag = { - # True: ["-Xtype-enhancement-improvements-strict-mode"], - # }, - # ), - # "x_jsr_305": struct( - # args = dict( - # default = "", - # doc = "Specifies how to handle JSR-305 annotations in Kotlin code. Options are 'default', 'ignore', 'warn', and 'strict'.", - # values = ["ignore", "warn", "strict"], - # ), - # type = attr.string, - # flag_name = "jsr305", - # ), - # "x_assertions": struct( - # args = dict( - # default = None, - # doc = "Configures how assertions are handled. The 'jvm' option enables assertions in JVM code.", - # values = ["jvm"], - # ), - # type = attr.string, - # flag_name = "assertions", - # ), - # "x_jspecify_annotations": struct( - # args = dict( - # default = None, - # doc = "Controls how JSpecify annotations are treated. Options are 'default', 'ignore', 'warn', and 'strict'.", - # values = ["ignore", "warn", "strict"], - # ), - # type = attr.string, - # add_arg = attr.string, - # flag_name = "jspecify-annotations", - # ), "jvm_target": struct( args = dict( default = 0, @@ -362,22 +88,20 @@ _KOPTS = { ), type = attr.string, ), - "jvm_emit_jdeps": struct( + "emit_jdeps": struct( args = dict( default = True, doc = "", ), type = attr.bool, ), - # "x_jdk_release": struct( - # args = dict( - # default = "", - # doc = "The -jvm_target flag. This is only tested at 1.8.", - # values = ["1.6", "1.8", "9", "10", "11", "12", "13", "15", "16", "17"], - # ), - # type = attr.string, - # flag_name = "jdk_release", - # ), + "jps_threshold": struct( + args = dict( + default = -1, + doc = "", + ), + type = attr.int, + ), } # todo: experimental_strict_kotlin_deps, experimental_reduce_classpath_mode diff --git a/build/jvm-rules/src/kotlin-builder/ArgMap.kt b/build/jvm-rules/src/compiler-util/ArgMap.kt similarity index 61% rename from build/jvm-rules/src/kotlin-builder/ArgMap.kt rename to build/jvm-rules/src/compiler-util/ArgMap.kt index d9f2ac36fc1d..203cdb6a4b9c 100644 --- a/build/jvm-rules/src/kotlin-builder/ArgMap.kt +++ b/build/jvm-rules/src/compiler-util/ArgMap.kt @@ -1,33 +1,10 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.bazel.jvm.kotlin import java.util.* -internal class ArgMap>( - private val map: EnumMap>, -) { - /** - * Get the mandatory single value from a key - */ - fun mandatorySingle(key: T): String { - return requireNotNull(optionalSingle(key)) { "$key is not optional" } - } +class ArgMap> internal constructor(private val map: EnumMap>) { + fun mandatorySingle(key: T): String = requireNotNull(optionalSingle(key)) { "$key is not optional" } fun optionalSingle(key: T): String? { return map[key]?.let { @@ -48,11 +25,7 @@ internal class ArgMap>( } } - fun mandatory(key: T): List { - return map[key] ?: throw IllegalArgumentException("$key is not optional") - } - - fun has(key: T): Boolean = map[key]?.isNotEmpty() ?: false + fun mandatory(key: T): List = requireNotNull(map[key]) { "$key is not optional"} fun optional(key: T): List? = map[key] @@ -69,7 +42,7 @@ internal class ArgMap>( } } -internal fun > createArgMap( +fun > createArgMap( args: List, enumClass: Class, ): ArgMap { diff --git a/build/jvm-rules/src/compiler-util/BUILD.bazel b/build/jvm-rules/src/compiler-util/BUILD.bazel new file mode 100644 index 000000000000..531f977102f1 --- /dev/null +++ b/build/jvm-rules/src/compiler-util/BUILD.bazel @@ -0,0 +1,16 @@ +load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") +load("//:jvm.bzl", "jvm_provided_library") + +kt_jvm_library( + name = "compiler-util", + srcs = glob(["*.kt"]), + deps = [ + ":kotlin-compiler-provided" + ], + visibility = ["//visibility:public"], +) + +jvm_provided_library( + name = "kotlin-compiler-provided", + lib = "//:kotlin-compiler" +) \ No newline at end of file diff --git a/build/jvm-rules/src/compiler-util/JvmBuilderFlags.kt b/build/jvm-rules/src/compiler-util/JvmBuilderFlags.kt new file mode 100644 index 000000000000..3b6f28d64ebc --- /dev/null +++ b/build/jvm-rules/src/compiler-util/JvmBuilderFlags.kt @@ -0,0 +1,103 @@ +package org.jetbrains.bazel.jvm.kotlin + +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments +import java.nio.file.Files +import java.nio.file.Path +import java.util.regex.Pattern + +private val FLAG_FILE_RE: Regex = Pattern.compile("""^--flagfile=((.*)-(\d+).params)$""").toRegex() + +fun parseArgs(args: List): ArgMap { + check(args.isNotEmpty()) { + "expected at least a single arg got: ${args.joinToString(" ")}" + } + + return createArgMap( + args = FLAG_FILE_RE.matchEntire(args[0])?.groups?.get(1)?.let { + Files.readAllLines(Path.of(it.value)) + } ?: args, + enumClass = JvmBuilderFlags::class.java, + ) +} + +enum class JvmBuilderFlags { + TARGET_LABEL, + CLASSPATH, + DIRECT_DEPENDENCIES, + DEPS_ARTIFACTS, + + PLUGIN_ID, + PLUGIN_CLASSPATH, + + OUTPUT, + RULE_KIND, + KOTLIN_MODULE_NAME, + + API_VERSION, + LANGUAGE_VERSION, + JVM_TARGET, + + OPT_IN, + ALLOW_KOTLIN_PACKAGE, + LAMBDAS, + JVM_DEFAULT, + INLINE_CLASSES, + CONTEXT_RECEIVERS, + + WARN, + + FRIEND_PATHS, + KOTLIN_OUTPUT_JDEPS, + TRACE, + ABI_JAR, + STRICT_KOTLIN_DEPS, + REDUCED_CLASSPATH_MODE, + + // makes sense only for JPS, not needed for Kotlinc + ADD_EXPORT, +} + +fun configureCommonCompilerArgs(kotlinArgs: K2JVMCompilerArguments, args: ArgMap, workingDir: Path) { + kotlinArgs.noStdlib = true + kotlinArgs.disableStandardScript = true + + kotlinArgs.apiVersion = args.optionalSingle(JvmBuilderFlags.API_VERSION) + kotlinArgs.languageVersion = args.optionalSingle(JvmBuilderFlags.LANGUAGE_VERSION) + // jdkRelease leads to some strange compilation failures like "cannot access class 'Map.Entry'" + kotlinArgs.jvmTarget = args.mandatorySingle(JvmBuilderFlags.JVM_TARGET).let { if (it == "8") "1.8" else it } + + // kotlin bug - not compatible with a new X compiler-plugin syntax + //compilationArgs.disableDefaultScriptingPlugin = true + args.optional(JvmBuilderFlags.FRIEND_PATHS)?.let { value -> + kotlinArgs.friendPaths = value.map { workingDir.resolve(it).toString() }.toTypedArray() + } + + args.optional(JvmBuilderFlags.OPT_IN)?.let { + kotlinArgs.optIn = it.toTypedArray() + } + + val allowKotlinPackage = args.boolFlag(JvmBuilderFlags.ALLOW_KOTLIN_PACKAGE) + if (allowKotlinPackage) { + kotlinArgs.allowKotlinPackage = true + } + + args.optionalSingle(JvmBuilderFlags.LAMBDAS)?.let { + kotlinArgs.lambdas = it + } + args.optionalSingle(JvmBuilderFlags.JVM_DEFAULT)?.let { + kotlinArgs.jvmDefault = it + } + if (args.boolFlag(JvmBuilderFlags.INLINE_CLASSES)) { + kotlinArgs.inlineClasses = true + } + if (args.boolFlag(JvmBuilderFlags.CONTEXT_RECEIVERS)) { + kotlinArgs.contextReceivers = true + } + args.optionalSingle(JvmBuilderFlags.WARN)?.let { + when (it) { + "off" -> kotlinArgs.suppressWarnings = true + "error" -> kotlinArgs.allWarningsAsErrors = true + else -> throw IllegalArgumentException("unsupported kotlinc warning option: $it") + } + } +} \ No newline at end of file diff --git a/build/jvm-rules/src/jps-builder/BUILD.bazel b/build/jvm-rules/src/jps-builder/BUILD.bazel new file mode 100644 index 000000000000..74c8c2749b7c --- /dev/null +++ b/build/jvm-rules/src/jps-builder/BUILD.bazel @@ -0,0 +1,78 @@ +load("@rules_java//java:defs.bzl", "java_binary") +load("@rules_jvm//:jvm.bzl", "jvm_import") +load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") + +kt_jvm_library( + name = "worker-lib", + srcs = glob(["*.kt"]), + deps = [ + ":jps-standalone", + "//src/compiler-util", + "//src/worker-framework", + "//zip:build-zip", + "@rules_java//java/runfiles", + "//:kotlin-jps-plugin", + ], + runtime_deps = [ + # jps needs these libs + "@lib//:asm", + "@lib//:fastutil-min", + "@lib//:aalto-xml", + "@lib//:mvstore", + "@lib//:hash4j", + "@lib//:caffeine", + "@lib//:platform-jps-build-qdox-java-parser", + "@lib//:jps-javac-extension", + # JPS plugin to compile Kotlin requires it + "@lib//:kotlin-reflect", + "//:kotlin-build-tools-api", + "//:kotlin-metadata", + "//:kotlin-util-klib", + "//:kotlin-util-klib-metadata", + ], + visibility = ["//visibility:public"], +) + +java_import( + name = "jps-standalone", + jars = ["jps-build-standalone-2.jar"], +) + +java_binary( + name = "worker-jvm", + runtime_deps = [":worker-lib"], + main_class = "org.jetbrains.bazel.jvm.jps.JpsBuildWorker", + jvm_flags = [ + "-Xms1000m", + "-Xmx6000m", + "-Djava.awt.headless=true", + "-Dapple.awt.UIElement=true", + "-Dkotlin.environment.keepalive=true", + "-Djps.use.experimental.storage=true", + # Kotlin Compiler sets it + "-Didea.io.use.nio2=true", + "-Dzip.handler.uses.crc.instead.of.timestamp=true", + ], + visibility = ["//visibility:public"], +) + +java_binary( + name = "test-worker", + runtime_deps = [":worker-lib"], + data = [ + "@kotlinc//:kotlinc_dist", + "@kotlin-serialization-compiler-plugin//file", + ], + main_class = "org.jetbrains.bazel.jvm.jps.TestJpsBuildWorker", + jvm_flags = [ + "-Xms1000m", + "-Xmx6000m", + "-Djps.service.manager.impl=org.jetbrains.bazel.jvm.jps.BazelJpsServiceManager", + "-Djava.awt.headless=true", + "-Dapple.awt.UIElement=true", + "-Dkotlin.environment.keepalive=true", + "-Djps.use.experimental.storage=true", + "-Djps.kotlin.home=$(rlocationpath @kotlinc//:kotlinc_dist)", + "-Dorg.jetbrains.kotlin.kotlin-serialization-compiler-plugin.path=$(rlocationpath @kotlin-serialization-compiler-plugin//file)", + ], +) diff --git a/build/jvm-rules/src/jps-builder/BazelJpsModelLoader.kt b/build/jvm-rules/src/jps-builder/BazelJpsModelLoader.kt new file mode 100644 index 000000000000..66811546ea4f --- /dev/null +++ b/build/jvm-rules/src/jps-builder/BazelJpsModelLoader.kt @@ -0,0 +1,166 @@ +@file:Suppress("UnstableApiUsage") + +package org.jetbrains.bazel.jvm.jps + +import com.google.devtools.build.runfiles.Runfiles +import org.jetbrains.bazel.jvm.kotlin.ArgMap +import org.jetbrains.bazel.jvm.kotlin.JvmBuilderFlags +import org.jetbrains.bazel.jvm.kotlin.configureCommonCompilerArgs +import org.jetbrains.jps.model.JpsDummyElement +import org.jetbrains.jps.model.JpsElementFactory +import org.jetbrains.jps.model.JpsModel +import org.jetbrains.jps.model.JpsProject +import org.jetbrains.jps.model.java.* +import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerOptions +import org.jetbrains.jps.model.library.JpsOrderRootType +import org.jetbrains.jps.model.library.impl.JpsLibraryImpl +import org.jetbrains.jps.model.module.JpsDependenciesList +import org.jetbrains.jps.model.module.impl.JpsModuleImpl +import org.jetbrains.jps.model.module.impl.JpsModuleSourceRootImpl +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments +import org.jetbrains.kotlin.config.KotlinFacetSettings +import org.jetbrains.kotlin.jps.model.JpsKotlinFacetModuleExtension +import java.nio.file.Files +import java.nio.file.Path +import java.util.* +import kotlin.io.path.invariantSeparatorsPathString + +private val jpsElementFactory = JpsElementFactory.getInstance() + +internal val runFiles by lazy { + Runfiles.preload().unmapped() +} + +private fun createClasspath(args: ArgMap, baseDir: Path): Sequence { + // REDUCED_CLASSPATH_MODE is not supported for JPS + return args.mandatory(JvmBuilderFlags.CLASSPATH).asSequence().map { baseDir.resolve(it).normalize() } +} + +internal class BazelJpsModelLoader( + private val sources: List, + private val args: ArgMap, + private val classPathRootDir: Path, + private val classOutDir: Path +) : org.jetbrains.jps.cmdline.JpsModelLoader { + private val javaHome = Path.of(System.getProperty("java.home")).normalize() ?: error("No java.home system property") + + override fun loadModel(): JpsModel { + val model = jpsElementFactory.createModel() + + // properties not needed for us (not implemented for java) + // extension.loadModuleOptions not needed for us (not implemented for java) + val module = JpsModuleImpl( + JpsJavaModuleType.INSTANCE, + args.mandatorySingle(JvmBuilderFlags.TARGET_LABEL), + jpsElementFactory.createDummyElement(), + ) + val jpsJavaModuleExtension = JpsJavaExtensionService.getInstance().getOrCreateModuleExtension(module) + jpsJavaModuleExtension.outputUrl = classOutDir.toUri().toString() + + val languageLevelEnumName = "JDK_" + args.mandatorySingle(JvmBuilderFlags.JVM_TARGET).let { if (it == "8") "1_8" else it } + jpsJavaModuleExtension.languageLevel = LanguageLevel.valueOf(languageLevelEnumName) + + for (source in sources) { + // used as a key - immutable instance cannot be used + val properties = JavaSourceRootProperties("", false) + module.addSourceRoot(JpsModuleSourceRootImpl(source.toUri().toString(), JavaSourceRootType.SOURCE, properties)) + } + + configureKotlinCompiler(module, args) + + val dependencyList = module.dependenciesList + dependencyList.clear() + configureJdk(model = model, module = module, dependencyList = dependencyList) + dependencyList.addModuleSourceDependency() + + configureClasspath(module, dependencyList) + + val project = model.project + project.addModule(module) + + configureJavac(project, args) + return model + } + + private fun configureJavac(project: JpsProject, args: ArgMap) { + val configuration = JpsJavaExtensionService.getInstance().getCompilerConfiguration(project) + val compilerOptions = JpsJavaCompilerOptions() + compilerOptions.PREFER_TARGET_JDK_COMPILER = false + compilerOptions.DEPRECATION = false + compilerOptions.GENERATE_NO_WARNINGS = true + compilerOptions.MAXIMUM_HEAP_SIZE = 512 + compilerOptions.ADDITIONAL_OPTIONS_STRING = args.optionalList(JvmBuilderFlags.ADD_EXPORT).joinToString(separator = " ") { + "--add-exports $it" + } + configuration.setCompilerOptions("Javac", compilerOptions) + } + + private fun configureKotlinCompiler(module: JpsModuleImpl, args: ArgMap) { + val kotlinFacetSettings = KotlinFacetSettings() + kotlinFacetSettings.useProjectSettings = false + val kotlinArgs = K2JVMCompilerArguments() + kotlinFacetSettings.compilerArguments = kotlinArgs + configureCommonCompilerArgs(kotlinArgs = kotlinArgs, args = args, workingDir = classPathRootDir) + + val plugins = args.optionalList(JvmBuilderFlags.PLUGIN_ID).zip(args.optionalList(JvmBuilderFlags.PLUGIN_CLASSPATH)) + if (plugins.isNotEmpty()) { + val pluginClassPaths = mutableListOf() + @Suppress("UnusedVariable") + for ((id, paths) in plugins) { + val propertyName = "$id.path" + val relativePath = System.getProperty(propertyName) + if (relativePath == null) { + throw IllegalArgumentException("Missing system property $propertyName") + } + + pluginClassPaths.add(runFiles.rlocation(relativePath)) + } + kotlinArgs.pluginClasspaths = pluginClassPaths.toTypedArray() + } + + module.container.setChild(JpsKotlinFacetModuleExtension.KIND, JpsKotlinFacetModuleExtension(kotlinFacetSettings)) + } + + private fun configureJdk( + model: JpsModel, + module: JpsModuleImpl, + dependencyList: JpsDependenciesList, + ) { + val jdkName = "default-jdk" + // do not use JpsJavaExtensionService.getInstance().addJavaSdk - we don't need to detect version and collect roots for non-modular JDK + val jdkLib = model.global.addSdk(jdkName, javaHome.invariantSeparatorsPathString, null, JpsJavaSdkType.INSTANCE) + for (moduleUrl in readModulesFromJdkReleaseFile(javaHome)) { + jdkLib.addRoot(moduleUrl, JpsOrderRootType.COMPILED) + } + + val sdk = jdkLib.properties + val sdkType = sdk.getSdkType() + module.sdkReferencesTable.setSdkReference(sdkType, sdk.createReference()) + dependencyList.addSdkDependency(sdkType) + } + + private fun configureClasspath( + module: JpsModuleImpl, + dependencyList: JpsDependenciesList + ) { + val lib = JpsLibraryImpl( + "class-path-lib", + JpsJavaLibraryType.INSTANCE, + jpsElementFactory.createDummyElement() + ) + for (file in createClasspath(args, classPathRootDir)) { + lib.addRoot(file.toUri().toString(), JpsOrderRootType.COMPILED) + } + module.addModuleLibrary(lib) + dependencyList.addLibraryDependency(lib) + } +} + +private fun readModulesFromJdkReleaseFile(javaHome: Path): Sequence { + val p = Files.newInputStream(javaHome.resolve("release")).use { stream -> + Properties().also { it.load(stream) } + } + val jbrBaseUrl = "jrt://${javaHome.invariantSeparatorsPathString}!/" + val modules = p.getProperty("MODULES") ?: return emptySequence() + return modules.removeSurrounding("\"").removeSurrounding("'").splitToSequence(' ').map { jbrBaseUrl + it } +} diff --git a/build/jvm-rules/src/jps-builder/BazelJpsServiceManager.kt b/build/jvm-rules/src/jps-builder/BazelJpsServiceManager.kt new file mode 100644 index 000000000000..4877007994e4 --- /dev/null +++ b/build/jvm-rules/src/jps-builder/BazelJpsServiceManager.kt @@ -0,0 +1,123 @@ +@file:Suppress("UnstableApiUsage", "ReplaceGetOrSet", "ReplaceJavaStaticMethodWithKotlinAnalog") + +package org.jetbrains.bazel.jvm.jps + +import org.jetbrains.jps.backwardRefs.JavaBackwardReferenceIndexBuilder +import org.jetbrains.jps.builders.AdditionalRootsProviderService +import org.jetbrains.jps.builders.impl.java.JavacCompilerTool +import org.jetbrains.jps.builders.java.ExcludedJavaSourceRootProvider +import org.jetbrains.jps.builders.java.JavaCompilingTool +import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType +import org.jetbrains.jps.incremental.BuilderService +import org.jetbrains.jps.incremental.ModuleLevelBuilder +import org.jetbrains.jps.incremental.java.JavaBuilder +import org.jetbrains.jps.model.* +import org.jetbrains.jps.service.JpsServiceManager +import org.jetbrains.jps.service.SharedThreadPool +import org.jetbrains.kotlin.jps.build.KotlinBuilderService +import java.util.* +import java.util.concurrent.ConcurrentHashMap + +@Suppress("RemoveRedundantQualifierName") +private fun listOf(vararg elements: T): List = java.util.List.of(*elements) +@Suppress("RemoveRedundantQualifierName") +private fun listOf(): List = java.util.List.of() + +@Suppress("unused") +internal class BazelJpsServiceManager : JpsServiceManager() { + private val services = ConcurrentHashMap, Any>() + private val extensions = ConcurrentHashMap, List<*>>() + + init { + extensions.put(JavaCompilingTool::class.java, listOf(JavacCompilerTool())) + extensions.put(BuilderService::class.java, listOf(BazelJavaBuilderService, KotlinBuilderService())) + // org.jetbrains.kotlin.jps.build.KotlinResourcesRootProvider and KotlinSourceRootProvider are not needed + extensions.put(AdditionalRootsProviderService::class.java, listOf()) + extensions.put(ExcludedJavaSourceRootProvider::class.java, listOf()) + + services.put(SharedThreadPool::class.java, BazelSharedThreadPool) + services.put(JpsEncodingConfigurationService::class.java, DummyJpsEncodingConfigurationService) + } + + @Suppress("UNCHECKED_CAST") + override fun getService(serviceClass: Class): T { + services.get(serviceClass)?.let { + return it as T + } + + // confine costly service initialization to single thread for defined startup profile + return synchronized(services) { + return services.computeIfAbsent(serviceClass) { + doComputeService(it) as T + } as T + } + } + + private fun doComputeService(serviceClass: Class<*>): Any { + val iterator = ServiceLoader.load(serviceClass, serviceClass.getClassLoader()).iterator() + if (!iterator.hasNext()) { + throw ServiceConfigurationError("Implementation for $serviceClass not found") + } + + val result = iterator.next() + if (iterator.hasNext()) { + throw ServiceConfigurationError( + "More than one implementation for $serviceClass found: ${result::class.java} and ${iterator.next()::class.java}" + ) + } + //System.err.println("Extensions for $serviceClass not registered: $result") + return result + } + + @Suppress("UNCHECKED_CAST") + override fun getExtensions(extensionClass: Class): Iterable { + extensions.get(extensionClass)?.let { + return it as List + } + + // confine costly service initialization to single thread for defined startup profile + synchronized(extensions) { + val result = extensions.computeIfAbsent(extensionClass) { + ServiceLoader.load(it, extensionClass.getClassLoader()).toList() + } as List + + //System.err.println("Extensions for $extensionClass not registered: $result") + return result + } + } +} + +private object DummyJpsEncodingConfigurationService : JpsEncodingConfigurationService() { + override fun getGlobalEncoding(global: JpsGlobal) = "UTF-8" + + override fun setGlobalEncoding(global: JpsGlobal, encoding: String?) { + throw UnsupportedOperationException() + } + + override fun getProjectEncoding(model: JpsModel) = "UTF-8" + + override fun getEncodingConfiguration(project: JpsProject): JpsEncodingProjectConfiguration? = null + + override fun setEncodingConfiguration( + project: JpsProject, + projectEncoding: String?, + urlToEncoding: Map + ): JpsEncodingProjectConfiguration { + throw UnsupportedOperationException() + } +} + +// remove ResourcesBuilder +private object BazelJavaBuilderService : BuilderService() { + // remove ResourcesTargetType.ALL_TYPES and ProjectDependenciesResolver.ProjectDependenciesResolvingTargetType.INSTANCE + override fun getTargetTypes() = listOf(JavaModuleBuildTargetType.PRODUCTION) + +// remove RmiStubsGenerator and DependencyResolvingBuilder + override fun createModuleLevelBuilders(): List { + return listOf( + JavaBuilder(SharedThreadPool.getInstance()), + //NotNullInstrumentingBuilder(), + JavaBackwardReferenceIndexBuilder() + ) + } +} \ No newline at end of file diff --git a/build/jvm-rules/src/jps-builder/BazelSharedThreadPool.kt b/build/jvm-rules/src/jps-builder/BazelSharedThreadPool.kt new file mode 100644 index 000000000000..b199b8e516fc --- /dev/null +++ b/build/jvm-rules/src/jps-builder/BazelSharedThreadPool.kt @@ -0,0 +1,107 @@ +@file:Suppress("UnstableApiUsage") + +package org.jetbrains.bazel.jvm.jps + +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.asExecutor +import org.jetbrains.jps.service.SharedThreadPool +import java.util.concurrent.* +import java.util.concurrent.atomic.AtomicBoolean + +object BazelSharedThreadPool : SharedThreadPool() { + private val executor = Dispatchers.Default.asExecutor() + + // JPS uses MAX_BUILDER_THREADS as maxThreads - doesn't make sense for standalone, use coroutine dispatcher pool + override fun createBoundedExecutor(name: String, maxThreads: Int) = this + + override fun createCustomPriorityQueueBoundedExecutor(name: String, maxThreads: Int, comparator: Comparator): Executor { + return PriorityQueueExecutor(this, comparator) + } + + override fun execute(command: Runnable) { + executor.execute(command) + } + + override fun shutdown() { + throw UnsupportedOperationException() + } + + override fun shutdownNow(): List { + throw UnsupportedOperationException() + } + + override fun isShutdown(): Boolean = false + + override fun isTerminated(): Boolean = false + + override fun awaitTermination(timeout: Long, unit: TimeUnit): Boolean { + throw UnsupportedOperationException() + } + + @OptIn(DelicateCoroutinesApi::class) + override fun submit(task: Callable): Future = CompletableFuture.supplyAsync({ task.call() }, executor) + + override fun submit(task: Runnable, result: T): Future { + return CompletableFuture.supplyAsync({ + task.run() + result + }, executor) + } + + override fun submit(task: Runnable): Future<*> = CompletableFuture.runAsync(task, executor) + + override fun invokeAll(tasks: Collection>): List> { + return tasks.map { task -> + CompletableFuture.supplyAsync({ task.call() }, executor) + } + } + + override fun invokeAll(tasks: Collection>, timeout: Long, unit: TimeUnit): List> { + throw UnsupportedOperationException() + } + + override fun invokeAny(tasks: Collection>): T { + throw UnsupportedOperationException() + } + + override fun invokeAny(tasks: Collection>, timeout: Long, unit: TimeUnit): T? { + throw UnsupportedOperationException() + } +} + +private class PriorityQueueExecutor( + private val delegateExecutor: Executor, + comparator: Comparator +) : Executor { + private val taskQueue = PriorityBlockingQueue(11, comparator) + private val isProcessing = AtomicBoolean(false) + + override fun execute(command: Runnable) { + taskQueue.put(command) + processQueue() + } + + private fun processQueue() { + if (!isProcessing.compareAndSet(false, true)) { + return + } + + delegateExecutor.execute { + try { + while (true) { + val task = taskQueue.poll() ?: break + task.run() + } + } + finally { + if (taskQueue.isEmpty()) { + isProcessing.set(false) + } + else { + processQueue() + } + } + } + } +} diff --git a/build/jvm-rules/src/jps-builder/JpsBuilder.kt b/build/jvm-rules/src/jps-builder/JpsBuilder.kt new file mode 100644 index 000000000000..bb3591f93ff4 --- /dev/null +++ b/build/jvm-rules/src/jps-builder/JpsBuilder.kt @@ -0,0 +1,179 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +@file:Suppress("HardCodedStringLiteral", "UnstableApiUsage") + +package org.jetbrains.bazel.jvm.jps + +import com.google.devtools.build.lib.worker.WorkerProtocol +import org.jetbrains.bazel.jvm.WorkRequestExecutor +import org.jetbrains.bazel.jvm.kotlin.ArgMap +import org.jetbrains.bazel.jvm.kotlin.JvmBuilderFlags +import org.jetbrains.bazel.jvm.kotlin.parseArgs +import org.jetbrains.bazel.jvm.processRequests +import org.jetbrains.jps.api.CanceledStatus +import org.jetbrains.jps.api.GlobalOptions +import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType +import org.jetbrains.jps.cmdline.BuildRunner +import org.jetbrains.jps.cmdline.ProjectDescriptor +import org.jetbrains.jps.incremental.* +import org.jetbrains.jps.incremental.fs.BuildFSState +import org.jetbrains.jps.incremental.messages.BuildMessage +import org.jetbrains.jps.incremental.messages.CompilerMessage +import org.jetbrains.kotlin.config.IncrementalCompilation +import java.io.PrintWriter +import java.io.Writer +import java.nio.file.Path + +// Please note: for performance reasons, we do not set `jps.new.storage.compact.on.close` to true. +// As a result, the database file on disk may grow to some extent. + +// kotlin.serialization.plugin.path +private fun configureKotlincHome() { + val relativePath = requireNotNull(System.getProperty("jps.kotlin.home")) + // todo a more robust solution to avoid `toRealPath` + // resolve symlink to real dir + val singleFile = Path.of(runFiles.rlocation(relativePath)).toRealPath() + System.setProperty("jps.kotlin.home", singleFile.parent.toString()) +} + +internal fun configureGlobalJps() { + System.setProperty(GlobalOptions.COMPILE_PARALLEL_MAX_THREADS_OPTION, Runtime.getRuntime().availableProcessors().toString()) + System.setProperty(GlobalOptions.COMPILE_PARALLEL_OPTION, "true") + System.setProperty(GlobalOptions.DEPENDENCY_GRAPH_ENABLED, "true") + System.setProperty(GlobalOptions.ALLOW_PARALLEL_AUTOMAKE_OPTION, "true") + System.setProperty("idea.compression.enabled", "false") + System.setProperty(IncrementalCompilation.INCREMENTAL_COMPILATION_JVM_PROPERTY, "true") + configureKotlincHome() +} + +object JpsBuildWorker : WorkRequestExecutor { + @JvmStatic + fun main(startupArgs: Array) { + configureGlobalJps() + processRequests(startupArgs, this) + } + + override suspend fun execute(request: WorkerProtocol.WorkRequest, writer: Writer, baseDir: Path): Int { + val sources = request.inputsList.asSequence() + .filter { it.path.endsWith(".kt") || it.path.endsWith(".java") } + .map { baseDir.resolve(it.path) } + .toList() + return buildUsingJps(workingDir = baseDir, args = parseArgs(request.argumentsList), out = writer, sources = sources) + } +} + +internal fun buildUsingJps( + workingDir: Path, + args: ArgMap, + out: Writer, + sources: List, + classPathRootDir: Path = workingDir, +): Int { + + val messageHandler = ConsoleMessageHandler(out) + + // todo - do we need LowMemoryWatcherManager? + + + val outJar = workingDir.resolve(args.mandatorySingle(JvmBuilderFlags.OUTPUT)).normalize() + val prefix = outJar.fileName.toString().removeSuffix(".jar") + val bazelOutDir = outJar.parent + val dataStorageRoot = bazelOutDir.resolve("$prefix-jps-data") + + // incremental compilation - we do not clear dir + val classOutDir = bazelOutDir.resolve("$prefix-classes") + + val buildRunner = BuildRunner(BazelJpsModelLoader(sources = sources, args = args, classPathRootDir = classPathRootDir, classOutDir = classOutDir)) + val projectDescriptor = buildRunner.load(messageHandler, dataStorageRoot, BuildFSState(/* alwaysScanFS = */ true)) + try { + runBuild( + projectDescriptor = projectDescriptor, + canceledStatus = CanceledStatus.NULL, + messageHandler = messageHandler, + forceClean = false, + out = out, + ) + } + finally { + projectDescriptor.release() + } + + return if (messageHandler.hasErrors()) 1 else 0 +} + +@Suppress("SameParameterValue") +private fun runBuild( + projectDescriptor: ProjectDescriptor, + canceledStatus: CanceledStatus, + messageHandler: MessageHandler, + forceClean: Boolean, + out: Writer, +) { + var attempt = 0 + var forceCleanCaches = forceClean + val targetType = JavaModuleBuildTargetType.PRODUCTION + while (attempt < 2 && !canceledStatus.isCanceled) { + val targetTypes = setOf(targetType) + val targetTypesToForceBuild = if (forceClean) setOf(targetType) else emptySet() + val compileScope = CompileScopeImpl( + /* types = */ targetTypes, + /* typesToForceBuild = */ targetTypesToForceBuild, + /* targets = */ emptySet(), + /* files = */ emptyMap() + ) + val builder = IncProjectBuilder( + /* pd = */ projectDescriptor, + /* builderRegistry = */ BuilderRegistry.getInstance(), + /* builderParams = */ emptyMap(), + /* cs = */ canceledStatus, + /* isTestMode = */ false, + ) + builder.addMessageHandler(messageHandler) + try { + builder.build(compileScope, forceClean) + break + } + catch (e: RebuildRequestedException) { + if (attempt == 0) { + PrintWriter(out).use { + e.printStackTrace(it) + } + forceCleanCaches = true + } + else { + throw e + } + } + attempt++ + } +} + +private class ConsoleMessageHandler(private val out: Writer) : MessageHandler { + private var hasErrors = false + + override fun processMessage(message: BuildMessage) { + val messageText = when (message) { + is CompilerMessage -> { + when { + message.sourcePath == null -> message.messageText + message.line < 0 -> message.sourcePath + ": " + message.messageText + else -> message.sourcePath + "(" + message.line + ":" + message.column + "): " + message.messageText + } + } + else -> message.messageText + } + + if (messageText.isEmpty()) { + return + } + + if (message.kind == BuildMessage.Kind.ERROR) { + out.appendLine("Error: $messageText") + hasErrors = true + } + else if (message.kind !== BuildMessage.Kind.PROGRESS || !messageText.startsWith("Compiled") && !messageText.startsWith("Copying")) { + out.appendLine(messageText) + } + } + + fun hasErrors(): Boolean = hasErrors +} \ No newline at end of file diff --git a/build/jvm-rules/src/jps-builder/TestJpsBuildWorker.kt b/build/jvm-rules/src/jps-builder/TestJpsBuildWorker.kt new file mode 100644 index 000000000000..c9392052a542 --- /dev/null +++ b/build/jvm-rules/src/jps-builder/TestJpsBuildWorker.kt @@ -0,0 +1,305 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.bazel.jvm.jps + +import org.jetbrains.bazel.jvm.kotlin.parseArgs +import java.io.PrintWriter +import java.nio.file.Files +import java.nio.file.Path +import kotlin.io.path.ExperimentalPathApi +import kotlin.io.path.invariantSeparatorsPathString +import kotlin.io.path.walk + +object TestJpsBuildWorker { + @OptIn(ExperimentalPathApi::class) + @JvmStatic + fun main(startupArgs: Array) { + configureGlobalJps() + + val userHomeDir = Path.of(System.getProperty("user.home")) + val workingDir = userHomeDir.resolve("bazel-jps-test") + Files.createDirectories(workingDir) + try { + val out = PrintWriter(System.out) + try { + //val sources = Files.newDirectoryStream(userHomeDir.resolve("projects/idea/community/platform/util/xmlDom/src")).use { it.toList() } + val sourceDir = userHomeDir.resolve("projects/idea/community/platform/platform-impl/src") + val sources = sourceDir + .walk() + .filter { + val p = it.toString() + p.endsWith(".kt") || p.endsWith(".java") + } + .sortedBy { sourceDir.relativize(it).invariantSeparatorsPathString } + .toList() + buildUsingJps( + workingDir = workingDir, + args = parseArgs(testParams.trimStart().lines()), + out = out, + sources = sources, + classPathRootDir = Path.of("/private/var/tmp/_bazel_develar/1693e3b60d193556354eca5e9446027e/execroot/_main"), + ) + } + finally { + out.flush() + } + } + finally { + //workingDir.deleteRecursively() + } + } +} + +private const val testParams = """ +--target_label +@community//platform/platform-impl:ide-impl +--rule_kind +kt_jvm_library +--kotlin_module_name +intellij.platform.ide.impl +--add-export +java.desktop/sun.awt=ALL-UNNAMED +java.desktop/sun.font=ALL-UNNAMED +java.desktop/java.awt.peer=ALL-UNNAMED +jdk.attach/sun.tools.attach=ALL-UNNAMED +java.desktop/sun.awt.image=ALL-UNNAMED +java.desktop/sun.awt.datatransfer=ALL-UNNAMED +java.desktop/sun.swing=ALL-UNNAMED +java.base/sun.nio.fs=ALL-UNNAMED +--output +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/platform-impl/ide-impl.jar +--warn +off +--jvm-default +all +--jvm-target +17 +--opt_in +com.intellij.openapi.util.IntellijInternalApi +org.jetbrains.kotlin.utils.addToStdlib.UnsafeCastFunction +--classpath +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/eawtstub/lib+/eawtstub-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/platform-api/ide.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/util.abi.jar +../lib++_repo_rules+annotations-24_0_0_http/file/annotations-24.0.0.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util-rt/util-rt-hjar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/base/base.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/core-api/core.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/extensions/extensions.abi.jar +../lib++_repo_rules+kotlinx-coroutines-core-jvm-1_8_0-intellij-11_http/file/kotlinx-coroutines-core-jvm-1.8.0-intellij-11.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/forms_rt/java-guiForms-rt-hjar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/projectModel-api/projectModel.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/jps/model-api/model-hjar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/analysis-api/analysis.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/editor-ui-api/editor.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/credential-store/credentialStore.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/remote-core/remote-core.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/ide-core/ide-core.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/progress/shared/ide-progress.abi.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/oro_matcher/lib++_repo_rules+oro-2_0_8_http/file/oro-2.0.8-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/lang-api/lang.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/lang-core/lang-core.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/lvcs-api/lvcs.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/indexing-api/indexing.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/code-style-api/codeStyle.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/execution/execution.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/refactoring/refactoring.abi.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/jna-platform-5_14_0_http_import/lib++_repo_rules+jna-platform-5_14_0_http/file/jna-platform-5.14.0-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/jna-5_14_0_http_import/lib++_repo_rules+jna-5_14_0_http/file/jna-5.14.0-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/winp/lib++_repo_rules+winp-1_30_1_http/file/winp-1.30.1-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/swingx/lib++_repo_rules+swingx-core-1_6_2-2_http/file/swingx-core-1.6.2-2-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/core-impl/core-impl.abi.jar +../lib++_repo_rules+kotlin-stdlib-2_1_0_http/file/kotlin-stdlib-2.1.0.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/miglayout-swing-11_4_http_import/lib++_repo_rules+miglayout-swing-11_4_http/file/miglayout-swing-11.4-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/miglayout-core-11_4_http_import/lib++_repo_rules+miglayout-core-11_4_http/file/miglayout-core-11.4-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/projectModel-impl/projectModel-impl.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/jps/model-serialization/model-serialization-hjar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util-ex/util-ex.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/concurrency/concurrency.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/workspace/storage/storage.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/workspace/jps/jps.abi.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/commons-imaging/lib++_repo_rules+commons-imaging-1_0-RC-1_http/file/commons-imaging-1.0-RC-1-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/guava-33_3_1-jre_http_import/lib++_repo_rules+guava-33_3_1-jre_http/file/guava-33.3.1-jre-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/failureaccess-1_0_2_http_import/lib++_repo_rules+failureaccess-1_0_2_http/file/failureaccess-1.0.2-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/j2objc-annotations-3_0_0_http_import/lib++_repo_rules+j2objc-annotations-3_0_0_http/file/j2objc-annotations-3.0.0-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/jps/model-impl/model-impl-hjar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/analysis-impl/analysis-impl.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/editor-ui-ex/editor-ex.abi.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/gson/lib++_repo_rules+gson-2_11_0_http/file/gson-2.11.0-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/httpmime-4_5_14_http_import/lib++_repo_rules+httpmime-4_5_14_http/file/httpmime-4.5.14-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/httpclient-4_5_14_http_import/lib++_repo_rules+httpclient-4_5_14_http/file/httpclient-4.5.14-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/httpcore-4_4_16_http_import/lib++_repo_rules+httpcore-4_4_16_http/file/httpcore-4.4.16-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/diff-api/diff.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/diff/diff.abi.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/imgscalr/lib++_repo_rules+imgscalr-lib-4_2_http/file/imgscalr-lib-4.2-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/built-in-server-api/builtInServer.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/observable/ide-observable.abi.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/stream_ex/lib++_repo_rules+streamex-0_8_2_http/file/streamex-0.8.2-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/netty-codec-http2-4_2_0_RC1_http_import/lib++_repo_rules+netty-codec-http2-4_2_0_RC1_http/file/netty-codec-http2-4.2.0.RC1-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/netty-transport-4_2_0_RC1_http_import/lib++_repo_rules+netty-transport-4_2_0_RC1_http/file/netty-transport-4.2.0.RC1-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/netty-resolver-4_2_0_RC1_http_import/lib++_repo_rules+netty-resolver-4_2_0_RC1_http/file/netty-resolver-4.2.0.RC1-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/netty-codec-4_2_0_RC1_http_import/lib++_repo_rules+netty-codec-4_2_0_RC1_http/file/netty-codec-4.2.0.RC1-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/netty-codec-base-4_2_0_RC1_http_import/lib++_repo_rules+netty-codec-base-4_2_0_RC1_http/file/netty-codec-base-4.2.0.RC1-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/netty-handler-4_2_0_RC1_http_import/lib++_repo_rules+netty-handler-4_2_0_RC1_http/file/netty-handler-4.2.0.RC1-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/netty-transport-native-unix-common-4_2_0_RC1_http_import/lib++_repo_rules+netty-transport-native-unix-common-4_2_0_RC1_http/file/netty-transport-native-unix-common-4.2.0.RC1-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/netty-codec-http-4_2_0_RC1_http_import/lib++_repo_rules+netty-codec-http-4_2_0_RC1_http/file/netty-codec-http-4.2.0.RC1-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/jackson/lib++_repo_rules+jackson-core-2_17_0_http/file/jackson-core-2.17.0-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/java_compatibility/lib++_repo_rules+java-compatibility-1_0_1_http/file/java-compatibility-1.0.1-ijar.jar +../lib++_repo_rules+kotlin-reflect-2_1_0_http/file/kotlin-reflect-2.1.0.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/jackson-databind-2_17_2_http_import/lib++_repo_rules+jackson-databind-2_17_2_http/file/jackson-databind-2.17.2-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/jackson-annotations-2_17_2_http_import/lib++_repo_rules+jackson-annotations-2_17_2_http/file/jackson-annotations-2.17.2-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/util-ui.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/platform-util-io-impl/ide-util-io-impl.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/platform-util-io/ide-util-io.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/instanceContainer/instanceContainer.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/service-container/serviceContainer.abi.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/jcef/lib++_repo_rules+jcef-122_1_9-gd14e051-chromium-122_0_6261_94-api-1_17-251-b2_http/file/jcef-122.1.9-gd14e051-chromium-122.0.6261.94-api-1.17-251-b2-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/statistics/statistics.abi.jar +../lib++_repo_rules+ap-validation-76_http/file/ap-validation-76.jar +../lib++_repo_rules+model-76_http/file/model-76.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/asm/lib++_repo_rules+asm-all-9_6_1_http/file/asm-all-9.6.1-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/jsoup/lib++_repo_rules+jsoup-1_18_1_http/file/jsoup-1.18.1-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/rd-platform-community/rd-community.abi.jar +../lib++_repo_rules+rd-core-2024_3_1_http/file/rd-core-2024.3.1.jar +../lib++_repo_rules+rd-framework-2024_3_1_http/file/rd-framework-2024.3.1.jar +../lib++_repo_rules+rd-swing-2024_3_1_http/file/rd-swing-2024.3.1.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/fastutil-min/lib++_repo_rules+intellij-deps-fastutil-8_5_14-jb1_http/file/intellij-deps-fastutil-8.5.14-jb1-ijar.jar +../lib++_repo_rules+blockmap-1_0_7_http/file/blockmap-1.0.7.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util-class-loader/util-classLoader-hjar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/netty-buffer-4_2_0_RC1_http_import/lib++_repo_rules+netty-buffer-4_2_0_RC1_http/file/netty-buffer-4.2.0.RC1-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/netty-common-4_2_0_RC1_http_import/lib++_repo_rules+netty-common-4_2_0_RC1_http/file/netty-common-4.2.0.RC1-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/progress/progress.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/core-ui/core-ui.abi.jar +../lib++_repo_rules+marketplace-zip-signer-0_1_24_http/file/marketplace-zip-signer-0.1.24.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/caffeine/lib++_repo_rules+caffeine-3_1_8_http/file/caffeine-3.1.8-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/classgraph/lib++_repo_rules+classgraph-4_8_174_http/file/classgraph-4.8.174-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/zip/zip-hjar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/icu4j/lib++_repo_rules+icu4j-73_2_http/file/icu4j-73.2-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/xmlDom/xmlDom.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/ide-core-impl/ide-core-impl.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/ide-core/plugins/ide-core-plugins.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/platform-util-netty/ide-util-netty.abi.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/aalto-xml-1_3_3_http_import/lib++_repo_rules+aalto-xml-1_3_3_http/file/aalto-xml-1.3.3-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/stax2-api-4_2_2_http_import/lib++_repo_rules+stax2-api-4_2_2_http/file/stax2-api-4.2.2-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/jbr-api/lib++_repo_rules+jbr-api-1_0_0_http/file/jbr-api-1.0.0-ijar.jar +../lib++_repo_rules+kotlinx-serialization-json-jvm-1_7_3_http/file/kotlinx-serialization-json-jvm-1.7.3.jar +../lib++_repo_rules+kotlinx-serialization-core-jvm-1_7_3_http/file/kotlinx-serialization-core-jvm-1.7.3.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/jdom/jdom-hjar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/jvm-native-trusted-roots/lib++_repo_rules+jvm-native-trusted-roots-1_0_21_http/file/jvm-native-trusted-roots-1.0.21-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/opentelemetry-sdk-1_45_0_http_import/lib++_repo_rules+opentelemetry-sdk-1_45_0_http/file/opentelemetry-sdk-1.45.0-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/opentelemetry-api-1_45_0_http_import/lib++_repo_rules+opentelemetry-api-1_45_0_http/file/opentelemetry-api-1.45.0-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/opentelemetry-context-1_45_0_http_import/lib++_repo_rules+opentelemetry-context-1_45_0_http/file/opentelemetry-context-1.45.0-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/opentelemetry-sdk-common-1_45_0_http_import/lib++_repo_rules+opentelemetry-sdk-common-1_45_0_http/file/opentelemetry-sdk-common-1.45.0-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/opentelemetry-sdk-trace-1_45_0_http_import/lib++_repo_rules+opentelemetry-sdk-trace-1_45_0_http/file/opentelemetry-sdk-trace-1.45.0-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/opentelemetry-api-incubator-1_45_0-alpha_http_import/lib++_repo_rules+opentelemetry-api-incubator-1_45_0-alpha_http/file/opentelemetry-api-incubator-1.45.0-alpha-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/opentelemetry-sdk-metrics-1_45_0_http_import/lib++_repo_rules+opentelemetry-sdk-metrics-1_45_0_http/file/opentelemetry-sdk-metrics-1.45.0-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/opentelemetry-sdk-logs-1_45_0_http_import/lib++_repo_rules+opentelemetry-sdk-logs-1_45_0_http/file/opentelemetry-sdk-logs-1.45.0-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/opentelemetry-semconv/lib++_repo_rules+opentelemetry-semconv-1_28_0-alpha_http/file/opentelemetry-semconv-1.28.0-alpha-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/diagnostic/telemetry/telemetry.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/diagnostic/diagnostic.abi.jar +../lib++_repo_rules+opentelemetry-extension-kotlin-1_45_0_http/file/opentelemetry-extension-kotlin-1.45.0.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/hdr_histogram/lib++_repo_rules+HdrHistogram-2_2_2_http/file/HdrHistogram-2.2.2-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/code-style-impl/codeStyle-impl.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/text-matching/text-matching-hjar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/platform-impl/rpc/ide-rpc.abi.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/hash4j/lib++_repo_rules+hash4j-0_19_0_http/file/hash4j-0.19.0-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/backend/workspace/workspace.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/diagnostic/startUpPerformanceReporter/startUpPerformanceReporter.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/diagnostic/telemetry-impl/telemetry-impl.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/diagnostic/telemetry.exporters/telemetry-exporters.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/diagnostic/telemetry/rt/diagnostic-telemetry-rt-hjar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/ijent/ijent.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/eel/eel.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/backend/observation/observation.abi.jar +../lib++_repo_rules+pty4j-0_13_1_http/file/pty4j-0.13.1.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/settings/settings.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/coroutines/coroutines.abi.jar +../lib++_repo_rules+rwmutex-idea-0_0_7_http/file/rwmutex-idea-0.0.7.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/lz4-java/lib++_repo_rules+lz4-java-1_8_0_http/file/lz4-java-1.8.0-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/ml-api/ml.abi.jar +../lib++_repo_rules+extension-34_http/file/extension-34.jar +../lib++_repo_rules+kotlinx-collections-immutable-jvm-0_3_8_http/file/kotlinx-collections-immutable-jvm-0.3.8.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/storages/io-storages-hjar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/core-nio-fs/libcore-nio-fs-hjar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/ijent/impl/community-impl.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/ijent/buildConstants/community-buildConstants.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/kernel/shared/kernel.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/kernel/rpc/rpc.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/fleet/rpc/rpc.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/fleet/kernel/kernel.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/fleet/rhizomedb/rhizomedb.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/fleet/util/core/fleet-util-core.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/fleet/util/logging/api/fleet-util-logging-api.abi.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/slf4j-api/lib++_repo_rules+slf4j-api-2_0_13_http/file/slf4j-api-2.0.13-ijar.jar +../lib++_repo_rules+kotlinx-coroutines-slf4j-1_8_0-intellij-11_http/file/kotlinx-coroutines-slf4j-1.8.0-intellij-11.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/project/shared/project.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/jbr/jbr-hjar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/ui.jcef/ui-jcef.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/eel-provider/eel-provider.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/platform-impl/ui/ide-ui.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/buildData/buildData.abi.jar +../lib++_repo_rules+annotations-java5-24_0_0_http/file/annotations-java5-24.0.0.jar +../lib++_repo_rules+kotlinx-coroutines-debug-1_8_0-intellij-11_http/file/kotlinx-coroutines-debug-1.8.0-intellij-11.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/jaxen/lib++_repo_rules+jaxen-1_2_0_http/file/jaxen-1.2.0-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/log4_j/lib++_repo_rules+log4j-over-slf4j-1_7_36_http/file/log4j-over-slf4j-1.7.36-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/rt-java8/rt-java8-hjar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/commons-compress/lib++_repo_rules+commons-compress-1_26_1_http/file/commons-compress-1.26.1-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/troveCompileOnly/troveCompileOnly-hjar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/kryo5/lib++_repo_rules+kryo5-5_6_0_http/file/kryo5-5.6.0-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/jcip/lib++_repo_rules+jcip-annotations-1_0_http/file/jcip-annotations-1.0-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/mvstore/lib++_repo_rules+h2-mvstore-2_3_232_http/file/h2-mvstore-2.3.232-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/jsvg/lib++_repo_rules+jsvg-1_3_0-jb_8_http/file/jsvg-1.3.0-jb.8-ijar.jar +../lib++_repo_rules+kotlinx-serialization-protobuf-jvm-1_7_3_http/file/kotlinx-serialization-protobuf-jvm-1.7.3.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/automaton/lib++_repo_rules+automaton-1_12-4_http/file/automaton-1.12-4-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/fleet/reporting/api/fleet-reporting-api.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/fleet/preferences/preferences.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/fleet/util/os/fleet-util-os-hjar.jar +../lib++_repo_rules+expects-compiler-plugin-2_1_0-0_3_http/file/expects-compiler-plugin-2.1.0-0.3.jar +../lib++_repo_rules+rpc-compiler-plugin-2_1_0-0_4_http/file/rpc-compiler-plugin-2.1.0-0.4.jar +../lib++_repo_rules+rhizomedb-compiler-plugin-2_1_0-0_2_http/file/rhizomedb-compiler-plugin-2.1.0-0.2.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/usageView/usageView.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/statistics/uploader/uploader.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/statistics/config/config.abi.jar +../lib++_repo_rules+jackson-module-kotlin-2_17_2_http/file/jackson-module-kotlin-2.17.2.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/runtime/product/product.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/runtime/repository/repository-hjar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/indexing-impl/indexing-impl.abi.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/nanoxml/nanoxml-hjar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/proxy-vole-1_1_6_http_import/lib++_repo_rules+proxy-vole-1_1_6_http/file/proxy-vole-1.1.6-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/delight-rhino-sandbox-0_0_17_http_import/lib++_repo_rules+delight-rhino-sandbox-0_0_17_http/file/delight-rhino-sandbox-0.0.17-ijar.jar +../lib++_repo_rules+rd-text-2024_3_1_http/file/rd-text-2024.3.1.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/opentelemetry-exporter-otlp-common-1_45_0_http_import/lib++_repo_rules+opentelemetry-exporter-otlp-common-1_45_0_http/file/opentelemetry-exporter-otlp-common-1.45.0-ijar.jar +bazel-out/lib+/darwin_arm64-fastbuild/bin/_ijar/opentelemetry-exporter-common-1_45_0_http_import/lib++_repo_rules+opentelemetry-exporter-common-1_45_0_http/file/opentelemetry-exporter-common-1.45.0-ijar.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/http/http.abi.jar +../lib++_repo_rules+ktor-client-core-jvm-2_3_13_http/file/ktor-client-core-jvm-2.3.13.jar +../lib++_repo_rules+ktor-http-jvm-2_3_13_http/file/ktor-http-jvm-2.3.13.jar +../lib++_repo_rules+ktor-utils-jvm-2_3_13_http/file/ktor-utils-jvm-2.3.13.jar +../lib++_repo_rules+ktor-io-jvm-2_3_13_http/file/ktor-io-jvm-2.3.13.jar +../lib++_repo_rules+ktor-events-jvm-2_3_13_http/file/ktor-events-jvm-2.3.13.jar +../lib++_repo_rules+ktor-websocket-serialization-jvm-2_3_13_http/file/ktor-websocket-serialization-jvm-2.3.13.jar +../lib++_repo_rules+ktor-serialization-jvm-2_3_13_http/file/ktor-serialization-jvm-2.3.13.jar +../lib++_repo_rules+ktor-websockets-jvm-2_3_13_http/file/ktor-websockets-jvm-2.3.13.jar +../lib++_repo_rules+ktor-client-java-jvm-2_3_13_http/file/ktor-client-java-jvm-2.3.13.jar +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/eel-impl/eel-impl.abi.jar +--deps_artifacts +bazel-out/community+/darwin_arm64-fastbuild/bin/jps/model-impl/model-impl.jdeps +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/observable/ide-observable-kt.jdeps +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/rd-platform-community/rd-community-kt.jdeps +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util-class-loader/util-classLoader.jdeps +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/zip/zip.jdeps +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/xmlDom/xmlDom-kt.jdeps +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/jdom/jdom.jdeps +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/text-matching/text-matching.jdeps +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/platform-impl/rpc/ide-rpc-kt.jdeps +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/diagnostic/startUpPerformanceReporter/startUpPerformanceReporter-kt.jdeps +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/backend/observation/observation-kt.jdeps +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/ml-api/ml-kt.jdeps +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/util/storages/io-storages.jdeps +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/core-nio-fs/libcore-nio-fs.jdeps +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/project/shared/project-kt.jdeps +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/jbr/jbr.jdeps +bazel-out/community+/darwin_arm64-fastbuild/bin/fleet/util/core/fleet-util-core-kt.jdeps +bazel-out/community+/darwin_arm64-fastbuild/bin/platform/buildData/buildData-kt.jdeps +--plugin-id +org.jetbrains.kotlin.kotlin-serialization-compiler-plugin +--plugin-classpath +""" \ No newline at end of file diff --git a/build/jvm-rules/src/kotlin-builder/BUILD.bazel b/build/jvm-rules/src/kotlin-builder/BUILD.bazel index 80b960ebe1f9..f3b8fccfc50a 100644 --- a/build/jvm-rules/src/kotlin-builder/BUILD.bazel +++ b/build/jvm-rules/src/kotlin-builder/BUILD.bazel @@ -10,6 +10,7 @@ kt_jvm_library( "//:kotlin-build-tools-impl", "//src/worker-framework", "//src/jar", + "//src/compiler-util", "//zip:build-zip", # we parse `jdeps` to support reduced classpath building and checking for unused deps # (both features are disabled by default for now) diff --git a/build/jvm-rules/src/kotlin-builder/CompilationArgs.kt b/build/jvm-rules/src/kotlin-builder/CompilationArgs.kt deleted file mode 100644 index 68054b9e7139..000000000000 --- a/build/jvm-rules/src/kotlin-builder/CompilationArgs.kt +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2020 The Bazel Authors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.jetbrains.bazel.jvm.kotlin - -/** - * CompilationArgs collects the arguments for executing the Kotlin compiler. - */ -class CompilationArgs( - val args: MutableList = mutableListOf(), -) { - interface SetFlag { - fun flag( - name: String, - value: String, - ): SetFlag - } - - //fun plugin(p: CompilerPlugin): CompilationArgs = plugin(p) {} - - fun plugin( - id: String, - flagArgs: SetFlag.() -> Unit, - ) { - object : SetFlag { - override fun flag( - name: String, - value: String, - ): SetFlag { - args.add("-P") - args.add("plugin:$id:$name=$value") - return this - } - }.flagArgs() - } - - operator fun plus(other: CompilationArgs): CompilationArgs { - return CompilationArgs((args.asSequence() + other.args.asSequence()).toMutableList()) - } - - fun value(value: String): CompilationArgs { - args.add(value) - return this - } - - fun append(compilationArgs: CompilationArgs): CompilationArgs { - args.addAll(compilationArgs.args) - return this - } - - fun flag(value: String): CompilationArgs { - args.add(value) - return this - } - - fun flag( - key: String, - value: () -> String, - ): CompilationArgs { - args.add(key) - args.add(value()) - return this - } - - fun flag( - flag: String, - value: String, - ): CompilationArgs { - args.add(flag) - args.add(value) - return this - } - - fun values(values: Collection): CompilationArgs { - args.addAll(values) - return this - } - - fun xFlag( - flag: String, - value: String, - ): CompilationArgs { - args.add("-X$flag=$value") - return this - } - - fun toList(): List = args.toList() -} diff --git a/build/jvm-rules/src/kotlin-builder/KotlinBuilder.kt b/build/jvm-rules/src/kotlin-builder/KotlinBuilder.kt index 55be4a28b821..09f388056e2a 100644 --- a/build/jvm-rules/src/kotlin-builder/KotlinBuilder.kt +++ b/build/jvm-rules/src/kotlin-builder/KotlinBuilder.kt @@ -5,11 +5,7 @@ import com.google.devtools.build.lib.worker.WorkerProtocol import org.jetbrains.bazel.jvm.WorkRequestExecutor import org.jetbrains.bazel.jvm.processRequests import java.io.Writer -import java.nio.file.Files import java.nio.file.Path -import java.util.regex.Pattern - -private val FLAG_FILE_RE = Pattern.compile("""^--flagfile=((.*)-(\d+).params)$""").toRegex() object KotlinBuildWorker : WorkRequestExecutor { @JvmStatic @@ -23,7 +19,7 @@ object KotlinBuildWorker : WorkRequestExecutor { .filter { it.path.endsWith(".kt") || it.path.endsWith(".java") } .map { baseDir.resolve(it.path) } .toList() - return buildKotlin(workingDir = baseDir, args = request.argumentsList, out = writer, sources = sources) + return buildKotlin(workingDir = baseDir, args = parseArgs(request.argumentsList), out = writer, sources = sources) } } @@ -32,32 +28,21 @@ object KotlinBuildWorker : WorkRequestExecutor { private suspend fun buildKotlin( workingDir: Path, out: Writer, - args: List, + args: ArgMap, sources: List, ): Int { - check(args.isNotEmpty()) { - "expected at least a single arg got: ${args.joinToString(" ")}" - } - - val argMap = createArgMap( - FLAG_FILE_RE.matchEntire(args[0])?.groups?.get(1)?.let { - Files.readAllLines(Path.of(it.value)) - } ?: args, - enumClass = KotlinBuilderFlags::class.java, - ) - - val compileContext = TraceHelper(isTracing = argMap.boolFlag(KotlinBuilderFlags.TRACE)) + val compileContext = TraceHelper(isTracing = args.boolFlag(JvmBuilderFlags.TRACE)) if (compileContext.isTracing) { - out.appendLine("Worker Task Args: $argMap") + out.appendLine("Worker Task Args: $args") } - val info = createBuildInfo(argMap) + val info = createBuildInfo(args) when (info.platform) { Platform.JVM -> { compileContext.execute("compile classes") { val code = compileContext.execute("kotlinc") { - compileKotlinForJvm(args = argMap, context = compileContext, sources = sources, out = out, workingDir = workingDir, info = info) + compileKotlinForJvm(args = args, context = compileContext, sources = sources, out = out, workingDir = workingDir, info = info) } if (code != 0) { return code @@ -71,21 +56,21 @@ private suspend fun buildKotlin( return 0 } -private fun createBuildInfo(argMap: ArgMap): CompilationTaskInfo { - val ruleKind = argMap.mandatorySingle(KotlinBuilderFlags.RULE_KIND).split('_') +private fun createBuildInfo(argMap: ArgMap): CompilationTaskInfo { + val ruleKind = argMap.mandatorySingle(JvmBuilderFlags.RULE_KIND).split('_') check(ruleKind.size == 3 && ruleKind[0] == "kt") { "invalid rule kind $ruleKind" } return CompilationTaskInfo( - label = argMap.mandatorySingle(KotlinBuilderFlags.TARGET_LABEL), + label = argMap.mandatorySingle(JvmBuilderFlags.TARGET_LABEL), ruleKind = checkNotNull(RuleKind.valueOf(ruleKind[2].uppercase())) { "unrecognized rule kind ${ruleKind[2]}" }, platform = checkNotNull(Platform.valueOf(ruleKind[1].uppercase())) { "unrecognized platform ${ruleKind[1]}" }, - moduleName = argMap.mandatorySingle(KotlinBuilderFlags.KOTLIN_MODULE_NAME).also { + moduleName = argMap.mandatorySingle(JvmBuilderFlags.KOTLIN_MODULE_NAME).also { check(it.isNotBlank()) { "--kotlin_module_name should not be blank" } }, ) diff --git a/build/jvm-rules/src/kotlin-builder/KotlinBuilderFlags.kt b/build/jvm-rules/src/kotlin-builder/KotlinBuilderFlags.kt deleted file mode 100644 index 43e0cccf926b..000000000000 --- a/build/jvm-rules/src/kotlin-builder/KotlinBuilderFlags.kt +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package org.jetbrains.bazel.jvm.kotlin - -internal enum class KotlinBuilderFlags { - TARGET_LABEL, - CLASSPATH, - DIRECT_DEPENDENCIES, - DEPS_ARTIFACTS, - - PLUGIN_ID, - PLUGIN_CLASSPATH, - - OUTPUT, - RULE_KIND, - KOTLIN_MODULE_NAME, - - API_VERSION, - LANGUAGE_VERSION, - JVM_TARGET, - - OPT_IN, - ALLOW_KOTLIN_PACKAGE, - LAMBDAS, - JVM_DEFAULT, - INLINE_CLASSES, - CONTEXT_RECEIVERS, - - WARN, - - KOTLIN_OUTPUT_SRCJAR, - FRIEND_PATHS, - KOTLIN_OUTPUT_JDEPS, - TRACE, - ABI_JAR, - STRICT_KOTLIN_DEPS, - REDUCED_CLASSPATH_MODE, -} \ No newline at end of file diff --git a/build/jvm-rules/src/kotlin-builder/KotlinJvmTaskExecutor.kt b/build/jvm-rules/src/kotlin-builder/KotlinJvmTaskExecutor.kt index 829fd5d7ffda..9db94c7a481c 100644 --- a/build/jvm-rules/src/kotlin-builder/KotlinJvmTaskExecutor.kt +++ b/build/jvm-rules/src/kotlin-builder/KotlinJvmTaskExecutor.kt @@ -7,7 +7,7 @@ import com.intellij.openapi.util.Disposer import kotlinx.coroutines.ensureActive import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.ExitCode -import org.jetbrains.kotlin.cli.common.arguments.* +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.cli.common.messages.* import org.jetbrains.kotlin.cli.common.setupCommonArguments import org.jetbrains.kotlin.cli.jvm.compiler.configurePlugins @@ -19,13 +19,12 @@ import org.jetbrains.kotlin.metadata.deserialization.MetadataVersion import java.io.BufferedInputStream import java.io.File import java.io.Writer -import java.lang.reflect.Field import java.nio.file.Files import java.nio.file.Path import kotlin.coroutines.coroutineContext internal suspend fun compileKotlinForJvm( - args: ArgMap, + args: ArgMap, context: TraceHelper, sources: List, out: Writer, @@ -33,51 +32,12 @@ internal suspend fun compileKotlinForJvm( info: CompilationTaskInfo, ): Int { val kotlinArgs = K2JVMCompilerArguments() - kotlinArgs.noStdlib = true + configureCommonCompilerArgs(kotlinArgs, args, workingDir) kotlinArgs.classpath = createClasspath(args, workingDir) - kotlinArgs.apiVersion = args.optionalSingle(KotlinBuilderFlags.API_VERSION) - kotlinArgs.languageVersion = args.optionalSingle(KotlinBuilderFlags.LANGUAGE_VERSION) - // jdkRelease leads to some strange compilation failures like "cannot access class 'Map.Entry'" - kotlinArgs.jvmTarget = args.mandatorySingle(KotlinBuilderFlags.JVM_TARGET).let { if (it == "8") "1.8" else it } kotlinArgs.moduleName = info.moduleName - kotlinArgs.disableStandardScript = true - // kotlin bug - not compatible with a new X compiler-plugin syntax - //compilationArgs.disableDefaultScriptingPlugin = true - args.optional(KotlinBuilderFlags.FRIEND_PATHS)?.let { value -> - kotlinArgs.friendPaths = value.map { workingDir.resolve(it).toString() }.toTypedArray() - } - - kotlinArgs.destination = workingDir.resolve(args.mandatorySingle(KotlinBuilderFlags.OUTPUT)).toString() - - args.optional(KotlinBuilderFlags.OPT_IN)?.let { - kotlinArgs.optIn = it.toTypedArray() - } - val allowKotlinPackage = args.boolFlag(KotlinBuilderFlags.ALLOW_KOTLIN_PACKAGE) - if (allowKotlinPackage) { - kotlinArgs.allowKotlinPackage = true - } - - args.optionalSingle(KotlinBuilderFlags.LAMBDAS)?.let { - kotlinArgs.lambdas = it - } - args.optionalSingle(KotlinBuilderFlags.JVM_DEFAULT)?.let { - kotlinArgs.jvmDefault = it - } - if (args.boolFlag(KotlinBuilderFlags.INLINE_CLASSES)) { - kotlinArgs.inlineClasses = true - } - if (args.boolFlag(KotlinBuilderFlags.CONTEXT_RECEIVERS)) { - kotlinArgs.contextReceivers = true - } - args.optionalSingle(KotlinBuilderFlags.WARN)?.let { - when (it) { - "off" -> kotlinArgs.suppressWarnings = true - "error" -> kotlinArgs.allWarningsAsErrors = true - else -> throw IllegalArgumentException("unsupported kotlinc warning option: $it") - } - } + kotlinArgs.destination = workingDir.resolve(args.mandatorySingle(JvmBuilderFlags.OUTPUT)).toString() val pluginConfigurations = configurePlugins(args = args, workingDir = workingDir, label = info.label) @@ -103,7 +63,7 @@ internal suspend fun compileKotlinForJvm( } config.setupCommonArguments(kotlinArgs) { version -> MetadataVersion(*version) } config.setupJvmSpecificArguments(kotlinArgs) - if (allowKotlinPackage) { + if (args.boolFlag(JvmBuilderFlags.ALLOW_KOTLIN_PACKAGE)) { config.put(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE, true) } @@ -122,22 +82,24 @@ internal suspend fun compileKotlinForJvm( if (collector.hasErrors()) { code = ExitCode.COMPILATION_ERROR.code } - if (code != 0 || context.isTracing) { - if (!context.isTracing) { - printOptions() + if (code == 0 && !context.isTracing) { + return 0 + } + + if (!context.isTracing) { + printOptions() + } + + val renderer = object : PlainTextMessageRenderer(/* colorEnabled = */ true) { + override fun getPath(location: CompilerMessageSourceLocation): String { + return workingDir.relativize(Path.of(location.path)).toString() } - val renderer = object : PlainTextMessageRenderer(/* colorEnabled = */ true) { - override fun getPath(location: CompilerMessageSourceLocation): String { - return workingDir.relativize(Path.of(location.path)).toString() - } - - override fun getName(): String = "RelativePath" - } - wrapOutput(out, info.label, classifier = "K2JVM Compiler Messages") { - for (entry in messageCollector.entries) { - out.appendLine(renderer.render(entry.severity, entry.message, entry.location)) - } + override fun getName(): String = "RelativePath" + } + wrapOutput(out, info.label, classifier = "K2JVM Compiler Messages") { + for (entry in messageCollector.entries) { + out.appendLine(renderer.render(entry.severity, entry.message, entry.location)) } } return code @@ -149,100 +111,14 @@ private inline fun wrapOutput(out: Writer, label: String, classifier: String, ta out.appendLine("\u001B[1m=============== END of $classifier ($label) ===============\u001B[0m") } -private fun getAllFields(): Sequence { - return sequence { - var aClass: Class<*>? = K2JVMCompilerArguments::class.java - while (aClass != null) { - yieldAll(aClass.declaredFields.asSequence()) - aClass = aClass.superclass.takeIf { it != Any::class.java } - } - } -} - -// we do not have kotlin reflection -private fun toArgumentStrings( - thisArgs: T, - shortArgumentKeys: Boolean = false, - compactArgumentValues: Boolean = true, -): List { - val result = ArrayList() - val defaultArguments = K2JVMCompilerArguments() - for (field in getAllFields()) { - val argAnnotation = field.getAnnotation(Argument::class.java) ?: continue - field.setAccessible(true) - val rawPropertyValue = field.get(thisArgs) - val rawDefaultValue = field.get(defaultArguments) - - /* Default value can be omitted */ - if (rawPropertyValue == rawDefaultValue) { - continue - } - - val argumentStringValues = when { - field.type == java.lang.Boolean.TYPE -> { - listOf(rawPropertyValue?.toString() ?: false.toString()) - } - field.type.isArray -> { - getArgumentStringValue( - argAnnotation = argAnnotation, - values = rawPropertyValue as Array<*>?, - compactArgValues = compactArgumentValues, - ) - } - field.type == java.util.List::class.java -> { - getArgumentStringValue( - argAnnotation = argAnnotation, - values = (rawPropertyValue as List<*>?)?.toTypedArray(), - compactArgValues = compactArgumentValues, - ) - } - else -> listOf(rawPropertyValue.toString()) - } - - val argumentName = if (shortArgumentKeys && argAnnotation.shortName.isNotEmpty()) argAnnotation.shortName else argAnnotation.value - - for (argumentStringValue in argumentStringValues) { - when { - /* We can just enable the flag by passing the argument name like -myFlag: Value not required */ - rawPropertyValue is Boolean && rawPropertyValue -> { - result.add(argumentName) - } - - /* Advanced (e.g. -X arguments) or boolean properties need to be passed using the '=' */ - argAnnotation.isAdvanced || field.type == java.lang.Boolean.TYPE -> { - result.add("$argumentName=$argumentStringValue") - } - - else -> { - result.add(argumentName) - result.add(argumentStringValue) - } - } - } +private fun createClasspath(args: ArgMap, baseDir: Path): String { + if (!args.boolFlag(JvmBuilderFlags.REDUCED_CLASSPATH_MODE)) { + return args.mandatory(JvmBuilderFlags.CLASSPATH).joinToString(File.pathSeparator) { baseDir.resolve(it).normalize().toString() } } - result.addAll(thisArgs.freeArgs) - result.addAll(thisArgs.internalArguments.map { it.stringRepresentation }) - return result -} + val directDependencies = args.mandatory(JvmBuilderFlags.DIRECT_DEPENDENCIES) -private fun getArgumentStringValue(argAnnotation: Argument, values: Array<*>?, compactArgValues: Boolean): List { - if (values.isNullOrEmpty()) { - return emptyList() - } - - val delimiter = argAnnotation.resolvedDelimiter - return if (delimiter.isNullOrEmpty() || !compactArgValues) values.map { it.toString() } else listOf(values.joinToString(delimiter)) -} - -private fun createClasspath(args: ArgMap, baseDir: Path): String { - if (!args.boolFlag(KotlinBuilderFlags.REDUCED_CLASSPATH_MODE)) { - return args.mandatory(KotlinBuilderFlags.CLASSPATH).joinToString(File.pathSeparator) { baseDir.resolve(it).normalize().toString() } - } - - val directDependencies = args.mandatory(KotlinBuilderFlags.DIRECT_DEPENDENCIES) - - val depsArtifacts = args.optional(KotlinBuilderFlags.DEPS_ARTIFACTS) ?: return directDependencies.joinToString(File.pathSeparator) + val depsArtifacts = args.optional(JvmBuilderFlags.DEPS_ARTIFACTS) ?: return directDependencies.joinToString(File.pathSeparator) val transitiveDepsForCompile = LinkedHashSet() for (jdepsPath in depsArtifacts) { BufferedInputStream(Files.newInputStream(Path.of(jdepsPath))).use { diff --git a/build/jvm-rules/src/kotlin-builder/compilation/plugins.kt b/build/jvm-rules/src/kotlin-builder/compilation/plugins.kt index 22772e2709b7..083cfe6d9b8a 100644 --- a/build/jvm-rules/src/kotlin-builder/compilation/plugins.kt +++ b/build/jvm-rules/src/kotlin-builder/compilation/plugins.kt @@ -8,7 +8,7 @@ import dev.drewhamilton.poko.PokoCompilerPluginRegistrar import io.bazel.kotlin.plugin.jdeps.JdepsGenCommandLineProcessor import io.bazel.kotlin.plugin.jdeps.JdepsGenComponentRegistrar import org.jetbrains.bazel.jvm.kotlin.ArgMap -import org.jetbrains.bazel.jvm.kotlin.KotlinBuilderFlags +import org.jetbrains.bazel.jvm.kotlin.JvmBuilderFlags import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser.RegisteredPluginInfo import org.jetbrains.kotlin.compiler.plugin.CliOptionValue import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi @@ -28,7 +28,7 @@ private fun cliOptionValue(name: String, value: String) = CliOptionValue(pluginI @OptIn(ExperimentalCompilerApi::class) internal fun configurePlugins( - args: ArgMap, + args: ArgMap, workingDir: Path, label: String, ): List { @@ -39,7 +39,7 @@ internal fun configurePlugins( } // put user plugins first - val plugins = args.optionalList(KotlinBuilderFlags.PLUGIN_ID).zip(args.optionalList(KotlinBuilderFlags.PLUGIN_CLASSPATH)) + val plugins = args.optionalList(JvmBuilderFlags.PLUGIN_ID).zip(args.optionalList(JvmBuilderFlags.PLUGIN_CLASSPATH)) for ((id, paths) in plugins) { val classpath = if (paths.isBlank()) { emptyList() @@ -85,12 +85,12 @@ internal fun configurePlugins( } } - args.optionalSingle(KotlinBuilderFlags.KOTLIN_OUTPUT_JDEPS)?.let { workingDir.resolve(it) }?.let { jdeps -> + args.optionalSingle(JvmBuilderFlags.KOTLIN_OUTPUT_JDEPS)?.let { workingDir.resolve(it) }?.let { jdeps -> val options = mutableListOf( cliOptionValue("output", jdeps.toString()), cliOptionValue("target_label", label), ) - args.optionalSingle(KotlinBuilderFlags.STRICT_KOTLIN_DEPS)?.let { + args.optionalSingle(JvmBuilderFlags.STRICT_KOTLIN_DEPS)?.let { options.add(cliOptionValue("strict_kotlin_deps", it)) } addPlugin(RegisteredPluginInfo( @@ -101,7 +101,7 @@ internal fun configurePlugins( )) } - args.optionalSingle(KotlinBuilderFlags.ABI_JAR)?.let { workingDir.resolve(it) }?.let { abiJar -> + args.optionalSingle(JvmBuilderFlags.ABI_JAR)?.let { workingDir.resolve(it) }?.let { abiJar -> addPlugin(RegisteredPluginInfo( componentRegistrar = null, compilerPluginRegistrar = JvmAbiComponentRegistrar(), diff --git a/build/jvm-rules/src/kotlin-builder/kotlin-arg-util.kt b/build/jvm-rules/src/kotlin-builder/kotlin-arg-util.kt new file mode 100644 index 000000000000..0d5f52c74902 --- /dev/null +++ b/build/jvm-rules/src/kotlin-builder/kotlin-arg-util.kt @@ -0,0 +1,88 @@ +package org.jetbrains.bazel.jvm.kotlin + +import org.jetbrains.kotlin.cli.common.arguments.* +import java.lang.reflect.Field + +// we do not have kotlin reflection +internal fun toArgumentStrings( + thisArgs: T, + shortArgumentKeys: Boolean = false, + compactArgumentValues: Boolean = true, +): List { + val result = ArrayList() + val defaultArguments = K2JVMCompilerArguments() + for (field in getAllFields()) { + val argAnnotation = field.getAnnotation(Argument::class.java) ?: continue + field.setAccessible(true) + val rawPropertyValue = field.get(thisArgs) + val rawDefaultValue = field.get(defaultArguments) + if (rawPropertyValue == rawDefaultValue) { + continue + } + + val argumentStringValues = when { + field.type == java.lang.Boolean.TYPE -> { + listOf(rawPropertyValue?.toString() ?: false.toString()) + } + field.type.isArray -> { + getArgumentStringValue( + argAnnotation = argAnnotation, + values = rawPropertyValue as Array<*>?, + compactArgValues = compactArgumentValues, + ) + } + field.type == java.util.List::class.java -> { + getArgumentStringValue( + argAnnotation = argAnnotation, + values = (rawPropertyValue as List<*>?)?.toTypedArray(), + compactArgValues = compactArgumentValues, + ) + } + else -> listOf(rawPropertyValue.toString()) + } + + val argumentName = if (shortArgumentKeys && argAnnotation.shortName.isNotEmpty()) argAnnotation.shortName else argAnnotation.value + + for (argumentStringValue in argumentStringValues) { + when { + /* We can just enable the flag by passing the argument name like -myFlag: Value not required */ + rawPropertyValue is Boolean && rawPropertyValue -> { + result.add(argumentName) + } + + /* Advanced (e.g. -X arguments) or boolean properties need to be passed using the '=' */ + argAnnotation.isAdvanced || field.type == java.lang.Boolean.TYPE -> { + result.add("$argumentName=$argumentStringValue") + } + + else -> { + result.add(argumentName) + result.add(argumentStringValue) + } + } + } + } + + result.addAll(thisArgs.freeArgs) + result.addAll(thisArgs.internalArguments.map { it.stringRepresentation }) + return result +} + +private fun getAllFields(): Sequence { + return sequence { + var aClass: Class<*>? = K2JVMCompilerArguments::class.java + while (aClass != null) { + yieldAll(aClass.declaredFields.asSequence()) + aClass = aClass.superclass.takeIf { it != Any::class.java } + } + } +} + +private fun getArgumentStringValue(argAnnotation: Argument, values: Array<*>?, compactArgValues: Boolean): List { + if (values.isNullOrEmpty()) { + return emptyList() + } + + val delimiter = argAnnotation.resolvedDelimiter + return if (delimiter.isNullOrEmpty() || !compactArgValues) values.map { it.toString() } else listOf(values.joinToString(delimiter)) +} \ No newline at end of file diff --git a/build/jvm-rules/src/kotlin-builder/task.kt b/build/jvm-rules/src/kotlin-builder/task.kt index 54defef9686c..a446281f4a65 100644 --- a/build/jvm-rules/src/kotlin-builder/task.kt +++ b/build/jvm-rules/src/kotlin-builder/task.kt @@ -20,5 +20,5 @@ data class CompilationTaskInfo( ) internal data class JvmCompilationTask( - @JvmField val args: ArgMap, + @JvmField val args: ArgMap, ) \ No newline at end of file diff --git a/build/jvm-rules/src/kotlin-plugins/abi/BUILD.bazel b/build/jvm-rules/src/kotlin-plugins/abi/BUILD.bazel index 680c090cb12a..91cb743109f7 100644 --- a/build/jvm-rules/src/kotlin-plugins/abi/BUILD.bazel +++ b/build/jvm-rules/src/kotlin-plugins/abi/BUILD.bazel @@ -1,5 +1,4 @@ load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_import", "kt_jvm_library") -load("//:jvm.bzl", "jvm_resources") kt_jvm_library( name = "abi", diff --git a/build/jvm-rules/src/kotlin-plugins/jdeps/BUILD.bazel b/build/jvm-rules/src/kotlin-plugins/jdeps/BUILD.bazel index 80696ca72332..7295384fe919 100644 --- a/build/jvm-rules/src/kotlin-plugins/jdeps/BUILD.bazel +++ b/build/jvm-rules/src/kotlin-plugins/jdeps/BUILD.bazel @@ -1,5 +1,4 @@ load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_import", "kt_jvm_library") -load("//:jvm.bzl", "jvm_resources") kt_jvm_library( name = "jdeps", diff --git a/java/java-impl/BUILD.bazel b/java/java-impl/BUILD.bazel index 8fa5781cef92..8f7ed686c470 100644 --- a/java/java-impl/BUILD.bazel +++ b/java/java-impl/BUILD.bazel @@ -71,6 +71,8 @@ jvm_library( "//platform/eel", "//platform/eel-impl", "//platform/eel-provider", + "//platform/bookmarks", + "//platform/todo", ], exports = [ "//platform/lang-impl", diff --git a/java/java-tests/BUILD.bazel b/java/java-tests/BUILD.bazel index 7d69260c412d..e7a5646c8c92 100644 --- a/java/java-tests/BUILD.bazel +++ b/java/java-tests/BUILD.bazel @@ -112,6 +112,7 @@ jvm_library( "//java/unscramble", "@lib//:asm", "//plugins/gradle", + "//platform/todo", ], runtime_deps = [ "//community-resources:customization", diff --git a/platform/bookmarks/BUILD.bazel b/platform/bookmarks/BUILD.bazel index 88689b597dbd..684bf535e05a 100644 --- a/platform/bookmarks/BUILD.bazel +++ b/platform/bookmarks/BUILD.bazel @@ -20,7 +20,14 @@ jvm_library( "@lib//:kotlinx-serialization-json", "//platform/project/shared:project", "//platform/platform-impl:ide-impl", + "//platform/lang-api:lang", + "//platform/favoritesTreeView:ide-favoritesTreeView", + "//platform/core-ui", + "//platform/lang-impl", + "//platform/util/jdom", + "//platform/editor-ui-ex:editor-ex", ], + exports = ["//platform/favoritesTreeView:ide-favoritesTreeView"], runtime_deps = [":bookmarks_resources"] ) ### auto-generated section `build intellij.platform.bookmarks` end \ No newline at end of file diff --git a/platform/build-scripts/bazel/src/org/jetbrains/intellij/build/bazel/JpsModuleToBazel.kt b/platform/build-scripts/bazel/src/org/jetbrains/intellij/build/bazel/JpsModuleToBazel.kt index b8f240ee90a4..57220e0106fe 100644 --- a/platform/build-scripts/bazel/src/org/jetbrains/intellij/build/bazel/JpsModuleToBazel.kt +++ b/platform/build-scripts/bazel/src/org/jetbrains/intellij/build/bazel/JpsModuleToBazel.kt @@ -58,7 +58,6 @@ internal class JpsModuleToBazel { val ultimateTargets = ultimateFiles.keys .sorted() .map { projectDir.relativize(it).invariantSeparatorsPathString } - .filter { !it.startsWith("rider/test/cases-supplementary") } .joinToString("\n") { "//$it:all" } diff --git a/platform/icons/BUILD.bazel b/platform/icons/BUILD.bazel index 138872e4b29e..8cbd5dccdea4 100644 --- a/platform/icons/BUILD.bazel +++ b/platform/icons/BUILD.bazel @@ -4,6 +4,12 @@ load("@rules_jvm//:jvm.bzl", "jvm_resources") jvm_resources( name = "icons_resources", + files = glob(["compatibilityResources/**/*"]), + strip_prefix = "compatibilityResources" +) + +jvm_resources( + name = "icons_resources_1", files = glob(["src/**/*"]), strip_prefix = "src" ) @@ -11,6 +17,9 @@ jvm_resources( java_library( name = "icons", visibility = ["//visibility:public"], - runtime_deps = [":icons_resources"] + runtime_deps = [ + ":icons_resources", + ":icons_resources_1", + ] ) ### auto-generated section `build intellij.platform.icons` end \ No newline at end of file diff --git a/platform/lang-impl/BUILD.bazel b/platform/lang-impl/BUILD.bazel index 46eb94938709..af4e4561d376 100644 --- a/platform/lang-impl/BUILD.bazel +++ b/platform/lang-impl/BUILD.bazel @@ -108,7 +108,6 @@ jvm_library( "//platform/eel", "//platform/eel-impl", "//platform/eel-provider", - "//platform/favoritesTreeView:ide-favoritesTreeView", "//platform/foldings", ], exports = [ @@ -118,7 +117,6 @@ jvm_library( "//platform/analysis-impl", "//platform/structure-view-impl:structureView-impl", "//platform/util", - "//platform/favoritesTreeView:ide-favoritesTreeView", "//platform/foldings", ], runtime_deps = [":lang-impl_resources"] diff --git a/platform/main/intellij.platform.main/BUILD.bazel b/platform/main/intellij.platform.main/BUILD.bazel index bdd12c64a56b..8a424a344cfd 100644 --- a/platform/main/intellij.platform.main/BUILD.bazel +++ b/platform/main/intellij.platform.main/BUILD.bazel @@ -13,6 +13,7 @@ java_library( "//platform/platform-impl/ui-inspector:ide-ui-inspector", "//platform/inline-completion/shared:inline-completion", "//platform/bookmarks", + "//platform/todo", ] ) ### auto-generated section `build intellij.platform.main` end \ No newline at end of file diff --git a/platform/platform-tests/BUILD.bazel b/platform/platform-tests/BUILD.bazel index a534367b25ae..a01d3af60591 100644 --- a/platform/platform-tests/BUILD.bazel +++ b/platform/platform-tests/BUILD.bazel @@ -128,6 +128,7 @@ jvm_library( "//platform/eel-provider", "@lib//:io-mockk", "@lib//:io-mockk-jvm", + "//platform/bookmarks", ], runtime_deps = [ "//xml/dom-impl", diff --git a/platform/tasks-platform-impl/BUILD.bazel b/platform/tasks-platform-impl/BUILD.bazel index 8442e7e37eed..1ce742052bbb 100644 --- a/platform/tasks-platform-impl/BUILD.bazel +++ b/platform/tasks-platform-impl/BUILD.bazel @@ -29,6 +29,7 @@ jvm_library( "@lib//:kotlinx-coroutines-core", "//platform/util/text-matching", "//platform/statistics", + "//platform/bookmarks", ], exports = ["//platform/statistics"], runtime_deps = [":tasks-impl_resources"] diff --git a/platform/testFramework/BUILD.bazel b/platform/testFramework/BUILD.bazel index fff6fab6c62d..8ba2be48ae1b 100644 --- a/platform/testFramework/BUILD.bazel +++ b/platform/testFramework/BUILD.bazel @@ -49,6 +49,7 @@ jvm_library( "//platform/backend/workspace", "//platform/util/coroutines", "@lib//:assert_j", + "//platform/todo", ], exports = [ "//platform/execution-impl", @@ -125,6 +126,7 @@ jvm_library( "@lib//:assert_j", "//platform/testFramework/junit5", "//platform/testFramework/junit5:junit5_test_lib", + "//platform/todo", ], runtime_deps = [":testFramework_resources"] ) diff --git a/platform/todo/BUILD.bazel b/platform/todo/BUILD.bazel new file mode 100644 index 000000000000..1c94be2ade25 --- /dev/null +++ b/platform/todo/BUILD.bazel @@ -0,0 +1,25 @@ +### auto-generated section `build intellij.platform.todo` start +load("@rules_jvm//:jvm.bzl", "jvm_library", "jvm_resources") + +jvm_resources( + name = "todo_resources", + files = glob(["resources/**/*"]), + strip_prefix = "resources" +) + +jvm_library( + name = "todo", + module_name = "intellij.platform.todo", + visibility = ["//visibility:public"], + srcs = glob(["src/**/*.kt", "src/**/*.java"], allow_empty = True), + deps = [ + "//platform/lang-impl", + "//platform/core-ui", + "@lib//:stream_ex", + "//platform/platform-impl:ide-impl", + "//platform/indexing-impl", + "//platform/editor-ui-ex:editor-ex", + ], + runtime_deps = [":todo_resources"] +) +### auto-generated section `build intellij.platform.todo` end \ No newline at end of file diff --git a/platform/vcs-impl/lang/BUILD.bazel b/platform/vcs-impl/lang/BUILD.bazel index 126c357d19c6..a79922855a20 100644 --- a/platform/vcs-impl/lang/BUILD.bazel +++ b/platform/vcs-impl/lang/BUILD.bazel @@ -27,6 +27,7 @@ jvm_library( "//platform/diagnostic", "//platform/statistics", "@lib//:fastutil-min", + "//platform/todo", ], runtime_deps = [":vcs-impl-lang_resources"] ) diff --git a/platform/vcs-log/impl/BUILD.bazel b/platform/vcs-log/impl/BUILD.bazel index 95c67876394e..899ca4ab762d 100644 --- a/platform/vcs-log/impl/BUILD.bazel +++ b/platform/vcs-log/impl/BUILD.bazel @@ -43,6 +43,7 @@ jvm_library( "//platform/util/coroutines", "//platform/util/storages:io-storages", "//platform/vcs-impl/shared:vcs-impl-shared", + "//platform/bookmarks", ], runtime_deps = [":vcs-log-impl_resources"] ) @@ -98,6 +99,7 @@ jvm_library( "//platform/util/storages:io-storages", "//platform/vcs-impl/shared:vcs-impl-shared", "@lib//:mockito", + "//platform/bookmarks", ], runtime_deps = [":vcs-log-impl_resources"] ) diff --git a/plugins/devkit/devkit-java-tests/BUILD.bazel b/plugins/devkit/devkit-java-tests/BUILD.bazel index 21316f9ededd..bf405ac57572 100644 --- a/plugins/devkit/devkit-java-tests/BUILD.bazel +++ b/plugins/devkit/devkit-java-tests/BUILD.bazel @@ -22,6 +22,7 @@ jvm_library( "//java/execution/openapi:java-execution", "//java/idea-ui:ui", "//java/openapi:java", + "@lib//:assert_j", "//xml/dom-impl", "//jvm/jvm-analysis-api:analysis", "//plugins/devkit/devkit-tests:testFramework", diff --git a/plugins/search-everywhere-ml/ranking/core/BUILD.bazel b/plugins/search-everywhere-ml/ranking/core/BUILD.bazel index 4f4146bda37b..10aaff9cd2bf 100644 --- a/plugins/search-everywhere-ml/ranking/core/BUILD.bazel +++ b/plugins/search-everywhere-ml/ranking/core/BUILD.bazel @@ -74,6 +74,7 @@ jvm_library( "//plugins/search-everywhere-ml/ranking/ext:searchEverywhereMl-ranking-ext", "//plugins/search-everywhere-ml:searchEverywhereMl", "//plugins/search-everywhere-ml:searchEverywhereMl_test_lib", + "//platform/bookmarks", ], runtime_deps = [":searchEverywhereMl-ranking-core_resources"] ) diff --git a/plugins/tasks/tasks-tests/BUILD.bazel b/plugins/tasks/tasks-tests/BUILD.bazel index 2b2a95e70030..3577d0126aca 100644 --- a/plugins/tasks/tasks-tests/BUILD.bazel +++ b/plugins/tasks/tasks-tests/BUILD.bazel @@ -46,6 +46,7 @@ jvm_library( "@lib//:stream_ex", "//platform/core-ui", "//platform/util/jdom", + "//platform/bookmarks", ], runtime_deps = ["//spellchecker"] ) diff --git a/python/BUILD.bazel b/python/BUILD.bazel index 3d11feaffc3a..ee1d68265edc 100644 --- a/python/BUILD.bazel +++ b/python/BUILD.bazel @@ -369,6 +369,7 @@ jvm_library( "//platform/testFramework/junit5", "//platform/testFramework/junit5:junit5_test_lib", "@lib//:kotlin-reflect", + "//platform/todo", ], runtime_deps = [ "//python/pluginCore/impl:python-community-plugin-impl", diff --git a/python/junit5Tests-framework/BUILD.bazel b/python/junit5Tests-framework/BUILD.bazel index df5e27014366..445037cedee2 100644 --- a/python/junit5Tests-framework/BUILD.bazel +++ b/python/junit5Tests-framework/BUILD.bazel @@ -35,7 +35,10 @@ jvm_library( "@lib//:jna", "@lib//:hamcrest", ], - runtime_deps = ["//python:pycharm-community-main"] + runtime_deps = [ + "//python:pycharm-community", + "//python/pluginCore:community-plugin", + ] ) jvm_test(