LCOV - code coverage report
Current view: top level - src/torque - utils.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 77 94 81.9 %
Date: 2019-04-17 Functions: 17 20 85.0 %

          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             : #include <algorithm>
       6             : #include <fstream>
       7             : #include <iostream>
       8             : #include <string>
       9             : 
      10             : #include "src/base/logging.h"
      11             : #include "src/torque/ast.h"
      12             : #include "src/torque/utils.h"
      13             : 
      14             : namespace v8 {
      15             : namespace internal {
      16             : namespace torque {
      17             : 
      18         367 : std::string StringLiteralUnquote(const std::string& s) {
      19             :   DCHECK(('"' == s.front() && '"' == s.back()) ||
      20             :          ('\'' == s.front() && '\'' == s.back()));
      21         734 :   std::stringstream result;
      22       11287 :   for (size_t i = 1; i < s.length() - 1; ++i) {
      23        5460 :     if (s[i] == '\\') {
      24           0 :       switch (s[++i]) {
      25             :         case 'n':
      26             :           result << '\n';
      27             :           break;
      28             :         case 'r':
      29             :           result << '\r';
      30             :           break;
      31             :         case 't':
      32             :           result << '\t';
      33             :           break;
      34             :         case '\'':
      35             :         case '"':
      36             :         case '\\':
      37             :           result << s[i];
      38             :           break;
      39             :         default:
      40           0 :           UNREACHABLE();
      41             :       }
      42             :     } else {
      43             :       result << s[i];
      44             :     }
      45             :   }
      46         367 :   return result.str();
      47             : }
      48             : 
      49        1735 : std::string StringLiteralQuote(const std::string& s) {
      50        3470 :   std::stringstream result;
      51             :   result << '"';
      52      115959 :   for (size_t i = 0; i < s.length(); ++i) {
      53       57112 :     switch (s[i]) {
      54             :       case '\n':
      55           0 :         result << "\\n";
      56             :         break;
      57             :       case '\r':
      58           0 :         result << "\\r";
      59             :         break;
      60             :       case '\t':
      61           0 :         result << "\\t";
      62             :         break;
      63             :       case '\'':
      64             :       case '"':
      65             :       case '\\':
      66             :         result << "\\" << s[i];
      67             :         break;
      68             :       default:
      69             :         result << s[i];
      70             :     }
      71             :   }
      72             :   result << '"';
      73        1735 :   return result.str();
      74             : }
      75             : 
      76             : static const char kFileUriPrefix[] = "file://";
      77             : static const int kFileUriPrefixLength = sizeof(kFileUriPrefix) - 1;
      78             : 
      79           4 : static int HexCharToInt(unsigned char c) {
      80           4 :   if (isdigit(c)) return c - '0';
      81           2 :   if (isupper(c)) return c - 'A' + 10;
      82             :   DCHECK(islower(c));
      83           1 :   return c - 'a' + 10;
      84             : }
      85             : 
      86           7 : base::Optional<std::string> FileUriDecode(const std::string& uri) {
      87             :   // Abort decoding of URIs that don't start with "file://".
      88           7 :   if (uri.rfind(kFileUriPrefix) != 0) return base::nullopt;
      89             : 
      90           6 :   const std::string path = uri.substr(kFileUriPrefixLength);
      91          12 :   std::ostringstream decoded;
      92             : 
      93         103 :   for (auto iter = path.begin(), end = path.end(); iter != end; ++iter) {
      94         100 :     std::string::value_type c = (*iter);
      95             : 
      96             :     // Normal characters are appended.
      97         100 :     if (c != '%') {
      98             :       decoded << c;
      99             :       continue;
     100             :     }
     101             : 
     102             :     // If '%' is not followed by at least two hex digits, we abort.
     103           5 :     if (std::distance(iter, end) <= 2) return base::nullopt;
     104             : 
     105           3 :     unsigned char first = (*++iter);
     106           3 :     unsigned char second = (*++iter);
     107           3 :     if (!isxdigit(first) || !isxdigit(second)) return base::nullopt;
     108             : 
     109             :     // An escaped hex value needs converting.
     110           2 :     unsigned char value = HexCharToInt(first) * 16 + HexCharToInt(second);
     111             :     decoded << value;
     112             :   }
     113             : 
     114           3 :   return decoded.str();
     115             : }
     116             : 
     117           0 : std::string CurrentPositionAsString() {
     118           0 :   return PositionAsString(CurrentSourcePosition::Get());
     119             : }
     120             : 
     121          12 : DEFINE_CONTEXTUAL_VARIABLE(LintErrorStatus)
     122             : 
     123           2 : [[noreturn]] void ThrowTorqueError(const std::string& message,
     124             :                                    bool include_position) {
     125           4 :   TorqueError error(message);
     126           2 :   if (include_position) error.position = CurrentSourcePosition::Get();
     127           4 :   throw error;
     128             : }
     129             : 
     130           0 : void LintError(const std::string& error) {
     131             :   LintErrorStatus::SetLintError();
     132           0 :   std::cerr << CurrentPositionAsString() << ": Lint error: " << error << "\n";
     133           0 : }
     134             : 
     135           0 : void NamingConventionError(const std::string& type, const std::string& name,
     136             :                            const std::string& convention) {
     137           0 :   std::stringstream sstream;
     138             :   sstream << type << " \"" << name << "\" doesn't follow \"" << convention
     139           0 :           << "\" naming convention.";
     140           0 :   LintError(sstream.str());
     141           0 : }
     142             : 
     143             : namespace {
     144             : 
     145             : bool ContainsUnderscore(const std::string& s) {
     146        3754 :   if (s.empty()) return false;
     147        3754 :   return s.find("_") != std::string::npos;
     148             : }
     149             : 
     150          50 : bool ContainsUpperCase(const std::string& s) {
     151          50 :   if (s.empty()) return false;
     152         579 :   return std::any_of(s.begin(), s.end(), [](char c) { return isupper(c); });
     153             : }
     154             : 
     155             : // Torque has some namespace constants that are used like language level
     156             : // keywords, e.g.: 'True', 'Undefined', etc.
     157             : // These do not need to follow the default naming convention for constants.
     158             : bool IsKeywordLikeName(const std::string& s) {
     159             :   static const char* const keyword_like_constants[]{"True", "False", "Hole",
     160             :                                                     "Null", "Undefined"};
     161             : 
     162             :   return std::find(std::begin(keyword_like_constants),
     163             :                    std::end(keyword_like_constants),
     164             :                    s) != std::end(keyword_like_constants);
     165             : }
     166             : 
     167             : // Untagged/MachineTypes like 'int32', 'intptr' etc. follow a 'all-lowercase'
     168             : // naming convention and are those exempt from the normal type convention.
     169             : bool IsMachineType(const std::string& s) {
     170             :   static const char* const machine_types[]{
     171             :       "void",    "never",   "int8",    "uint8",  "int16",  "uint16",
     172             :       "int31",   "uint31",  "int32",   "uint32", "int64",  "intptr",
     173             :       "uintptr", "float32", "float64", "bool",   "string", "bint"};
     174             : 
     175             :   return std::find(std::begin(machine_types), std::end(machine_types), s) !=
     176             :          std::end(machine_types);
     177             : }
     178             : 
     179             : }  // namespace
     180             : 
     181        2712 : bool IsLowerCamelCase(const std::string& s) {
     182        2712 :   if (s.empty()) return false;
     183        5424 :   return islower(s[0]) && !ContainsUnderscore(s);
     184             : }
     185             : 
     186        1042 : bool IsUpperCamelCase(const std::string& s) {
     187        1042 :   if (s.empty()) return false;
     188        2084 :   return isupper(s[0]) && !ContainsUnderscore(s);
     189             : }
     190             : 
     191          50 : bool IsSnakeCase(const std::string& s) {
     192          50 :   if (s.empty()) return false;
     193          50 :   return !ContainsUpperCase(s);
     194             : }
     195             : 
     196          33 : bool IsValidNamespaceConstName(const std::string& s) {
     197          33 :   if (s.empty()) return false;
     198          33 :   if (IsKeywordLikeName(s)) return true;
     199             : 
     200          56 :   return s[0] == 'k' && IsUpperCamelCase(s.substr(1));
     201             : }
     202             : 
     203         215 : bool IsValidTypeName(const std::string& s) {
     204         215 :   if (s.empty()) return false;
     205         215 :   if (IsMachineType(s)) return true;
     206             : 
     207         193 :   return IsUpperCamelCase(s);
     208             : }
     209             : 
     210         119 : std::string CapifyStringWithUnderscores(const std::string& camellified_string) {
     211             :   std::string result;
     212             :   bool previousWasLower = false;
     213        1851 :   for (auto current : camellified_string) {
     214        1732 :     if (previousWasLower && isupper(current)) {
     215             :       result += "_";
     216             :     }
     217        1732 :     result += toupper(current);
     218        1732 :     previousWasLower = (islower(current));
     219             :   }
     220         119 :   return result;
     221             : }
     222             : 
     223        5496 : std::string CamelifyString(const std::string& underscore_string) {
     224             :   std::string result;
     225             :   bool word_beginning = true;
     226       42264 :   for (auto current : underscore_string) {
     227       36768 :     if (current == '_' || current == '-') {
     228             :       word_beginning = true;
     229             :       continue;
     230             :     }
     231       35307 :     if (word_beginning) {
     232        6957 :       current = toupper(current);
     233             :     }
     234             :     result += current;
     235             :     word_beginning = false;
     236             :   }
     237        5496 :   return result;
     238             : }
     239             : 
     240        1808 : std::string DashifyString(const std::string& underscore_string) {
     241             :   std::string result = underscore_string;
     242             :   std::replace(result.begin(), result.end(), '_', '-');
     243        1808 :   return result;
     244             : }
     245             : 
     246          87 : void ReplaceFileContentsIfDifferent(const std::string& file_path,
     247             :                                     const std::string& contents) {
     248         174 :   std::ifstream old_contents_stream(file_path.c_str());
     249             :   std::string old_contents;
     250          87 :   if (old_contents_stream.good()) {
     251             :     std::istreambuf_iterator<char> eos;
     252           0 :     old_contents =
     253             :         std::string(std::istreambuf_iterator<char>(old_contents_stream), eos);
     254           0 :     old_contents_stream.close();
     255             :   }
     256          87 :   if (old_contents.length() == 0 || old_contents != contents) {
     257         174 :     std::ofstream new_contents_stream;
     258          87 :     new_contents_stream.open(file_path.c_str());
     259             :     new_contents_stream << contents;
     260          87 :     new_contents_stream.close();
     261             :   }
     262          87 : }
     263             : 
     264             : }  // namespace torque
     265             : }  // namespace internal
     266       59456 : }  // namespace v8

Generated by: LCOV version 1.10