Skip to content

Commit dc8c442

Browse files
coadometa-codesync[bot]
authored andcommitted
Normalize template specialization angle bracket spacing (facebook#55910)
Summary: Pull Request resolved: facebook#55910 Normalizes angle bracket spacing in scope names for template specializations. Doxygen encodes template specializations with spaces around angle brackets in compound names (e.g., `CSSDataTypeParser< CSSMatrix >`). This caused inconsistent output in API snapshots. The fix applies `normalize_angle_brackets()` to qualified paths when parsing scope names, ensuring consistent output: - `CSSDataTypeParser< CSSMatrix >` → `CSSDataTypeParser<CSSMatrix>` - `Callback< R(Args...)>` → `Callback<R(Args...)>` Added a new test case `should_normalize_template_specialization_angle_brackets` to verify the fix. Changelog: [Internal] Reviewed By: cipolleschi Differential Revision: D95204780 fbshipit-source-id: d0d5fe7759a414b32630647f334b39e26da15108
1 parent 78c8842 commit dc8c442

6 files changed

Lines changed: 76 additions & 2 deletions

File tree

scripts/cxx-api/parser/__main__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ def main():
201201
"input_filters",
202202
"doxygen_strip_comments.py",
203203
)
204+
204205
input_filter = None
205206
if os.path.exists(input_filter_path):
206207
input_filter = f"python3 {input_filter_path}"
@@ -263,3 +264,7 @@ def build_snapshots(output_dir: str, verbose: bool) -> None:
263264
)
264265
)
265266
build_snapshots(output_dir, verbose=True)
267+
268+
269+
if __name__ == "__main__":
270+
main()

scripts/cxx-api/parser/builders.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
Argument,
3434
extract_qualifiers,
3535
InitializerType,
36+
normalize_angle_brackets,
3637
normalize_pointer_spacing,
3738
parse_qualified_path,
3839
resolve_linked_text_name,
@@ -59,7 +60,7 @@ def get_base_classes(
5960
# - prot: protection level (public, protected, private)
6061
# - virt: virtual inheritance (non-virtual, virtual, pure-virtual)
6162
# - valueOf_: the name of the base class
62-
base_name = base.valueOf_
63+
base_name = normalize_angle_brackets(base.valueOf_)
6364
base_prot = base.prot
6465
base_virt = base.virt
6566
base_refid = base.refid

scripts/cxx-api/parser/utils/qualified_path.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
from __future__ import annotations
77

8+
from .text_resolution import normalize_angle_brackets
9+
810

911
def parse_qualified_path(path: str) -> list[str]:
1012
"""
@@ -19,7 +21,12 @@ def parse_qualified_path(path: str) -> list[str]:
1921
- Comparison operators inside parentheses: "std::enable_if<(N > 0)>::type"
2022
- Arrow operators: "decltype(ptr->member)::type"
2123
- Bitshift operators: "std::integral_constant<int, (1 >> 2)>::value"
24+
25+
Normalizes angle bracket spacing (e.g., "Foo< Bar >" -> "Foo<Bar>").
2226
"""
27+
# Normalize angle bracket spacing before parsing
28+
path = normalize_angle_brackets(path)
29+
2330
result = []
2431
current = ""
2532
angle_depth = 0

scripts/cxx-api/tests/snapshots/should_handle_template_specialization_self_reference/snapshot.api

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ class test::Callback {
33
}
44

55
template <typename R, typename... Args>
6-
class test::Callback< R(Args...)> {
6+
class test::Callback<R(Args...)> {
77
public Callback(const test::Callback&) = delete;
88
public Callback(test::Callback&& other) noexcept;
99
public R call(Args... args) const;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class AndroidSwitchComponentDescriptor : public ConcreteComponentDescriptor<AndroidSwitchShadowNode> {
2+
public AndroidSwitchComponentDescriptor(const ComponentDescriptorParameters& parameters);
3+
public void adopt(ShadowNode& shadowNode) const;
4+
}
5+
6+
struct CSSDataTypeParser<CSSMatrix> {
7+
public static constexpr std::optional<CSSMatrix> consumeFunctionBlock(const CSSFunctionBlock& func, CSSValueParser& parser);
8+
}
9+
10+
struct CSSMatrix {
11+
public constexpr bool operator==(const CSSMatrix& rhs) const = default;
12+
public std::array<float, 6> values;
13+
}
14+
15+
template <typename ShadowNodeT>
16+
class ConcreteComponentDescriptor {
17+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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+
struct CSSMatrix {
9+
std::array<float, 6> values{};
10+
11+
constexpr bool operator==(const CSSMatrix &rhs) const = default;
12+
};
13+
14+
template <>
15+
struct CSSDataTypeParser<CSSMatrix> {
16+
static constexpr auto consumeFunctionBlock(const CSSFunctionBlock &func, CSSValueParser &parser)
17+
-> std::optional<CSSMatrix>
18+
{
19+
if (!iequals(func.name, "matrix")) {
20+
return {};
21+
}
22+
23+
CSSMatrix matrix{};
24+
for (int i = 0; i < 6; i++) {
25+
auto value = parser.parseNextValue<CSSNumber>(i == 0 ? CSSDelimiter::None : CSSDelimiter::Comma);
26+
if (std::holds_alternative<std::monostate>(value)) {
27+
return {};
28+
}
29+
matrix.values[i] = std::get<CSSNumber>(value).value;
30+
}
31+
32+
return matrix;
33+
}
34+
};
35+
36+
// Test base class inheritance with template angle brackets
37+
template <typename ShadowNodeT>
38+
class ConcreteComponentDescriptor {};
39+
40+
class AndroidSwitchComponentDescriptor : public ConcreteComponentDescriptor<AndroidSwitchShadowNode> {
41+
public:
42+
AndroidSwitchComponentDescriptor(const ComponentDescriptorParameters &parameters);
43+
void adopt(ShadowNode &shadowNode) const;
44+
};

0 commit comments

Comments
 (0)