Skip to content

Commit

Permalink
Provide more context when shadow tree ops (StubViewTree) consistency …
Browse files Browse the repository at this point in the history
…error reporting (#39144)

Summary:
Pull Request resolved: #39144

## Changelog:
[Internal] -

This adds more information into internal shadow tree consistency check error reporting, as well as some minor code refactorings.

Note that the code is run only in debug, and normally you don't trigger such issues, unless you look into a new platform implementation (which I did).

Reviewed By: javache

Differential Revision: D48643602

fbshipit-source-id: a6475f2f577c7b461622472af1c6855072ae319e
  • Loading branch information
rshest authored and facebook-github-bot committed Aug 25, 2023
1 parent dab7738 commit 18c4cb1
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,20 @@ namespace facebook::react {
StubViewTree::StubViewTree(ShadowView const &shadowView) {
auto view = std::make_shared<StubView>();
view->update(shadowView);
rootTag = shadowView.tag;
registry[shadowView.tag] = view;
rootTag_ = shadowView.tag;
registry_[shadowView.tag] = view;
}

StubView const &StubViewTree::getRootStubView() const {
return *registry.at(rootTag);
return *registry_.at(rootTag_);
}

StubView const &StubViewTree::getStubView(Tag tag) const {
return *registry.at(tag);
return *registry_.at(tag);
}

size_t StubViewTree::size() const {
return registry.size();
return registry_.size();
}

void StubViewTree::mutate(ShadowViewMutationList const &mutations) {
Expand All @@ -52,8 +52,14 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) {
LOG(ERROR) << "StubView: Create [" << tag << "] ##"
<< std::hash<ShadowView>{}((ShadowView)*stubView);
});
react_native_assert(registry.find(tag) == registry.end());
registry[tag] = stubView;
if (hasTag(tag)) {
LOG(ERROR) << "StubView: Create [" << tag << "]: tag already exists"
<< (tag == rootTag_ ? " (and it's the root tag)" : "")
<< ". The current registry: ";
dumpTags(LOG(ERROR));
}
react_native_assert(!hasTag(tag));
registry_[tag] = stubView;
break;
}

Expand All @@ -66,8 +72,8 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) {
react_native_assert(mutation.parentShadowView == ShadowView{});
react_native_assert(mutation.newChildShadowView == ShadowView{});
auto tag = mutation.oldChildShadowView.tag;
react_native_assert(registry.find(tag) != registry.end());
auto stubView = registry[tag];
react_native_assert(hasTag(tag));
auto stubView = registry_[tag];
if ((ShadowView)(*stubView) != mutation.oldChildShadowView) {
LOG(ERROR)
<< "StubView: ASSERT FAILURE: DELETE mutation assertion failure: oldChildShadowView does not match stubView: ["
Expand All @@ -85,7 +91,7 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) {
}
react_native_assert(
(ShadowView)(*stubView) == mutation.oldChildShadowView);
registry.erase(tag);
registry_.erase(tag);
break;
}

Expand All @@ -94,20 +100,20 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) {
react_native_assert(mutation.oldChildShadowView == ShadowView{});
auto parentTag = mutation.parentShadowView.tag;
auto childTag = mutation.newChildShadowView.tag;
if (registry.find(parentTag) == registry.end()) {
if (!hasTag(parentTag)) {
LOG(ERROR)
<< "StubView: ASSERT FAILURE: INSERT mutation assertion failure: parentTag not found: ["
<< parentTag << "] inserting child: [" << childTag << "]";
}
if (registry.find(childTag) == registry.end()) {
if (!hasTag(childTag)) {
LOG(ERROR)
<< "StubView: ASSERT FAILURE: INSERT mutation assertion failure: childTag not found: ["
<< parentTag << "] inserting child: [" << childTag << "]";
}
react_native_assert(registry.find(parentTag) != registry.end());
auto parentStubView = registry[parentTag];
react_native_assert(registry.find(childTag) != registry.end());
auto childStubView = registry[childTag];
react_native_assert(hasTag(parentTag));
auto parentStubView = registry_[parentTag];
react_native_assert(hasTag(childTag));
auto childStubView = registry_[childTag];
childStubView->update(mutation.newChildShadowView);
STUB_VIEW_LOG({
LOG(ERROR) << "StubView: Insert [" << childTag << "] into ["
Expand All @@ -124,8 +130,8 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) {
parentStubView->children.begin() + mutation.index, childStubView);
} else {
auto childTag = mutation.newChildShadowView.tag;
react_native_assert(registry.find(childTag) != registry.end());
auto childStubView = registry[childTag];
react_native_assert(hasTag(childTag));
auto childStubView = registry_[childTag];
childStubView->update(mutation.newChildShadowView);
}
break;
Expand All @@ -136,13 +142,13 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) {
react_native_assert(mutation.newChildShadowView == ShadowView{});
auto parentTag = mutation.parentShadowView.tag;
auto childTag = mutation.oldChildShadowView.tag;
if (registry.find(parentTag) == registry.end()) {
if (!hasTag(parentTag)) {
LOG(ERROR)
<< "StubView: ASSERT FAILURE: REMOVE mutation assertion failure: parentTag not found: ["
<< parentTag << "] removing child: [" << childTag << "]";
}
react_native_assert(registry.find(parentTag) != registry.end());
auto parentStubView = registry[parentTag];
react_native_assert(hasTag(parentTag));
auto parentStubView = registry_[parentTag];
STUB_VIEW_LOG({
LOG(ERROR) << "StubView: Remove [" << childTag << "] from ["
<< parentTag << "] @" << mutation.index << " with "
Expand All @@ -152,8 +158,8 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) {
mutation.index >= 0 &&
parentStubView->children.size() >
static_cast<size_t>(mutation.index));
react_native_assert(registry.find(childTag) != registry.end());
auto childStubView = registry[childTag];
react_native_assert(hasTag(childTag));
auto childStubView = registry_[childTag];
if ((ShadowView)(*childStubView) != mutation.oldChildShadowView) {
LOG(ERROR)
<< "StubView: ASSERT FAILURE: REMOVE mutation assertion failure: oldChildShadowView does not match oldStubView: ["
Expand Down Expand Up @@ -217,9 +223,8 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) {
react_native_assert(mutation.newChildShadowView.props);
react_native_assert(
mutation.newChildShadowView.tag == mutation.oldChildShadowView.tag);
react_native_assert(
registry.find(mutation.newChildShadowView.tag) != registry.end());
auto oldStubView = registry[mutation.newChildShadowView.tag];
react_native_assert(hasTag(mutation.newChildShadowView.tag));
auto oldStubView = registry_[mutation.newChildShadowView.tag];
react_native_assert(oldStubView->tag != 0);
if ((ShadowView)(*oldStubView) != mutation.oldChildShadowView) {
LOG(ERROR)
Expand Down Expand Up @@ -257,39 +262,34 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) {
google::FlushLogFiles(google::GLOG_INFO);
}

std::ostream &StubViewTree::dumpTags(std::ostream &stream) {
for (auto const &pair : registry_) {
auto &stubView = *registry_.at(pair.first);
stream << "[" << stubView.tag << "]##"
<< std::hash<ShadowView>{}((ShadowView)stubView) << " ";
}
return stream;
}

bool operator==(StubViewTree const &lhs, StubViewTree const &rhs) {
if (lhs.registry.size() != rhs.registry.size()) {
if (lhs.registry_.size() != rhs.registry_.size()) {
STUB_VIEW_LOG({
LOG(ERROR) << "Registry sizes are different. Sizes: LHS: "
<< lhs.registry.size() << " RHS: " << rhs.registry.size();
<< lhs.registry_.size() << " RHS: " << rhs.registry_.size();

[&](std::ostream &stream) -> std::ostream & {
stream << "Tags in LHS: ";
for (auto const &pair : lhs.registry) {
auto &lhsStubView = *lhs.registry.at(pair.first);
stream << "[" << lhsStubView.tag << "]##"
<< std::hash<ShadowView>{}((ShadowView)lhsStubView) << " ";
}
return stream;
}(LOG(ERROR));
LOG(ERROR) << "Tags in LHS: ";
lhs.dumpTagsHash(LOG(ERROR));

[&](std::ostream &stream) -> std::ostream & {
stream << "Tags in RHS: ";
for (auto const &pair : rhs.registry) {
auto &rhsStubView = *rhs.registry.at(pair.first);
stream << "[" << rhsStubView.tag << "]##"
<< std::hash<ShadowView>{}((ShadowView)rhsStubView) << " ";
}
return stream;
}(LOG(ERROR));
LOG(ERROR) << "Tags in RHS: ";
rhs.dumpTagsHash(LOG(ERROR));
});

return false;
}

for (auto const &pair : lhs.registry) {
auto &lhsStubView = *lhs.registry.at(pair.first);
auto &rhsStubView = *rhs.registry.at(pair.first);
for (auto const &pair : lhs.registry_) {
auto &lhsStubView = *lhs.registry_.at(pair.first);
auto &rhsStubView = *rhs.registry_.at(pair.first);

if (lhsStubView != rhsStubView) {
STUB_VIEW_LOG({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,17 @@ class StubViewTree {
size_t size() const;

private:
Tag rootTag;
std::unordered_map<Tag, StubView::Shared> registry{};
Tag rootTag_{};
std::unordered_map<Tag, StubView::Shared> registry_{};

friend bool operator==(StubViewTree const &lhs, StubViewTree const &rhs);
friend bool operator!=(StubViewTree const &lhs, StubViewTree const &rhs);

std::ostream &dumpTags(std::ostream &stream);

bool hasTag(Tag tag) const {
return registry_.find(tag) != registry_.end();
}
};

bool operator==(StubViewTree const &lhs, StubViewTree const &rhs);
Expand Down

0 comments on commit 18c4cb1

Please sign in to comment.