DebugStringConvertible.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. */
  7. #include "DebugStringConvertible.h"
  8. #include <folly/Conv.h>
  9. #include <folly/Format.h>
  10. namespace facebook {
  11. namespace react {
  12. #if RN_DEBUG_STRING_CONVERTIBLE
  13. std::string DebugStringConvertible::getDebugChildrenDescription(
  14. DebugStringConvertibleOptions options) const {
  15. if (options.depth >= options.maximumDepth) {
  16. return "";
  17. }
  18. options.depth++;
  19. auto trailing = options.format ? std::string{"\n"} : std::string{""};
  20. auto childrenString = std::string{""};
  21. for (auto child : getDebugChildren()) {
  22. if (!child) {
  23. continue;
  24. }
  25. childrenString += child->getDebugDescription(options) + trailing;
  26. }
  27. if (!childrenString.empty() && !trailing.empty()) {
  28. // Removing trailing fragment.
  29. childrenString.erase(childrenString.end() - 1);
  30. }
  31. return childrenString;
  32. }
  33. std::string DebugStringConvertible::getDebugPropsDescription(
  34. DebugStringConvertibleOptions options) const {
  35. if (options.depth >= options.maximumDepth) {
  36. return "";
  37. }
  38. options.depth++;
  39. auto propsString = std::string{""};
  40. for (auto prop : getDebugProps()) {
  41. if (!prop) {
  42. continue;
  43. }
  44. auto name = prop->getDebugName();
  45. auto value = prop->getDebugValue();
  46. auto children = prop->getDebugPropsDescription(options);
  47. auto valueAndChildren =
  48. value + (children.empty() ? "" : "(" + children + ")");
  49. propsString +=
  50. " " + name + (valueAndChildren.empty() ? "" : "=" + valueAndChildren);
  51. }
  52. if (!propsString.empty()) {
  53. // Removing leading space character.
  54. propsString.erase(propsString.begin());
  55. }
  56. return propsString;
  57. }
  58. std::string DebugStringConvertible::getDebugDescription(
  59. DebugStringConvertibleOptions options) const {
  60. auto nameString = getDebugName();
  61. auto valueString = getDebugValue();
  62. // Convention:
  63. // If `name` and `value` are empty, `description` is also empty.
  64. if (nameString.empty() && valueString.empty()) {
  65. return "";
  66. }
  67. // Convention:
  68. // If `name` is empty and `value` isn't empty, `description` equals `value`.
  69. if (nameString.empty()) {
  70. return valueString;
  71. }
  72. auto childrenString = getDebugChildrenDescription(options);
  73. auto propsString = getDebugPropsDescription(options);
  74. auto leading =
  75. options.format ? std::string(options.depth * 2, ' ') : std::string{""};
  76. auto trailing = options.format ? std::string{"\n"} : std::string{""};
  77. return leading + "<" + nameString +
  78. (valueString.empty() ? "" : "=" + valueString) +
  79. (propsString.empty() ? "" : " " + propsString) +
  80. (childrenString.empty() ? "/>"
  81. : ">" + trailing + childrenString + trailing +
  82. leading + "</" + nameString + ">");
  83. }
  84. std::string DebugStringConvertible::getDebugName() const {
  85. return "Node";
  86. }
  87. std::string DebugStringConvertible::getDebugValue() const {
  88. return "";
  89. }
  90. SharedDebugStringConvertibleList DebugStringConvertible::getDebugChildren()
  91. const {
  92. return SharedDebugStringConvertibleList();
  93. }
  94. SharedDebugStringConvertibleList DebugStringConvertible::getDebugProps() const {
  95. return SharedDebugStringConvertibleList();
  96. }
  97. /*
  98. * `toString`-family implementation.
  99. */
  100. std::string toString(std::string const &value) {
  101. return value;
  102. }
  103. std::string toString(int const &value) {
  104. return folly::to<std::string>(value);
  105. }
  106. std::string toString(bool const &value) {
  107. return folly::to<std::string>(value);
  108. }
  109. std::string toString(float const &value) {
  110. return folly::to<std::string>(value);
  111. }
  112. std::string toString(double const &value) {
  113. return folly::to<std::string>(value);
  114. }
  115. std::string toString(void const *value) {
  116. if (value == nullptr) {
  117. return "null";
  118. }
  119. return folly::sformat("0x{0:016x}", reinterpret_cast<size_t>(value));
  120. }
  121. #endif
  122. } // namespace react
  123. } // namespace facebook