V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
utils.cc
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 std::string StringLiteralUnquote(const std::string& s) {
19  DCHECK(('"' == s.front() && '"' == s.back()) ||
20  ('\'' == s.front() && '\'' == s.back()));
21  std::stringstream result;
22  for (size_t i = 1; i < s.length() - 1; ++i) {
23  if (s[i] == '\\') {
24  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  UNREACHABLE();
41  }
42  } else {
43  result << s[i];
44  }
45  }
46  return result.str();
47 }
48 
49 std::string StringLiteralQuote(const std::string& s) {
50  std::stringstream result;
51  result << '"';
52  for (size_t i = 0; i < s.length(); ++i) {
53  switch (s[i]) {
54  case '\n':
55  result << "\\n";
56  break;
57  case '\r':
58  result << "\\r";
59  break;
60  case '\t':
61  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  return result.str();
74 }
75 
76 std::string CurrentPositionAsString() {
77  return PositionAsString(CurrentSourcePosition::Get());
78 }
79 
80 DEFINE_CONTEXTUAL_VARIABLE(LintErrorStatus)
81 
82 [[noreturn]] void ReportErrorString(const std::string& error) {
83  std::cerr << CurrentPositionAsString() << ": Torque error: " << error << "\n";
84  v8::base::OS::Abort();
85 }
86 
87 void LintError(const std::string& error) {
88  LintErrorStatus::SetLintError();
89  std::cerr << CurrentPositionAsString() << ": Lint error: " << error << "\n";
90 }
91 
92 void NamingConventionError(const std::string& type, const std::string& name,
93  const std::string& convention) {
94  std::stringstream sstream;
95  sstream << type << " \"" << name << "\" doesn't follow \"" << convention
96  << "\" naming convention.";
97  LintError(sstream.str());
98 }
99 
100 namespace {
101 
102 bool ContainsUnderscore(const std::string& s) {
103  if (s.empty()) return false;
104  return s.find("_") != std::string::npos;
105 }
106 
107 bool ContainsUpperCase(const std::string& s) {
108  if (s.empty()) return false;
109  return std::any_of(s.begin(), s.end(), [](char c) { return isupper(c); });
110 }
111 
112 // Torque has some namespace constants that are used like language level
113 // keywords, e.g.: 'True', 'Undefined', etc.
114 // These do not need to follow the default naming convention for constants.
115 bool IsKeywordLikeName(const std::string& s) {
116  static const char* const keyword_like_constants[]{"True", "False", "Hole",
117  "Null", "Undefined"};
118 
119  return std::find(std::begin(keyword_like_constants),
120  std::end(keyword_like_constants),
121  s) != std::end(keyword_like_constants);
122 }
123 
124 // Untagged/MachineTypes like 'int32', 'intptr' etc. follow a 'all-lowercase'
125 // naming convention and are those exempt from the normal type convention.
126 bool IsMachineType(const std::string& s) {
127  static const char* const machine_types[]{
128  "void", "never", "int32", "uint32", "int64", "intptr",
129  "uintptr", "float32", "float64", "bool", "string", "int31"};
130 
131  return std::find(std::begin(machine_types), std::end(machine_types), s) !=
132  std::end(machine_types);
133 }
134 
135 } // namespace
136 
137 bool IsLowerCamelCase(const std::string& s) {
138  if (s.empty()) return false;
139  return islower(s[0]) && !ContainsUnderscore(s);
140 }
141 
142 bool IsUpperCamelCase(const std::string& s) {
143  if (s.empty()) return false;
144  return isupper(s[0]) && !ContainsUnderscore(s);
145 }
146 
147 bool IsSnakeCase(const std::string& s) {
148  if (s.empty()) return false;
149  return !ContainsUpperCase(s);
150 }
151 
152 bool IsValidNamespaceConstName(const std::string& s) {
153  if (s.empty()) return false;
154  if (IsKeywordLikeName(s)) return true;
155 
156  return s[0] == 'k' && IsUpperCamelCase(s.substr(1));
157 }
158 
159 bool IsValidTypeName(const std::string& s) {
160  if (s.empty()) return false;
161  if (IsMachineType(s)) return true;
162 
163  return IsUpperCamelCase(s);
164 }
165 
166 std::string CamelifyString(const std::string& underscore_string) {
167  std::string result;
168  bool word_beginning = true;
169  for (auto current : underscore_string) {
170  if (current == '_' || current == '-') {
171  word_beginning = true;
172  continue;
173  }
174  if (word_beginning) {
175  current = toupper(current);
176  }
177  result += current;
178  word_beginning = false;
179  }
180  return result;
181 }
182 
183 std::string DashifyString(const std::string& underscore_string) {
184  std::string result = underscore_string;
185  std::replace(result.begin(), result.end(), '_', '-');
186  return result;
187 }
188 
189 void ReplaceFileContentsIfDifferent(const std::string& file_path,
190  const std::string& contents) {
191  std::ifstream old_contents_stream(file_path.c_str());
192  std::string old_contents;
193  if (old_contents_stream.good()) {
194  std::istreambuf_iterator<char> eos;
195  old_contents =
196  std::string(std::istreambuf_iterator<char>(old_contents_stream), eos);
197  old_contents_stream.close();
198  }
199  if (old_contents.length() == 0 || old_contents != contents) {
200  std::ofstream new_contents_stream;
201  new_contents_stream.open(file_path.c_str());
202  new_contents_stream << contents;
203  new_contents_stream.close();
204  }
205 }
206 
207 } // namespace torque
208 } // namespace internal
209 } // namespace v8
Definition: libplatform.h:13