diff --git a/scala/private/phases/phase_compile.bzl b/scala/private/phases/phase_compile.bzl index 185f7219d..ea39ac480 100644 --- a/scala/private/phases/phase_compile.bzl +++ b/scala/private/phases/phase_compile.bzl @@ -125,7 +125,12 @@ def _phase_compile( jars2labels = p.collect_jars.jars2labels.jars_to_labels deps_providers = p.collect_jars.deps_providers default_classpath = p.scalac_provider.default_classpath - plugins = ctx.attr.plugins + + # Merge toolchain plugins with target-specific plugins + toolchain = ctx.toolchains["//scala:toolchain_type"] + toolchain_plugins = getattr(toolchain, "plugins", []) + plugins = toolchain_plugins + ctx.attr.plugins + additional_outputs = [] scalacopts = p.scalacopts diff --git a/scala/scala_toolchain.bzl b/scala/scala_toolchain.bzl index dc8e9f907..384f0adf1 100644 --- a/scala/scala_toolchain.bzl +++ b/scala/scala_toolchain.bzl @@ -81,6 +81,7 @@ def _scala_toolchain_impl(ctx): toolchain = platform_common.ToolchainInfo( scalacopts = ctx.attr.scalacopts, + plugins = ctx.attr.plugins, dep_providers = ctx.attr.dep_providers, dependency_mode = dependency_mode, strict_deps_mode = strict_deps_mode, @@ -122,6 +123,10 @@ _scala_toolchain = rule( _scala_toolchain_impl, attrs = { "scalacopts": attr.string_list(), + "plugins": attr.label_list( + doc = "Compiler plugins to be enabled for all scala targets using this toolchain", + allow_files = [".jar"], + ), "dep_providers": attr.label_list( default = _default_dep_providers(), providers = [_DepsInfo], diff --git a/test/toolchain_plugins/BUILD.bazel b/test/toolchain_plugins/BUILD.bazel new file mode 100644 index 000000000..9cd16b9b1 --- /dev/null +++ b/test/toolchain_plugins/BUILD.bazel @@ -0,0 +1,42 @@ +load("//scala:scala_toolchain.bzl", "scala_toolchain") +load("//scala:scala.bzl", "scala_library") + +# Toolchain WITH the kind-projector plugin +scala_toolchain( + name = "with_plugin_impl", + plugins = ["@org_typelevel_kind_projector//jar"], + visibility = ["//visibility:public"], +) + +toolchain( + name = "with_plugin", + toolchain = ":with_plugin_impl", + toolchain_type = "//scala:toolchain_type", + visibility = ["//visibility:public"], +) + +# Toolchain WITHOUT the plugin (but otherwise identical) +scala_toolchain( + name = "without_plugin_impl", + # No plugins attribute + visibility = ["//visibility:public"], +) + +toolchain( + name = "without_plugin", + toolchain = ":without_plugin_impl", + toolchain_type = "//scala:toolchain_type", + visibility = ["//visibility:public"], +) + +# Test that requires kind-projector plugin +scala_library( + name = "requires_plugin", + srcs = ["RequiresPlugin.scala"], +) + +# Test that doesn't require any plugin +scala_library( + name = "no_plugin_needed", + srcs = ["NoPlugin.scala"], +) \ No newline at end of file diff --git a/test/toolchain_plugins/NoPlugin.scala b/test/toolchain_plugins/NoPlugin.scala new file mode 100644 index 000000000..657c9a7b5 --- /dev/null +++ b/test/toolchain_plugins/NoPlugin.scala @@ -0,0 +1,6 @@ +package test.toolchain_plugins + +// Standard Scala - no plugin needed +class NoPlugin { + def hello: String = "This compiles without any plugin" +} \ No newline at end of file diff --git a/test/toolchain_plugins/RequiresPlugin.scala b/test/toolchain_plugins/RequiresPlugin.scala new file mode 100644 index 000000000..2e2a8f5d9 --- /dev/null +++ b/test/toolchain_plugins/RequiresPlugin.scala @@ -0,0 +1,7 @@ +package test.toolchain_plugins + +import scala.language.higherKinds + +// This REQUIRES kind-projector plugin - uses the * syntax +class HKT[F[_]] +class RequiresPlugin extends HKT[Either[String, *]] \ No newline at end of file