diff --git a/scripts/cxx-api/manual_test/.doxygen.config.template b/scripts/cxx-api/manual_test/.doxygen.config.template index 9a4e9b94f37f..80290595ec93 100644 --- a/scripts/cxx-api/manual_test/.doxygen.config.template +++ b/scripts/cxx-api/manual_test/.doxygen.config.template @@ -2442,7 +2442,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = +PREDEFINED = FOLLY_PACK_PUSH="" FOLLY_PACK_POP="" FOLLY_PACK_ATTR="" __attribute__(x)="" ${PREDEFINED} # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/scripts/cxx-api/parser/main.py b/scripts/cxx-api/parser/main.py index 563fdac88439..2db54b9f26a1 100644 --- a/scripts/cxx-api/parser/main.py +++ b/scripts/cxx-api/parser/main.py @@ -8,7 +8,6 @@ import os import re from enum import Enum -from pprint import pprint from doxmlparser import compound, index @@ -17,10 +16,11 @@ EnumMember, FriendMember, FunctionMember, + PropertyMember, TypedefMember, VariableMember, ) -from .scope import StructLikeScopeKind +from .scope import InterfaceScopeKind, ProtocolScopeKind, StructLikeScopeKind from .snapshot import Snapshot from .template import Template from .utils import Argument, extract_qualifiers, parse_qualified_path @@ -119,6 +119,15 @@ def _qualify_text_with_refid(text: str, refid: str) -> str: return prepend + "::" + text +def normalize_angle_brackets(text: str) -> str: + """Doxygen adds spaces around < and > to avoid XML ambiguity. + e.g. "NSArray< id< RCTBridgeMethod > > *" -> "NSArray> *" + """ + text = re.sub(r"<\s+", "<", text) + text = re.sub(r"\s+>", ">", text) + return text + + def extract_namespace_from_refid(refid: str) -> str: """Extract the namespace prefix from a doxygen refid. e.g. 'namespacefacebook_1_1yoga_1a...' -> 'facebook::yoga' @@ -202,12 +211,13 @@ def resolve_linked_text_name( initialier_type = InitializerType.BRACE name = name[1:-1].strip() - return (name.strip(), initialier_type) + return (normalize_angle_brackets(name.strip()), initialier_type) def get_base_classes( compound_object: compound.CompounddefType, -) -> [StructLikeScopeKind.Base]: + base_class=StructLikeScopeKind.Base, +) -> list: """ Get the base classes of a compound object. """ @@ -229,7 +239,7 @@ def get_base_classes( continue base_classes.append( - StructLikeScopeKind.Base( + base_class( base_name, base_prot, base_virt == "virtual", @@ -484,6 +494,31 @@ def get_concept_member( return concept +def get_property_member( + member_def: compound.MemberdefType, + visibility: str, + is_static: bool = False, +) -> PropertyMember: + """ + Get the property member from a member definition. + """ + property_name = member_def.get_name() + property_type = resolve_linked_text_name(member_def.get_type())[0].strip() + accessor = member_def.accessor if hasattr(member_def, "accessor") else None + is_readable = getattr(member_def, "readable", "no") == "yes" + is_writable = getattr(member_def, "writable", "no") == "yes" + + return PropertyMember( + property_name, + property_type, + visibility, + is_static, + accessor, + is_readable, + is_writable, + ) + + def create_enum_scope(snapshot: Snapshot, enum_def: compound.EnumdefType): """ Create an enum scope in the snapshot. @@ -507,6 +542,131 @@ def create_enum_scope(snapshot: Snapshot, enum_def: compound.EnumdefType): ) +def create_protocol_scope(snapshot: Snapshot, scope_def: compound.CompounddefType): + """ + Create a protocol scope in the snapshot. + """ + # Doxygen appends "-p" to ObjC protocol compound names + protocol_name = scope_def.compoundname + if protocol_name.endswith("-p"): + protocol_name = protocol_name[:-2] + + protocol_scope = snapshot.create_protocol(protocol_name) + base_classes = get_base_classes(scope_def, base_class=ProtocolScopeKind.Base) + for base in base_classes: + base.name = base.name.strip("<>") + protocol_scope.kind.add_base(base_classes) + protocol_scope.location = scope_def.location.file + + for section_def in scope_def.sectiondef: + kind = section_def.kind + parts = kind.split("-") + visibility = parts[0] + is_static = "static" in parts + member_type = parts[-1] + + if visibility == "private": + pass + elif visibility in ("public", "protected"): + if member_type == "attrib": + for member_def in section_def.memberdef: + if member_def.kind == "variable": + protocol_scope.add_member( + get_variable_member(member_def, visibility, is_static) + ) + elif member_type == "func": + for function_def in section_def.memberdef: + protocol_scope.add_member( + get_function_member(function_def, visibility, is_static) + ) + elif member_type == "type": + for member_def in section_def.memberdef: + if member_def.kind == "enum": + create_enum_scope(snapshot, member_def) + elif member_def.kind == "typedef": + protocol_scope.add_member( + get_typedef_member(member_def, visibility) + ) + else: + print( + f"Unknown section member kind: {member_def.kind} in {scope_def.location.file}" + ) + else: + print( + f"Unknown protocol section kind: {kind} in {scope_def.location.file}" + ) + elif visibility == "property": + for member_def in section_def.memberdef: + if member_def.kind == "property": + protocol_scope.add_member( + get_property_member(member_def, "public", is_static) + ) + else: + print( + f"Unknown protocol visibility: {visibility} in {scope_def.location.file}" + ) + + +def create_interface_scope(snapshot: Snapshot, scope_def: compound.CompounddefType): + """ + Create an interface scope in the snapshot (Objective-C @interface). + """ + interface_name = scope_def.compoundname + + 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) + interface_scope.location = scope_def.location.file + + for section_def in scope_def.sectiondef: + kind = section_def.kind + parts = kind.split("-") + visibility = parts[0] + is_static = "static" in parts + member_type = parts[-1] + + if visibility == "private": + pass + elif visibility in ("public", "protected"): + if member_type == "attrib": + for member_def in section_def.memberdef: + if member_def.kind == "variable": + interface_scope.add_member( + get_variable_member(member_def, visibility, is_static) + ) + elif member_type == "func": + for function_def in section_def.memberdef: + interface_scope.add_member( + get_function_member(function_def, visibility, is_static) + ) + elif member_type == "type": + for member_def in section_def.memberdef: + if member_def.kind == "enum": + create_enum_scope(snapshot, member_def) + elif member_def.kind == "typedef": + interface_scope.add_member( + get_typedef_member(member_def, visibility) + ) + else: + print( + f"Unknown section member kind: {member_def.kind} in {scope_def.location.file}" + ) + else: + print( + f"Unknown interface section kind: {kind} in {scope_def.location.file}" + ) + elif visibility == "property": + for member_def in section_def.memberdef: + if member_def.kind == "property": + interface_scope.add_member( + get_property_member(member_def, "public", is_static) + ) + else: + print( + f"Unknown interface visibility: {visibility} in {scope_def.location.file}" + ) + + def build_snapshot(xml_dir: str) -> Snapshot: """ Reads the Doxygen XML output and builds a snapshot of the C++ API. @@ -527,12 +687,23 @@ def build_snapshot(xml_dir: str) -> Snapshot: doxygen_object = compound.parse(detail_file, silence=True) for compound_object in doxygen_object.compounddef: + # Check if this is an Objective-C interface by looking at the compound id + # Doxygen reports ObjC interfaces as kind="class" but with id starting with "interface" + is_objc_interface = ( + compound_object.kind == "class" + and compound_object.id.startswith("interface") + ) + # classes and structs are represented by the same scope with a different kind if ( compound_object.kind == "class" or compound_object.kind == "struct" or compound_object.kind == "union" ): + # Handle Objective-C interfaces separately + if is_objc_interface: + create_interface_scope(snapshot, compound_object) + continue class_scope = ( snapshot.create_struct_like( compound_object.compoundname, StructLikeScopeKind.Type.CLASS @@ -679,7 +850,9 @@ def build_snapshot(xml_dir: str) -> Snapshot: # Contains deprecation info pass elif compound_object.kind == "protocol": - print(f"Protocol not supported: {compound_object.compoundname}") + create_protocol_scope(snapshot, compound_object) + elif compound_object.kind == "interface": + create_interface_scope(snapshot, compound_object) else: print(f"Unknown compound kind: {compound_object.kind}") diff --git a/scripts/cxx-api/parser/member.py b/scripts/cxx-api/parser/member.py index 7a9debcf1c32..e4cb35cc8b7b 100644 --- a/scripts/cxx-api/parser/member.py +++ b/scripts/cxx-api/parser/member.py @@ -381,6 +381,56 @@ def to_string( return result +class PropertyMember(Member): + def __init__( + self, + name: str, + type: str, + visibility: str, + is_static: bool, + accessor: str | None, + is_readable: bool, + is_writable: bool, + ) -> None: + super().__init__(name, visibility) + self.type: str = type + self.is_static: bool = is_static + self.accessor: str | None = accessor + self.is_readable: bool = is_readable + self.is_writable: bool = is_writable + + @property + def member_kind(self) -> MemberKind: + return MemberKind.VARIABLE + + def to_string( + self, + indent: int = 0, + qualification: str | None = None, + hide_visibility: bool = False, + ) -> str: + name = self._get_qualified_name(qualification) + result = " " * indent + + if not hide_visibility: + result += self.visibility + " " + + attributes = [] + if self.accessor: + attributes.append(self.accessor) + if not self.is_writable and self.is_readable: + attributes.append("readonly") + + attrs_str = f"({', '.join(attributes)}) " if attributes else "" + + if self.is_static: + result += "static " + + result += f"@property {attrs_str}{self.type} {name};" + + return result + + class ConceptMember(Member): def __init__( self, diff --git a/scripts/cxx-api/parser/scope.py b/scripts/cxx-api/parser/scope.py index d3b02febfdec..18880f12374a 100644 --- a/scripts/cxx-api/parser/scope.py +++ b/scripts/cxx-api/parser/scope.py @@ -153,6 +153,106 @@ def to_string(self, scope: Scope) -> str: return result +class ProtocolScopeKind(ScopeKind): + class Base: + def __init__( + self, name: str, protection: str, virtual: bool, refid: str + ) -> None: + self.name: str = name + self.protection: str = protection + self.virtual: bool = virtual + self.refid: str = refid + + def __init__(self) -> None: + super().__init__("protocol") + self.base_classes: [ProtocolScopeKind.Base] = [] + + def add_base(self, base: ProtocolScopeKind.Base | [ProtocolScopeKind.Base]) -> None: + if isinstance(base, list): + for b in base: + self.base_classes.append(b) + else: + self.base_classes.append(base) + + def to_string(self, scope: Scope) -> str: + result = "" + + bases = [] + for base in self.base_classes: + base_text = [base.protection] + if base.virtual: + base_text.append("virtual") + base_text.append(base.name) + bases.append(" ".join(base_text)) + + inheritance_string = " : " + ", ".join(bases) if bases else "" + + result += f"{self.name} {scope.get_qualified_name()}{inheritance_string} {{" + + stringified_members = [] + for member in scope.get_members(): + stringified_members.append(member.to_string(2)) + stringified_members = natsorted(stringified_members) + result += ("\n" if len(stringified_members) > 0 else "") + "\n".join( + stringified_members + ) + + result += "\n}" + + return result + + +class InterfaceScopeKind(ScopeKind): + class Base: + def __init__( + self, name: str, protection: str, virtual: bool, refid: str + ) -> None: + self.name: str = name + self.protection: str = protection + self.virtual: bool = virtual + self.refid: str = refid + + def __init__(self) -> None: + super().__init__("interface") + self.base_classes: [InterfaceScopeKind.Base] = [] + + def add_base( + self, base: InterfaceScopeKind.Base | [InterfaceScopeKind.Base] + ) -> None: + if isinstance(base, list): + for b in base: + self.base_classes.append(b) + else: + self.base_classes.append(base) + + def to_string(self, scope: Scope) -> str: + result = "" + + bases = [] + for base in self.base_classes: + base_text = [base.protection] + if base.virtual: + base_text.append("virtual") + base_text.append(base.name) + bases.append(" ".join(base_text)) + + inheritance_string = " : " + ", ".join(bases) if bases else "" + + result += f"{self.name} {scope.get_qualified_name()}{inheritance_string} {{" + + stringified_members = [] + for member in scope.get_members(): + stringified_members.append(member.to_string(2)) + stringified_members = natsorted(stringified_members) + result += ("\n" if len(stringified_members) > 0 else "") + "\n".join( + stringified_members + ) + + result += "\n}" + + return result + + class TemporaryScopeKind(ScopeKind): def __init__(self) -> None: super().__init__("temporary") diff --git a/scripts/cxx-api/parser/snapshot.py b/scripts/cxx-api/parser/snapshot.py index e9c8da42456f..87664bc84904 100644 --- a/scripts/cxx-api/parser/snapshot.py +++ b/scripts/cxx-api/parser/snapshot.py @@ -7,7 +7,9 @@ from .scope import ( EnumScopeKind, + InterfaceScopeKind, NamespaceScopeKind, + ProtocolScopeKind, Scope, StructLikeScopeKind, TemporaryScopeKind, @@ -84,6 +86,54 @@ def create_or_get_namespace(self, qualified_name: str) -> Scope[NamespaceScopeKi current_scope.inner_scopes[namespace_name] = new_scope return new_scope + def create_protocol(self, qualified_name: str) -> Scope[ProtocolScopeKind]: + """ + Create a protocol in the snapshot. + """ + path = parse_qualified_path(qualified_name) + scope_path = path[0:-1] + scope_name = path[-1] + current_scope = self.ensure_scope(scope_path) + + if scope_name in current_scope.inner_scopes: + scope = current_scope.inner_scopes[scope_name] + if scope.kind.name == "temporary": + scope.kind = ProtocolScopeKind() + else: + raise RuntimeError( + f"Identifier {scope_name} already exists in scope {current_scope.name}" + ) + return scope + else: + new_scope = Scope(ProtocolScopeKind(), scope_name) + new_scope.parent_scope = current_scope + current_scope.inner_scopes[scope_name] = new_scope + return new_scope + + def create_interface(self, qualified_name: str) -> Scope[InterfaceScopeKind]: + """ + Create an interface in the snapshot. + """ + path = parse_qualified_path(qualified_name) + scope_path = path[0:-1] + scope_name = path[-1] + current_scope = self.ensure_scope(scope_path) + + if scope_name in current_scope.inner_scopes: + scope = current_scope.inner_scopes[scope_name] + if scope.kind.name == "temporary": + scope.kind = InterfaceScopeKind() + else: + raise RuntimeError( + f"Identifier {scope_name} already exists in scope {current_scope.name}" + ) + return scope + else: + new_scope = Scope(InterfaceScopeKind(), scope_name) + new_scope.parent_scope = current_scope + current_scope.inner_scopes[scope_name] = new_scope + return new_scope + def create_enum(self, qualified_name: str) -> Scope[EnumScopeKind]: """ Create an enum in the snapshot. diff --git a/scripts/cxx-api/parser/utils/type_qualification.py b/scripts/cxx-api/parser/utils/type_qualification.py index db5ff592c96c..d3b1595c9613 100644 --- a/scripts/cxx-api/parser/utils/type_qualification.py +++ b/scripts/cxx-api/parser/utils/type_qualification.py @@ -50,7 +50,7 @@ def qualify_type_str(type_str: str, scope: Scope) -> str: # Split template arguments and qualify each one args = _split_arguments(template_args) qualified_args = [qualify_type_str(arg.strip(), scope) for arg in args] - qualified_template = "< " + ", ".join(qualified_args) + " >" + qualified_template = "<" + ", ".join(qualified_args) + ">" # Recursively qualify the suffix (handles nested templates, pointers, etc.) qualified_suffix = qualify_type_str(suffix, scope) if suffix else "" diff --git a/scripts/cxx-api/tests/snapshots/should_handle_array_param/snapshot.api b/scripts/cxx-api/tests/snapshots/should_handle_array_param/snapshot.api index 33b7d58819d1..79c7f047c95d 100644 --- a/scripts/cxx-api/tests/snapshots/should_handle_array_param/snapshot.api +++ b/scripts/cxx-api/tests/snapshots/should_handle_array_param/snapshot.api @@ -1,7 +1,7 @@ struct test::Node { public void setArray(int(&arr)[10]); template - public static std::vector< test::PropNameID > names(test::PropNameID(&&propertyNames)[N]); + public static std::vector names(test::PropNameID(&&propertyNames)[N]); } struct test::PropNameID { diff --git a/scripts/cxx-api/tests/snapshots/should_handle_brace_initialized_optional_field/snapshot.api b/scripts/cxx-api/tests/snapshots/should_handle_brace_initialized_optional_field/snapshot.api index ef41a7398208..19fa56a75e6e 100644 --- a/scripts/cxx-api/tests/snapshots/should_handle_brace_initialized_optional_field/snapshot.api +++ b/scripts/cxx-api/tests/snapshots/should_handle_brace_initialized_optional_field/snapshot.api @@ -1,4 +1,4 @@ struct test::Config { - public std::optional< bool > expanded; - public std::optional< std::string > label; + public std::optional expanded; + public std::optional label; } diff --git a/scripts/cxx-api/tests/snapshots/should_handle_class_public_method_arguments/snapshot.api b/scripts/cxx-api/tests/snapshots/should_handle_class_public_method_arguments/snapshot.api index 1204a64ce870..f0d525d1c1c9 100644 --- a/scripts/cxx-api/tests/snapshots/should_handle_class_public_method_arguments/snapshot.api +++ b/scripts/cxx-api/tests/snapshots/should_handle_class_public_method_arguments/snapshot.api @@ -2,19 +2,19 @@ class test::Clss { public virtual void fn16() = 0; public void fn0(int32_t arg1); public void fn1(int32_t arg1, int32_t arg2); - public void fn2(std::function< int32_t(int32_t) > arg1); - public void fn3(std::function< int32_t(int32_t) > arg1, std::function< int32_t(int32_t, int32_t) > arg2); - public void fn4(std::map< std::string, int > m); - public void fn5(std::unordered_map< K, std::vector< V > > m); - public void fn6(std::tuple< int, float, std::string > t); - public void fn7(std::vector< std::vector< std::pair< int, int > > > v); - public void fn8(std::map< K, std::function< void(A, B) > > m); + public void fn2(std::function arg1); + public void fn3(std::function arg1, std::function arg2); + public void fn4(std::map m); + public void fn5(std::unordered_map> m); + public void fn6(std::tuple t); + public void fn7(std::vector>> v); + public void fn8(std::map> m); public void fn9(int(*)(int, int) callback); public void fn10(void(*)(const char *, size_t) handler); public void fn11(int(*(*fp)(int))(double)); public void fn12(int x = 5, std::string s = "default"); - public void fn13(std::function< void() > f = nullptr); - public void fn14(std::vector< int > v = {1, 2, 3}); + public void fn13(std::function f = nullptr); + public void fn14(std::vector v = {1, 2, 3}); public void fn15() noexcept; public void fn17() = default; public void fn18() = delete; diff --git a/scripts/cxx-api/tests/snapshots/should_handle_interface_empty/snapshot.api b/scripts/cxx-api/tests/snapshots/should_handle_interface_empty/snapshot.api new file mode 100644 index 000000000000..d34dd4d4b97b --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_interface_empty/snapshot.api @@ -0,0 +1,2 @@ +interface RCTEmptyInterface { +} diff --git a/scripts/cxx-api/tests/snapshots/should_handle_interface_empty/test.h b/scripts/cxx-api/tests/snapshots/should_handle_interface_empty/test.h new file mode 100644 index 000000000000..dd07ab5f1eaa --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_interface_empty/test.h @@ -0,0 +1,10 @@ +/* + * 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. + */ + +@interface RCTEmptyInterface + +@end diff --git a/scripts/cxx-api/tests/snapshots/should_handle_interface_inheritance/snapshot.api b/scripts/cxx-api/tests/snapshots/should_handle_interface_inheritance/snapshot.api new file mode 100644 index 000000000000..a76ddd4246e8 --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_interface_inheritance/snapshot.api @@ -0,0 +1,7 @@ +interface RCTBaseInterface { + public virtual void baseMethod(); +} + +interface RCTChildInterface : public RCTBaseInterface { + public virtual void childMethod(); +} diff --git a/scripts/cxx-api/tests/snapshots/should_handle_interface_inheritance/test.h b/scripts/cxx-api/tests/snapshots/should_handle_interface_inheritance/test.h new file mode 100644 index 000000000000..d431b5357c7a --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_interface_inheritance/test.h @@ -0,0 +1,18 @@ +/* + * 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. + */ + +@interface RCTBaseInterface + +- (void)baseMethod; + +@end + +@interface RCTChildInterface : RCTBaseInterface + +- (void)childMethod; + +@end diff --git a/scripts/cxx-api/tests/snapshots/should_handle_interface_with_method/snapshot.api b/scripts/cxx-api/tests/snapshots/should_handle_interface_with_method/snapshot.api new file mode 100644 index 000000000000..09d8acf70147 --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_interface_with_method/snapshot.api @@ -0,0 +1,5 @@ +interface RCTInterfaceWithMethod { + public virtual NSString * getTitle(); + public virtual void doSomething(); + public virtual void processValue:withName:(int value, NSString * name); +} diff --git a/scripts/cxx-api/tests/snapshots/should_handle_interface_with_method/test.h b/scripts/cxx-api/tests/snapshots/should_handle_interface_with_method/test.h new file mode 100644 index 000000000000..d889dbf21176 --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_interface_with_method/test.h @@ -0,0 +1,14 @@ +/* + * 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. + */ + +@interface RCTInterfaceWithMethod + +- (void)doSomething; +- (NSString *)getTitle; +- (void)processValue:(int)value withName:(NSString *)name; + +@end diff --git a/scripts/cxx-api/tests/snapshots/should_handle_interface_with_property/snapshot.api b/scripts/cxx-api/tests/snapshots/should_handle_interface_with_property/snapshot.api new file mode 100644 index 000000000000..b5649f46485f --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_interface_with_property/snapshot.api @@ -0,0 +1,5 @@ +interface RCTInterfaceWithProperty { + public @property (assign) BOOL enabled; + public @property (copy) NSString * title; + public @property (weak) id delegate; +} diff --git a/scripts/cxx-api/tests/snapshots/should_handle_interface_with_property/test.h b/scripts/cxx-api/tests/snapshots/should_handle_interface_with_property/test.h new file mode 100644 index 000000000000..e000d1845b6e --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_interface_with_property/test.h @@ -0,0 +1,14 @@ +/* + * 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. + */ + +@interface RCTInterfaceWithProperty + +@property (nonatomic, copy) NSString *title; +@property (nonatomic, assign) BOOL enabled; +@property (nonatomic, weak) id delegate; + +@end diff --git a/scripts/cxx-api/tests/snapshots/should_handle_protocol_empty/snapshot.api b/scripts/cxx-api/tests/snapshots/should_handle_protocol_empty/snapshot.api new file mode 100644 index 000000000000..a4e95e7e1002 --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_protocol_empty/snapshot.api @@ -0,0 +1,2 @@ +protocol RCTEmptyProtocol { +} diff --git a/scripts/cxx-api/tests/snapshots/should_handle_protocol_empty/test.h b/scripts/cxx-api/tests/snapshots/should_handle_protocol_empty/test.h new file mode 100644 index 000000000000..8975fea28e06 --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_protocol_empty/test.h @@ -0,0 +1,10 @@ +/* + * 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. + */ + +@protocol RCTEmptyProtocol + +@end diff --git a/scripts/cxx-api/tests/snapshots/should_handle_protocol_inheritance/snapshot.api b/scripts/cxx-api/tests/snapshots/should_handle_protocol_inheritance/snapshot.api new file mode 100644 index 000000000000..2c9218fcb2d9 --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_protocol_inheritance/snapshot.api @@ -0,0 +1,7 @@ +protocol RCTBaseProtocol { + public virtual void baseMethod(); +} + +protocol RCTChildProtocol : public RCTBaseProtocol { + public virtual void childMethod(); +} diff --git a/scripts/cxx-api/tests/snapshots/should_handle_protocol_inheritance/test.h b/scripts/cxx-api/tests/snapshots/should_handle_protocol_inheritance/test.h new file mode 100644 index 000000000000..e930448d16ad --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_protocol_inheritance/test.h @@ -0,0 +1,18 @@ +/* + * 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. + */ + +@protocol RCTBaseProtocol + +- (void)baseMethod; + +@end + +@protocol RCTChildProtocol + +- (void)childMethod; + +@end diff --git a/scripts/cxx-api/tests/snapshots/should_handle_protocol_with_method/snapshot.api b/scripts/cxx-api/tests/snapshots/should_handle_protocol_with_method/snapshot.api new file mode 100644 index 000000000000..3cd0361bbc06 --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_protocol_with_method/snapshot.api @@ -0,0 +1,5 @@ +protocol RCTProtocolWithMethod { + public virtual NSString * getTitle(); + public virtual void doSomething(); + public virtual void processValue:withName:(int value, NSString * name); +} diff --git a/scripts/cxx-api/tests/snapshots/should_handle_protocol_with_method/test.h b/scripts/cxx-api/tests/snapshots/should_handle_protocol_with_method/test.h new file mode 100644 index 000000000000..59f9a2632988 --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_protocol_with_method/test.h @@ -0,0 +1,14 @@ +/* + * 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. + */ + +@protocol RCTProtocolWithMethod + +- (void)doSomething; +- (NSString *)getTitle; +- (void)processValue:(int)value withName:(NSString *)name; + +@end diff --git a/scripts/cxx-api/tests/snapshots/should_handle_protocol_with_property/snapshot.api b/scripts/cxx-api/tests/snapshots/should_handle_protocol_with_property/snapshot.api new file mode 100644 index 000000000000..c2322a45e0bb --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_protocol_with_property/snapshot.api @@ -0,0 +1,5 @@ +protocol RCTProtocolWithProperty { + public @property (assign) BOOL enabled; + public @property (copy) NSString * title; + public @property (weak) id delegate; +} diff --git a/scripts/cxx-api/tests/snapshots/should_handle_protocol_with_property/test.h b/scripts/cxx-api/tests/snapshots/should_handle_protocol_with_property/test.h new file mode 100644 index 000000000000..8454a588f0d6 --- /dev/null +++ b/scripts/cxx-api/tests/snapshots/should_handle_protocol_with_property/test.h @@ -0,0 +1,14 @@ +/* + * 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. + */ + +@protocol RCTProtocolWithProperty + +@property (nonatomic, copy) NSString *title; +@property (nonatomic, assign) BOOL enabled; +@property (nonatomic, weak) id delegate; + +@end diff --git a/scripts/cxx-api/tests/snapshots/should_handle_pure_virtual_trailing_return/snapshot.api b/scripts/cxx-api/tests/snapshots/should_handle_pure_virtual_trailing_return/snapshot.api index e2c51844a8fa..ea4b88b13cd4 100644 --- a/scripts/cxx-api/tests/snapshots/should_handle_pure_virtual_trailing_return/snapshot.api +++ b/scripts/cxx-api/tests/snapshots/should_handle_pure_virtual_trailing_return/snapshot.api @@ -1,6 +1,6 @@ class test::Base { public virtual const char * getName() = 0; - public virtual std::vector< test::Method > getMethods() = 0; + public virtual std::vector getMethods() = 0; } struct test::Method { diff --git a/scripts/cxx-api/tests/snapshots/should_handle_struct_inline_enum_brace_init/snapshot.api b/scripts/cxx-api/tests/snapshots/should_handle_struct_inline_enum_brace_init/snapshot.api index ec3c672d4185..92ae623da73c 100644 --- a/scripts/cxx-api/tests/snapshots/should_handle_struct_inline_enum_brace_init/snapshot.api +++ b/scripts/cxx-api/tests/snapshots/should_handle_struct_inline_enum_brace_init/snapshot.api @@ -2,7 +2,7 @@ struct test::AccessibilityState { public bool busy; public bool disabled; public bool selected; - public std::optional< bool > expanded; + public std::optional expanded; public test::AccessibilityState::CheckedState checked; } diff --git a/scripts/cxx-api/tests/snapshots/should_handle_unnamed_template_param_with_default_value/snapshot.api b/scripts/cxx-api/tests/snapshots/should_handle_unnamed_template_param_with_default_value/snapshot.api index 9bd7cb104a9a..2e9194009dbb 100644 --- a/scripts/cxx-api/tests/snapshots/should_handle_unnamed_template_param_with_default_value/snapshot.api +++ b/scripts/cxx-api/tests/snapshots/should_handle_unnamed_template_param_with_default_value/snapshot.api @@ -11,6 +11,6 @@ class test::Symbol { } struct test::Value { - template ::value || std::is_base_of::value || std::is_base_of::value || std::is_base_of::value>> + template ::value || std::is_base_of::value || std::is_base_of::value || std::is_base_of::value>> public Value(T && other); } diff --git a/scripts/cxx-api/tests/snapshots/should_qualify_nested_template_type_with_underscore/snapshot.api b/scripts/cxx-api/tests/snapshots/should_qualify_nested_template_type_with_underscore/snapshot.api index 4792062a6df4..616760305e9b 100644 --- a/scripts/cxx-api/tests/snapshots/should_qualify_nested_template_type_with_underscore/snapshot.api +++ b/scripts/cxx-api/tests/snapshots/should_qualify_nested_template_type_with_underscore/snapshot.api @@ -1,8 +1,8 @@ template -facebook::react::detail::is_dynamic< T >::type & facebook::react::jsArgAsDynamic(T && args, size_t n); +facebook::react::detail::is_dynamic::type & facebook::react::jsArgAsDynamic(T && args, size_t n); template struct facebook::react::detail::is_dynamic { - public using type = typename std::enable_if< std::is_assignable< folly::dynamic, T >::value, T >::type; + public using type = typename std::enable_if::value, T>::type; } diff --git a/scripts/cxx-api/tests/snapshots/should_qualify_variable_inline_function_type/snapshot.api b/scripts/cxx-api/tests/snapshots/should_qualify_variable_inline_function_type/snapshot.api index 977576a2f088..fdbf54e36b3a 100644 --- a/scripts/cxx-api/tests/snapshots/should_qualify_variable_inline_function_type/snapshot.api +++ b/scripts/cxx-api/tests/snapshots/should_qualify_variable_inline_function_type/snapshot.api @@ -1,7 +1,7 @@ struct test::Container { - public std::function< test::Result(test::Param, int)> processor; - public std::function< void(const test::Param&, test::Result)> multiRef; - public std::function< void(test::Param)> simpleCallback; + public std::function processor; + public std::function multiRef; + public std::function simpleCallback; public test::Result(*fnPtrReturn)(const test::Param&); public void(*fnPtr)(test::Param, int); }