LCOV - code coverage report
Current view: top level - src/torque - utils.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 73 97 75.3 %
Date: 2019-03-21 Functions: 16 20 80.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         349 : std::string StringLiteralUnquote(const std::string& s) {
      19             :   DCHECK(('"' == s.front() && '"' == s.back()) ||
      20             :          ('\'' == s.front() && '\'' == s.back()));
      21         698 :   std::stringstream result;
      22       10357 :   for (size_t i = 1; i < s.length() - 1; ++i) {
      23        5004 :     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         349 :   return result.str();
      47             : }
      48             : 
      49        1378 : std::string StringLiteralQuote(const std::string& s) {
      50        2756 :   std::stringstream result;
      51             :   result << '"';
      52       92766 :   for (size_t i = 0; i < s.length(); ++i) {
      53       45694 :     switch (s[i]) {
      54             :       case '\n':
      55           0 :         result << "\\n";
      56           0 :         break;
      57             :       case '\r':
      58           0 :         result << "\\r";
      59           0 :         break;
      60             :       case '\t':
      61           0 :         result << "\\t";
      62           0 :         break;
      63             :       case '\'':
      64             :       case '"':
      65             :       case '\\':
      66             :         result << "\\" << s[i];
      67             :         break;
      68             :       default:
      69             :         result << s[i];
      70             :     }
      71             :   }
      72             :   result << '"';
      73        1378 :   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           0 : [[noreturn]] void ReportErrorString(const std::string& error,
     124             :                                     bool print_position) {
     125           0 :   if (print_position) std::cerr << CurrentPositionAsString() << ": ";
     126           0 :   std::cerr << ": Torque error: " << error << "\n";
     127           0 :   v8::base::OS::Abort();
     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        3588 :   if (s.empty()) return false;
     147        3588 :   return s.find("_") != std::string::npos;
     148             : }
     149             : 
     150          45 : bool ContainsUpperCase(const std::string& s) {
     151          45 :   if (s.empty()) return false;
     152         544 :   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        2618 : bool IsLowerCamelCase(const std::string& s) {
     182        2618 :   if (s.empty()) return false;
     183        5236 :   return islower(s[0]) && !ContainsUnderscore(s);
     184             : }
     185             : 
     186         970 : bool IsUpperCamelCase(const std::string& s) {
     187         970 :   if (s.empty()) return false;
     188        1940 :   return isupper(s[0]) && !ContainsUnderscore(s);
     189             : }
     190             : 
     191          45 : bool IsSnakeCase(const std::string& s) {
     192          45 :   if (s.empty()) return false;
     193          45 :   return !ContainsUpperCase(s);
     194             : }
     195             : 
     196          31 : bool IsValidNamespaceConstName(const std::string& s) {
     197          31 :   if (s.empty()) return false;
     198          31 :   if (IsKeywordLikeName(s)) return true;
     199             : 
     200          52 :   return s[0] == 'k' && IsUpperCamelCase(s.substr(1));
     201             : }
     202             : 
     203         185 : bool IsValidTypeName(const std::string& s) {
     204         185 :   if (s.empty()) return false;
     205         185 :   if (IsMachineType(s)) return true;
     206             : 
     207         163 :   return IsUpperCamelCase(s);
     208             : }
     209             : 
     210          88 : std::string CapifyStringWithUnderscores(const std::string& camellified_string) {
     211             :   std::string result;
     212             :   bool previousWasLower = false;
     213        1353 :   for (auto current : camellified_string) {
     214        1265 :     if (previousWasLower && isupper(current)) {
     215             :       result += "_";
     216             :     }
     217        1265 :     result += toupper(current);
     218        1265 :     previousWasLower = (islower(current));
     219             :   }
     220          88 :   return result;
     221             : }
     222             : 
     223        4192 : std::string CamelifyString(const std::string& underscore_string) {
     224             :   std::string result;
     225             :   bool word_beginning = true;
     226       31590 :   for (auto current : underscore_string) {
     227       27398 :     if (current == '_' || current == '-') {
     228             :       word_beginning = true;
     229             :       continue;
     230             :     }
     231       26356 :     if (word_beginning) {
     232        5234 :       current = toupper(current);
     233             :     }
     234             :     result += current;
     235             :     word_beginning = false;
     236             :   }
     237        4192 :   return result;
     238             : }
     239             : 
     240        1642 : std::string DashifyString(const std::string& underscore_string) {
     241             :   std::string result = underscore_string;
     242             :   std::replace(result.begin(), result.end(), '_', '-');
     243        1642 :   return result;
     244             : }
     245             : 
     246          82 : void ReplaceFileContentsIfDifferent(const std::string& file_path,
     247             :                                     const std::string& contents) {
     248         164 :   std::ifstream old_contents_stream(file_path.c_str());
     249             :   std::string old_contents;
     250          82 :   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          82 :   if (old_contents.length() == 0 || old_contents != contents) {
     257         164 :     std::ofstream new_contents_stream;
     258          82 :     new_contents_stream.open(file_path.c_str());
     259             :     new_contents_stream << contents;
     260          82 :     new_contents_stream.close();
     261             :   }
     262          82 : }
     263             : 
     264             : }  // namespace torque
     265             : }  // namespace internal
     266        6150 : }  // namespace v8

Generated by: LCOV version 1.10