Skip to content

Commit 78ebd11

Browse files
coadometa-codesync[bot]
authored andcommitted
Filter category members from interface scope
Summary: Doxygen incorrectly merges category members into the base interface XML output. This causes duplicate members to appear in both the category scope and the interface scope. The fix detects category members by checking if their definition contains the pattern `ClassName(CategoryName)::` (e.g., `RCTBridgeProxy(Cxx)::cxxOnlyProperty`) and filters them out when processing interface sections. Changelog: [Internal] Reviewed By: cortinico Differential Revision: D95191148
1 parent 575a645 commit 78ebd11

File tree

5 files changed

+34
-6
lines changed

5 files changed

+34
-6
lines changed

scripts/cxx-api/parser/builders.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,15 +401,40 @@ def create_enum_scope(snapshot: Snapshot, enum_def: compound.EnumdefType) -> Non
401401
)
402402

403403

404+
def _is_category_member(member_def: compound.MemberdefType) -> bool:
405+
"""
406+
Check if a member comes from a category based on its definition.
407+
408+
Doxygen merges category members into the base interface XML output, but the
409+
member's definition field contains the category name in parentheses, e.g.:
410+
"int RCTBridgeProxy(Cxx)::cxxOnlyProperty"
411+
412+
We use this to filter out category members from the interface scope.
413+
"""
414+
definition = member_def.definition
415+
if not definition:
416+
return False
417+
418+
# Look for pattern: ClassName(CategoryName)::memberName
419+
# The definition contains the qualified name with category info
420+
return bool(re.search(r"\w+\([^)]+\)::", definition))
421+
422+
404423
def _process_objc_sections(
405424
snapshot: Snapshot,
406425
scope,
407426
section_defs: list,
408427
location_file: str,
409428
scope_type: str,
429+
filter_category_members: bool = False,
410430
) -> None:
411431
"""
412432
Common section processing for protocols and interfaces.
433+
434+
Args:
435+
filter_category_members: If True, skip members that come from categories.
436+
This is used for interfaces since Doxygen incorrectly merges category
437+
members into the base interface XML output.
413438
"""
414439
for section_def in section_defs:
415440
kind = section_def.kind
@@ -424,11 +449,15 @@ def _process_objc_sections(
424449
if member_type == "attrib":
425450
for member_def in section_def.memberdef:
426451
if member_def.kind == "variable":
452+
if filter_category_members and _is_category_member(member_def):
453+
continue
427454
scope.add_member(
428455
get_variable_member(member_def, visibility, is_static)
429456
)
430457
elif member_type == "func":
431458
for function_def in section_def.memberdef:
459+
if filter_category_members and _is_category_member(function_def):
460+
continue
432461
scope.add_member(
433462
get_function_member(function_def, visibility, is_static)
434463
)
@@ -437,6 +466,8 @@ def _process_objc_sections(
437466
if member_def.kind == "enum":
438467
create_enum_scope(snapshot, member_def)
439468
elif member_def.kind == "typedef":
469+
if filter_category_members and _is_category_member(member_def):
470+
continue
440471
scope.add_member(get_typedef_member(member_def, visibility))
441472
else:
442473
print(
@@ -447,6 +478,8 @@ def _process_objc_sections(
447478
elif visibility == "property":
448479
for member_def in section_def.memberdef:
449480
if member_def.kind == "property":
481+
if filter_category_members and _is_category_member(member_def):
482+
continue
450483
scope.add_member(
451484
get_property_member(member_def, "public", is_static)
452485
)
@@ -519,6 +552,7 @@ def create_interface_scope(
519552
scope_def.sectiondef,
520553
scope_def.location.file,
521554
"interface",
555+
filter_category_members=True,
522556
)
523557

524558

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,4 @@ category RCTConvert(UIActivityIndicatorView) {
33
}
44

55
interface RCTConvert : public NSObject {
6-
public virtual static UIActivityIndicatorViewStyle UIActivityIndicatorViewStyle:(id json);
76
}

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,4 @@ category RCTConvert(Transform) {
44
}
55

66
interface RCTConvert : public NSObject {
7-
public virtual static CATransform3D CATransform3D:(id json);
8-
public virtual static RCTTransformOrigin RCTTransformOrigin:(id json);
97
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,4 @@ category RCTBridgeProxy(Cxx) {
33
}
44

55
interface RCTBridgeProxy : public NSObject {
6-
public @property (assign) int cxxOnlyProperty;
76
}

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,4 @@ category RCTConvert(CategoryTwo) {
77
}
88

99
interface RCTConvert : public NSObject {
10-
public virtual static NSString* methodOne:(id json);
11-
public virtual static NSString* methodTwo:(id json);
1210
}

0 commit comments

Comments
 (0)