mirror of
https://github.com/react/react-native.git
synced 2026-09-29 16:58:04 +08:00
Refactor doxygen xml parser (#56084)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/56084 Changelog: [Internal] Replaces a wall of if-else statements with a map (compound_type -> parser method). Reviewed By: cipolleschi Differential Revision: D96455723 fbshipit-source-id: bd44c02a4a8d08bf9abf463bacdfa0f77615dcff
This commit is contained in:
committed by
meta-codesync[bot]
parent
b3032d866c
commit
3a14967f81
+117
-91
@@ -28,6 +28,118 @@ from .snapshot import Snapshot
|
||||
from .utils import has_scope_resolution_outside_angles, parse_qualified_path
|
||||
|
||||
|
||||
def _process_namespace_sections(snapshot, namespace_scope, compound_object):
|
||||
"""
|
||||
Process all section definitions inside a namespace compound.
|
||||
"""
|
||||
for section_def in compound_object.sectiondef:
|
||||
if section_def.kind == "var":
|
||||
for variable_def in section_def.memberdef:
|
||||
# Skip out-of-class definitions (e.g. "Strct<T>::VALUE")
|
||||
if has_scope_resolution_outside_angles(variable_def.get_name()):
|
||||
continue
|
||||
is_static = variable_def.static == "yes"
|
||||
namespace_scope.add_member(
|
||||
get_variable_member(variable_def, "public", is_static)
|
||||
)
|
||||
elif section_def.kind == "func":
|
||||
for function_def in section_def.memberdef:
|
||||
# Skip out-of-class definitions (e.g. "Strct<T>::convert")
|
||||
if has_scope_resolution_outside_angles(function_def.get_name()):
|
||||
continue
|
||||
function_static = function_def.static == "yes"
|
||||
|
||||
if not function_static:
|
||||
namespace_scope.add_member(
|
||||
get_function_member(function_def, "public")
|
||||
)
|
||||
elif section_def.kind == "typedef":
|
||||
for typedef_def in section_def.memberdef:
|
||||
namespace_scope.add_member(get_typedef_member(typedef_def, "public"))
|
||||
elif section_def.kind == "enum":
|
||||
for enum_def in section_def.memberdef:
|
||||
create_enum_scope(snapshot, enum_def)
|
||||
else:
|
||||
print(
|
||||
f"Unknown section kind: {section_def.kind} in {compound_object.location.file}"
|
||||
)
|
||||
|
||||
|
||||
def _handle_namespace_compound(snapshot, compound_object):
|
||||
"""
|
||||
Handle a namespace compound definition.
|
||||
"""
|
||||
# Skip anonymous namespaces (internal linkage, not public API).
|
||||
# Doxygen encodes them with a '@' prefix in the compound name.
|
||||
if "@" in compound_object.compoundname:
|
||||
return
|
||||
|
||||
namespace_scope = snapshot.create_or_get_namespace(compound_object.compoundname)
|
||||
|
||||
namespace_scope.location = compound_object.location.file
|
||||
|
||||
_process_namespace_sections(snapshot, namespace_scope, compound_object)
|
||||
|
||||
|
||||
def _handle_concept_compound(snapshot, compound_object):
|
||||
"""
|
||||
Handle a concept compound definition.
|
||||
"""
|
||||
# Concepts belong to a namespace, so we need to find or create the parent namespace
|
||||
concept_name = compound_object.compoundname
|
||||
concept_path = parse_qualified_path(concept_name)
|
||||
namespace_path = "::".join(concept_path[:-1]) if concept_path else ""
|
||||
|
||||
if namespace_path:
|
||||
namespace_scope = snapshot.create_or_get_namespace(namespace_path)
|
||||
else:
|
||||
namespace_scope = snapshot.root_scope
|
||||
|
||||
namespace_scope.add_member(get_concept_member(compound_object))
|
||||
|
||||
|
||||
def _handle_class_compound(snapshot, compound_object):
|
||||
"""
|
||||
Handle class, struct, and union compound definitions.
|
||||
"""
|
||||
# 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")
|
||||
)
|
||||
|
||||
# Handle Objective-C interfaces separately
|
||||
if is_objc_interface:
|
||||
create_interface_scope(snapshot, compound_object)
|
||||
return
|
||||
|
||||
# classes and structs are represented by the same scope with a different kind
|
||||
create_class_scope(snapshot, compound_object)
|
||||
|
||||
|
||||
# Dispatch table for compound kinds that map directly to a single builder call.
|
||||
_COMPOUND_HANDLERS = {
|
||||
"class": _handle_class_compound,
|
||||
"struct": _handle_class_compound,
|
||||
"union": _handle_class_compound,
|
||||
"namespace": _handle_namespace_compound,
|
||||
"concept": _handle_concept_compound,
|
||||
"category": create_category_scope,
|
||||
"protocol": create_protocol_scope,
|
||||
"interface": create_interface_scope,
|
||||
}
|
||||
|
||||
# Compound kinds that are intentionally ignored.
|
||||
_IGNORED_COMPOUNDS = frozenset(
|
||||
{
|
||||
"file",
|
||||
"dir",
|
||||
# Contains deprecation info
|
||||
"page",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def build_snapshot(xml_dir: str) -> Snapshot:
|
||||
"""
|
||||
Reads the Doxygen XML output and builds a snapshot of the C++ API.
|
||||
@@ -51,100 +163,14 @@ def build_snapshot(xml_dir: str) -> Snapshot:
|
||||
if compound_object.prot == "private":
|
||||
continue
|
||||
|
||||
# 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")
|
||||
)
|
||||
kind = compound_object.kind
|
||||
|
||||
# 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
|
||||
create_class_scope(snapshot, compound_object)
|
||||
elif compound_object.kind == "namespace":
|
||||
# Skip anonymous namespaces (internal linkage, not public API).
|
||||
# Doxygen encodes them with a '@' prefix in the compound name.
|
||||
if "@" in compound_object.compoundname:
|
||||
continue
|
||||
|
||||
namespace_scope = snapshot.create_or_get_namespace(
|
||||
compound_object.compoundname
|
||||
)
|
||||
|
||||
namespace_scope.location = compound_object.location.file
|
||||
|
||||
for section_def in compound_object.sectiondef:
|
||||
if section_def.kind == "var":
|
||||
for variable_def in section_def.memberdef:
|
||||
# Skip out-of-class definitions (e.g. "Strct<T>::VALUE")
|
||||
if has_scope_resolution_outside_angles(
|
||||
variable_def.get_name()
|
||||
):
|
||||
continue
|
||||
is_static = variable_def.static == "yes"
|
||||
namespace_scope.add_member(
|
||||
get_variable_member(variable_def, "public", is_static)
|
||||
)
|
||||
elif section_def.kind == "func":
|
||||
for function_def in section_def.memberdef:
|
||||
# Skip out-of-class definitions (e.g. "Strct<T>::convert")
|
||||
if has_scope_resolution_outside_angles(
|
||||
function_def.get_name()
|
||||
):
|
||||
continue
|
||||
function_static = function_def.static == "yes"
|
||||
|
||||
if not function_static:
|
||||
namespace_scope.add_member(
|
||||
get_function_member(function_def, "public")
|
||||
)
|
||||
elif section_def.kind == "typedef":
|
||||
for typedef_def in section_def.memberdef:
|
||||
namespace_scope.add_member(
|
||||
get_typedef_member(typedef_def, "public")
|
||||
)
|
||||
elif section_def.kind == "enum":
|
||||
for enum_def in section_def.memberdef:
|
||||
create_enum_scope(snapshot, enum_def)
|
||||
else:
|
||||
print(
|
||||
f"Unknown section kind: {section_def.kind} in {compound_object.location.file}"
|
||||
)
|
||||
elif compound_object.kind == "concept":
|
||||
# Concepts belong to a namespace, so we need to find or create the parent namespace
|
||||
concept_name = compound_object.compoundname
|
||||
concept_path = parse_qualified_path(concept_name)
|
||||
namespace_path = "::".join(concept_path[:-1]) if concept_path else ""
|
||||
|
||||
if namespace_path:
|
||||
namespace_scope = snapshot.create_or_get_namespace(namespace_path)
|
||||
else:
|
||||
namespace_scope = snapshot.root_scope
|
||||
|
||||
namespace_scope.add_member(get_concept_member(compound_object))
|
||||
elif compound_object.kind == "file":
|
||||
if kind in _IGNORED_COMPOUNDS:
|
||||
pass
|
||||
elif compound_object.kind == "dir":
|
||||
pass
|
||||
elif compound_object.kind == "category":
|
||||
create_category_scope(snapshot, compound_object)
|
||||
elif compound_object.kind == "page":
|
||||
# Contains deprecation info
|
||||
pass
|
||||
elif compound_object.kind == "protocol":
|
||||
create_protocol_scope(snapshot, compound_object)
|
||||
elif compound_object.kind == "interface":
|
||||
create_interface_scope(snapshot, compound_object)
|
||||
elif kind in _COMPOUND_HANDLERS:
|
||||
_COMPOUND_HANDLERS[kind](snapshot, compound_object)
|
||||
else:
|
||||
print(f"Unknown compound kind: {compound_object.kind}")
|
||||
print(f"Unknown compound kind: {kind}")
|
||||
|
||||
snapshot.finish()
|
||||
return snapshot
|
||||
|
||||
Reference in New Issue
Block a user