diff options
Diffstat (limited to 'kotlin/jvm/internal_do_not_use/traverse_exports/traverse_exports.bzl')
-rw-r--r-- | kotlin/jvm/internal_do_not_use/traverse_exports/traverse_exports.bzl | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/kotlin/jvm/internal_do_not_use/traverse_exports/traverse_exports.bzl b/kotlin/jvm/internal_do_not_use/traverse_exports/traverse_exports.bzl new file mode 100644 index 0000000..f0f9e6a --- /dev/null +++ b/kotlin/jvm/internal_do_not_use/traverse_exports/traverse_exports.bzl @@ -0,0 +1,122 @@ +# Copyright 2022 Google LLC. 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. + +"""Combined aspect for all rules_kotlin behaviours that need to traverse exports.""" + +load(":compiler_plugin.bzl", "kt_compiler_plugin_visitor") +load(":direct_jdeps.bzl", "kt_direct_jdeps_visitor") +load(":forbidden_deps.bzl", "kt_forbidden_deps_visitor") +load(":friend_jars.bzl", "kt_friend_jars_visitor", "kt_friend_labels_visitor") +load(":java_plugin.bzl", "java_plugin_visitor") +load("//:visibility.bzl", "RULES_KOTLIN") + +# java_xxx_proto_library don't populate java_outputs but we can get them through +# required_aspect_providers from their proto_library deps. +_DEPS_AS_EXPORTS_RULES = [ + "java_proto_library", + "java_lite_proto_library", + "java_mutable_proto_library", +] + +_NO_SRCS_DEPS_AS_EXPORTS_RULES = [ + "proto_library", +] + +# visitor = struct[T]( +# name = string, +# visit_target = function(Target, ctx.rule): list[T], +# filter_edge = None|(function(src: ?, dest: Target): bool), +# process_unvisited_target = None|(function(Target): list[T]), +# finish_expansion = None|(function(depset[T]): depset[T]), +# ) +_VISITORS = [ + kt_forbidden_deps_visitor, + kt_direct_jdeps_visitor, + kt_compiler_plugin_visitor, + kt_friend_jars_visitor, + kt_friend_labels_visitor, + java_plugin_visitor, +] + +_KtTraverseExportsInfo = provider( + doc = "depsets for transitive info about exports", + fields = { + v.name: ("depset[%s]" % v.name) + for v in _VISITORS + }, +) + +_EMPTY_KT_TRAVERSE_EXPORTS_INFO = _KtTraverseExportsInfo(**{ + v.name: depset() + for v in _VISITORS +}) + +def _aspect_impl(target, ctx): + if not (JavaInfo in target): + # Ignore non-JVM targets. This also chops-up the + # traversal domain at these targets. + # TODO: Support non-JVM targets for KMP + return _EMPTY_KT_TRAVERSE_EXPORTS_INFO + + exports = [] + exports.extend(getattr(ctx.rule.attr, "exports", [])) # exports list is frozen + if ctx.rule.kind in _DEPS_AS_EXPORTS_RULES: + exports.extend(ctx.rule.attr.deps) + elif ctx.rule.kind in _NO_SRCS_DEPS_AS_EXPORTS_RULES and not ctx.rule.attr.srcs: + exports.extend(ctx.rule.attr.deps) + + return _KtTraverseExportsInfo(**{ + v.name: depset( + direct = v.visit_target(target, ctx.rule), + transitive = [ + getattr(e[_KtTraverseExportsInfo], v.name) + for e in exports + if (not v.filter_edge or v.filter_edge(target, e)) + ], + ) + for v in _VISITORS + }) + +_aspect = aspect( + implementation = _aspect_impl, + provides = [_KtTraverseExportsInfo], + # Transitively check exports, since they are effectively directly depended on. + # "deps" needed for rules that treat deps as exports (usually absent srcs). + attr_aspects = ["exports", "deps"], + required_aspect_providers = [JavaInfo], # to get at JavaXxxProtoAspects' JavaInfos +) + +def _create_visitor_expand(visitor): + def _visitor_expand(targets, root = None): + direct = [] + transitive = [] + for t in targets: + if (not visitor.filter_edge or visitor.filter_edge(root, t)): + if _KtTraverseExportsInfo in t: + transitive.append(getattr(t[_KtTraverseExportsInfo], visitor.name)) + elif visitor.process_unvisited_target: + direct.extend(visitor.process_unvisited_target(t)) + + expanded_set = depset(direct = direct, transitive = transitive) + return visitor.finish_expansion(expanded_set) if visitor.finish_expansion else expanded_set + + return _visitor_expand + +kt_traverse_exports = struct( + aspect = _aspect, + **{ + "expand_" + v.name: _create_visitor_expand(v) + for v in _VISITORS + } +) |