Skip to content

Commit a5daece

Browse files
j-piaseckimeta-codesync[bot]
authored andcommitted
Add reverse mapping for default values in base class specialization (#56032)
Summary: Pull Request resolved: #56032 Changelog: [Internal] When generating xml output, doxygen replaces template arguments in specialized base classes with the default values: ``` template <typename T = int> class Test : public Base<T> {}; ``` becomes ``` template <typename T = int> class Test : public Base<int> {}; ``` To work around this issue, this diff adds reverse mapping for template params in the base classes. In the above case, the map would be: `{ "int" -> "T" }`, and `int` in `Base<int>` would be replaced with T. This approach assumes that none of the default values are used directly in the base class specialization, which holds for the React Native codebase. Reviewed By: cortinico Differential Revision: D95933835 fbshipit-source-id: c1dd79a09f0f368fb106330409e15d54ebad2b4f
1 parent 7425a5f commit a5daece

3 files changed

Lines changed: 96 additions & 1 deletion

File tree

scripts/cxx-api/parser/builders.py

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,65 @@
3939
parse_qualified_path,
4040
resolve_linked_text_name,
4141
)
42+
from .utils.argument_parsing import _find_matching_angle, _split_arguments
43+
44+
45+
######################
46+
# Base class fixups
47+
######################
48+
49+
50+
def _fix_base_class_default_substitution(
51+
base_name: str,
52+
template_params: list[Template],
53+
) -> str:
54+
"""
55+
Workaround for Doxygen's substitution of template parameters with their
56+
defaults in base class template arguments. For example, given:
57+
58+
template <typename BazT = Baz>
59+
class Foo : public Bar<BazT> {};
60+
61+
Doxygen emits ``Bar<Baz>`` instead of ``Bar<BazT>``.
62+
63+
This function builds a reverse mapping (default_value -> param_name) and
64+
replaces matching template arguments in base_name with the parameter names.
65+
"""
66+
angle_start = base_name.find("<")
67+
if angle_start == -1:
68+
return base_name
69+
70+
angle_end = _find_matching_angle(base_name, angle_start)
71+
if angle_end == -1:
72+
return base_name
73+
74+
# Build reverse mapping: default_value -> param_name.
75+
# Map both fully qualified and unqualified names.
76+
default_to_param: dict[str, str] = {}
77+
for param in template_params:
78+
if param.value is not None and param.name is not None:
79+
default_to_param[param.value] = param.name
80+
last_sep = param.value.rfind("::")
81+
if last_sep != -1:
82+
default_to_param[param.value[last_sep + 2 :]] = param.name
83+
84+
if not default_to_param:
85+
return base_name
86+
87+
prefix = base_name[:angle_start]
88+
inner = base_name[angle_start + 1 : angle_end]
89+
suffix = base_name[angle_end + 1 :]
90+
91+
args = _split_arguments(inner)
92+
fixed_args = []
93+
for arg in args:
94+
stripped = arg.strip()
95+
if stripped in default_to_param:
96+
fixed_args.append(default_to_param[stripped])
97+
else:
98+
fixed_args.append(stripped)
99+
100+
return f"{prefix}<{', '.join(fixed_args)}>{suffix}"
42101

43102

44103
######################
@@ -604,7 +663,14 @@ def create_class_scope(
604663
)
605664

606665
class_scope.kind.add_base(get_base_classes(compound_object))
607-
class_scope.kind.add_template(get_template_params(compound_object))
666+
template_params = get_template_params(compound_object)
667+
668+
# Fix Doxygen's substitution of template param defaults in base classes
669+
if template_params:
670+
for base in class_scope.kind.base_classes:
671+
base.name = _fix_base_class_default_substitution(base.name, template_params)
672+
673+
class_scope.kind.add_template(template_params)
608674
class_scope.location = compound_object.location.file
609675

610676
for section_def in compound_object.sectiondef:
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
template <typename T = int>
2+
class test::Derived : public test::Base<T> {
3+
}
4+
5+
template <typename T>
6+
class test::Base {
7+
public T value;
8+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#pragma once
9+
10+
namespace test {
11+
12+
template <typename T>
13+
class Base {
14+
public:
15+
T value;
16+
};
17+
18+
template <typename T = int>
19+
class Derived : public Base<T> {};
20+
21+
} // namespace test

0 commit comments

Comments
 (0)