|  | # Copyright 2024 The Bazel Authors. All rights reserved. | 
|  | # | 
|  | # Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | # you may not use this file except in compliance with the License. | 
|  | # You may obtain a copy of the License at | 
|  | # | 
|  | #     http://www.apache.org/licenses/LICENSE-2.0 | 
|  | # | 
|  | # Unless required by applicable law or agreed to in writing, software | 
|  | # distributed under the License is distributed on an "AS IS" BASIS, | 
|  | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | # See the License for the specific language governing permissions and | 
|  | # limitations under the License. | 
|  | """Test subjects for cc_toolchain_info providers.""" | 
|  |  | 
|  | load("@bazel_skylib//lib:structs.bzl", "structs") | 
|  | load("@rules_testing//lib:truth.bzl", _subjects = "subjects") | 
|  | load( | 
|  | "//cc/toolchains:cc_toolchain_info.bzl", | 
|  | "ActionTypeInfo", | 
|  | "ActionTypeSetInfo", | 
|  | "ArgsInfo", | 
|  | "ArgsListInfo", | 
|  | "EnvInfo", | 
|  | "FeatureConstraintInfo", | 
|  | "FeatureInfo", | 
|  | "FeatureSetInfo", | 
|  | "MutuallyExclusiveCategoryInfo", | 
|  | "NestedArgsInfo", | 
|  | "ToolCapabilityInfo", | 
|  | "ToolConfigInfo", | 
|  | "ToolInfo", | 
|  | "ToolchainConfigInfo", | 
|  | ) | 
|  | load(":generate_factory.bzl", "ProviderDepset", "ProviderSequence", "generate_factory") | 
|  | load(":generics.bzl", "dict_key_subject", "optional_subject", "result_subject", "struct_subject", _result_fn_wrapper = "result_fn_wrapper") | 
|  |  | 
|  | visibility("//tests/rule_based_toolchain/...") | 
|  |  | 
|  | # The default runfiles subject uses path instead of short_path. | 
|  | # This makes it rather awkward for copybara. | 
|  | runfiles_subject = lambda value, meta: _subjects.depset_file(value.files, meta = meta) | 
|  |  | 
|  | # The string type has .equals(), which is all we can really do for an unknown | 
|  | # type. | 
|  | unknown_subject = _subjects.str | 
|  |  | 
|  | # Directory depsets are quite complex, so just simplify them as a list of paths. | 
|  | # buildifier: disable=name-conventions | 
|  | _FakeDirectoryDepset = lambda value, *, meta: _subjects.collection([v.path for v in value.to_list()], meta = meta) | 
|  |  | 
|  | # buildifier: disable=name-conventions | 
|  | _ActionTypeFactory = generate_factory( | 
|  | ActionTypeInfo, | 
|  | "ActionTypeInfo", | 
|  | dict( | 
|  | name = _subjects.str, | 
|  | ), | 
|  | ) | 
|  |  | 
|  | # buildifier: disable=name-conventions | 
|  | _ActionTypeSetFactory = generate_factory( | 
|  | ActionTypeSetInfo, | 
|  | "ActionTypeInfo", | 
|  | dict( | 
|  | actions = ProviderDepset(_ActionTypeFactory), | 
|  | ), | 
|  | ) | 
|  |  | 
|  | # buildifier: disable=name-conventions | 
|  | _MutuallyExclusiveCategoryFactory = generate_factory( | 
|  | MutuallyExclusiveCategoryInfo, | 
|  | "MutuallyExclusiveCategoryInfo", | 
|  | dict(name = _subjects.str), | 
|  | ) | 
|  |  | 
|  | _FEATURE_FLAGS = dict( | 
|  | name = _subjects.str, | 
|  | enabled = _subjects.bool, | 
|  | args = None, | 
|  | implies = None, | 
|  | requires_any_of = None, | 
|  | mutually_exclusive = ProviderSequence(_MutuallyExclusiveCategoryFactory), | 
|  | overridable = _subjects.bool, | 
|  | external = _subjects.bool, | 
|  | overrides = None, | 
|  | allowlist_include_directories = _FakeDirectoryDepset, | 
|  | allowlist_absolute_include_directories = ProviderDepset(_subjects.str), | 
|  | ) | 
|  |  | 
|  | # Break the dependency loop. | 
|  | # buildifier: disable=name-conventions | 
|  | _FakeFeatureFactory = generate_factory( | 
|  | FeatureInfo, | 
|  | "FeatureInfo", | 
|  | _FEATURE_FLAGS, | 
|  | ) | 
|  |  | 
|  | # buildifier: disable=name-conventions | 
|  | _FeatureSetFactory = generate_factory( | 
|  | FeatureSetInfo, | 
|  | "FeatureSetInfo", | 
|  | dict(features = ProviderDepset(_FakeFeatureFactory)), | 
|  | ) | 
|  |  | 
|  | # buildifier: disable=name-conventions | 
|  | _FeatureConstraintFactory = generate_factory( | 
|  | FeatureConstraintInfo, | 
|  | "FeatureConstraintInfo", | 
|  | dict( | 
|  | all_of = ProviderDepset(_FakeFeatureFactory), | 
|  | none_of = ProviderDepset(_FakeFeatureFactory), | 
|  | ), | 
|  | ) | 
|  |  | 
|  | _NESTED_ARGS_FLAGS = dict( | 
|  | nested = None, | 
|  | files = _subjects.depset_file, | 
|  | iterate_over = optional_subject(_subjects.str), | 
|  | legacy_flag_group = unknown_subject, | 
|  | requires_types = _subjects.dict, | 
|  | unwrap_options = _subjects.collection, | 
|  | ) | 
|  |  | 
|  | # buildifier: disable=name-conventions | 
|  | _FakeNestedArgsFactory = generate_factory( | 
|  | NestedArgsInfo, | 
|  | "NestedArgsInfo", | 
|  | _NESTED_ARGS_FLAGS, | 
|  | ) | 
|  |  | 
|  | # buildifier: disable=name-conventions | 
|  | _NestedArgsFactory = generate_factory( | 
|  | NestedArgsInfo, | 
|  | "NestedArgsInfo", | 
|  | _NESTED_ARGS_FLAGS | dict( | 
|  | nested = ProviderSequence(_FakeNestedArgsFactory), | 
|  | ), | 
|  | ) | 
|  |  | 
|  | # buildifier: disable=name-conventions | 
|  | _EnvInfoFactory = generate_factory( | 
|  | EnvInfo, | 
|  | "EnvInfo", | 
|  | dict( | 
|  | entries = _subjects.dict, | 
|  | requires_not_none = optional_subject(_subjects.str), | 
|  | ), | 
|  | ) | 
|  |  | 
|  | # buildifier: disable=name-conventions | 
|  | _ArgsFactory = generate_factory( | 
|  | ArgsInfo, | 
|  | "ArgsInfo", | 
|  | dict( | 
|  | actions = ProviderDepset(_ActionTypeFactory), | 
|  | env = _EnvInfoFactory.factory, | 
|  | files = _subjects.depset_file, | 
|  | # Use .factory so it's not inlined. | 
|  | nested = optional_subject(_NestedArgsFactory.factory), | 
|  | requires_any_of = ProviderSequence(_FeatureConstraintFactory), | 
|  | allowlist_include_directories = _FakeDirectoryDepset, | 
|  | allowlist_absolute_include_directories = ProviderDepset(_subjects.str), | 
|  | ), | 
|  | ) | 
|  |  | 
|  | # buildifier: disable=name-conventions | 
|  | _ArgsListFactory = generate_factory( | 
|  | ArgsListInfo, | 
|  | "ArgsListInfo", | 
|  | dict( | 
|  | args = ProviderSequence(_ArgsFactory), | 
|  | by_action = lambda values, *, meta: dict_key_subject(struct_subject( | 
|  | args = _subjects.collection, | 
|  | files = _subjects.depset_file, | 
|  | ))({value.action: value for value in values}, meta = meta), | 
|  | files = _subjects.depset_file, | 
|  | allowlist_include_directories = _FakeDirectoryDepset, | 
|  | allowlist_absolute_include_directories = ProviderDepset(_subjects.str), | 
|  | ), | 
|  | ) | 
|  |  | 
|  | # buildifier: disable=name-conventions | 
|  | _FeatureFactory = generate_factory( | 
|  | FeatureInfo, | 
|  | "FeatureInfo", | 
|  | _FEATURE_FLAGS | dict( | 
|  | # Use .factory so it's not inlined. | 
|  | args = _ArgsListFactory.factory, | 
|  | implies = ProviderDepset(_FakeFeatureFactory), | 
|  | requires_any_of = ProviderSequence(_FeatureSetFactory), | 
|  | overrides = optional_subject(_FakeFeatureFactory.factory), | 
|  | ), | 
|  | ) | 
|  |  | 
|  | # buildifier: disable=name-conventions | 
|  | _ToolCapabilityFactory = generate_factory( | 
|  | ToolCapabilityInfo, | 
|  | "ToolCapabilityInfo", | 
|  | dict( | 
|  | name = _subjects.str, | 
|  | ), | 
|  | ) | 
|  |  | 
|  | # buildifier: disable=name-conventions | 
|  | _ToolFactory = generate_factory( | 
|  | ToolInfo, | 
|  | "ToolInfo", | 
|  | dict( | 
|  | exe = _subjects.file, | 
|  | runfiles = runfiles_subject, | 
|  | execution_requirements = _subjects.collection, | 
|  | allowlist_include_directories = _FakeDirectoryDepset, | 
|  | capabilities = ProviderSequence(_ToolCapabilityFactory), | 
|  | ), | 
|  | ) | 
|  |  | 
|  | # buildifier: disable=name-conventions | 
|  | _ToolConfigFactory = generate_factory( | 
|  | ToolConfigInfo, | 
|  | "ToolConfigInfo", | 
|  | dict( | 
|  | configs = dict_key_subject(_ToolFactory.factory), | 
|  | ), | 
|  | ) | 
|  |  | 
|  | # buildifier: disable=name-conventions | 
|  | _ToolchainConfigFactory = generate_factory( | 
|  | ToolchainConfigInfo, | 
|  | "ToolchainConfigInfo", | 
|  | dict( | 
|  | features = ProviderDepset(_FeatureFactory), | 
|  | enabled_features = _subjects.collection, | 
|  | tool_map = optional_subject(_ToolConfigFactory.factory), | 
|  | args = ProviderSequence(_ArgsFactory), | 
|  | files = dict_key_subject(_subjects.depset_file), | 
|  | allowlist_include_directories = _FakeDirectoryDepset, | 
|  | allowlist_absolute_include_directories = ProviderDepset(_subjects.str), | 
|  | artifact_name_patterns = [], | 
|  | make_variables = [], | 
|  | ), | 
|  | ) | 
|  |  | 
|  | FACTORIES = [ | 
|  | _ActionTypeFactory, | 
|  | _ActionTypeSetFactory, | 
|  | _NestedArgsFactory, | 
|  | _ArgsFactory, | 
|  | _ArgsListFactory, | 
|  | _MutuallyExclusiveCategoryFactory, | 
|  | _FeatureFactory, | 
|  | _FeatureConstraintFactory, | 
|  | _FeatureSetFactory, | 
|  | _ToolFactory, | 
|  | _ToolConfigFactory, | 
|  | _ToolchainConfigFactory, | 
|  | ] | 
|  |  | 
|  | result_fn_wrapper = _result_fn_wrapper | 
|  |  | 
|  | subjects = struct( | 
|  | **(structs.to_dict(_subjects) | dict( | 
|  | unknown = unknown_subject, | 
|  | result = result_subject, | 
|  | optional = optional_subject, | 
|  | struct = struct_subject, | 
|  | runfiles = runfiles_subject, | 
|  | dict_key = dict_key_subject, | 
|  | ) | {factory.name: factory.factory for factory in FACTORIES}) | 
|  | ) |