Skip to content

Commit 5e4da84

Browse files
j-piaseckimeta-codesync[bot]
authored andcommitted
Fix handling of unnamed template arguments (facebook#55646)
Summary: Pull Request resolved: facebook#55646 Changelog: [Internal] Updates the C++ API snapshot generator script to correctly handle unnamed template arguments. Reviewed By: cipolleschi Differential Revision: D93407624 fbshipit-source-id: 50928b596fe64fa3549cde5d69da7146b452d784
1 parent 269a2ee commit 5e4da84

6 files changed

Lines changed: 96 additions & 3 deletions

File tree

scripts/cxx-api/parser/main.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,16 @@ def get_template_params(
152152
template_type = " ".join(parts[:-1])
153153
template_name = parts[-1]
154154
elif len(parts) == 1:
155-
# Just a name like "T" with no type keyword
156-
template_name = parts[0]
155+
# Check if this is an unnamed template parameter
156+
# (just "typename" or "class" with or without a default value)
157+
# In this case, we leave name as None/empty
158+
if parts[0] in ("typename", "class"):
159+
# Unnamed template parameter
160+
# e.g., "typename" or "typename = std::enable_if_t<...>"
161+
template_name = None
162+
else:
163+
# Just a name like "T" with no type keyword
164+
template_name = parts[0]
157165

158166
template_params.append(
159167
Template(template_type, template_name, template_value)

scripts/cxx-api/parser/template.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,32 @@
33
# This source code is licensed under the MIT license found in the
44
# LICENSE file in the root directory of this source tree.
55

6+
import re
7+
8+
9+
def _normalize_whitespace(text: str) -> str:
10+
"""
11+
Normalize whitespace by collapsing multiple consecutive whitespace
12+
characters into a single space.
13+
"""
14+
return re.sub(r"\s+", " ", text).strip()
15+
616

717
class Template:
818
def __init__(self, type: str, name: str, value: str | None) -> None:
919
self.type: str = type
1020
self.name: str = name
11-
self.value: str | None = value
21+
self.value: str | None = _normalize_whitespace(value) if value else value
1222

1323
def to_string(self) -> str:
24+
# Handle unnamed template parameters (e.g., "typename = std::enable_if_t<...>")
25+
# When the name is empty or None, we just output "type = value" or "type"
26+
if not self.name:
27+
if self.value is None:
28+
return self.type
29+
else:
30+
return f"{self.type} = {self.value}"
31+
1432
if self.value is None:
1533
return f"{self.type} {self.name}"
1634
else:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
template <typename>
2+
struct test::is_optional : public std::false_type {
3+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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+
#include <type_traits>
11+
12+
namespace test {
13+
14+
// Unnamed template parameter without default value
15+
template <typename>
16+
struct is_optional : std::false_type {};
17+
18+
} // namespace test
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class test::BigInt {
2+
}
3+
4+
class test::Object {
5+
}
6+
7+
class test::String {
8+
}
9+
10+
class test::Symbol {
11+
}
12+
13+
struct test::Value {
14+
template <typename T, typename = std::enable_if_t< std::is_base_of<Symbol, T>::value || std::is_base_of<BigInt, T>::value || std::is_base_of<String, T>::value || std::is_base_of<Object, T>::value>>
15+
public Value(T && other);
16+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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+
#include <type_traits>
11+
12+
namespace test {
13+
14+
class Symbol {};
15+
class BigInt {};
16+
class String {};
17+
class Object {};
18+
19+
struct Value {
20+
template <
21+
typename T,
22+
typename = std::enable_if_t<
23+
std::is_base_of<Symbol, T>::value || std::is_base_of<BigInt, T>::value || std::is_base_of<String, T>::value ||
24+
std::is_base_of<Object, T>::value>>
25+
/* implicit */ Value(T &&other)
26+
{
27+
}
28+
};
29+
30+
} // namespace test

0 commit comments

Comments
 (0)