Skip to content

Commit

Permalink
Add emit_extension_block_symbols for symbol graph extraction
Browse files Browse the repository at this point in the history
The `emit_extension_block_symbols` attr can be used in the `swift_extract_symbol_graph` rule to pass the `-emit-extension-block-symbols` flag when creating the symbol graphs. This enables generating symbol graph information for extensions of custom types.
  • Loading branch information
luispadron committed Jun 20, 2024
1 parent 6e48feb commit 94e4693
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 3 deletions.
7 changes: 4 additions & 3 deletions doc/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -543,9 +543,9 @@ The module name derived from the label.
## swift_common.extract_symbol_graph

<pre>
swift_common.extract_symbol_graph(<a href="#swift_common.extract_symbol_graph-actions">actions</a>, <a href="#swift_common.extract_symbol_graph-compilation_contexts">compilation_contexts</a>, <a href="#swift_common.extract_symbol_graph-feature_configuration">feature_configuration</a>,
<a href="#swift_common.extract_symbol_graph-include_dev_srch_paths">include_dev_srch_paths</a>, <a href="#swift_common.extract_symbol_graph-minimum_access_level">minimum_access_level</a>, <a href="#swift_common.extract_symbol_graph-module_name">module_name</a>,
<a href="#swift_common.extract_symbol_graph-output_dir">output_dir</a>, <a href="#swift_common.extract_symbol_graph-swift_infos">swift_infos</a>, <a href="#swift_common.extract_symbol_graph-swift_toolchain">swift_toolchain</a>)
swift_common.extract_symbol_graph(<a href="#swift_common.extract_symbol_graph-actions">actions</a>, <a href="#swift_common.extract_symbol_graph-compilation_contexts">compilation_contexts</a>, <a href="#swift_common.extract_symbol_graph-emit_extension_block_symbols">emit_extension_block_symbols</a>,
<a href="#swift_common.extract_symbol_graph-feature_configuration">feature_configuration</a>, <a href="#swift_common.extract_symbol_graph-include_dev_srch_paths">include_dev_srch_paths</a>, <a href="#swift_common.extract_symbol_graph-minimum_access_level">minimum_access_level</a>,
<a href="#swift_common.extract_symbol_graph-module_name">module_name</a>, <a href="#swift_common.extract_symbol_graph-output_dir">output_dir</a>, <a href="#swift_common.extract_symbol_graph-swift_infos">swift_infos</a>, <a href="#swift_common.extract_symbol_graph-swift_toolchain">swift_toolchain</a>)
</pre>

Extracts the symbol graph from a Swift module.
Expand All @@ -557,6 +557,7 @@ Extracts the symbol graph from a Swift module.
| :------------- | :------------- | :------------- |
| <a id="swift_common.extract_symbol_graph-actions"></a>actions | The object used to register actions. | none |
| <a id="swift_common.extract_symbol_graph-compilation_contexts"></a>compilation_contexts | A list of `CcCompilationContext`s 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 the `CcInfo` providers of a target's dependencies. | none |
| <a id="swift_common.extract_symbol_graph-emit_extension_block_symbols"></a>emit_extension_block_symbols | A `bool` that indicates whether `extension` block information should be included in the symbol graph. | `None` |
| <a id="swift_common.extract_symbol_graph-feature_configuration"></a>feature_configuration | The Swift feature configuration. | none |
| <a id="swift_common.extract_symbol_graph-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.extract_symbol_graph-minimum_access_level"></a>minimum_access_level | The minimum access level of the declarations that should be extracted into the symbol graphs. The default value is `None`, which means the Swift compiler's default behavior should be used (at the time of this writing, the default behavior is "public"). | `None` |
Expand Down
16 changes: 16 additions & 0 deletions swift/internal/swift_extract_symbol_graph.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,22 @@ done

swift_extract_symbol_graph = rule(
attrs = {
# TODO: use `attr.bool` once https://github.com/bazelbuild/bazel/issues/22809 is resolved.
"emit_extension_block_symbols": attr.string(
default = "0",
doc = """\
Defines if the symbol graph information for `extension` blocks should be
emitted in addition to the default symbol graph information.
This value must be either `"0"` or `"1"`.When the value is `"1"`, the symbol
graph information for `extension` blocks will be emitted in addition to
the default symbol graph information. The default value is `"0"`.
""",
values = [
"0",
"1",
],
),
"minimum_access_level": attr.string(
default = "public",
doc = """\
Expand Down
26 changes: 26 additions & 0 deletions swift/internal/swift_symbol_graph_aspect.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def _swift_symbol_graph_aspect_impl(target, aspect_ctx):
else:
compilation_context = cc_common.create_compilation_context()

emit_extension_block_symbols = aspect_ctx.attr.emit_extension_block_symbols
minimum_access_level = aspect_ctx.attr.minimum_access_level

for module in swift_info.direct_modules:
Expand All @@ -55,6 +56,7 @@ def _swift_symbol_graph_aspect_impl(target, aspect_ctx):
extract_symbol_graph(
actions = aspect_ctx.actions,
compilation_contexts = [compilation_context],
emit_extension_block_symbols = emit_extension_block_symbols,
feature_configuration = feature_configuration,
include_dev_srch_paths = include_developer_search_paths(
aspect_ctx.rule.attr,
Expand Down Expand Up @@ -109,12 +111,16 @@ def _testonly_symbol_graph_aspect_impl(target, aspect_ctx):

def _make_swift_symbol_graph_aspect(
*,
default_emit_extension_block_symbols,
default_minimum_access_level,
doc = "",
testonly_targets):
"""Creates an aspect that extracts Swift symbol graphs from dependencies.
Args:
default_emit_extension_block_symbols: The default value for the `emit_extension_block_symbols`
attribute of the aspect. A rule that applies this aspect can let users
override this value if it also provides an attribute named `emit_extension_block_symbols`.
default_minimum_access_level: The default minimum access level of the
declarations that should be emitted in the symbol graphs. A rule
that applies this aspect can let users override this value if it
Expand All @@ -136,6 +142,24 @@ def _make_swift_symbol_graph_aspect(
attrs = dicts.add(
swift_toolchain_attrs(),
{
# TODO: use `attr.bool` once https://github.com/bazelbuild/bazel/issues/22809 is resolved.
"emit_extension_block_symbols": attr.string(
default = default_emit_extension_block_symbols,
doc = """\
Defines if the symbol graph information for `extension` blocks should be
emitted in addition to the default symbol graph information.
This value must be either `"0"` or `"1"`.When the value is `"1"`, the symbol
graph information for `extension` blocks will be emitted in addition to
the default symbol graph information. The default value is `"{default_value}"`.
""".format(
default_value = default_emit_extension_block_symbols,
),
values = [
"0",
"1",
],
),
"minimum_access_level": attr.string(
default = default_minimum_access_level,
doc = """\
Expand Down Expand Up @@ -164,6 +188,7 @@ default value is {default_value}.

# This aspect is exported as public API by `swift_common`.
swift_symbol_graph_aspect = _make_swift_symbol_graph_aspect(
default_emit_extension_block_symbols = "0",
default_minimum_access_level = "public",
doc = """\
Extracts symbol graphs from Swift modules in the build graph.
Expand All @@ -183,6 +208,7 @@ implementation of `swift_extract_symbol_graph`.
# This aspect is only meant to be used by `swift_test` and should not be
# exported by `swift_common`.
test_discovery_symbol_graph_aspect = _make_swift_symbol_graph_aspect(
default_emit_extension_block_symbols = "0",
default_minimum_access_level = "internal",
testonly_targets = True,
)
17 changes: 17 additions & 0 deletions swift/internal/symbol_graph_extracting.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ def symbol_graph_action_configs():
The list of action configs needed to extract symbol graphs.
"""
return [
swift_toolchain_config.action_config(
actions = [swift_action_names.SYMBOL_GRAPH_EXTRACT],
configurators = [
_symbol_graph_emit_extension_block_symbols_configurator,
],
),
swift_toolchain_config.action_config(
actions = [swift_action_names.SYMBOL_GRAPH_EXTRACT],
configurators = [
Expand All @@ -44,6 +50,13 @@ def symbol_graph_action_configs():
),
]

def _symbol_graph_emit_extension_block_symbols_configurator(prerequisites, args):
"""Configures whether `extension` block information should be emitted in the symbol graph."""

# TODO: update to use `bool` once https://github.com/bazelbuild/bazel/issues/22809 is resolved.
if prerequisites.emit_extension_block_symbols == "1":
args.add("-emit-extension-block-symbols")

def _symbol_graph_minimum_access_level_configurator(prerequisites, args):
"""Configures the minimum access level of the symbol graph extraction."""
if prerequisites.minimum_access_level:
Expand All @@ -57,6 +70,7 @@ def extract_symbol_graph(
*,
actions,
compilation_contexts,
emit_extension_block_symbols = None,
feature_configuration,
include_dev_srch_paths,
minimum_access_level = None,
Expand All @@ -73,6 +87,8 @@ def extract_symbol_graph(
Swift-compatible preprocessor defines, header search paths, and so
forth. These are typically retrieved from the `CcInfo` providers of
a target's dependencies.
emit_extension_block_symbols: A `bool` that indicates whether `extension` block
information should be included in the symbol graph.
feature_configuration: The Swift feature configuration.
include_dev_srch_paths: A `bool` that indicates whether the developer
framework search paths will be added to the compilation command.
Expand Down Expand Up @@ -121,6 +137,7 @@ def extract_symbol_graph(
bin_dir = feature_configuration._bin_dir,
cc_compilation_context = merged_compilation_context,
developer_dirs = swift_toolchain.developer_dirs,
emit_extension_block_symbols = emit_extension_block_symbols,
genfiles_dir = feature_configuration._genfiles_dir,
include_dev_srch_paths = include_dev_srch_paths,
is_swift = True,
Expand Down
14 changes: 14 additions & 0 deletions test/fixtures/symbol_graphs/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ swift_library(
tags = FIXTURE_TAGS,
)

swift_library(
name = "some_module_with_extension",
srcs = ["SomeModuleWithExtension.swift"],
module_name = "SomeModuleWithExtension",
tags = FIXTURE_TAGS,
)

swift_library(
name = "importing_module",
srcs = ["ImportingModule.swift"],
Expand All @@ -36,6 +43,13 @@ swift_extract_symbol_graph(
targets = [":some_module"],
)

swift_extract_symbol_graph(
name = "some_module_symbol_graph_with_extension_block_symbols",
emit_extension_block_symbols = "1",
tags = FIXTURE_TAGS,
targets = [":some_module_with_extension"],
)

swift_extract_symbol_graph(
name = "importing_module_symbol_graph",
tags = FIXTURE_TAGS,
Expand Down
19 changes: 19 additions & 0 deletions test/fixtures/symbol_graphs/SomeModuleWithExtension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/// This class is documented.
public class SomeClass {
/// This method is documented.
///
/// - Parameter count: This parameter is documented.
/// - Returns: This return value is documented.
public func someMethod(someParameter count: Int) -> String {
return String(repeating: "someString", count: count)
}
}

extension SomeClass {
/// This method is documented, and it's on an extension of a custom type.
///
/// - Returns: This return value is documented.
public func someExtensionMethod() -> String {
return "someString"
}
}
18 changes: 18 additions & 0 deletions test/symbol_graphs_tests.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ def symbol_graphs_test_suite(name):
target_under_test = "@build_bazel_rules_swift//test/fixtures/symbol_graphs:some_module_symbol_graph",
)

# TODO: ideally this tests the contents of the json file(s) to ensure
# the extension block symbols are present, but requires a json content test which
# is not yet implemented.
#
# Verify that the `swift_extract_symbol_graph` rule produces a directory
# output containing the correct files when the rule additionally requests
# to emit extension block symbols.
directory_test(
name = "{}_extract_rule_outputs_extension_block_symbols_files".format(name),
expected_directories = {
"test/fixtures/symbol_graphs/some_module_symbol_graph_with_extension_block_symbols.symbolgraphs": [
"SomeModuleWithExtension.symbols.json",
],
},
tags = [name],
target_under_test = "@build_bazel_rules_swift//test/fixtures/symbol_graphs:some_module_symbol_graph_with_extension_block_symbols",
)

# Verify that the `swift_extract_symbol_graph` rule produces a directory
# output containing only the graph for the requested target and not its
# dependencies.
Expand Down

0 comments on commit 94e4693

Please sign in to comment.