xref: /aosp_15_r20/external/bazelbuild-kotlin-rules/kotlin/compiler_opt.bzl (revision 3a22c0a33dd99bcca39a024d43e6fbcc55c2806e)
1# Copyright 2022 Google LLC. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the License);
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""A rule for declaring and passing kotlinc opts in a restricted way.
16
17It is a goal for rules_kotlin that Kotlin libraries use consistent default compiler
18options across as much of the repo as possible. Doing so makes Kotlin easier to
19maintain at scale.
20
21If an exception needs to be made for some library, `kt_compiler_opt` can be used to
22declare a set of additional options with restricted visibility. That target can then
23be passed to the `custom_kotlincopts` attribute. The set of directories that allow
24`kt_compiler_opt` targets is also limited, to prevent misuse.
25"""
26
27load("//bazel:stubs.bzl", "check_compiler_opt_allowlist")
28load("//:visibility.bzl", "RULES_DEFS_THAT_COMPILE_KOTLIN")
29
30# Intentionally private to prevent misuse.
31_KtCompilerOptInfo = provider(
32    doc = "A restricted set of kotlinc opts",
33    fields = {"opts": "list[string]"},
34)
35
36_ALLOWED_VISIBILITY_NAMES = [
37    "__pkg__",
38    "__subpackages__",
39]
40
41def _kt_compiler_opt_impl(ctx):
42    check_compiler_opt_allowlist(ctx.label)
43
44    visibility_groups = [v for v in ctx.attr.visibility if not v.name in _ALLOWED_VISIBILITY_NAMES]
45    if len(visibility_groups) > 0:
46        fail("Using package groups for visibility may expose custom options too broadly: " + str(visibility_groups))
47
48    return [_KtCompilerOptInfo(opts = ctx.attr.opts)]
49
50kt_compiler_opt = rule(
51    implementation = _kt_compiler_opt_impl,
52    attrs = {
53        "opts": attr.string_list(
54            doc = "The opt(s) this target represents.",
55            mandatory = True,
56        ),
57    },
58)
59
60def kotlincopts_attrs():
61    return dict(
62        custom_kotlincopts = attr.label_list(
63            doc = "kt_compiler_opt targets to pass to Kotlin compiler. Most users should not need this attr.",
64            providers = [[_KtCompilerOptInfo]],
65            cfg = "exec",
66        ),
67    )
68
69def merge_kotlincopts(ctx):
70    """Returns the complete list of opts behind custom_kotlincopts
71
72    Args:
73      ctx: A ctx matching kotlincopts_attrs
74
75    Returns:
76      The list of opts
77    """
78    custom_opts = []
79    for target in ctx.attr.custom_kotlincopts:
80        custom_opts.extend(target[_KtCompilerOptInfo].opts)
81
82    return custom_opts
83