Skip to content

Commit 40b7230

Browse files
coadometa-codesync[bot]
authored andcommitted
Normalize pointer and reference spacing in parser output (#55901)
Summary: Pull Request resolved: #55901 Fixes inconsistent spacing around pointer (`*`) and reference (`&`, `&&`) symbols in the parser output. Doxygen outputs types with a space before `*` and `&` (e.g., `NSString *`), which is inconsistent. This diff adds `normalize_pointer_spacing()` to standardize the output: - `NSString *` → `NSString*` - `int &` → `int&` - `T &&` → `T&&` - For function arguments: `NSString *name` → `NSString* name` ## Changes 1. Added `normalize_pointer_spacing()` function in `text_resolution.py` 2. Applied normalization in `resolve_ref_text_name()` and `resolve_linked_text_name()` 3. Applied normalization to block property argsstrings in `builders.py` 4. Updated all affected snapshot files to use normalized spacing Changelog: [Internal] Reviewed By: cortinico Differential Revision: D95078214
1 parent a1cb055 commit 40b7230

File tree

21 files changed

+75
-35
lines changed

21 files changed

+75
-35
lines changed

scripts/cxx-api/parser/builders.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
Argument,
3434
extract_qualifiers,
3535
InitializerType,
36+
normalize_pointer_spacing,
3637
parse_qualified_path,
3738
resolve_linked_text_name,
3839
)
@@ -344,7 +345,9 @@ def get_property_member(
344345
if property_type.endswith("(^"):
345346
argsstring = member_def.get_argsstring()
346347
if argsstring:
347-
property_type = f"{property_type}{property_name}{argsstring}"
348+
# Normalize pointer spacing in the argsstring
349+
normalized_argsstring = normalize_pointer_spacing(argsstring)
350+
property_type = f"{property_type}{property_name}{normalized_argsstring}"
348351
property_name = ""
349352

350353
return PropertyMember(

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
extract_namespace_from_refid,
1919
InitializerType,
2020
normalize_angle_brackets,
21+
normalize_pointer_spacing,
2122
resolve_linked_text_name,
2223
)
2324
from .type_qualification import qualify_arguments, qualify_parsed_type, qualify_type_str

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

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,46 @@ def extract_namespace_from_refid(refid: str) -> str:
8383

8484
def normalize_angle_brackets(text: str) -> str:
8585
"""Doxygen adds spaces around < and > to avoid XML ambiguity.
86-
e.g. "NSArray< id< RCTBridgeMethod > > *" -> "NSArray<id<RCTBridgeMethod>> *"
86+
e.g. "NSArray< id< RCTBridgeMethod > > *" -> "NSArray<id<RCTBridgeMethod>>*"
8787
"""
8888
text = re.sub(r"<\s+", "<", text)
8989
text = re.sub(r"\s+>", ">", text)
9090
return text
9191

9292

93+
def normalize_pointer_spacing(text: str) -> str:
94+
"""Normalize spacing around pointer (*) and reference (&, &&) symbols.
95+
96+
Doxygen outputs types with a space before * and &, e.g.:
97+
- "NSString *" -> "NSString*"
98+
- "int &" -> "int&"
99+
- "T &&" -> "T&&"
100+
101+
But for function arguments like "NSString *name", we want "NSString* name"
102+
(space moved from before * to after *).
103+
104+
This normalizes to have no space before the pointer/reference symbol,
105+
while preserving the space after if there's an identifier following.
106+
"""
107+
# For patterns like "Type *name" -> "Type* name" (move space from before to after)
108+
# Match: word/type character or > followed by space(s), then *, then word char
109+
text = re.sub(r"(\w|>)\s+\*(\w)", r"\1* \2", text)
110+
# For patterns like "Type *" at end or before comma/paren/angle/open-paren -> "Type*"
111+
text = re.sub(r"(\w|>)\s+\*(?=\s*[,)>(]|$)", r"\1*", text)
112+
# For patterns like "Type *" followed by another * (pointer to pointer)
113+
text = re.sub(r"(\w|>)\s+\*(?=\*)", r"\1*", text)
114+
115+
# Same for && (rvalue reference)
116+
text = re.sub(r"(\w|>)\s+&&(\w)", r"\1&& \2", text)
117+
text = re.sub(r"(\w|>)\s+&&(?=\s*[,)>(]|$)", r"\1&&", text)
118+
119+
# Same for & (lvalue reference) - but don't match &&
120+
text = re.sub(r"(\w|>)\s+&(?!&)(\w)", r"\1& \2", text)
121+
text = re.sub(r"(\w|>)\s+&(?!&)(?=\s*[,)>(]|$)", r"\1&", text)
122+
123+
return text
124+
125+
93126
class InitializerType(Enum):
94127
NONE = (0,)
95128
ASSIGNMENT = (1,)
@@ -145,7 +178,10 @@ def resolve_linked_text_name(
145178
initialier_type = InitializerType.BRACE
146179
name = name[1:-1].strip()
147180

148-
return (normalize_angle_brackets(name.strip()), initialier_type)
181+
return (
182+
normalize_pointer_spacing(normalize_angle_brackets(name.strip())),
183+
initialier_type,
184+
)
149185

150186

151187
def _qualify_text_with_refid(text: str, refid: str) -> str:

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class test::Clss {
1010
public void fn7(std::vector<std::vector<std::pair<int, int>>> v);
1111
public void fn8(std::map<K, std::function<void(A, B)>> m);
1212
public void fn9(int(*)(int, int) callback);
13-
public void fn10(void(*)(const char *, size_t) handler);
13+
public void fn10(void(*)(const char*, size_t) handler);
1414
public void fn11(int(*(*fp)(int))(double));
1515
public void fn12(int x = 5, std::string s = "default");
1616
public void fn13(std::function<void()> f = nullptr);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
template <typename T, typename ReturnT = std::any>
2-
concept test::CSSParserSink = requires(CSSSyntaxParser &parser) {
2+
concept test::CSSParserSink = requires(CSSSyntaxParser& parser) {
33
{ T::consume(parser) } -> std::convertible_to<ReturnT>;
44
};
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
template <typename ReturnT, typename... VisitorsT>
2-
concept test::CSSUniqueComponentValueVisitors = CSSSyntaxVisitorReturn<ReturnT> && (CSSComponentValueVisitor<VisitorsT, ReturnT> && ...) &&
3-
((CSSFunctionVisitor<VisitorsT, ReturnT> ? 1 : 0) + ... + 0) <= 1 &&
4-
((CSSPreservedTokenVisitor<VisitorsT, ReturnT> ? 1 : 0) + ... + 0) <= 1 &&
2+
concept test::CSSUniqueComponentValueVisitors = CSSSyntaxVisitorReturn<ReturnT>&& (CSSComponentValueVisitor<VisitorsT, ReturnT> && ...) &&
3+
((CSSFunctionVisitor<VisitorsT, ReturnT> ? 1 : 0) + ... + 0) <= 1&&
4+
((CSSPreservedTokenVisitor<VisitorsT, ReturnT> ? 1 : 0) + ... + 0) <= 1&&
55
((CSSSimpleBlockVisitor<VisitorsT, ReturnT> ? 1 : 0) + ... + 0) <= 1;
66
template <typename T, typename ReturnT = std::any>
7-
concept test::CSSParserSink = requires(CSSSyntaxParser &parser) {
7+
concept test::CSSParserSink = requires(CSSSyntaxParser& parser) {
88
{ T::consume(parser) } -> std::convertible_to<ReturnT>;
99
};

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ interface RCTDeprecatedInterface {
66
}
77

88
interface RCTTestInterface {
9-
public virtual NSArray * deprecatedMethod:(id param);
10-
public virtual void normalMethod:(NSString * name);
9+
public virtual NSArray* deprecatedMethod:(id param);
10+
public virtual void normalMethod:(NSString* name);
1111
}
1212

1313
protocol RCTDeprecatedProtocol {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
struct test::FunctionPointers {
22
public int(*withReturn)(double, float);
3-
public void *(*returnsPointer)(const char *);
43
public void(*simple)(int);
4+
public void*(*returnsPointer)(const char *);
55
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
interface RCTInterfaceWithBlockProperty : public NSObject {
2-
public @property (copy) NSString *(^blockWithReturn)(int value);
3-
public @property (copy) void(^eventInterceptor)(NSString *eventName, NSDictionary *event, NSNumber *reactTag);
2+
public @property (copy) NSString*(^blockWithReturn)(int value);
3+
public @property (copy) void(^eventInterceptor)(NSString* eventName, NSDictionary* event, NSNumber* reactTag);
44
public @property (copy) void(^simpleBlock)(void);
55
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
interface RCTInterfaceWithMethod {
2-
public virtual NSString * getTitle();
2+
public virtual NSString* getTitle();
33
public virtual void doSomething();
4-
public virtual void processValue:withName:(int value, NSString * name);
4+
public virtual void processValue:withName:(int value, NSString* name);
55
}

0 commit comments

Comments
 (0)