Skip to content

Commit b53c220

Browse files
committed
feat(rules_score): parse unit implementations with libclang
1 parent fd1e6c2 commit b53c220

1 file changed

Lines changed: 71 additions & 32 deletions

File tree

bazel/rules/rules_score/private/unit.bzl

Lines changed: 71 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,32 @@ following S-CORE process guidelines. A unit is the smallest testable
1919
software element with associated design, implementation, and tests.
2020
"""
2121

22+
load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
2223
load("@lobster//:lobster.bzl", "subrule_gtest_report")
24+
load("@rules_cc//cc:find_cc_toolchain.bzl", "use_cc_toolchain")
2325
load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
2426
load("@rules_rust//rust:defs.bzl", "rust_common")
2527
load("//bazel/rules/rules_score:providers.bzl", "CcDependencyInfo", "CertifiedScope", "SphinxSourcesInfo", "UnitDesignInfo", "UnitInfo")
28+
load("//cpp/libclang:cpp_parser.bzl", "cpp_parser_action_internal_attrs", "cpp_parser_target_aspects", "has_cpp_parser_inputs", "run_cpp_parser_action")
2629
load(":cc_dependency_aspect.bzl", "cc_dependencies_aspect")
2730

31+
def _run_implementation_cpp_parser(ctx, impl, output_prefix):
32+
return run_cpp_parser_action(
33+
ctx,
34+
target = impl,
35+
output_prefix = output_prefix,
36+
tool = ctx.attr._tool,
37+
libclang = ctx.file._libclang,
38+
llvm_cxx_builtin_include = ctx.attr._llvm_cxx_builtin_include,
39+
llvm_extra_config_site = ctx.attr._llvm_extra_config_site,
40+
log_level = ctx.attr._log_level[BuildSettingInfo].value,
41+
)
42+
43+
def _target_output_prefix(ctx, target):
44+
package_name = target.label.package.replace("/", "_")
45+
target_name = target.label.name.replace("/", "_")
46+
return "{}_{}_{}".format(ctx.label.name, package_name, target_name)
47+
2848
# ============================================================================
2949
# Private Rule Implementation
3050
# ============================================================================
@@ -59,28 +79,41 @@ def _unit_impl(ctx):
5979
design_static_fbs_depset = depset(transitive = design_static_fbs)
6080
design_dynamic_fbs_depset = depset(transitive = design_dynamic_fbs)
6181

82+
# Generate FBS files for implementation targets supported by the libclang parser.
83+
implementation_class_fbs = []
84+
collected_dependent_labels = []
85+
for impl in ctx.attr.implementation:
86+
if CcDependencyInfo in impl:
87+
collected_dependent_labels.append(impl[CcDependencyInfo].dependencies)
88+
89+
if not has_cpp_parser_inputs(impl):
90+
continue
91+
92+
output_prefix = _target_output_prefix(ctx, impl)
93+
parser_outputs = _run_implementation_cpp_parser(ctx, impl, output_prefix)
94+
implementation_class_fbs.append(parser_outputs.class_fbs)
95+
6296
# Run each test executable via subrule_gtest_report and collect the XML outputs
6397
xml_files = []
6498
for test_target in ctx.attr.tests:
65-
pkg = test_target.label.package.replace("/", "_")
66-
test_name = test_target.label.name.replace("/", "_")
67-
unique_name = "{}_{}_{}_gtest_report".format(ctx.label.name, pkg, test_name)
68-
xml = subrule_gtest_report(unique_name, test_target.files_to_run.executable, test_target.default_runfiles.files)
99+
unique_name = "{}_gtest_report".format(
100+
_target_output_prefix(ctx, test_target),
101+
)
102+
xml = subrule_gtest_report(
103+
unique_name,
104+
test_target.files_to_run.executable,
105+
test_target.default_runfiles.files,
106+
)
69107
xml_files.append(xml)
70108

71109
tests_depset = depset(xml_files)
72110

73111
# Combine all files for DefaultInfo
74112
all_files = depset(
75-
xml_files,
113+
xml_files + implementation_class_fbs,
76114
transitive = [design_depset],
77115
)
78116

79-
collected_dependent_labels = []
80-
for impl in ctx.attr.implementation:
81-
if CcDependencyInfo in impl:
82-
collected_dependent_labels.append(impl[CcDependencyInfo].dependencies)
83-
84117
return [
85118
DefaultInfo(files = all_files),
86119
CertifiedScope(transitive_scopes = depset(ctx.attr.scope)),
@@ -103,32 +136,38 @@ def _unit_impl(ctx):
103136
# Rule Definition
104137
# ============================================================================
105138

139+
_unit_attrs = {
140+
"unit_design": attr.label_list(
141+
mandatory = True,
142+
providers = [UnitDesignInfo],
143+
doc = "Unit design artifacts (unit_design targets only)",
144+
),
145+
"implementation": attr.label_list(
146+
mandatory = True,
147+
providers = [[CcInfo], [rust_common.crate_info]],
148+
aspects = [cc_dependencies_aspect] + cpp_parser_target_aspects(),
149+
doc = "Implementation targets (cc_library, cc_binary, rust_library, rust_binary, etc.).",
150+
),
151+
"scope": attr.string_list(
152+
default = [],
153+
doc = "Additional not explicitly named targets which are needed for the unit implementation",
154+
),
155+
"tests": attr.label_list(
156+
mandatory = True,
157+
cfg = "exec",
158+
doc = "Test targets that verify the unit (cc_test, py_test, rust_test, etc.)",
159+
),
160+
}
161+
162+
_unit_attrs.update(cpp_parser_action_internal_attrs())
163+
106164
_unit = rule(
107165
implementation = _unit_impl,
108166
doc = "Defines a software unit with design, implementation, and tests for S-CORE process compliance",
109167
subrules = [subrule_gtest_report],
110-
attrs = {
111-
"unit_design": attr.label_list(
112-
mandatory = True,
113-
providers = [UnitDesignInfo],
114-
doc = "Unit design artifacts (unit_design targets only)",
115-
),
116-
"implementation": attr.label_list(
117-
mandatory = True,
118-
providers = [[CcInfo], [rust_common.crate_info]],
119-
aspects = [cc_dependencies_aspect],
120-
doc = "Implementation targets (cc_library, cc_binary, rust_library, rust_binary, etc.)",
121-
),
122-
"scope": attr.string_list(
123-
default = [],
124-
doc = "Additional not explicitly named targets which are needed for the unit implementation",
125-
),
126-
"tests": attr.label_list(
127-
mandatory = True,
128-
cfg = "exec",
129-
doc = "Test targets that verify the unit (cc_test, py_test, rust_test, etc.)",
130-
),
131-
},
168+
attrs = _unit_attrs,
169+
toolchains = use_cc_toolchain(),
170+
fragments = ["cpp"],
132171
)
133172

134173
# ============================================================================

0 commit comments

Comments
 (0)