Commit 4a96850a authored by Yang Guo's avatar Yang Guo Committed by Commit Bot

Revert "inspector: find magic comment using V8 scanner"

This reverts commit 1b3b808a.

Reason for revert: crbug/879988

TBR=kozy@chromium.org

Original change's description:
> inspector: find magic comment using V8 scanner
>
> Inspector tries to provide sourceURL and sourceMappingURL for scripts
> with parser errors. Without this CL we convert source of each script
> to inspector string and search for magic comment there. Some web sites
> use pattern when they get some data from network and constantly try to
> parse this data as JSON, in this case we do a lot of useless work.
>
> So we can parse magic comments on V8 side only for compilation errors
> (excluding parse JSON errors), to do it we can reuse scanner by running
> it on each potential comment.
>
> R=​alph@chromium.org,verwaest@chromium.org,yangguo@chromium.org
>
> Bug: chromium:873865,v8:7731
> Cq-Include-Trybots: luci.chromium.try:linux_chromium_headless_rel;master.tryserver.blink:linux_trusty_blink_rel
> Change-Id: I77c270fd0e95cd7b2c9ee4b7f72ef344bc1fa104
> Reviewed-on: https://chromium-review.googlesource.com/1182446
> Reviewed-by: Toon Verwaest <verwaest@chromium.org>
> Reviewed-by: Alexei Filippov <alph@chromium.org>
> Commit-Queue: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#55280}

TBR=alph@chromium.org,yangguo@chromium.org,kozyatinskiy@chromium.org,verwaest@chromium.org

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: chromium:873865, v8:7731, chromium:879988
Change-Id: Ia7ac766e19f9b58562d9430811f10b25c4556a46
Cq-Include-Trybots: luci.chromium.try:linux_chromium_headless_rel;master.tryserver.blink:linux_trusty_blink_rel
Reviewed-on: https://chromium-review.googlesource.com/1202583
Commit-Queue: Yang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55594}
parent 55b59e30
......@@ -32,8 +32,6 @@
#include "src/objects/debug-objects-inl.h"
#include "src/objects/js-generator-inl.h"
#include "src/objects/js-promise-inl.h"
#include "src/parsing/scanner-character-streams.h"
#include "src/parsing/scanner.h"
#include "src/snapshot/natives.h"
#include "src/snapshot/snapshot.h"
#include "src/wasm/wasm-objects-inl.h"
......@@ -1844,60 +1842,15 @@ bool Debug::SetScriptSource(Handle<Script> script, Handle<String> source,
return result->status == debug::LiveEditResult::OK;
}
void Debug::OnParseJSONError(Handle<Script> script) {
ProcessCompileEvent(CompileStatus::JSON_PARSE_ERROR, script);
}
void Debug::OnCompileError(Handle<Script> script) {
ProcessCompileEvent(CompileStatus::COMPILE_ERROR, script);
ProcessCompileEvent(true, script);
}
void Debug::OnAfterCompile(Handle<Script> script) {
ProcessCompileEvent(CompileStatus::OK, script);
}
namespace {
void EnsureMagicComments(Isolate* isolate, Handle<Script> script) {
Handle<Object> source_value(script->source(), isolate);
DCHECK(source_value->IsString());
Handle<String> comment_start =
isolate->factory()->NewStringFromStaticChars("//");
Handle<String> source(Handle<String>::cast(source_value));
std::unique_ptr<Utf16CharacterStream> scanner_stream(
ScannerStream::For(isolate, source));
Scanner scanner(isolate->unicode_cache(), scanner_stream.get(), false);
scanner.Initialize();
bool has_source_url = script->source_url()->IsString();
bool has_source_mapping_url = script->source_mapping_url()->IsString();
int prev_start = source->length();
while (prev_start > 0 && (!has_source_mapping_url || !has_source_url)) {
int start = Smi::ToInt(
String::LastIndexOf(isolate, source, comment_start,
handle(Smi::FromInt(prev_start), isolate)));
if (start == -1) return;
scanner_stream->Seek(start);
scanner_stream->Advance();
scanner.Next();
Handle<String> source_url = scanner.SourceUrl(isolate);
if (!has_source_url && !source_url.is_null()) {
script->set_source_url(*source_url);
has_source_url = true;
}
Handle<String> source_mapping_url = scanner.SourceMappingUrl(isolate);
if (!has_source_mapping_url && !source_mapping_url.is_null()) {
script->set_source_mapping_url(*source_mapping_url);
has_source_mapping_url = true;
}
prev_start = start - 1;
}
ProcessCompileEvent(false, script);
}
} // namespace
void Debug::ProcessCompileEvent(CompileStatus status, Handle<Script> script) {
void Debug::ProcessCompileEvent(bool has_compile_error, Handle<Script> script) {
// TODO(kozyatinskiy): teach devtools to work with liveedit scripts better
// first and then remove this fast return.
if (running_live_edit_) return;
......@@ -1909,19 +1862,13 @@ void Debug::ProcessCompileEvent(CompileStatus status, Handle<Script> script) {
return;
}
if (!debug_delegate_) return;
if (status == CompileStatus::COMPILE_ERROR) {
EnsureMagicComments(isolate_, script);
}
SuppressDebug while_processing(this);
DebugScope debug_scope(this);
HandleScope scope(isolate_);
DisableBreak no_recursive_break(this);
AllowJavascriptExecution allow_script(isolate_);
debug_delegate_->ScriptCompiled(ToApiHandle<debug::Script>(script),
running_live_edit_,
status != CompileStatus::OK);
running_live_edit_, has_compile_error);
}
int Debug::CurrentFrameCount() {
......
......@@ -222,7 +222,6 @@ class Debug {
void OnThrow(Handle<Object> exception);
void OnPromiseReject(Handle<Object> promise, Handle<Object> value);
void OnCompileError(Handle<Script> script);
void OnParseJSONError(Handle<Script> script);
void OnAfterCompile(Handle<Script> script);
void HandleDebugBreak(IgnoreBreakMode ignore_break_mode);
......@@ -409,8 +408,7 @@ class Debug {
void OnException(Handle<Object> exception, Handle<Object> promise);
enum CompileStatus { OK, COMPILE_ERROR, JSON_PARSE_ERROR };
void ProcessCompileEvent(CompileStatus status, Handle<Script> script);
void ProcessCompileEvent(bool has_compile_error, Handle<Script> script);
// Find the closest source position for a break point for a given position.
int FindBreakablePosition(Handle<DebugInfo> debug_info, int source_position);
......
......@@ -13,6 +13,57 @@ namespace v8_inspector {
namespace {
String16 findMagicComment(const String16& content, const String16& name,
bool multiline) {
DCHECK_EQ(String16::kNotFound, name.find("="));
size_t length = content.length();
size_t nameLength = name.length();
size_t pos = length;
size_t equalSignPos = 0;
size_t closingCommentPos = 0;
while (true) {
pos = content.reverseFind(name, pos);
if (pos == String16::kNotFound) return String16();
// Check for a /\/[\/*][@#][ \t]/ regexp (length of 4) before found name.
if (pos < 4) return String16();
pos -= 4;
if (content[pos] != '/') continue;
if ((content[pos + 1] != '/' || multiline) &&
(content[pos + 1] != '*' || !multiline))
continue;
if (content[pos + 2] != '#' && content[pos + 2] != '@') continue;
if (content[pos + 3] != ' ' && content[pos + 3] != '\t') continue;
equalSignPos = pos + 4 + nameLength;
if (equalSignPos < length && content[equalSignPos] != '=') continue;
if (multiline) {
closingCommentPos = content.find("*/", equalSignPos + 1);
if (closingCommentPos == String16::kNotFound) return String16();
}
break;
}
DCHECK(equalSignPos);
DCHECK(!multiline || closingCommentPos);
size_t urlPos = equalSignPos + 1;
String16 match = multiline
? content.substring(urlPos, closingCommentPos - urlPos)
: content.substring(urlPos);
size_t newLine = match.find("\n");
if (newLine != String16::kNotFound) match = match.substring(0, newLine);
match = match.stripWhiteSpace();
for (size_t i = 0; i < match.length(); ++i) {
UChar c = match[i];
if (c == '"' || c == '\'' || c == ' ' || c == '\t') return "";
}
return match;
}
String16 createSearchRegexSource(const String16& text) {
String16Builder result;
......@@ -102,4 +153,13 @@ searchInTextByLinesImpl(V8InspectorSession* session, const String16& text,
result.push_back(buildObjectForSearchMatch(match.first, match.second));
return result;
}
String16 findSourceURL(const String16& content, bool multiline) {
return findMagicComment(content, "sourceURL", multiline);
}
String16 findSourceMapURL(const String16& content, bool multiline) {
return findMagicComment(content, "sourceMappingURL", multiline);
}
} // namespace v8_inspector
......@@ -12,6 +12,8 @@ namespace v8_inspector {
class V8InspectorSession;
String16 findSourceURL(const String16& content, bool multiline);
String16 findSourceMapURL(const String16& content, bool multiline);
std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>>
searchInTextByLinesImpl(V8InspectorSession*, const String16& text,
const String16& query, bool caseSensitive,
......
......@@ -1377,6 +1377,12 @@ bool V8DebuggerAgentImpl::isPaused() const {
void V8DebuggerAgentImpl::didParseSource(
std::unique_ptr<V8DebuggerScript> script, bool success) {
v8::HandleScope handles(m_isolate);
if (!success) {
DCHECK(!script->isSourceLoadedLazily());
String16 scriptSource = script->source(0);
script->setSourceURL(findSourceURL(scriptSource, false));
script->setSourceMappingURL(findSourceMapURL(scriptSource, false));
}
int contextId = script->executionContextId();
int contextGroupId = m_inspector->contextGroupId(contextId);
......
......@@ -201,7 +201,7 @@ MaybeHandle<Object> JsonParser<seq_one_byte>::ParseJson() {
}
// We should sent compile error event because we compile JSON object in
// separated source file.
isolate()->debug()->OnParseJSONError(script);
isolate()->debug()->OnCompileError(script);
MessageLocation location(script, position_, position_ + 1);
Handle<Object> error = factory->NewSyntaxError(message, arg1, arg2);
return isolate()->template Throw<Object>(error, &location);
......
......@@ -692,24 +692,6 @@ scriptFailedToParse
startLine : 0
url : failed.js
}
scriptFailedToParse
{
scriptSource : {a:2://# sourceURL=failed.js<nl>//# sourceMappingURL=failed-map
}
{
endColumn : 31
endLine : 1
executionContextId : <executionContextId>
hasSourceURL : true
hash : 370d368557b75a8e281e4a84625a9e0263647da6
isModule : false
length : 60
scriptId : <scriptId>
sourceMapURL : failed-map
startColumn : 0
startLine : 0
url : failed.js
}
scriptParsed
{
scriptSource : function foo16(){}<nl>
......
......@@ -37,7 +37,6 @@ function addScripts() {
.then(() => addScript("{a:2:\n//# sourceURL=http://a.js"))
// sourceURL and sourceMappingURL works even for script with syntax error
.then(() => addScript("}//# sourceURL=failed.js\n//# sourceMappingURL=failed-map"))
.then(() => addScript("{a:2://# sourceURL=failed.js\n//# sourceMappingURL=failed-map"))
// empty lines at end
.then(() => addScript("function foo16(){}\n"))
.then(() => addScript("function foo17(){}\n\n"))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment