Skip to content

Commit

Permalink
[kt_compiler_plugin] Add kt_plugin_cfg for reusuable and composable o…
Browse files Browse the repository at this point in the history
…ptions
  • Loading branch information
restingbull committed Mar 8, 2024
1 parent 0ccba53 commit 5d846b0
Show file tree
Hide file tree
Showing 22 changed files with 4,376 additions and 324 deletions.
3,603 changes: 3,603 additions & 0 deletions MODULE.bazel.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions kotlin/core.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ load(
"//kotlin/internal/jvm:jvm.bzl",
_kt_compiler_plugin = "kt_compiler_plugin",
_kt_ksp_plugin = "kt_ksp_plugin",
_kt_plugin_cfg = "kt_plugin_cfg",
)

define_kt_toolchain = _define_kt_toolchain
Expand All @@ -20,3 +21,4 @@ kt_javac_options = _kt_javac_options
kt_kotlinc_options = _kt_kotlinc_options
kt_compiler_plugin = _kt_compiler_plugin
kt_ksp_plugin = _kt_ksp_plugin
kt_plugin_cfg = _kt_plugin_cfg
21 changes: 0 additions & 21 deletions kotlin/internal/compiler_plugins.bzl

This file was deleted.

12 changes: 11 additions & 1 deletion kotlin/internal/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@
# 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.#
load("//src/main/starlark/core/plugins:providers.bzl", _KspPluginInfo = "KspPluginInfo", _KtCompilerPluginInfo = "KtCompilerPluginInfo")
load(
"//src/main/starlark/core/plugin:providers.bzl",
_KspPluginInfo = "KspPluginInfo",
_KtCompilerPluginInfo = "KtCompilerPluginInfo",
_KtCompilerPluginOption = "KtCompilerPluginOption",
_KtPluginConfiguration = "KtPluginConfiguration",
)

# The Kotlin Toolchain type.
TOOLCHAIN_TYPE = "%s" % Label("//kotlin/internal:kt_toolchain_type")
Expand Down Expand Up @@ -54,3 +60,7 @@ KtJsInfo = provider(
KtCompilerPluginInfo = _KtCompilerPluginInfo

KspPluginInfo = _KspPluginInfo

KtCompilerPluginOption = _KtCompilerPluginOption

KtPluginConfiguration = _KtPluginConfiguration
160 changes: 102 additions & 58 deletions kotlin/internal/jvm/compile.bzl
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
load(
"@bazel_tools//tools/jdk:toolchain_utils.bzl",
"find_java_runtime_toolchain",
"find_java_toolchain",
)

# Copyright 2018 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -17,11 +11,21 @@ load(
# 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.
load("@rules_java//java:defs.bzl", "JavaInfo", "java_common")
load(
"@bazel_tools//tools/jdk:toolchain_utils.bzl",
"find_java_runtime_toolchain",
"find_java_toolchain",
)
load(
"@rules_java//java:defs.bzl",
"JavaInfo",
"java_common",
)
load(
"//kotlin/internal:defs.bzl",
_KtCompilerPluginInfo = "KtCompilerPluginInfo",
_KtJvmInfo = "KtJvmInfo",
_KtPluginConfiguration = "KtPluginConfiguration",
_TOOLCHAIN_TYPE = "TOOLCHAIN_TYPE",
)
load(
Expand All @@ -47,12 +51,6 @@ load(
"//kotlin/internal/utils:utils.bzl",
_utils = "utils",
)
load(
"//src/main/starlark/core/plugins:providers.bzl",
"KspPluginInfo",
"KtCompilerPluginInfo",
"KtPluginConfiguration",
)

# UTILITY ##############################################################################################################

Expand Down Expand Up @@ -184,9 +182,83 @@ def _adjust_resources_path(path, resource_strip_prefix):
else:
return _adjust_resources_path_by_default_prefixes(path)

def _format_compile_plugin_options(options):
"""Format options into id:value for cmd line."""
return ["%s:%s" % (o.id, o.value) for o in options]
def _format_compile_plugin_options(o):
"""Format compiler option into id:value for cmd line."""
return [
"%s:%s" % (o.id, o.value),
]

def _new_plugins_from(targets):
"""Returns a struct containing the plugin metadata for the given targets.
Args:
targets: A list of targets.
Returns:
A struct containing the plugins for the given targets in the format:
{
stubs_phase = {
classpath = depset,
options= List[KtCompilerPluginOption],
),
compile = {
classpath = depset,
options = List[KtCompilerPluginOption],
},
}
"""

all_plugins = {}
plugins_without_phase = []
for t in targets:
if _KtCompilerPluginInfo not in t:
continue
plugin = t[_KtCompilerPluginInfo]
if not (plugin.stubs or plugin.compile):
plugins_without_phase.append("%s: %s" % (t.label, plugin.id))
if plugin.id in all_plugins:
# This need a more robust error messaging.
fail("has multiple plugins with the same id: %s." % plugin.id)
all_plugins[plugin.id] = plugin

if plugins_without_phase:
fail("has plugin without a phase defined: %s" % cfgs_without_plugin)

all_plugin_cfgs = {}
cfgs_without_plugin = []
for t in targets:
if _KtPluginConfiguration not in t:
continue
cfg = t[_KtPluginConfiguration]
if cfg.id not in all_plugins:
cfgs_without_plugin.append("%s: %s" % (t.label, cfg.id))
all_plugin_cfgs[cfg.id] = cfg

if cfgs_without_plugin:
fail("has plugin configurations without corresponding plugins: %s" % cfgs_without_plugin)

return struct(
stubs_phase = _new_plugin_from(all_plugin_cfgs, [p for p in all_plugins.values() if p.stubs]),
compile_phase = _new_plugin_from(all_plugin_cfgs, [p for p in all_plugins.values() if p.compile]),
)

def _new_plugin_from(all_cfgs, plugins_for_phase):
classpath = []
data = []
options = []
for p in plugins_for_phase:
classpath.append(p.classpath)
options.extend(p.options)
if p.id in all_cfgs:
cfg = all_cfgs[p.id]
classpath.append(cfg.classpath)
data.append(cfg.data)
options.extend(cfg.options)

return struct(
classpath = depset(transitive = classpath),
data = depset(transitive = data),
options = options,
)

# INTERNAL ACTIONS #####################################################################################################
def _fold_jars_action(ctx, rule_kind, toolchains, output_jar, input_jars, action_type = ""):
Expand Down Expand Up @@ -431,64 +503,28 @@ def _run_kt_builder_action(
uniquify = True,
)

compiler_plugins = [
p[_KtCompilerPluginInfo]
for p in plugins
if _KtCompilerPluginInfo in p and p[_KtCompilerPluginInfo]
]

compiler_plugin_configurations = {
p[KtPluginConfiguration].plugin: p[KtPluginConfiguration]
for p in plugins
if KtPluginConfiguration in p and p[KtPluginConfiguration]
}

stubs_compiler_plugins = [
kcp
for kcp in compiler_plugins
if kcp.stubs
]

stubs_compiler_configurations = [
compiler_plugin_configurations[kcp]
for kcp in stubs_compiler_plugins
]

compiler_compiler_plugins = [
ccp
for ccp in compiler_plugins
if ccp.compile
]
compiler_compiler_configurations = [
compiler_plugin_configurations[kcp]
for kcp in compiler_compiler_plugins
]

if compiler_plugins and not (stubs_compiler_plugins or compiler_compiler_plugins):
fail("has plugins without a phase: %s" % compiler_plugins)

args.add_all(
"--stubs_plugin_classpath",
depset(transitive = [p.classpath for p in stubs_compiler_plugins]),
plugins.stubs_phase.classpath,
omit_if_empty = True,
)

args.add_all(
"--stubs_plugin_options",
[p.options for p in stubs_compiler_plugins] + [p.options for p in stubs_compiler_configurations],
plugins.stubs_phase.options,
map_each = _format_compile_plugin_options,
omit_if_empty = True,
)

args.add_all(
"--compiler_plugin_classpath",
depset(transitive = [p.classpath for p in compiler_compiler_plugins] + [p.deps for p in compiler_compiler_configurations]),
plugins.compile_phase.classpath,
omit_if_empty = True,
)

args.add_all(
"--compiler_plugin_options",
[p.options for p in compiler_compiler_plugins] + [p.options for p in compiler_compiler_configurations],
plugins.compile_phase.options,
map_each = _format_compile_plugin_options,
omit_if_empty = True,
)
Expand All @@ -514,7 +550,13 @@ def _run_kt_builder_action(
mnemonic = mnemonic,
inputs = depset(
srcs.all_srcs + srcs.src_jars + generated_src_jars,
transitive = [compile_deps.compile_jars, transitive_runtime_jars, deps_artifacts] + [p.classpath for p in compiler_plugins],
transitive = [
compile_deps.compile_jars,
transitive_runtime_jars,
deps_artifacts,
plugins.stubs_phase.classpath,
plugins.compile_phase.classpath,
],
),
tools = tools,
input_manifests = input_manifests,
Expand Down Expand Up @@ -554,10 +596,12 @@ def kt_jvm_produce_jar_actions(ctx, rule_kind):
deps = ctx.attr.deps,
runtime_deps = ctx.attr.runtime_deps,
)

annotation_processors = _plugin_mappers.targets_to_annotation_processors(ctx.attr.plugins + ctx.attr.deps)
ksp_annotation_processors = _plugin_mappers.targets_to_ksp_annotation_processors(ctx.attr.plugins + ctx.attr.deps)
transitive_runtime_jars = _plugin_mappers.targets_to_transitive_runtime_jars(ctx.attr.plugins + ctx.attr.deps)
plugins = ctx.attr.plugins + _exported_plugins(deps = ctx.attr.deps)
plugins = _new_plugins_from(ctx.attr.plugins + _exported_plugins(deps = ctx.attr.deps))

deps_artifacts = _deps_artifacts(toolchains, ctx.attr.deps + associates.targets)

generated_src_jars = []
Expand Down
62 changes: 47 additions & 15 deletions kotlin/internal/jvm/impl.bzl
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
load("@rules_java//java:defs.bzl", "JavaInfo", "JavaPluginInfo", "java_common")
load(
"//kotlin/internal:defs.bzl",
_KspPluginInfo = "KspPluginInfo",
_KtCompilerPluginInfo = "KtCompilerPluginInfo",
_KtJvmInfo = "KtJvmInfo",
_TOOLCHAIN_TYPE = "TOOLCHAIN_TYPE",
)

# Copyright 2018 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -20,6 +11,17 @@ load(
# 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.

load("@rules_java//java:defs.bzl", "JavaInfo", "JavaPluginInfo", "java_common")
load(
"//kotlin/internal:defs.bzl",
"KtCompilerPluginOption",
"KtPluginConfiguration",
_KspPluginInfo = "KspPluginInfo",
_KtCompilerPluginInfo = "KtCompilerPluginInfo",
_KtJvmInfo = "KtJvmInfo",
_TOOLCHAIN_TYPE = "TOOLCHAIN_TYPE",
)
load(
"//kotlin/internal/jvm:compile.bzl",
"export_only_providers",
Expand Down Expand Up @@ -383,16 +385,40 @@ def _deshade_embedded_kotlinc_jars(target, ctx, jars, deps):
],
)

def kt_compiler_plugin_impl(ctx):
plugin_id = ctx.attr.id
def _resolve_plugin_options(id, string_dict):
"""
Resolves plugin options from a string dict to a dict of strings.
Args:
id: the plugin id
string_dict: a dict of strings
Returns:
a dict of strings
"""
options = []
for (k, v) in ctx.attr.options.items():
for (k, v) in string_dict.items():
if "=" in k:
fail("kt_compiler_plugin options keys cannot contain the = symbol")
options.append(struct(id = plugin_id, value = "%s=%s" % (k, v)))
options.append(KtCompilerPluginOption(id = id, value = k + "=" + v))
return options

# This is naive reference implementation for resolving configurations.
# A more complicated plugin will need to provide its own implementation.
def _resolve_plugin_cfg(info, options, deps):
classpath = []
for dep in deps:
if JavaInfo in dep:
classpath.append(dep[JavaInfo].compile_jars)
return KtPluginConfiguration(
id = info.id,
options = _resolve_plugin_options(info.id, options),
classpath = depset(transitive = classpath),
data = depset(),
)

if not (ctx.attr.compile_phase or ctx.attr.stubs_phase):
fail("Plugin must execute during in one or more phases: stubs_phase, compile_phase")
def kt_compiler_plugin_impl(ctx):
plugin_id = ctx.attr.id
options = _resolve_plugin_options(plugin_id, ctx.attr.options)

deps = ctx.attr.deps
info = None
Expand All @@ -414,13 +440,19 @@ def kt_compiler_plugin_impl(ctx):
return [
DefaultInfo(files = classpath),
_KtCompilerPluginInfo(
id = plugin_id,
classpath = classpath,
options = options,
stubs = ctx.attr.stubs_phase,
compile = ctx.attr.compile_phase,
resolve_cfg = _resolve_plugin_cfg,
),
]

def kt_plugin_cfg_impl(ctx):
plugin = ctx.attr.plugin[_KtCompilerPluginInfo]
return plugin.resolve_cfg(plugin, ctx.attr.options, ctx.attr.deps)

def kt_ksp_plugin_impl(ctx):
info = java_common.merge([dep[JavaInfo] for dep in ctx.attr.deps])
classpath = depset(info.runtime_output_jars, transitive = [info.transitive_runtime_jars])
Expand Down
Loading

0 comments on commit 5d846b0

Please sign in to comment.