Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(251)

Side by Side Diff: third_party/WebKit/Source/platform/v8_inspector/V8StringUtil.cpp

Issue 1767883002: DevTools: generate string16-based handlers for v8_inspector. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: for landing 2 Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "platform/v8_inspector/V8StringUtil.h" 5 #include "platform/v8_inspector/V8StringUtil.h"
6 6
7 #include "platform/inspector_protocol/String16.h"
7 #include "platform/v8_inspector/V8DebuggerImpl.h" 8 #include "platform/v8_inspector/V8DebuggerImpl.h"
8 #include "platform/v8_inspector/V8Regex.h" 9 #include "platform/v8_inspector/V8Regex.h"
9 #include "platform/v8_inspector/public/V8ContentSearchUtil.h" 10 #include "platform/v8_inspector/public/V8ContentSearchUtil.h"
10 #include "wtf/text/StringBuilder.h" 11 #include "platform/v8_inspector/public/V8ToProtocolValue.h"
11 12
12 namespace blink { 13 namespace blink {
13 14
14 namespace { 15 namespace {
15 16
16 String findMagicComment(const String& content, const String& name, bool multilin e, bool* deprecated) 17 String16 findMagicComment(const String16& content, const String16& name, bool mu ltiline, bool* deprecated)
17 { 18 {
18 ASSERT(name.find("=") == kNotFound); 19 ASSERT(name.find("=") == kNotFound);
19 if (deprecated) 20 if (deprecated)
20 *deprecated = false; 21 *deprecated = false;
21 22
22 unsigned length = content.length(); 23 unsigned length = content.length();
23 unsigned nameLength = name.length(); 24 unsigned nameLength = name.length();
24 25
25 size_t pos = length; 26 size_t pos = length;
26 size_t equalSignPos = 0; 27 size_t equalSignPos = 0;
27 size_t closingCommentPos = 0; 28 size_t closingCommentPos = 0;
28 while (true) { 29 while (true) {
29 pos = content.reverseFind(name, pos); 30 pos = content.reverseFind(name, pos);
30 if (pos == kNotFound) 31 if (pos == kNotFound)
31 return String(); 32 return String16();
32 33
33 // Check for a /\/[\/*][@#][ \t]/ regexp (length of 4) before found name . 34 // Check for a /\/[\/*][@#][ \t]/ regexp (length of 4) before found name .
34 if (pos < 4) 35 if (pos < 4)
35 return String(); 36 return String16();
36 pos -= 4; 37 pos -= 4;
37 if (content[pos] != '/') 38 if (content[pos] != '/')
38 continue; 39 continue;
39 if ((content[pos + 1] != '/' || multiline) 40 if ((content[pos + 1] != '/' || multiline)
40 && (content[pos + 1] != '*' || !multiline)) 41 && (content[pos + 1] != '*' || !multiline))
41 continue; 42 continue;
42 if (content[pos + 2] != '#' && content[pos + 2] != '@') 43 if (content[pos + 2] != '#' && content[pos + 2] != '@')
43 continue; 44 continue;
44 if (content[pos + 3] != ' ' && content[pos + 3] != '\t') 45 if (content[pos + 3] != ' ' && content[pos + 3] != '\t')
45 continue; 46 continue;
46 equalSignPos = pos + 4 + nameLength; 47 equalSignPos = pos + 4 + nameLength;
47 if (equalSignPos < length && content[equalSignPos] != '=') 48 if (equalSignPos < length && content[equalSignPos] != '=')
48 continue; 49 continue;
49 if (multiline) { 50 if (multiline) {
50 closingCommentPos = content.find("*/", equalSignPos + 1); 51 closingCommentPos = content.find("*/", equalSignPos + 1);
51 if (closingCommentPos == kNotFound) 52 if (closingCommentPos == kNotFound)
52 return String(); 53 return String16();
53 } 54 }
54 55
55 break; 56 break;
56 } 57 }
57 58
58 if (deprecated && content[pos + 2] == '@') 59 if (deprecated && content[pos + 2] == '@')
59 *deprecated = true; 60 *deprecated = true;
60 61
61 ASSERT(equalSignPos); 62 ASSERT(equalSignPos);
62 ASSERT(!multiline || closingCommentPos); 63 ASSERT(!multiline || closingCommentPos);
63 size_t urlPos = equalSignPos + 1; 64 size_t urlPos = equalSignPos + 1;
64 String match = multiline 65 String16 match = multiline
65 ? content.substring(urlPos, closingCommentPos - urlPos) 66 ? content.substring(urlPos, closingCommentPos - urlPos)
66 : content.substring(urlPos); 67 : content.substring(urlPos);
67 68
68 size_t newLine = match.find("\n"); 69 size_t newLine = match.find("\n");
69 if (newLine != kNotFound) 70 if (newLine != kNotFound)
70 match = match.substring(0, newLine); 71 match = match.substring(0, newLine);
71 match = match.stripWhiteSpace(); 72 match = match.stripWhiteSpace();
72 73
73 String disallowedChars("\"' \t"); 74 String16 disallowedChars("\"' \t");
74 for (unsigned i = 0; i < match.length(); ++i) { 75 for (unsigned i = 0; i < match.length(); ++i) {
75 if (disallowedChars.find(match[i]) != kNotFound) 76 if (disallowedChars.find(match[i]) != kNotFound)
76 return ""; 77 return "";
77 } 78 }
78 79
79 return match; 80 return match;
80 } 81 }
81 82
82 String createSearchRegexSource(const String& text) 83 String16 createSearchRegexSource(const String16& text)
83 { 84 {
84 StringBuilder result; 85 String16Builder result;
85 String specials("[](){}+-*.,?\\^$|"); 86 String16 specials("[](){}+-*.,?\\^$|");
86 87
87 for (unsigned i = 0; i < text.length(); i++) { 88 for (unsigned i = 0; i < text.length(); i++) {
88 if (specials.find(text[i]) != kNotFound) 89 if (specials.find(text[i]) != kNotFound)
89 result.append('\\'); 90 result.append('\\');
90 result.append(text[i]); 91 result.append(text[i]);
91 } 92 }
92 93
93 return result.toString(); 94 return result.toString();
94 } 95 }
95 96
96 PassOwnPtr<protocol::Vector<unsigned>> lineEndings(const String& text) 97 PassOwnPtr<protocol::Vector<unsigned>> lineEndings(const String16& text)
97 { 98 {
98 OwnPtr<protocol::Vector<unsigned>> result(adoptPtr(new protocol::Vector<unsi gned>())); 99 OwnPtr<protocol::Vector<unsigned>> result(adoptPtr(new protocol::Vector<unsi gned>()));
99 100
100 unsigned start = 0; 101 unsigned start = 0;
101 while (start < text.length()) { 102 while (start < text.length()) {
102 size_t lineEnd = text.find('\n', start); 103 size_t lineEnd = text.find('\n', start);
103 if (lineEnd == kNotFound) 104 if (lineEnd == kNotFound)
104 break; 105 break;
105 106
106 result->append(static_cast<unsigned>(lineEnd)); 107 result->append(static_cast<unsigned>(lineEnd));
107 start = lineEnd + 1; 108 start = lineEnd + 1;
108 } 109 }
109 result->append(text.length()); 110 result->append(text.length());
110 111
111 return result.release(); 112 return result.release();
112 } 113 }
113 114
114 protocol::Vector<std::pair<int, String>> scriptRegexpMatchesByLines(const V8Rege x& regex, const String& text) 115 protocol::Vector<std::pair<int, String16>> scriptRegexpMatchesByLines(const V8Re gex& regex, const String16& text)
115 { 116 {
116 protocol::Vector<std::pair<int, String>> result; 117 protocol::Vector<std::pair<int, String16>> result;
117 if (text.isEmpty()) 118 if (text.isEmpty())
118 return result; 119 return result;
119 120
120 OwnPtr<protocol::Vector<unsigned>> endings(lineEndings(text)); 121 OwnPtr<protocol::Vector<unsigned>> endings(lineEndings(text));
121 unsigned size = endings->size(); 122 unsigned size = endings->size();
122 unsigned start = 0; 123 unsigned start = 0;
123 for (unsigned lineNumber = 0; lineNumber < size; ++lineNumber) { 124 for (unsigned lineNumber = 0; lineNumber < size; ++lineNumber) {
124 unsigned lineEnd = endings->at(lineNumber); 125 unsigned lineEnd = endings->at(lineNumber);
125 String line = text.substring(start, lineEnd - start); 126 String16 line = text.substring(start, lineEnd - start);
126 if (line.endsWith('\r')) 127 if (line.endsWith('\r'))
127 line = line.left(line.length() - 1); 128 line = line.left(line.length() - 1);
128 129
129 int matchLength; 130 int matchLength;
130 if (regex.match(line, 0, &matchLength) != -1) 131 if (regex.match(line, 0, &matchLength) != -1)
131 result.append(std::pair<int, String>(lineNumber, line)); 132 result.append(std::pair<int, String16>(lineNumber, line));
132 133
133 start = lineEnd + 1; 134 start = lineEnd + 1;
134 } 135 }
135 return result; 136 return result;
136 } 137 }
137 138
138 PassOwnPtr<protocol::Debugger::SearchMatch> buildObjectForSearchMatch(int lineNu mber, const String& lineContent) 139 PassOwnPtr<protocol::Debugger::SearchMatch> buildObjectForSearchMatch(int lineNu mber, const String16& lineContent)
139 { 140 {
140 return protocol::Debugger::SearchMatch::create() 141 return protocol::Debugger::SearchMatch::create()
141 .setLineNumber(lineNumber) 142 .setLineNumber(lineNumber)
142 .setLineContent(lineContent) 143 .setLineContent(lineContent)
143 .build(); 144 .build();
144 } 145 }
145 146
146 PassOwnPtr<V8Regex> createSearchRegex(V8DebuggerImpl* debugger, const String& qu ery, bool caseSensitive, bool isRegex) 147 PassOwnPtr<V8Regex> createSearchRegex(V8DebuggerImpl* debugger, const String16& query, bool caseSensitive, bool isRegex)
147 { 148 {
148 String regexSource = isRegex ? query : createSearchRegexSource(query); 149 String16 regexSource = isRegex ? query : createSearchRegexSource(query);
149 return adoptPtr(new V8Regex(debugger, regexSource, caseSensitive ? TextCaseS ensitive : TextCaseInsensitive)); 150 return adoptPtr(new V8Regex(debugger, regexSource, caseSensitive));
150 } 151 }
151 152
152 } // namespace 153 } // namespace
153 154
154 v8::Local<v8::String> toV8String(v8::Isolate* isolate, const String& string) 155 v8::Local<v8::String> toV8String(v8::Isolate* isolate, const String16& string)
155 { 156 {
156 if (string.isNull()) 157 if (string.isNull())
157 return v8::String::Empty(isolate); 158 return v8::String::Empty(isolate);
158 if (string.is8Bit()) 159 if (string.is8Bit())
159 return v8::String::NewFromOneByte(isolate, string.characters8(), v8::New StringType::kNormal, string.length()).ToLocalChecked(); 160 return v8::String::NewFromOneByte(isolate, string.characters8(), v8::New StringType::kNormal, string.length()).ToLocalChecked();
160 return v8::String::NewFromTwoByte(isolate, reinterpret_cast<const uint16_t*> (string.characters16()), v8::NewStringType::kNormal, string.length()).ToLocalChe cked(); 161 return v8::String::NewFromTwoByte(isolate, reinterpret_cast<const uint16_t*> (string.characters16()), v8::NewStringType::kNormal, string.length()).ToLocalChe cked();
161 } 162 }
162 163
163 v8::Local<v8::String> toV8StringInternalized(v8::Isolate* isolate, const String& string) 164 v8::Local<v8::String> toV8StringInternalized(v8::Isolate* isolate, const String1 6& string)
164 { 165 {
165 if (string.isNull()) 166 if (string.isNull())
166 return v8::String::Empty(isolate); 167 return v8::String::Empty(isolate);
167 if (string.is8Bit()) 168 if (string.is8Bit())
168 return v8::String::NewFromOneByte(isolate, string.characters8(), v8::New StringType::kInternalized, string.length()).ToLocalChecked(); 169 return v8::String::NewFromOneByte(isolate, string.characters8(), v8::New StringType::kInternalized, string.length()).ToLocalChecked();
169 return v8::String::NewFromTwoByte(isolate, reinterpret_cast<const uint16_t*> (string.characters16()), v8::NewStringType::kInternalized, string.length()).ToLo calChecked(); 170 return v8::String::NewFromTwoByte(isolate, reinterpret_cast<const uint16_t*> (string.characters16()), v8::NewStringType::kInternalized, string.length()).ToLo calChecked();
170 } 171 }
171 172
172 String toWTFString(v8::Local<v8::String> value) 173 String16 toProtocolString(v8::Local<v8::String> value)
173 { 174 {
174 if (value.IsEmpty() || value->IsNull() || value->IsUndefined()) 175 if (value.IsEmpty() || value->IsNull() || value->IsUndefined())
175 return String(); 176 return String16();
176 UChar* buffer; 177 UChar* buffer;
177 String result = String::createUninitialized(value->Length(), buffer); 178 String16 result = String16::createUninitialized(value->Length(), buffer);
178 value->Write(reinterpret_cast<uint16_t*>(buffer), 0, value->Length()); 179 value->Write(reinterpret_cast<uint16_t*>(buffer), 0, value->Length());
179 return result; 180 return result;
180 } 181 }
181 182
182 String toWTFStringWithTypeCheck(v8::Local<v8::Value> value) 183 String16 toProtocolStringWithTypeCheck(v8::Local<v8::Value> value)
183 { 184 {
184 if (value.IsEmpty() || !value->IsString()) 185 if (value.IsEmpty() || !value->IsString())
185 return String(); 186 return String16();
186 return toWTFString(value.As<v8::String>()); 187 return toProtocolString(value.As<v8::String>());
187 } 188 }
188 189
189 namespace V8ContentSearchUtil { 190 namespace V8ContentSearchUtil {
190 191
191 String findSourceURL(const String& content, bool multiline, bool* deprecated) 192 String16 findSourceURL(const String16& content, bool multiline, bool* deprecated )
192 { 193 {
193 return findMagicComment(content, "sourceURL", multiline, deprecated); 194 return findMagicComment(content, "sourceURL", multiline, deprecated);
194 } 195 }
195 196
196 String findSourceMapURL(const String& content, bool multiline, bool* deprecated) 197 String16 findSourceMapURL(const String16& content, bool multiline, bool* depreca ted)
197 { 198 {
198 return findMagicComment(content, "sourceMappingURL", multiline, deprecated); 199 return findMagicComment(content, "sourceMappingURL", multiline, deprecated);
199 } 200 }
200 201
201 PassOwnPtr<protocol::Array<protocol::Debugger::SearchMatch>> searchInTextByLines (V8Debugger* debugger, const String& text, const String& query, const bool caseS ensitive, const bool isRegex) 202 PassOwnPtr<protocol::Array<protocol::Debugger::SearchMatch>> searchInTextByLines (V8Debugger* debugger, const String16& text, const String16& query, const bool c aseSensitive, const bool isRegex)
202 { 203 {
203 OwnPtr<protocol::Array<protocol::Debugger::SearchMatch>> result = protocol:: Array<protocol::Debugger::SearchMatch>::create(); 204 OwnPtr<protocol::Array<protocol::Debugger::SearchMatch>> result = protocol:: Array<protocol::Debugger::SearchMatch>::create();
204 OwnPtr<V8Regex> regex = createSearchRegex(static_cast<V8DebuggerImpl*>(debug ger), query, caseSensitive, isRegex); 205 OwnPtr<V8Regex> regex = createSearchRegex(static_cast<V8DebuggerImpl*>(debug ger), query, caseSensitive, isRegex);
205 protocol::Vector<std::pair<int, String>> matches = scriptRegexpMatchesByLine s(*regex.get(), text); 206 protocol::Vector<std::pair<int, String16>> matches = scriptRegexpMatchesByLi nes(*regex.get(), text);
206 207
207 for (const auto& match : matches) 208 for (const auto& match : matches)
208 result->addItem(buildObjectForSearchMatch(match.first, match.second)); 209 result->addItem(buildObjectForSearchMatch(match.first, match.second));
209 210
210 return result.release(); 211 return result.release();
211 } 212 }
212 213
213 } // namespace V8ContentSearchUtil 214 } // namespace V8ContentSearchUtil
214 215
216 PassOwnPtr<protocol::Value> toProtocolValue(v8::Local<v8::Context> context, v8:: Local<v8::Value> value, int maxDepth)
217 {
218 if (value.IsEmpty()) {
219 ASSERT_NOT_REACHED();
220 return nullptr;
221 }
222
223 if (!maxDepth)
224 return nullptr;
225 maxDepth--;
226
227 if (value->IsNull() || value->IsUndefined())
228 return protocol::Value::null();
229 if (value->IsBoolean())
230 return protocol::FundamentalValue::create(value.As<v8::Boolean>()->Value ());
231 if (value->IsNumber())
232 return protocol::FundamentalValue::create(value.As<v8::Number>()->Value( ));
233 if (value->IsString())
234 return protocol::StringValue::create(toProtocolString(value.As<v8::Strin g>()));
235 if (value->IsArray()) {
236 v8::Local<v8::Array> array = value.As<v8::Array>();
237 OwnPtr<protocol::ListValue> inspectorArray = protocol::ListValue::create ();
238 uint32_t length = array->Length();
239 for (uint32_t i = 0; i < length; i++) {
240 v8::Local<v8::Value> value;
241 if (!array->Get(context, i).ToLocal(&value))
242 return nullptr;
243 OwnPtr<protocol::Value> element = toProtocolValue(context, value, ma xDepth);
244 if (!element)
245 return nullptr;
246 inspectorArray->pushValue(element.release());
247 }
248 return inspectorArray.release();
249 }
250 if (value->IsObject()) {
251 OwnPtr<protocol::DictionaryValue> jsonObject = protocol::DictionaryValue ::create();
252 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value);
253 v8::Local<v8::Array> propertyNames;
254 if (!object->GetPropertyNames(context).ToLocal(&propertyNames))
255 return nullptr;
256 uint32_t length = propertyNames->Length();
257 for (uint32_t i = 0; i < length; i++) {
258 v8::Local<v8::Value> name;
259 if (!propertyNames->Get(context, i).ToLocal(&name))
260 return nullptr;
261 // FIXME(yurys): v8::Object should support GetOwnPropertyNames
262 if (name->IsString()) {
263 v8::Maybe<bool> hasRealNamedProperty = object->HasRealNamedPrope rty(context, v8::Local<v8::String>::Cast(name));
264 if (!hasRealNamedProperty.IsJust() || !hasRealNamedProperty.From Just())
265 continue;
266 }
267 v8::Local<v8::String> propertyName;
268 if (!name->ToString(context).ToLocal(&propertyName))
269 continue;
270 v8::Local<v8::Value> property;
271 if (!object->Get(context, name).ToLocal(&property))
272 return nullptr;
273 OwnPtr<protocol::Value> propertyValue = toProtocolValue(context, pro perty, maxDepth);
274 if (!propertyValue)
275 return nullptr;
276 jsonObject->setValue(toProtocolString(propertyName), propertyValue.r elease());
277 }
278 return jsonObject.release();
279 }
280 ASSERT_NOT_REACHED();
281 return nullptr;
282 }
283
215 } // namespace blink 284 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698