From a5891b9776daa97bcb9859a24a697d181703ef18 Mon Sep 17 00:00:00 2001 From: Luis Padron Date: Thu, 20 Jun 2024 01:43:58 -0400 Subject: [PATCH] Add `emit_extension_block_symbols` for symbol graph extraction 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. --- doc/api.md | 7 ++--- swift/internal/swift_extract_symbol_graph.bzl | 16 ++++++++++++ swift/internal/swift_symbol_graph_aspect.bzl | 26 +++++++++++++++++++ swift/internal/symbol_graph_extracting.bzl | 16 ++++++++++++ test/fixtures/symbol_graphs/BUILD | 14 ++++++++++ .../SomeModuleWithExtension.swift | 19 ++++++++++++++ test/symbol_graphs_tests.bzl | 18 +++++++++++++ 7 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/symbol_graphs/SomeModuleWithExtension.swift diff --git a/doc/api.md b/doc/api.md index b3196d36d..062140cb0 100644 --- a/doc/api.md +++ b/doc/api.md @@ -543,9 +543,9 @@ The module name derived from the label. ## swift_common.extract_symbol_graph
-swift_common.extract_symbol_graph(actions, compilation_contexts, feature_configuration,
-                                  include_dev_srch_paths, minimum_access_level, module_name,
-                                  output_dir, swift_infos, swift_toolchain)
+swift_common.extract_symbol_graph(actions, compilation_contexts, emit_extension_block_symbols,
+                                  feature_configuration, include_dev_srch_paths, minimum_access_level,
+                                  module_name, output_dir, swift_infos, swift_toolchain)
 
Extracts the symbol graph from a Swift module. @@ -557,6 +557,7 @@ Extracts the symbol graph from a Swift module. | :------------- | :------------- | :------------- | | actions | The object used to register actions. | none | | 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 | +| emit_extension_block_symbols | A `bool` that indicates whether `extension` block information should be included in the symbol graph. | `None` | | feature_configuration | The Swift feature configuration. | none | | include_dev_srch_paths | A `bool` that indicates whether the developer framework search paths will be added to the compilation command. | none | | 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` | diff --git a/swift/internal/swift_extract_symbol_graph.bzl b/swift/internal/swift_extract_symbol_graph.bzl index 84d5ee306..e682e05a1 100644 --- a/swift/internal/swift_extract_symbol_graph.bzl +++ b/swift/internal/swift_extract_symbol_graph.bzl @@ -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 = """\ diff --git a/swift/internal/swift_symbol_graph_aspect.bzl b/swift/internal/swift_symbol_graph_aspect.bzl index c3380eebc..b05c3c3e2 100644 --- a/swift/internal/swift_symbol_graph_aspect.bzl +++ b/swift/internal/swift_symbol_graph_aspect.bzl @@ -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: @@ -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, @@ -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 @@ -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 = """\ @@ -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. @@ -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, ) diff --git a/swift/internal/symbol_graph_extracting.bzl b/swift/internal/symbol_graph_extracting.bzl index a5f02d80f..092ab0ec5 100644 --- a/swift/internal/symbol_graph_extracting.bzl +++ b/swift/internal/symbol_graph_extracting.bzl @@ -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 = [ @@ -44,6 +50,12 @@ 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: @@ -57,6 +69,7 @@ def extract_symbol_graph( *, actions, compilation_contexts, + emit_extension_block_symbols = None, feature_configuration, include_dev_srch_paths, minimum_access_level = None, @@ -73,6 +86,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. @@ -121,6 +136,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, diff --git a/test/fixtures/symbol_graphs/BUILD b/test/fixtures/symbol_graphs/BUILD index dfc1b4aeb..cde3c122b 100644 --- a/test/fixtures/symbol_graphs/BUILD +++ b/test/fixtures/symbol_graphs/BUILD @@ -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"], @@ -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, diff --git a/test/fixtures/symbol_graphs/SomeModuleWithExtension.swift b/test/fixtures/symbol_graphs/SomeModuleWithExtension.swift new file mode 100644 index 000000000..8cf1dc565 --- /dev/null +++ b/test/fixtures/symbol_graphs/SomeModuleWithExtension.swift @@ -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" + } +} diff --git a/test/symbol_graphs_tests.bzl b/test/symbol_graphs_tests.bzl index 98f6764f2..878604d27 100644 --- a/test/symbol_graphs_tests.bzl +++ b/test/symbol_graphs_tests.bzl @@ -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.