Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,7 @@ fix_*.patch

# [Experimental] Generated TS type definitions
/packages/**/types_generated/

# Doxygen XML output used for C++ API tracking
/packages/react-native/**/api/xml
/packages/react-native/**/.doxygen.config.generated
2,902 changes: 2,902 additions & 0 deletions packages/react-native/.doxygen.config.template

Large diffs are not rendered by default.

2,898 changes: 2,898 additions & 0 deletions scripts/cxx-api/manual_test/.doxygen.config.template

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions scripts/cxx-api/manual_test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
api/xml
23 changes: 23 additions & 0 deletions scripts/cxx-api/manual_test/code/test.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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 facebook {

namespace react {

enum class Enum {
A,
B,
};

void test(react::Enum e = Enum::A);

} // namespace react

} // namespace facebook
10 changes: 10 additions & 0 deletions scripts/cxx-api/parser/__init__.py
Original file line number Diff line number Diff line change
@@ -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.

from .main import build_snapshot
from .member import FunctionMember, FunctionModifiers
from .path_utils import get_repo_root

__all__ = ["build_snapshot", "FunctionMember", "FunctionModifiers", "get_repo_root"]
119 changes: 119 additions & 0 deletions scripts/cxx-api/parser/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# 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.

"""
Entry point for running the parser package as a script.
"""

import os
import subprocess

from .main import build_snapshot
from .path_utils import get_react_native_dir

DOXYGEN_CONFIG_FILE = ".doxygen.config.generated"

RUN_ON_REACT_NATIVE = False


def build_doxygen_config(
directory: str,
include_directories: list[str] = None,
exclude_patterns: list[str] = None,
definitions: dict[str, str | int] = None,
) -> None:
if include_directories is None:
include_directories = []
if exclude_patterns is None:
exclude_patterns = []
if definitions is None:
definitions = {}

include_directories_str = " ".join(include_directories)
exclude_patterns_str = "\\\n".join(exclude_patterns)
if len(exclude_patterns) > 0:
exclude_patterns_str = f"\\\n{exclude_patterns_str}"

definitions_str = " ".join(
[
f'{key}="{value}"' if isinstance(value, str) else f"{key}={value}"
for key, value in definitions.items()
]
)

# read the template file
with open(os.path.join(directory, ".doxygen.config.template")) as f:
template = f.read()

# replace the placeholder with the actual path
config = (
template.replace("${ADDITIONAL_INPUTS}", include_directories_str)
.replace("${ADDITIONAL_EXCLUDE_PATTERNS}", exclude_patterns_str)
.replace("${PREDEFINED}", definitions_str)
)

# write the config file
with open(os.path.join(directory, DOXYGEN_CONFIG_FILE), "w") as f:
f.write(config)


def main():
# Define the path to the react-native directory
react_native_dir = (
f"{get_react_native_dir()}/packages/react-native"
if RUN_ON_REACT_NATIVE
else f"{get_react_native_dir()}/scripts/cxx-api/manual_test"
)
print(f"Running in directory: {react_native_dir}")

# If there is already an output directory, delete it
if os.path.exists(os.path.join(react_native_dir, "api")):
print("Deleting existing output directory")
subprocess.run(["rm", "-rf", os.path.join(react_native_dir, "api")])

# Generate the Doxygen config file
print("Generating Doxygen config file")
if RUN_ON_REACT_NATIVE:
build_doxygen_config(
react_native_dir,
include_directories=["ReactAndroid"],
exclude_patterns=["*/platform/ios/*"],
definitions={"RN_SERIALIZABLE_STATE": 1},
)
else:
build_doxygen_config(react_native_dir)

print("Running Doxygen")

# Run doxygen with the config file
result = subprocess.run(
["doxygen", DOXYGEN_CONFIG_FILE],
cwd=react_native_dir,
capture_output=True,
text=True,
)

# Delete the Doxygen config file
print("Deleting Doxygen config file")
subprocess.run(["rm", DOXYGEN_CONFIG_FILE], cwd=react_native_dir)

# Check the result
if result.returncode != 0:
print(f"Doxygen finished with error: {result.stderr}")
else:
print("Doxygen finished successfully")

if RUN_ON_REACT_NATIVE:
# build snapshot, convert to string, and save to file
snapshot = build_snapshot(os.path.join(react_native_dir, "api", "xml"))
snapshot_string = snapshot.to_string()
with open(os.path.join(react_native_dir, "api", "snapshot.api"), "w") as f:
f.write(snapshot_string)
else:
build_snapshot(os.path.join(react_native_dir, "api", "xml")).print()


if __name__ == "__main__":
main()
Loading
Loading