5 #include "src/inspector/search-util.h" 7 #include "src/inspector/protocol/Protocol.h" 8 #include "src/inspector/v8-inspector-impl.h" 9 #include "src/inspector/v8-inspector-session-impl.h" 10 #include "src/inspector/v8-regex.h" 16 String16 findMagicComment(
const String16& content,
const String16& name,
18 DCHECK_EQ(String16::kNotFound, name.find(
"="));
19 size_t length = content.length();
20 size_t nameLength = name.length();
23 size_t equalSignPos = 0;
24 size_t closingCommentPos = 0;
26 pos = content.reverseFind(name, pos);
27 if (pos == String16::kNotFound)
return String16();
30 if (pos < 4)
return String16();
32 if (content[pos] !=
'/')
continue;
33 if ((content[pos + 1] !=
'/' || multiline) &&
34 (content[pos + 1] !=
'*' || !multiline))
36 if (content[pos + 2] !=
'#' && content[pos + 2] !=
'@')
continue;
37 if (content[pos + 3] !=
' ' && content[pos + 3] !=
'\t')
continue;
38 equalSignPos = pos + 4 + nameLength;
39 if (equalSignPos < length && content[equalSignPos] !=
'=')
continue;
41 closingCommentPos = content.find(
"*/", equalSignPos + 1);
42 if (closingCommentPos == String16::kNotFound)
return String16();
49 DCHECK(!multiline || closingCommentPos);
50 size_t urlPos = equalSignPos + 1;
51 String16 match = multiline
52 ? content.substring(urlPos, closingCommentPos - urlPos)
53 : content.substring(urlPos);
55 size_t newLine = match.find(
"\n");
56 if (newLine != String16::kNotFound) match = match.substring(0, newLine);
57 match = match.stripWhiteSpace();
59 for (
size_t i = 0;
i < match.length(); ++
i) {
61 if (c ==
'"' || c ==
'\'' || c ==
' ' || c ==
'\t')
return "";
67 String16 createSearchRegexSource(
const String16& text) {
68 String16Builder result;
70 for (
size_t i = 0;
i < text.length();
i++) {
72 if (c ==
'[' || c ==
']' || c ==
'(' || c ==
')' || c ==
'{' || c ==
'}' ||
73 c ==
'+' || c ==
'-' || c ==
'*' || c ==
'.' || c ==
',' || c ==
'?' ||
74 c ==
'\\' || c ==
'^' || c ==
'$' || c ==
'|') {
80 return result.toString();
83 std::unique_ptr<std::vector<size_t>> lineEndings(
const String16& text) {
84 std::unique_ptr<std::vector<size_t>> result(
new std::vector<size_t>());
86 const String16 lineEndString =
"\n";
88 while (start < text.length()) {
89 size_t lineEnd = text.find(lineEndString, start);
90 if (lineEnd == String16::kNotFound)
break;
92 result->push_back(lineEnd);
95 result->push_back(text.length());
100 std::vector<std::pair<int, String16>> scriptRegexpMatchesByLines(
101 const V8Regex& regex,
const String16& text) {
102 std::vector<std::pair<int, String16>> result;
103 if (text.isEmpty())
return result;
105 std::unique_ptr<std::vector<size_t>> endings(lineEndings(text));
106 size_t size = endings->size();
108 for (
size_t lineNumber = 0; lineNumber < size; ++lineNumber) {
109 size_t lineEnd = endings->at(lineNumber);
110 String16 line = text.substring(start, lineEnd - start);
111 if (line.length() && line[line.length() - 1] ==
'\r')
112 line = line.substring(0, line.length() - 1);
115 if (regex.match(line, 0, &matchLength) != -1)
116 result.push_back(std::pair<int, String16>(lineNumber, line));
123 std::unique_ptr<protocol::Debugger::SearchMatch> buildObjectForSearchMatch(
124 int lineNumber,
const String16& lineContent) {
125 return protocol::Debugger::SearchMatch::create()
126 .setLineNumber(lineNumber)
127 .setLineContent(lineContent)
131 std::unique_ptr<V8Regex> createSearchRegex(V8InspectorImpl* inspector,
132 const String16& query,
133 bool caseSensitive,
bool isRegex) {
134 String16 regexSource = isRegex ? query : createSearchRegexSource(query);
135 return std::unique_ptr<V8Regex>(
136 new V8Regex(inspector, regexSource, caseSensitive));
141 std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>>
142 searchInTextByLinesImpl(V8InspectorSession* session,
const String16& text,
143 const String16& query,
const bool caseSensitive,
144 const bool isRegex) {
145 std::unique_ptr<V8Regex> regex = createSearchRegex(
146 static_cast<V8InspectorSessionImpl*>(session)->inspector(), query,
147 caseSensitive, isRegex);
148 std::vector<std::pair<int, String16>> matches =
149 scriptRegexpMatchesByLines(*regex.get(), text);
151 std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>> result;
152 for (
const auto& match : matches)
153 result.push_back(buildObjectForSearchMatch(match.first, match.second));
157 String16 findSourceURL(
const String16& content,
bool multiline) {
158 return findMagicComment(content,
"sourceURL", multiline);
161 String16 findSourceMapURL(
const String16& content,
bool multiline) {
162 return findMagicComment(content,
"sourceMappingURL", multiline);