LCOV - code coverage report
Current view: top level - src/torque - utils.h (source / functions) Hit Total Coverage
Test: app.info Lines: 64 76 84.2 %
Date: 2019-04-17 Functions: 23 119 19.3 %

          Line data    Source code
       1             : // Copyright 2017 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_TORQUE_UTILS_H_
       6             : #define V8_TORQUE_UTILS_H_
       7             : 
       8             : #include <ostream>
       9             : #include <streambuf>
      10             : #include <string>
      11             : #include <unordered_set>
      12             : #include <vector>
      13             : 
      14             : #include "src/base/functional.h"
      15             : #include "src/base/optional.h"
      16             : #include "src/torque/contextual.h"
      17             : #include "src/torque/source-positions.h"
      18             : 
      19             : namespace v8 {
      20             : namespace internal {
      21             : namespace torque {
      22             : 
      23             : std::string StringLiteralUnquote(const std::string& s);
      24             : std::string StringLiteralQuote(const std::string& s);
      25             : 
      26             : // Decodes "file://" URIs into file paths which can then be used
      27             : // with the standard stream API.
      28             : V8_EXPORT_PRIVATE base::Optional<std::string> FileUriDecode(
      29             :     const std::string& s);
      30             : 
      31             : class LintErrorStatus : public ContextualClass<LintErrorStatus> {
      32             :  public:
      33           3 :   LintErrorStatus() : has_lint_errors_(false) {}
      34             : 
      35           3 :   static bool HasLintErrors() { return Get().has_lint_errors_; }
      36           0 :   static void SetLintError() { Get().has_lint_errors_ = true; }
      37             : 
      38             :  private:
      39             :   bool has_lint_errors_;
      40             : };
      41             : 
      42             : void LintError(const std::string& error);
      43             : 
      44             : // Prints a LintError with the format "{type} '{name}' doesn't follow
      45             : // '{convention}' naming convention".
      46             : void NamingConventionError(const std::string& type, const std::string& name,
      47             :                            const std::string& convention);
      48             : 
      49             : bool IsLowerCamelCase(const std::string& s);
      50             : bool IsUpperCamelCase(const std::string& s);
      51             : bool IsSnakeCase(const std::string& s);
      52             : bool IsValidNamespaceConstName(const std::string& s);
      53             : bool IsValidTypeName(const std::string& s);
      54             : 
      55          22 : struct TorqueError : public std::exception {
      56           6 :   explicit TorqueError(const std::string& message) : message(message) {}
      57             : 
      58             :   std::string message;
      59             :   base::Optional<SourcePosition> position;
      60             : };
      61             : 
      62             : [[noreturn]] void ThrowTorqueError(const std::string& error,
      63             :                                    bool include_position);
      64             : template <class... Args>
      65           2 : [[noreturn]] void ReportError(Args&&... args) {
      66           4 :   std::stringstream s;
      67           0 :   USE((s << std::forward<Args>(args))...);
      68           4 :   ThrowTorqueError(s.str(), true);
      69             : }
      70             : template <class... Args>
      71           0 : [[noreturn]] void ReportErrorWithoutPosition(Args&&... args) {
      72           0 :   std::stringstream s;
      73           0 :   USE((s << std::forward<Args>(args))...);
      74           0 :   ThrowTorqueError(s.str(), false);
      75             : }
      76             : 
      77             : std::string CapifyStringWithUnderscores(const std::string& camellified_string);
      78             : std::string CamelifyString(const std::string& underscore_string);
      79             : std::string DashifyString(const std::string& underscore_string);
      80             : 
      81             : void ReplaceFileContentsIfDifferent(const std::string& file_path,
      82             :                                     const std::string& contents);
      83             : 
      84             : std::string CurrentPositionAsString();
      85             : 
      86             : template <class T>
      87           9 : class Deduplicator {
      88             :  public:
      89             :   const T* Add(T x) { return &*(storage_.insert(std::move(x)).first); }
      90             : 
      91             :  private:
      92             :   std::unordered_set<T, base::hash<T>> storage_;
      93             : };
      94             : 
      95             : template <class C, class T>
      96        7757 : void PrintCommaSeparatedList(std::ostream& os, const T& list, C transform) {
      97             :   bool first = true;
      98       98503 :   for (auto& e : list) {
      99       45373 :     if (first) {
     100             :       first = false;
     101             :     } else {
     102       38080 :       os << ", ";
     103             :     }
     104       90746 :     os << transform(e);
     105             :   }
     106        7757 : }
     107             : 
     108             : template <class T,
     109             :           typename std::enable_if<
     110             :               std::is_pointer<typename T::value_type>::value, int>::type = 0>
     111           0 : void PrintCommaSeparatedList(std::ostream& os, const T& list) {
     112             :   bool first = true;
     113           0 :   for (auto& e : list) {
     114           0 :     if (first) {
     115             :       first = false;
     116             :     } else {
     117           0 :       os << ", ";
     118             :     }
     119           0 :     os << *e;
     120             :   }
     121           0 : }
     122             : 
     123             : template <class T,
     124             :           typename std::enable_if<
     125             :               !std::is_pointer<typename T::value_type>::value, int>::type = 0>
     126        5579 : void PrintCommaSeparatedList(std::ostream& os, const T& list) {
     127             :   bool first = true;
     128       15936 :   for (auto& e : list) {
     129       10357 :     if (first) {
     130             :       first = false;
     131             :     } else {
     132        4861 :       os << ", ";
     133             :     }
     134         363 :     os << e;
     135             :   }
     136        5579 : }
     137             : 
     138             : struct BottomOffset {
     139             :   size_t offset;
     140             :   BottomOffset& operator++() {
     141       15439 :     ++offset;
     142             :     return *this;
     143             :   }
     144       23302 :   BottomOffset operator+(size_t x) const { return BottomOffset{offset + x}; }
     145             :   BottomOffset operator-(size_t x) const {
     146             :     DCHECK_LE(x, offset);
     147      134148 :     return BottomOffset{offset - x};
     148             :   }
     149             :   bool operator<(const BottomOffset& other) const {
     150             :     return offset < other.offset;
     151             :   }
     152             :   bool operator<=(const BottomOffset& other) const {
     153             :     return offset <= other.offset;
     154             :   }
     155             :   bool operator==(const BottomOffset& other) const {
     156         204 :     return offset == other.offset;
     157             :   }
     158             :   bool operator!=(const BottomOffset& other) const {
     159             :     return offset != other.offset;
     160             :   }
     161             : };
     162             : 
     163             : inline std::ostream& operator<<(std::ostream& out, BottomOffset from_bottom) {
     164             :   return out << "BottomOffset{" << from_bottom.offset << "}";
     165             : }
     166             : 
     167             : // An iterator-style range of stack slots.
     168             : class StackRange {
     169             :  public:
     170       57549 :   StackRange(BottomOffset begin, BottomOffset end) : begin_(begin), end_(end) {
     171             :     DCHECK_LE(begin_, end_);
     172             :   }
     173             : 
     174             :   bool operator==(const StackRange& other) const {
     175         204 :     return begin_ == other.begin_ && end_ == other.end_;
     176             :   }
     177             : 
     178             :   void Extend(StackRange adjacent) {
     179             :     DCHECK_EQ(end_, adjacent.begin_);
     180        7860 :     end_ = adjacent.end_;
     181             :   }
     182             : 
     183      143881 :   size_t Size() const { return end_.offset - begin_.offset; }
     184             :   BottomOffset begin() const { return begin_; }
     185             :   BottomOffset end() const { return end_; }
     186             : 
     187             :  private:
     188             :   BottomOffset begin_;
     189             :   BottomOffset end_;
     190             : };
     191             : 
     192             : inline std::ostream& operator<<(std::ostream& out, StackRange range) {
     193             :   return out << "StackRange{" << range.begin() << ", " << range.end() << "}";
     194             : }
     195             : 
     196             : template <class T>
     197       70828 : class Stack {
     198             :  public:
     199             :   using value_type = T;
     200             :   Stack() = default;
     201           2 :   Stack(std::initializer_list<T> initializer)
     202           2 :       : Stack(std::vector<T>(initializer)) {}
     203             :   explicit Stack(std::vector<T> v) : elements_(std::move(v)) {}
     204             :   size_t Size() const { return elements_.size(); }
     205             :   const T& Peek(BottomOffset from_bottom) const {
     206             :     return elements_.at(from_bottom.offset);
     207             :   }
     208        1302 :   void Poke(BottomOffset from_bottom, T x) {
     209        1964 :     elements_.at(from_bottom.offset) = std::move(x);
     210        1302 :   }
     211      102977 :   void Push(T x) { elements_.push_back(std::move(x)); }
     212             :   StackRange TopRange(size_t slot_count) const {
     213             :     DCHECK_GE(Size(), slot_count);
     214             :     return StackRange{AboveTop() - slot_count, AboveTop()};
     215             :   }
     216       10171 :   StackRange PushMany(const std::vector<T>& v) {
     217       19422 :     for (const T& x : v) {
     218        9251 :       Push(x);
     219             :     }
     220       10171 :     return TopRange(v.size());
     221             :   }
     222      114446 :   const T& Top() const { return Peek(AboveTop() - 1); }
     223        4059 :   T Pop() {
     224       12184 :     T result = std::move(elements_.back());
     225             :     elements_.pop_back();
     226        4059 :     return result;
     227             :   }
     228        7475 :   std::vector<T> PopMany(size_t count) {
     229             :     DCHECK_GE(elements_.size(), count);
     230             :     std::vector<T> result;
     231        7475 :     result.reserve(count);
     232       16625 :     for (auto it = elements_.end() - count; it != elements_.end(); ++it) {
     233             :       result.push_back(std::move(*it));
     234             :     }
     235        7475 :     elements_.resize(elements_.size() - count);
     236        7475 :     return result;
     237             :   }
     238             :   // The invalid offset above the top element. This is useful for StackRange.
     239             :   BottomOffset AboveTop() const { return BottomOffset{Size()}; }
     240             :   // Delete the slots in {range}, moving higher slots to fill the gap.
     241       19834 :   void DeleteRange(StackRange range) {
     242             :     DCHECK_LE(range.end(), AboveTop());
     243       19834 :     if (range.Size() == 0) return;
     244       34956 :     for (BottomOffset i = range.end(); i < AboveTop(); ++i) {
     245       23334 :       elements_[i.offset - range.Size()] = std::move(elements_[i.offset]);
     246             :     }
     247       19517 :     elements_.resize(elements_.size() - range.Size());
     248             :   }
     249             : 
     250             :   bool operator==(const Stack& other) const {
     251        4710 :     return elements_ == other.elements_;
     252             :   }
     253             :   bool operator!=(const Stack& other) const {
     254             :     return elements_ != other.elements_;
     255             :   }
     256             : 
     257             :   T* begin() { return elements_.data(); }
     258             :   T* end() { return begin() + elements_.size(); }
     259             :   const T* begin() const { return elements_.data(); }
     260             :   const T* end() const { return begin() + elements_.size(); }
     261             : 
     262             :  private:
     263             :   std::vector<T> elements_;
     264             : };
     265             : 
     266             : template <class T>
     267             : T* CheckNotNull(T* x) {
     268             :   CHECK_NOT_NULL(x);
     269             :   return x;
     270             : }
     271             : 
     272             : template <class T>
     273             : inline std::ostream& operator<<(std::ostream& os, Stack<T>& t) {
     274             :   os << "Stack{";
     275             :   PrintCommaSeparatedList(os, t);
     276             :   os << "}";
     277             :   return os;
     278             : }
     279             : class ToString {
     280             :  public:
     281             :   template <class T>
     282             :   ToString& operator<<(T&& x) {
     283             :     s_ << std::forward<T>(x);
     284             :     return *this;
     285             :   }
     286             :   operator std::string() { return s_.str(); }
     287             : 
     288             :  private:
     289             :   std::stringstream s_;
     290             : };
     291             : 
     292             : static const char* const kBaseNamespaceName = "base";
     293             : static const char* const kTestNamespaceName = "test";
     294             : 
     295             : // Erase elements of a container that has a constant-time erase function, like
     296             : // std::set or std::list. Calling this on std::vector would have quadratic
     297             : // complexity.
     298             : template <class Container, class F>
     299         121 : void EraseIf(Container* container, F f) {
     300         303 :   for (auto it = container->begin(); it != container->end();) {
     301         364 :     if (f(*it)) {
     302             :       it = container->erase(it);
     303             :     } else {
     304             :       ++it;
     305             :     }
     306             :   }
     307         121 : }
     308             : 
     309           9 : class NullStreambuf : public std::streambuf {
     310             :  public:
     311        2724 :   virtual int overflow(int c) {
     312        2724 :     setp(buffer_, buffer_ + sizeof(buffer_));
     313        2724 :     return (c == traits_type::eof()) ? '\0' : c;
     314             :   }
     315             : 
     316             :  private:
     317             :   char buffer_[64];
     318             : };
     319             : 
     320           6 : class NullOStream : public std::ostream {
     321             :  public:
     322          12 :   NullOStream() : std::ostream(&buffer_) {}
     323             : 
     324             :  private:
     325             :   NullStreambuf buffer_;
     326             : };
     327             : 
     328             : }  // namespace torque
     329             : }  // namespace internal
     330             : }  // namespace v8
     331             : 
     332             : #endif  // V8_TORQUE_UTILS_H_

Generated by: LCOV version 1.10