Skip to content

Commit

Permalink
Provide default printing function for map_like and array_like native …
Browse files Browse the repository at this point in the history
…objects

Summary:
`array_like` and `map_like` implementations should generally print out to similar looking trees. This diff provides a default implementation for the *very* common case.

This is useful in future diffs where we make additions to the standard library which use array-like and map-like native objects more.

Reviewed By: yoney

Differential Revision: D68007921

fbshipit-source-id: b8a4c3e379112584960e1f535b24324a671e213b
  • Loading branch information
praihan authored and facebook-github-bot committed Jan 12, 2025
1 parent a1687a5 commit 6802998
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 18 deletions.
24 changes: 6 additions & 18 deletions thrift/compiler/whisker/mstch_compat.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,7 @@ class mstch_array_proxy final

void print_to(tree_printer::scope scope, const object_print_options& options)
const override {
assert(scope.semantic_depth() <= options.max_depth);

const auto size = proxied_.size();
scope.println("mstch::array (size={})", size);
for (std::size_t i = 0; i < size; ++i) {
auto element_scope = scope.open_transparent_property();
element_scope.println("[{}]", i);
whisker::print_to(*at(i), element_scope.open_node(), options);
}
default_print_to("mstch::array", std::move(scope), options);
}

bool operator==(const native_object& untyped_other) const override {
Expand Down Expand Up @@ -129,17 +121,13 @@ class mstch_map_proxy final

void print_to(tree_printer::scope scope, const object_print_options& options)
const override {
assert(scope.semantic_depth() <= options.max_depth);
const auto size = proxied_.size();
scope.println("mstch::map (size={})", size);

std::vector<std::string> property_names;
property_names.reserve(proxied_.size());
for (const auto& [key, _] : proxied_) {
auto cached = lookup_property(key);
assert(cached != nullptr);
auto element_scope = scope.open_transparent_property();
element_scope.println("'{}'", key);
whisker::print_to(*cached, element_scope.open_node(), options);
property_names.push_back(key);
}
default_print_to(
"mstch::map", std::move(property_names), std::move(scope), options);
}

bool operator==(const native_object& untyped_other) const override {
Expand Down
33 changes: 33 additions & 0 deletions thrift/compiler/whisker/object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,39 @@ class to_string_visitor {

} // namespace

void native_object::map_like::default_print_to(
std::string_view name,
std::vector<std::string> property_names,
tree_printer::scope scope,
const object_print_options& options) const {
assert(scope.semantic_depth() <= options.max_depth);
const auto size = property_names.size();
scope.println("{} (size={})", name, size);

for (const std::string& key : property_names) {
auto cached = lookup_property(key);
assert(cached != nullptr);
auto element_scope = scope.open_transparent_property();
element_scope.println("'{}'", key);
whisker::print_to(*cached, element_scope.open_node(), options);
}
}

void native_object::array_like::default_print_to(
std::string_view name,
tree_printer::scope scope,
const object_print_options& options) const {
assert(scope.semantic_depth() <= options.max_depth);

const auto sz = size();
scope.println("{} (size={})", name, sz);
for (std::size_t i = 0; i < sz; ++i) {
auto element_scope = scope.open_transparent_property();
element_scope.println("[{}]", i);
whisker::print_to(*at(i), element_scope.open_node(), options);
}
}

void native_object::print_to(
tree_printer::scope scope, const object_print_options&) const {
scope.println("<native_object>");
Expand Down
28 changes: 28 additions & 0 deletions thrift/compiler/whisker/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,22 @@ class native_object {
*/
virtual managed_object_ptr<> lookup_property(
std::string_view identifier) const = 0;

protected:
/**
* A default implementation of whisker::print_to for native object
* subclasses of map_like to use.
*
* For the default implementation to work, property names must be explicitly
* enumerated.
*
* The provided name allows the caller to expose type information.
*/
void default_print_to(
std::string_view name,
std::vector<std::string> property_names,
tree_printer::scope,
const object_print_options&) const;
};
/**
* Returns an implementation of map_list if this object supports map-like
Expand Down Expand Up @@ -219,6 +235,18 @@ class native_object {
* - index < size()
*/
virtual managed_object_ptr<> at(std::size_t index) const = 0;

protected:
/**
* A default implementation of whisker::print_to for native object
* subclasses of array_like to use.
*
* The provided name allows the caller to expose type information.
*/
void default_print_to(
std::string_view name,
tree_printer::scope,
const object_print_options&) const;
};
/**
* Returns an implementation of array_like if this object supports array-like
Expand Down

0 comments on commit 6802998

Please sign in to comment.