Skip to content

Commit

Permalink
Create an empty marker providerSwiftClangModuleAspectInfo
Browse files Browse the repository at this point in the history
that `swift_clang_module_aspect` always returns, so that other aspects can use `required_aspect_providers` to ensure correct ordering of aspect application and thus depend on the `SwiftInfo` provider attached by the aspect without having to unconditionally require it

PiperOrigin-RevId: 617942821
(cherry picked from commit f922a1d)
Signed-off-by: Brentley Jones <github@brentleyjones.com>
  • Loading branch information
allevato authored and brentleyjones committed Oct 14, 2024
1 parent e0eec8e commit cf9039b
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 6 deletions.
14 changes: 14 additions & 0 deletions swift/providers.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,20 @@ Swift build rules, and they are also passed to the C++ APIs used when linking
},
)

SwiftClangModuleAspectInfo = provider(
doc = """\
A "marker provider" (i.e., it has no fields) that is always returned when
`swift_clang_module_aspect` is applied to a target.
This provider exists because `swift_clang_module_aspect` cannot advertise that
it returns `SwiftInfo` (since some code paths do not). Users who want to ensure
aspect ordering via the `required_aspect_providers` parameter to their own
`aspect` function can require this provider instead, which
`swift_clang_module_aspect` does advertise.
""",
fields = {},
)

def create_swift_module_context(
*,
name,
Expand Down
28 changes: 22 additions & 6 deletions swift/swift_clang_module_aspect.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ load(
load(":module_name.bzl", "derive_swift_module_name")
load(
":providers.bzl",
"SwiftClangModuleAspectInfo",
"SwiftInfo",
"create_clang_module_inputs",
"create_swift_module_context",
Expand Down Expand Up @@ -672,9 +673,11 @@ def _find_swift_interop_info(target, aspect_ctx):
return None, default_direct_swift_infos, default_swift_infos

def _swift_clang_module_aspect_impl(target, aspect_ctx):
providers = [SwiftClangModuleAspectInfo()]

# Do nothing if the target already propagates `SwiftInfo`.
if SwiftInfo in target:
return []
return providers

requested_features = aspect_ctx.features
unsupported_features = aspect_ctx.disabled_features
Expand All @@ -684,7 +687,7 @@ def _swift_clang_module_aspect_impl(target, aspect_ctx):
# If the module should be suppressed, return immediately and propagate
# nothing (not even transitive dependencies).
if interop_info.suppressed:
return []
return providers

exclude_headers = interop_info.exclude_headers
module_map_file = interop_info.module_map
Expand Down Expand Up @@ -721,7 +724,7 @@ def _swift_clang_module_aspect_impl(target, aspect_ctx):
)

if interop_info or apple_common.Objc in target or CcInfo in target:
return _handle_module(
return providers + _handle_module(
aspect_ctx = aspect_ctx,
exclude_headers = exclude_headers,
feature_configuration = feature_configuration,
Expand All @@ -736,12 +739,12 @@ def _swift_clang_module_aspect_impl(target, aspect_ctx):
# If it's any other rule, just merge the `SwiftInfo` providers from its
# deps.
if direct_swift_infos or swift_infos:
return [SwiftInfo(
providers.append(SwiftInfo(
direct_swift_infos = direct_swift_infos,
swift_infos = swift_infos,
)]
))

return []
return providers

swift_clang_module_aspect = aspect(
attr_aspects = _MULTIPLE_TARGET_ASPECT_ATTRS + _SINGLE_TARGET_ASPECT_ATTRS,
Expand Down Expand Up @@ -774,9 +777,22 @@ propagated to any targets that depend on it, since they would not be propagated
via `deps`. In this case, the custom rule can attach this aspect to that support
library's attribute and then merge its `SwiftInfo` provider with any others that
it propagates for its targets.
### Returned Providers
* `SwiftClangModuleAspectInfo` _(always)_: An empty provider that is returned
so that other aspects that want to depend on the outputs of this aspect can
enforce ordering using `required_aspect_providers`.
* `SwiftInfo` _(optional)_: This provider is returned when the aspect is
applied to a target that is Swift-compatible or that has Swift-compatible
transitive dependencies. It is _not_ returned when a target has its module
suppressed (for example, using the `no_module` aspect hint). In this case,
transitive dependency information is intentionally discarded.
""",
fragments = ["cpp"],
implementation = _swift_clang_module_aspect_impl,
provides = [SwiftClangModuleAspectInfo],
required_aspect_providers = [
[apple_common.Objc],
[CcInfo],
Expand Down

0 comments on commit cf9039b

Please sign in to comment.