diff --git a/scripts/cxx-api/parser/builders.py b/scripts/cxx-api/parser/builders.py index 85d11f7ccc63..3361c25a35d7 100644 --- a/scripts/cxx-api/parser/builders.py +++ b/scripts/cxx-api/parser/builders.py @@ -465,7 +465,24 @@ def create_interface_scope( interface_scope = snapshot.create_interface(interface_name) base_classes = get_base_classes(scope_def, base_class=InterfaceScopeKind.Base) - interface_scope.kind.add_base(base_classes) + + # Doxygen incorrectly splits "Foo " into separate base classes: + # "Foo", "", "". Combine them back into "Foo ". + combined_bases = [] + for base in base_classes: + if base.name.startswith("<") and base.name.endswith(">") and combined_bases: + prev_name = combined_bases[-1].name + protocol = base.name[1:-1] # Strip < and > + if "<" in prev_name and prev_name.endswith(">"): + # Previous base already has protocols, merge inside the brackets + combined_bases[-1].name = f"{prev_name[:-1]}, {protocol}>" + else: + # First protocol for this base class + combined_bases[-1].name = f"{prev_name} <{protocol}>" + else: + combined_bases.append(base) + + interface_scope.kind.add_base(combined_bases) interface_scope.location = scope_def.location.file _process_objc_sections( diff --git a/scripts/cxx-api/tests/snapshots/should_handle_class_with_generic_inheritance/snapshot.api b/scripts/cxx-api/tests/snapshots/should_handle_class_with_generic_inheritance/snapshot.api new file mode 100644 index 000000000000..e10fec618c71 --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_class_with_generic_inheritance/snapshot.api @@ -0,0 +1,3 @@ +interface RCTAppearance : public RCTEventEmitter { + public virtual instancetype init(); +} diff --git a/scripts/cxx-api/tests/snapshots/should_handle_class_with_generic_inheritance/test.h b/scripts/cxx-api/tests/snapshots/should_handle_class_with_generic_inheritance/test.h new file mode 100644 index 000000000000..dc261f9b5083 --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_class_with_generic_inheritance/test.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +namespace test { + +@interface RCTAppearance : RCTEventEmitter +- (instancetype)init; +@end + +} // namespace test diff --git a/scripts/cxx-api/tests/snapshots/should_handle_class_with_multiple_protocol_conformances/snapshot.api b/scripts/cxx-api/tests/snapshots/should_handle_class_with_multiple_protocol_conformances/snapshot.api new file mode 100644 index 000000000000..f66dd58f6c0e --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_class_with_multiple_protocol_conformances/snapshot.api @@ -0,0 +1,2 @@ +interface RCTAlertManager : public NSObject { +} diff --git a/scripts/cxx-api/tests/snapshots/should_handle_class_with_multiple_protocol_conformances/test.h b/scripts/cxx-api/tests/snapshots/should_handle_class_with_multiple_protocol_conformances/test.h new file mode 100644 index 000000000000..02d7e217d22b --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_class_with_multiple_protocol_conformances/test.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +namespace test { + +@interface RCTAlertManager : NSObject + +@end + +} // namespace test