mirror of
https://github.com/react/react-native.git
synced 2026-09-28 21:33:11 +08:00
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/56239 Doxygen incorrectly merges base classes from primary templates into their partial specializations. In C++, a specialization's inheritance list completely replaces the primary template's, but Doxygen combines both into a single basecompoundref list. - **Contradictory type traits** — is_optional<std::optional<T>> and is_variant_of_data_types<std::variant<Ts...>> showed inheritance from both std::false_type (primary) and std::true_type (specialization) - **Duplicate base classes** — Converter<jsi::Object> listed ConverterBase<jsi::Object> twice (once from the primary template after substitution, once from the specialization) This diff fixes both issues with two complementary mechanisms: - **Dedup-by-name (Extendable._deduplicate_base_classes)**: removes exact duplicate base classes, keeping the last occurrence. Handles cases where Doxygen's template argument substitution produces identical names. - **Primary template base subtraction (StructLikeScopeKind._remove_merged_primary_bases)**: for partial specializations, looks up the primary template among sibling scopes and performs count-based subtraction of its bases. Count-based (rather than set-based) subtraction correctly preserves bases that a specialization explicitly re-inherits from the same class as the primary. Changelog: [Internal] Reviewed By: cipolleschi Differential Revision: D98291360 fbshipit-source-id: 82b34969b13c7df8babf2c5efc222b29979d6361
60 lines
2.0 KiB
Python
60 lines
2.0 KiB
Python
# 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 __future__ import annotations
|
|
|
|
|
|
class Extendable:
|
|
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:
|
|
self.base_classes = []
|
|
|
|
def add_base(self, base: Base | list[Base]) -> None:
|
|
if isinstance(base, list):
|
|
for b in base:
|
|
self.base_classes.append(b)
|
|
else:
|
|
self.base_classes.append(base)
|
|
self._deduplicate_base_classes()
|
|
|
|
def _deduplicate_base_classes(self) -> None:
|
|
"""Remove duplicate base classes.
|
|
|
|
Doxygen sometimes reports the same base class multiple times (e.g.
|
|
when template argument substitution produces identical names for
|
|
a primary template and its specialization). This keeps only the
|
|
last occurrence of each name.
|
|
"""
|
|
seen: dict[str, int] = {}
|
|
for i, base in enumerate(self.base_classes):
|
|
seen[base.name] = i
|
|
self.base_classes = [self.base_classes[i] for i in sorted(seen.values())]
|
|
|
|
def qualify_base_classes(self, scope) -> None:
|
|
"""Qualify base class names and their template arguments."""
|
|
from ..utils import qualify_type_str
|
|
|
|
for base in self.base_classes:
|
|
base.name = qualify_type_str(base.name, scope)
|
|
|
|
def get_inheritance_string(self) -> str:
|
|
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))
|
|
|
|
return (" : " + ", ".join(bases)) if bases else ""
|