Skip to content

Commit

Permalink
Extract derive_swift_module_name as a free function in its own `.bz…
Browse files Browse the repository at this point in the history
…l` file

Since rules may want to use this without the other functionality in `swift_common` (e.g., compilation), isolating it to its own file can reduce analysis churn when other parts of the rule implementations change.

PiperOrigin-RevId: 493078921
(cherry picked from commit 47bd14c)
Signed-off-by: Brentley Jones <github@brentleyjones.com>
  • Loading branch information
allevato authored and brentleyjones committed Oct 7, 2024
1 parent b2ba142 commit 16a50dc
Show file tree
Hide file tree
Showing 17 changed files with 45 additions and 101 deletions.
4 changes: 2 additions & 2 deletions doc/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ Compiles a Swift module.
| <a id="swift_common.compile-generated_header_name"></a>generated_header_name | The name of the Objective-C generated header that should be generated for this module. If omitted, no header will be generated. | `None` |
| <a id="swift_common.compile-is_test"></a>is_test | Deprecated. This argument will be removed in the next major release. Use the `include_dev_srch_paths` attribute instead. Represents if the `testonly` value of the context. | `None` |
| <a id="swift_common.compile-include_dev_srch_paths"></a>include_dev_srch_paths | A `bool` that indicates whether the developer framework search paths will be added to the compilation command. | `None` |
| <a id="swift_common.compile-module_name"></a>module_name | The name of the Swift module being compiled. This must be present and valid; use `swift_common.derive_module_name` to generate a default from the target's label if needed. | none |
| <a id="swift_common.compile-module_name"></a>module_name | The name of the Swift module being compiled. This must be present and valid; use `derive_swift_module_name` to generate a default from the target's label if needed. | none |
| <a id="swift_common.compile-objc_infos"></a>objc_infos | A list of `apple_common.ObjC` providers that represent C/Objective-C requirements of the target being compiled, such as Swift-compatible preprocessor defines, header search paths, and so forth. These are typically retrieved from a target's dependencies. | none |
| <a id="swift_common.compile-package_name"></a>package_name | The semantic package of the name of the Swift module being compiled. | none |
| <a id="swift_common.compile-plugins"></a>plugins | A list of `SwiftCompilerPluginInfo` providers that represent plugins that should be loaded by the compiler. | `[]` |
Expand Down Expand Up @@ -180,7 +180,7 @@ Compiles a Swift module interface.
| <a id="swift_common.compile_module_interface-copts"></a>copts | A list of compiler flags that apply to the target being built. | `[]` |
| <a id="swift_common.compile_module_interface-exec_group"></a>exec_group | Runs the Swift compilation action under the given execution group's context. If `None`, the default execution group is used. | `None` |
| <a id="swift_common.compile_module_interface-feature_configuration"></a>feature_configuration | A feature configuration obtained from `swift_common.configure_features`. | none |
| <a id="swift_common.compile_module_interface-module_name"></a>module_name | The name of the Swift module being compiled. This must be present and valid; use `swift_common.derive_module_name` to generate a default from the target's label if needed. | none |
| <a id="swift_common.compile_module_interface-module_name"></a>module_name | The name of the Swift module being compiled. This must be present and valid; use `derive_swift_module_name` to generate a default from the target's label if needed. | none |
| <a id="swift_common.compile_module_interface-swiftinterface_file"></a>swiftinterface_file | The Swift module interface file to compile. | none |
| <a id="swift_common.compile_module_interface-swift_infos"></a>swift_infos | A list of `SwiftInfo` providers from dependencies of the target being compiled. | none |
| <a id="swift_common.compile_module_interface-swift_toolchain"></a>swift_toolchain | The `SwiftToolchainInfo` provider of the toolchain. | none |
Expand Down
5 changes: 5 additions & 0 deletions doc/doc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ load(
"//proto:swift_proto_library_group.bzl",
_swift_proto_library_group = "swift_proto_library_group",
)
load(
"//swift:module_name.bzl",
_derive_swift_module_name = "derive_swift_module_name",
)
load(
"//swift:providers.bzl",
_SwiftInfo = "SwiftInfo",
Expand Down Expand Up @@ -103,6 +107,7 @@ swift_proto_library = _swift_proto_library
swift_proto_library_group = _swift_proto_library_group

# swift symbols
derive_swift_module_name = _derive_swift_module_name
swift_common = _swift_common
SwiftInfo = _SwiftInfo
SwiftToolchainInfo = _SwiftToolchainInfo
Expand Down
1 change: 1 addition & 0 deletions mixed_language/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ bzl_library(
"//mixed_language/internal:library",
"//mixed_language/internal:module_map",
"//mixed_language/internal:umbrella_header",
"//swift:module_name",
"//swift:swift_interop_hint",
"//swift:swift_library",
"//swift/internal:compiling",
Expand Down
6 changes: 2 additions & 4 deletions mixed_language/mixed_language_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,10 @@ load(
"//mixed_language/internal:umbrella_header.bzl",
"mixed_language_umbrella_header",
)
load("//swift:module_name.bzl", "derive_swift_module_name")
load("//swift:swift_interop_hint.bzl", "swift_interop_hint")
load("//swift:swift_library.bzl", "swift_library")

# buildifier: disable=bzl-visibility
load("//swift/internal:compiling.bzl", "derive_module_name")

# `mixed_language_library`

def mixed_language_library(
Expand Down Expand Up @@ -225,7 +223,7 @@ a mixed language Swift library, use a clang only library rule like \
)

if not module_name:
module_name = derive_module_name(native.package_name(), name)
module_name = derive_swift_module_name(native.package_name(), name)

if not module_map:
internal_modulemap_name = name + "_modulemap"
Expand Down
2 changes: 2 additions & 0 deletions proto/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ bzl_library(
srcs = ["swift_proto_library.bzl"],
deps = [
":swift_proto_utils",
"//swift:module_name",
"//swift:swift_clang_module_aspect",
"//swift:swift_common",
"//swift/internal:attrs",
Expand All @@ -54,6 +55,7 @@ bzl_library(
srcs = ["swift_proto_library_group.bzl"],
deps = [
":swift_proto_utils",
"//swift:module_name",
"//swift:providers",
"//swift:swift_common",
"//swift/internal:toolchain_utils",
Expand Down
3 changes: 2 additions & 1 deletion proto/swift_proto_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ load(
"@rules_proto//proto:defs.bzl",
"ProtoInfo",
)
load("//swift:module_name.bzl", "derive_swift_module_name")
load("//swift:providers.bzl", "SwiftProtoCompilerInfo")
load("//swift:swift_clang_module_aspect.bzl", "swift_clang_module_aspect")
load("//swift:swift_common.bzl", "swift_common")
Expand Down Expand Up @@ -51,7 +52,7 @@ def _get_module_name(attr, target_label):
"""
module_name = attr.module_name
if not module_name:
module_name = swift_common.derive_module_name(target_label)
module_name = derive_swift_module_name(target_label)
return module_name

# Rule
Expand Down
3 changes: 2 additions & 1 deletion proto/swift_proto_library_group.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ load(
"SwiftProtoCcInfo",
"compile_swift_protos_for_target",
)
load("//swift:module_name.bzl", "derive_swift_module_name")
load(
"//swift:providers.bzl",
"SwiftInfo",
Expand All @@ -47,7 +48,7 @@ load("//swift/internal:utils.bzl", "compact")

def _swift_proto_library_group_aspect_impl(target, aspect_ctx):
# Get the module name and generate the module mappings:
module_name = swift_common.derive_module_name(target.label)
module_name = derive_swift_module_name(target.label)

# Compile the source files to a module:
direct_providers = compile_swift_protos_for_target(
Expand Down
7 changes: 7 additions & 0 deletions swift/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ bzl_library(
name = "swift_binary",
srcs = ["swift_binary.bzl"],
deps = [
":module_name",
":providers",
":swift_common",
"//swift/internal:compiling",
Expand All @@ -72,6 +73,7 @@ bzl_library(
name = "swift_clang_module_aspect",
srcs = ["swift_clang_module_aspect.bzl"],
deps = [
":module_name",
":providers",
"//swift/internal:attrs",
"//swift/internal:compiling",
Expand All @@ -88,6 +90,7 @@ bzl_library(
name = "swift_common",
srcs = ["swift_common.bzl"],
deps = [
":module_name",
"//swift/internal:attrs",
"//swift/internal:compiling",
"//swift/internal:features",
Expand Down Expand Up @@ -160,6 +163,7 @@ bzl_library(
name = "swift_library",
srcs = ["swift_library.bzl"],
deps = [
":module_name",
":providers",
":swift_clang_module_aspect",
":swift_common",
Expand Down Expand Up @@ -192,6 +196,7 @@ bzl_library(
name = "swift_module_alias",
srcs = ["swift_module_alias.bzl"],
deps = [
":module_name",
":providers",
":swift_common",
"//swift/internal:linking",
Expand All @@ -214,6 +219,7 @@ bzl_library(
name = "swift_module_mapping_test",
srcs = ["swift_module_mapping_test.bzl"],
deps = [
":providers",
"//swift/internal:providers",
],
)
Expand Down Expand Up @@ -241,6 +247,7 @@ bzl_library(
name = "swift_test",
srcs = ["swift_test.bzl"],
deps = [
":module_name",
":providers",
":swift_common",
"//swift/internal:env_expansion",
Expand Down
1 change: 0 additions & 1 deletion swift/internal/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ bzl_library(
":wmo",
"@bazel_skylib//lib:paths",
"@bazel_skylib//lib:sets",
"@bazel_skylib//lib:types",
],
)

Expand Down
81 changes: 4 additions & 77 deletions swift/internal/compiling.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

load("@bazel_skylib//lib:paths.bzl", "paths")
load("@bazel_skylib//lib:sets.bzl", "sets")
load("@bazel_skylib//lib:types.bzl", "types")
load(
":action_names.bzl",
"SWIFT_ACTION_COMPILE",
Expand Down Expand Up @@ -81,78 +80,6 @@ load(":wmo.bzl", "find_num_threads_flag_value", "is_wmo_manually_requested")
# SWIFT_FEATURE_VFSOVERLAY is enabled.
_SWIFTMODULES_VFS_ROOT = "/__build_bazel_rules_swift/swiftmodules"

def _module_name_safe(string):
"""Returns a transformation of `string` that is safe for module names."""
result = ""
saw_non_identifier_char = False
for ch in string.elems():
if ch.isalnum() or ch == "_":
# If we're seeing an identifier character after a sequence of
# non-identifier characters, append an underscore and reset our
# tracking state before appending the identifier character.
if saw_non_identifier_char:
result += "_"
saw_non_identifier_char = False
result += ch
elif result:
# Only track this if `result` has content; this ensures that we
# (intentionally) drop leading non-identifier characters instead of
# adding a leading underscore.
saw_non_identifier_char = True

return result

def derive_module_name(*args):
"""Returns a derived module name from the given build label.
For targets whose module name is not explicitly specified, the module name
is computed using the following algorithm:
* The package and name components of the label are considered separately.
All _interior_ sequences of non-identifier characters (anything other
than `a-z`, `A-Z`, `0-9`, and `_`) are replaced by a single underscore
(`_`). Any leading or trailing non-identifier characters are dropped.
* If the package component is non-empty after the above transformation,
it is joined with the transformed name component using an underscore.
Otherwise, the transformed name is used by itself.
* If this would result in a string that begins with a digit (`0-9`), an
underscore is prepended to make it identifier-safe.
This mapping is intended to be fairly predictable, but not reversible.
Args:
*args: Either a single argument of type `Label`, or two arguments of
type `str` where the first argument is the package name and the
second argument is the target name.
Returns:
The module name derived from the label.
"""
if (len(args) == 1 and
hasattr(args[0], "package") and
hasattr(args[0], "name")):
label = args[0]
package = label.package
name = label.name
elif (len(args) == 2 and
types.is_string(args[0]) and
types.is_string(args[1])):
package = args[0]
name = args[1]
else:
fail("derive_module_name may only be called with a single argument " +
"of type 'Label' or two arguments of type 'str'.")

package_part = _module_name_safe(package.lstrip("//"))
name_part = _module_name_safe(name)
if package_part:
module_name = package_part + "_" + name_part
else:
module_name = name_part
if module_name[0].isdigit():
module_name = "_" + module_name
return module_name

def create_compilation_context(defines, srcs, transitive_modules):
"""Cretes a compilation context for a Swift target.
Expand Down Expand Up @@ -228,8 +155,8 @@ def compile_module_interface(
feature_configuration: A feature configuration obtained from
`swift_common.configure_features`.
module_name: The name of the Swift module being compiled. This must be
present and valid; use `swift_common.derive_module_name` to generate
a default from the target's label if needed.
present and valid; use `derive_swift_module_name` to generate a
default from the target's label if needed.
swiftinterface_file: The Swift module interface file to compile.
swift_infos: A list of `SwiftInfo` providers from dependencies of the
target being compiled.
Expand Down Expand Up @@ -416,8 +343,8 @@ def compile(
should be generated for this module. If omitted, no header will be
generated.
module_name: The name of the Swift module being compiled. This must be
present and valid; use `swift_common.derive_module_name` to generate
a default from the target's label if needed.
present and valid; use `derive_swift_module_name` to generate a
default from the target's label if needed.
objc_infos: A list of `apple_common.ObjC` providers that represent
C/Objective-C requirements of the target being compiled, such as
Swift-compatible preprocessor defines, header search paths, and so
Expand Down
4 changes: 2 additions & 2 deletions swift/module_name.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ def derive_swift_module_name(*args):
package = args[0]
name = args[1]
else:
fail("derive_module_name may only be called with a single argument " +
"of type 'Label' or two arguments of type 'str'.")
fail("derive_swift_module_name may only be called with a single " +
"argument of type 'Label' or two arguments of type 'str'.")

package_part = _module_name_safe(package.lstrip("//"))
name_part = _module_name_safe(name)
Expand Down
3 changes: 2 additions & 1 deletion swift/swift_binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ load(
"get_providers",
"include_developer_search_paths",
)
load(":module_name.bzl", "derive_swift_module_name")
load(":providers.bzl", "SwiftCompilerPluginInfo", "SwiftInfo")
load(":swift_common.bzl", "swift_common")

Expand Down Expand Up @@ -79,7 +80,7 @@ def _swift_binary_impl(ctx):
if srcs:
module_name = ctx.attr.module_name
if not module_name:
module_name = swift_common.derive_module_name(ctx.label)
module_name = derive_swift_module_name(ctx.label)

include_dev_srch_paths = include_developer_search_paths(ctx.attr)

Expand Down
11 changes: 4 additions & 7 deletions swift/swift_clang_module_aspect.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@

load("@bazel_skylib//lib:sets.bzl", "sets")
load("//swift/internal:attrs.bzl", "swift_toolchain_attrs")
load(
"//swift/internal:compiling.bzl",
"derive_module_name",
"precompile_clang_module",
)
load("//swift/internal:compiling.bzl", "precompile_clang_module")
load(
"//swift/internal:feature_names.bzl",
"SWIFT_FEATURE_EMIT_C_MODULE",
Expand Down Expand Up @@ -54,6 +50,7 @@ load(
"//swift/internal:utils.bzl",
"compilation_context_for_explicit_module_compilation",
)
load(":module_name.bzl", "derive_swift_module_name")
load(":providers.bzl", "SwiftInfo")

_MULTIPLE_TARGET_ASPECT_ATTRS = [
Expand Down Expand Up @@ -360,7 +357,7 @@ def _module_info_for_target(
# was some other `Objc`-providing target, derive the module name
# now.
if not module_name:
module_name = derive_module_name(target.label)
module_name = derive_swift_module_name(target.label)

# If we didn't get a module map above, generate it now.
if not module_map_file:
Expand Down Expand Up @@ -696,7 +693,7 @@ def _swift_clang_module_aspect_impl(target, aspect_ctx):
exclude_headers = interop_info.exclude_headers
module_map_file = interop_info.module_map
module_name = (
interop_info.module_name or derive_module_name(target.label)
interop_info.module_name or derive_swift_module_name(target.label)
)
swift_infos.extend(interop_info.swift_infos)
requested_features.extend(interop_info.requested_features)
Expand Down
6 changes: 4 additions & 2 deletions swift/swift_common.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ load(
"compile",
"compile_module_interface",
"create_compilation_context",
"derive_module_name",
"precompile_clang_module",
)
load(
Expand Down Expand Up @@ -61,6 +60,7 @@ load(
"get_swift_toolchain",
"use_swift_toolchain",
)
load(":module_name.bzl", "derive_swift_module_name")

# The exported `swift_common` module, which defines the public API for directly
# invoking actions that compile Swift code from other rules.
Expand All @@ -77,7 +77,9 @@ swift_common = struct(
create_swift_info = create_swift_info,
create_swift_interop_info = create_swift_interop_info,
create_swift_module = create_swift_module,
derive_module_name = derive_module_name,
# TODO(b/261444771): Remove this after everyone is migrated to the free
# function.
derive_module_name = derive_swift_module_name,
extract_symbol_graph = extract_symbol_graph,
get_toolchain = get_swift_toolchain,
is_enabled = is_feature_enabled,
Expand Down
Loading

0 comments on commit 16a50dc

Please sign in to comment.