24 Commits
Author SHA1 Message Date
artus9033 566c7ac2d1 fix: stabilize CXX API generator on MacOS, make parser indempotent for nested enums (#57536)
Summary:
Fixes C++ API snapshot generation failures for nested enums and macOS/Linux output drift due to platform-dependent behavior, in the CXX API generator.

### Problems

1. Duplicate enums: Doxygen parses codegen `EventEmitters.h` twice (direct codegen input + again via `.mm` includes). The parser raised `RuntimeError: Identifier OnOrientationChangeOrientation already exists in scope ModalHostViewEventEmitter` on `ReactApple*` views.

2. Inconsistent behaviour on MacOS vs Linux:
  - for codegen component aliases (`ConcreteComponentDescriptor`, `ConcreteViewShadowNode`), macOS Doxygen emits hybrid XML definitions (`typedef Type Name = Type`) while Linux CI emits `using Name = Type`. The parser keyed off `definition.startswith("typedef")`, so identical source produced different `.api` output per platform.
  - `CASE_SENSE_NAMES = SYSTEM` follows the host OS default (case-insensitive on macOS, case-sensitive on Linux), causing inconsistent symbol resolution.

### Resolution

- `.doxygen.config.template` files: set `CASE_SENSE_NAMES = YES` for deterministic name matching across macOS and Linux.
- `snapshot.py`: `create_enum()` returns an existing enum scope instead of raising when the enum is already registered.
- `builders.py`: `create_enum_scope()` to skip enums that already exist; `get_typedef_member()` to normalize Doxygen’s `typedef ... = ...` form to `using` so the output format is unified.

## Changelog:

[INTERNAL] [FIXED] - Fix C++ API snapshot generation crash on duplicate codegen enums
[INTERNAL] [FIXED] - Fix platform-dependent inconsistent CXX API generator output

Pull Request resolved: https://github.com/react/react-native/pull/57536

Test Plan:
- [x] `yarn cxx-api-build` completes on macOS (tested locally)
- [x] `yarn cxx-api-validate` passes (tested locally on MacOS & on the Linux CI)
- [x] `validate-cxx-api-snapshots` passes on Linux (tested on CI)

Reviewed By: j-piasecki

Differential Revision: D112793182

Pulled By: coado

fbshipit-source-id: ada818451fb1207d965c1bed4fb5ce23ee2fe00f
2026-07-20 05:01:24 -07:00
Dawid Małecki b60f0c9f04 Change parser config to accept regex in exclude symbols field. (#56367)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56367

Adds support for regex in the `exclude_symbols` field in the C++ API parser config. This enables better scoped definitions of symbols that should be matched.

Changelog:
[Internal]

Reviewed By: huntie

Differential Revision: D99844594

fbshipit-source-id: 0d2b4f9970c535afa6af8712c9435bdb06c50779
2026-04-09 07:04:52 -07:00
Dawid Małecki 8bf151f532 Remove members that reference excluded symbols (#56341)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56341

Exclude members from .api snapshots when their types (return type, parameter types, variable type, typedef target, property type) reference excluded symbols. Previously, only compounds whose names matched exclude_symbols patterns were excluded — but members of non-excluded compounds could still reference excluded types, causing dangling type references (e.g., `facebook::yoga::ExperimentalFeature`) to appear in the snapshot.

Changelog:
[Internal]

Reviewed By: huntie

Differential Revision: D99434605

fbshipit-source-id: 24d304754161ca891316061dbfee8c2be08d5d40
2026-04-09 07:04:52 -07:00
Jakub Piasecki f516811a95 Fix pointer-to-member-function param with ref-qualifier (#56219)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56219

Changelog: [Internal]

Doxygen has a bug where it incorrectly embeds the parameter name of pointer-to-member-function parameters with ref-qualifiers (& or &&) into the type string instead of providing a separate <declname> element.

This caused the snapshot to output `R(folly::dynamic::*)() const asFoo&` instead of the correct `R(folly::dynamic::*asFoo)() const &`.

This diff detects the misplaced name in the type string and reconstructs the correct pointer-to-member declarator.

Reviewed By: cipolleschi

Differential Revision: D98123353

fbshipit-source-id: a3a92c5d3897721f0b97a232fdaa59379b408b29
2026-03-26 08:40:54 -07:00
Jakub Piasecki 015cd13ab1 Deduplicate base classes from Doxygen using declaration (#56218)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56218

Changelog: [Internal]

When a class inherits constructors via `using Base::Base;`, Doxygen incorrectly emits duplicate `basecompoundref` entries for the same base class. This caused base classes like `ConverterBase` to appear twice in the snapshot output.

This diff deduplicates base classes by name in `get_base_classes()`.

Reviewed By: cipolleschi

Differential Revision: D98118659

fbshipit-source-id: c81f663480fda48c89e6dd625a504a78eb9d7c41
2026-03-26 08:40:54 -07:00
Jakub Piasecki 31f262ed2e Fix function pointer param args being qualified to outer class (#56217)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56217

Changelog: [Internal]

Doxygen may incorrectly cross-reference parameter names inside function
pointer types to member variables of the enclosing class. For example,
`void (*cb)(const void* data)` inside a class that has a `data` member
would produce `const void* Class::data` instead of
`const void* data` in the snapshot. This diff addresses two issues:

1. In `get_doxygen_params`, re-parse function pointer type strings
   through `parse_type_with_argstrings` which delegates to
   `_parse_single_argument` that already strips "::" from parameter
   names.
2. In `parse_type_with_argstrings`, recognize complex declarator groups
   starting with `*` or `&` (e.g. `*(*fp)(int)`) as non-argument-list
   parenthesized sections, preventing incorrect name extraction from
   nested function pointer declarators.

Reviewed By: cipolleschi

Differential Revision: D98118629

fbshipit-source-id: a8532e2adaec1dd2b50be8a20eae1068ac49d548
2026-03-26 08:40:54 -07:00
Jakub Piasecki cc9d06bef7 Fix array brackets appearing in the wrong place in the snapshot (#56214)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56214

Changelog: [Internal]

Snapshot generator was putting `[]` in wrong place when generating array type - it was adding it to the type name instead of the variable name. This diff addresses that.

Reviewed By: cipolleschi

Differential Revision: D98102328

fbshipit-source-id: c5b1f290da3c94ad4834a9756d849ae879733033
2026-03-26 08:40:54 -07:00
Dawid Małecki f0b51fc6bf Add ParsedSectionKind dataclass not to rely on strings directly (#56088)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56088

Changelog: [Internal]

Adds `ParsedSectionKind` which encapsulates logic related to parsing the section kind string.

Reviewed By: cipolleschi

Differential Revision: D96455765

fbshipit-source-id: 6d4866112511f24f5781e014eb720b96c3cfaf0d
2026-03-18 09:29:02 -07:00
Dawid Małecki 140509f7d4 Extract class specializations from name (#56075)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56075

Changelog: [Internal]

Updates the parser to extract the template specializations from name string in order to avoid repeated operations on the name string.

Reviewed By: cipolleschi

Differential Revision: D96303732

fbshipit-source-id: 08ff8ba34522426adccd53129590c5a7d59e0438
2026-03-18 09:29:02 -07:00
Dawid Małecki d0ec2956f8 Fix handling of member function pointers in the API snapshot (#56069)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56069

Changelog: [Internal]

Fixes handling of member function pointers in the C++ Api snapshot.

Reviewed By: cipolleschi

Differential Revision: D96279461

fbshipit-source-id: 42e7b004878eedfbbb8504345165bb1d60acde78
2026-03-18 09:29:02 -07:00
Dawid Małecki 882dbe0118 Handle template variables in the API snapshot (#56068)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56068

Changelog: [Internal]

Adds support for templates in variable declaration to the c++ API snapshot generator

Reviewed By: cipolleschi

Differential Revision: D96279463

fbshipit-source-id: eb68f97f926e4a407d6c7fa2dda6edf7e43e23ba
2026-03-18 09:29:02 -07:00
Jakub Piasecki 150377caf0 Move input_filters inside the parser package (#56054)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56054

Changelog: [Internal]

Moves `input_filers` inside the `parser` package. Imports outside of the package were causing errors when running the snapshot generator in OSS.

Reviewed By: cipolleschi

Differential Revision: D96109755

fbshipit-source-id: c29d70c895057fd51a92c1a073b331d27c0b289b
2026-03-11 23:58:46 -07:00
Jakub Piasecki a5daece0b3 Add reverse mapping for default values in base class specialization (#56032)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56032

Changelog: [Internal]

When generating xml output, doxygen replaces template arguments in specialized base classes with the default values:

```
template <typename T = int>
class Test : public Base<T> {};
```

becomes

```
template <typename T = int>
class Test : public Base<int> {};
```

To work around this issue, this diff adds reverse mapping for template params in the base classes. In the above case, the map would be: `{ "int" -> "T" }`, and `int` in `Base<int>` would be replaced with T.

This approach assumes that none of the default values are used directly in the base class specialization, which holds for the React Native codebase.

Reviewed By: cortinico

Differential Revision: D95933835

fbshipit-source-id: c1dd79a09f0f368fb106330409e15d54ebad2b4f
2026-03-11 01:40:36 -07:00
Jakub Piasecki 7f6790bf79 Inline private type aliases in the API snapshot (#56030)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56030

Changelog: [Internal]

Currently, the parser ignores all private sections, which causes private type aliases definitions not to be present in the snapshot. The refereces to those types can still appear in the public API, if they are resolvable to public types.

This diff updates the parser to track private type definitions, and inline them when referenced from the public API.

Reviewed By: cortinico

Differential Revision: D95920125

fbshipit-source-id: 054786987c266ac1062c0fa3ba1631cb179fb6ef
2026-03-11 00:14:41 -07:00
Jakub Piasecki 7d80d6e5a1 Use the derived class name in inherited constructors in the API snapshot (#56031)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56031

Changelog: [Internal]

Doxygen uses base class name for inherited constructors. This diff adds a guard to replace them with the derived class name in the final API snapshot.

Reviewed By: cipolleschi

Differential Revision: D95939080

fbshipit-source-id: 918135b8c5c603423e3a13537d9723e54ed4f035
2026-03-10 06:53:06 -07:00
Dawid Małecki 2be2770fc8 Fix issue with parsing lightweight objective-c generics (#55979)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55979

Fixes issue with parsing lightweight objective-c generics. Doxygen produces malformed xml output due to incorrect handling of interfaces such as:

```obj-c
interface Foo<T> : NSObject
end
```

The solution is to encode the interface into the form of `interface Foo__GENERICS_T_ENDGENERICS`, then produce the snapshot and finally decode it back to `interface Foo<T>`.

Changelog:
[Internal]

Reviewed By: cipolleschi

Differential Revision: D95567196

fbshipit-source-id: c8ae97f99e893ecd48ded21f24a650286d708c60
2026-03-10 04:50:31 -07:00
Dawid Małecki dc8c442aa5 Normalize template specialization angle bracket spacing (#55910)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55910

Normalizes angle bracket spacing in scope names for template specializations.

Doxygen encodes template specializations with spaces around angle brackets in compound names (e.g., `CSSDataTypeParser< CSSMatrix >`). This caused inconsistent output in API snapshots.

The fix applies `normalize_angle_brackets()` to qualified paths when parsing scope names, ensuring consistent output:
- `CSSDataTypeParser< CSSMatrix >` → `CSSDataTypeParser<CSSMatrix>`
- `Callback< R(Args...)>` → `Callback<R(Args...)>`

Added a new test case `should_normalize_template_specialization_angle_brackets` to verify the fix.

Changelog:
[Internal]

Reviewed By: cipolleschi

Differential Revision: D95204780

fbshipit-source-id: d0d5fe7759a414b32630647f334b39e26da15108
2026-03-05 07:21:42 -08:00
Dawid Małecki 725b056dc7 Filter category members from interface scope (#55899)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55899

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

fbshipit-source-id: 69d2f35d5aabd8e7567d254dc9b4686b4da2eb89
2026-03-05 07:21:42 -08:00
Dawid Małecki f2ea073857 Normalize pointer and reference spacing in parser output (#55901)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/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

fbshipit-source-id: 1a21361565fd7915a3a597ac729cecc2cfe99961
2026-03-05 07:21:42 -08:00
Dawid Małecki 47ef0e173f Fix parsing of Objective-C block properties (#55776)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55776

Doxygen splits block property types across `<type>` and `<argsstring>` elements. For example:

```objc
property (nonatomic, copy) void (^eventInterceptor)(NSString *eventName, NSDictionary *event, NSNumber *reactTag);
```

Produces XML like:
```xml
<type>void(^</type>
<name>eventInterceptor</name>
<argsstring>)(NSString *eventName, NSDictionary *event, NSNumber *reactTag)</argsstring>
```

This caused the parser to output incomplete types. The fix detects when the property type ends with `(^` and combines it with the property name and argsstring:
```
property (copy) void(^eventInterceptor)(NSString *eventName, NSDictionary *event, NSNumber *reactTag);
```

Changelog:
[Internal]

Reviewed By: cipolleschi

Differential Revision: D94366205

fbshipit-source-id: 2d741401f63916284d453f1112ae0f349234308e
2026-03-05 07:21:42 -08:00
Dawid Małecki d473d9b598 Fix parsing of Objective-C interface generic inheritance (#55775)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55775

Doxygen incorrectly parses Objective-C interface declarations with protocol conformance. For example:

```objc
interface RCTAppearance : RCTEventEmitter <RCTBridgeModule>
```

Doxygen splits this into **two separate base classes** in the XML:
```xml
<basecompoundref>RCTEventEmitter</basecompoundref>
<basecompoundref>&lt;RCTBridgeModule&gt;</basecompoundref>
```

This caused the parser to output:
```
interface RCTAppearance : public RCTEventEmitter, public <RCTBridgeModule> {
```

Instead of the expected:
```
interface RCTAppearance : public RCTEventEmitter <RCTBridgeModule> {
```

The fix detects when a "base class" name starts and ends with `<...>` (indicating it's a protocol conformance) and combines it with the preceding actual base class name.

Also for multiple generics like:
```
interface RCTAlertManager : NSObject <RCTBridgeModule, RCTInvalidating>

end
```

The output should be
```
interface RCTAlertManager : public NSObject <RCTBridgeModule, RCTInvalidating>
end
```

Changelog:
[Internal]

Reviewed By: cipolleschi

Differential Revision: D94351731

fbshipit-source-id: 05ee2729c7a60800e9350193ef04ee6e2b125522
2026-03-05 07:21:42 -08:00
Jakub Piasecki 84410fe330 Restore a single method for text parsing (#55909)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55909

Changelog: [Internal]

Restores the single path for doxygen ref parsing that was lost in refactor in D94072940

Reviewed By: cipolleschi

Differential Revision: D95206764

fbshipit-source-id: c2028872d8ff904187b41baf113dfe828796edcc
2026-03-04 23:54:39 -08:00
Dawid Małecki c90843d8f8 Add support for categories (#55773)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55773

This diff adds support for parsing Objective-C categories in the C++ API snapshot parser.

Changelog:
[Internal]

Reviewed By: cipolleschi

Differential Revision: D94076350

fbshipit-source-id: 7dd144a09b8cd5e2b91d008cb2a5882226dfd293
2026-03-04 02:47:32 -08:00
Dawid Małecki 851e5ae546 Parser refactor (#55772)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55772

The `main.py` increases rapidly in size. This diff refactors that into the `utils.py` and `builder.py` to form more modularized and easier to read structure.

Changelog:
[Internal]

Reviewed By: cipolleschi

Differential Revision: D94072940

fbshipit-source-id: f4b7b3c3bf4e2cf387829ced039d5645e2ad4b3e
2026-03-04 01:55:35 -08:00