From 34f8e7f848bf337e1c1e258faf8183204efa3e18 Mon Sep 17 00:00:00 2001 From: Kevin Gozali Date: Thu, 8 Mar 2018 17:50:17 -0800 Subject: [PATCH] `fabric/debug` module and `DebugStringConvertible` class Summary: This is a very first diff in a series of undefined length implementing React Native Shadow Tree infra in C++. All Shadow Nodes, Props and etc. implements `DebugStringConvertible`. Authored by shergin Reviewed By: shergin Differential Revision: D7163868 fbshipit-source-id: 9c001aa5bd0723f709a07b1833f512c51e3bec11 --- ReactCommon/fabric/BUCK | 16 ++--- ReactCommon/fabric/debug/BUCK | 46 ++++++++++++ .../fabric/debug/DebugStringConvertible.cpp | 71 +++++++++++++++++++ .../fabric/debug/DebugStringConvertible.h | 59 +++++++++++++++ .../debug/DebugStringConvertibleItem.cpp | 41 +++++++++++ .../fabric/debug/DebugStringConvertibleItem.h | 45 ++++++++++++ 6 files changed, 269 insertions(+), 9 deletions(-) create mode 100644 ReactCommon/fabric/debug/BUCK create mode 100644 ReactCommon/fabric/debug/DebugStringConvertible.cpp create mode 100644 ReactCommon/fabric/debug/DebugStringConvertible.h create mode 100644 ReactCommon/fabric/debug/DebugStringConvertibleItem.cpp create mode 100644 ReactCommon/fabric/debug/DebugStringConvertibleItem.h diff --git a/ReactCommon/fabric/BUCK b/ReactCommon/fabric/BUCK index fcf321eae..9c5cc4a63 100644 --- a/ReactCommon/fabric/BUCK +++ b/ReactCommon/fabric/BUCK @@ -1,10 +1,5 @@ load("@xplat//configurations/buck/apple:flag_defs.bzl", "get_debug_preprocessor_flags") -load("//ReactNative:DEFS.bzl", "IS_OSS_BUILD", "rn_xplat_cxx_library", "APPLE_INSPECTOR_FLAGS") - -CXX_LIBRARY_COMPILER_FLAGS = [ - "-std=c++14", - "-Wall", -] +load("//ReactNative:DEFS.bzl", "IS_OSS_BUILD", "react_native_xplat_target", "rn_xplat_cxx_library", "APPLE_INSPECTOR_FLAGS") APPLE_COMPILER_FLAGS = [] @@ -14,17 +9,19 @@ if not IS_OSS_BUILD: rn_xplat_cxx_library( name = "fabric", - srcs = glob(["**/*.cpp"]), + srcs = glob(["*.cpp"]), header_namespace = "", exported_headers = subdir_glob( [ - ("", "**/*.h"), + ("", "*.h"), ], prefix = "fabric", ), - compiler_flags = CXX_LIBRARY_COMPILER_FLAGS + [ + compiler_flags = [ "-fexceptions", "-frtti", + "-std=c++14", + "-Wall", ], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_preprocessor_flags = get_debug_preprocessor_flags() + APPLE_INSPECTOR_FLAGS, @@ -42,5 +39,6 @@ rn_xplat_cxx_library( "xplat//folly:memory", "xplat//folly:molly", "xplat//third-party/glog:glog", + react_native_xplat_target("fabric/debug:debug"), ], ) diff --git a/ReactCommon/fabric/debug/BUCK b/ReactCommon/fabric/debug/BUCK new file mode 100644 index 000000000..5a021202e --- /dev/null +++ b/ReactCommon/fabric/debug/BUCK @@ -0,0 +1,46 @@ +load("@xplat//configurations/buck/apple:flag_defs.bzl", "get_debug_preprocessor_flags") +load("//ReactNative:DEFS.bzl", "IS_OSS_BUILD", "react_native_xplat_target", "rn_xplat_cxx_library", "APPLE_INSPECTOR_FLAGS") + +APPLE_COMPILER_FLAGS = [] + +if not IS_OSS_BUILD: + load("@xplat//configurations/buck/apple:flag_defs.bzl", "get_static_library_ios_flags", "flags") + APPLE_COMPILER_FLAGS = flags.get_flag_value(get_static_library_ios_flags(), 'compiler_flags') + +rn_xplat_cxx_library( + name = "debug", + srcs = glob( + [ + "**/*.cpp", + ], + ), + headers = glob( + [ + "**/*.h", + ], + ), + header_namespace = "", + exported_headers = subdir_glob( + [ + ("", "*.h"), + ], + prefix = "fabric/debug", + ), + compiler_flags = [ + "-std=c++14", + "-Wall", + "-fexceptions", + "-frtti", + ], + fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, + fbobjc_preprocessor_flags = get_debug_preprocessor_flags() + APPLE_INSPECTOR_FLAGS, + force_static = True, + preprocessor_flags = [ + "-DLOG_TAG=\"ReactNative\"", + "-DWITH_FBSYSTRACE=1", + ], + visibility = ["PUBLIC"], + deps = [ + "xplat//folly:headers_only", + ], +) diff --git a/ReactCommon/fabric/debug/DebugStringConvertible.cpp b/ReactCommon/fabric/debug/DebugStringConvertible.cpp new file mode 100644 index 000000000..818629764 --- /dev/null +++ b/ReactCommon/fabric/debug/DebugStringConvertible.cpp @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "DebugStringConvertible.h" + +namespace facebook { +namespace react { + +std::string DebugStringConvertible::getDebugChildrenDescription(int level) const { + std::string childrenString = ""; + + for (auto child : getDebugChildren()) { + childrenString += child->getDebugDescription(level + 1); + } + + return childrenString; +} + +std::string DebugStringConvertible::getDebugPropsDescription(int level) const { + std::string propsString = ""; + + for (auto prop : getDebugProps()) { + auto name = prop->getDebugName(); + auto value = prop->getDebugValue(); + auto children = prop->getDebugPropsDescription(level + 1); + auto valueAndChildren = value + (children.empty() ? "" : "(" + children + ")"); + propsString += " " + name + (valueAndChildren.empty() ? "" : "=" + valueAndChildren); + } + + if (!propsString.empty()) { + // Removing leading space character. + propsString.erase(propsString.begin()); + } + + return propsString; +} + +std::string DebugStringConvertible::getDebugDescription(int level) const { + std::string nameString = getDebugName(); + std::string valueString = getDebugValue(); + std::string childrenString = getDebugChildrenDescription(level); + std::string propsString = getDebugPropsDescription(level); + + return "<" + nameString + + (valueString.empty() ? "" : "=" + valueString) + + (propsString.empty() ? "" : " " + propsString) + + (childrenString.empty() ? "/>" : ">" + childrenString + ""); +} + +std::string DebugStringConvertible::getDebugName() const { + return "Node"; +} + +std::string DebugStringConvertible::getDebugValue() const { + return ""; +} + +SharedDebugStringConvertibleList DebugStringConvertible::getDebugChildren() const { + return SharedDebugStringConvertibleList(); +} + +SharedDebugStringConvertibleList DebugStringConvertible::getDebugProps() const { + return SharedDebugStringConvertibleList(); +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/debug/DebugStringConvertible.h b/ReactCommon/fabric/debug/DebugStringConvertible.h new file mode 100644 index 000000000..b743a9332 --- /dev/null +++ b/ReactCommon/fabric/debug/DebugStringConvertible.h @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +namespace facebook { +namespace react { + +class DebugStringConvertible; + +using SharedDebugStringConvertible = std::shared_ptr; +using SharedDebugStringConvertibleList = std::vector; + +// Abstract class describes conformance to DebugStringConvertible concept +// and implements basic recursive debug string assembly algorithm. +// Use this as a base class for providing a debugging textual representation +// of your class. +// TODO (#26770211): Clear up the naming. +class DebugStringConvertible { + +public: + // Returns a name of the object. + // Default implementation returns "Node". + virtual std::string getDebugName() const; + + // Returns a value assosiate with the object. + // Default implementation returns an empty string. + virtual std::string getDebugValue() const; + + // Returns a list of `DebugStringConvertible` objects which can be considered + // as *children* of the object. + // Default implementation returns an empty list. + virtual SharedDebugStringConvertibleList getDebugChildren() const; + + // Returns a list of `DebugStringConvertible` objects which can be considered + // as *properties* of the object. + // Default implementation returns an empty list. + virtual SharedDebugStringConvertibleList getDebugProps() const; + + // Returns a string which represents the object in a human-readable way. + // Default implementation returns a description of the subtree + // rooted at this node, represented in XML-like format. + virtual std::string getDebugDescription(int level = 0) const; + + // Do same as `getDebugDescription` but return only *children* and + // *properties* parts (which are used in `getDebugDescription`). + virtual std::string getDebugPropsDescription(int level = 0) const; + virtual std::string getDebugChildrenDescription(int level = 0) const; +}; + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/debug/DebugStringConvertibleItem.cpp b/ReactCommon/fabric/debug/DebugStringConvertibleItem.cpp new file mode 100644 index 000000000..8baffb5b7 --- /dev/null +++ b/ReactCommon/fabric/debug/DebugStringConvertibleItem.cpp @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "DebugStringConvertibleItem.h" + +namespace facebook { +namespace react { + +DebugStringConvertibleItem::DebugStringConvertibleItem( + const std::string &name, + const std::string &value, + const SharedDebugStringConvertibleList &props, + const SharedDebugStringConvertibleList &children +): + name_(name), + value_(value), + props_(props), + children_(children) {} + +std::string DebugStringConvertibleItem::getDebugName() const { + return name_; +} + +std::string DebugStringConvertibleItem::getDebugValue() const { + return value_; +} + +SharedDebugStringConvertibleList DebugStringConvertibleItem::getDebugProps() const { + return props_; +} + +SharedDebugStringConvertibleList DebugStringConvertibleItem::getDebugChildren() const { + return children_; +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/debug/DebugStringConvertibleItem.h b/ReactCommon/fabric/debug/DebugStringConvertibleItem.h new file mode 100644 index 000000000..257ea1db2 --- /dev/null +++ b/ReactCommon/fabric/debug/DebugStringConvertibleItem.h @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +namespace facebook { +namespace react { + +// Trivial implementation of `DebugStringConvertible` abstract class +// with a stored output; useful for assembling `DebugStringConvertible` values +// in custom implementations of `getDebugChildren` and `getDebugProps`. +class DebugStringConvertibleItem: + public DebugStringConvertible { + +public: + DebugStringConvertibleItem() = default; + DebugStringConvertibleItem(const DebugStringConvertibleItem &item) = default; + + DebugStringConvertibleItem( + const std::string &name = "", + const std::string &value = "", + const SharedDebugStringConvertibleList &props = {}, + const SharedDebugStringConvertibleList &children = {} + ); + + std::string getDebugName() const override; + std::string getDebugValue() const override; + SharedDebugStringConvertibleList getDebugChildren() const override; + SharedDebugStringConvertibleList getDebugProps() const override; + +private: + std::string name_; + std::string value_; + SharedDebugStringConvertibleList props_; + SharedDebugStringConvertibleList children_; +}; + +} // namespace react +} // namespace facebook