Support setting brekpoint by script name set in //@ scriptURL= comment,
authormikhail.naganov@gmail.com <mikhail.naganov@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 1 Apr 2010 16:25:07 +0000 (16:25 +0000)
committermikhail.naganov@gmail.com <mikhail.naganov@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 1 Apr 2010 16:25:07 +0000 (16:25 +0000)
in case script name is missing.

BUG=http://crbug.com/39290

Author: Andrey Kosyakov (caseq@chromium.org)
Original issue: http://codereview.chromium.org/1303003

TBR=sgjesse@chromium.org

Review URL: http://codereview.chromium.org/1527007

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4337 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/debug-debugger.js
src/messages.js
src/mirror-debugger.js
test/mjsunit/debug-setbreakpoint.js

index c296e42..59a113c 100644 (file)
@@ -327,7 +327,7 @@ ScriptBreakPoint.prototype.matchesScript = function(script) {
   if (this.type_ == Debug.ScriptBreakPointType.ScriptId) {
     return this.script_id_ == script.id;
   } else {  // this.type_ == Debug.ScriptBreakPointType.ScriptName
-    return this.script_name_ == script.name &&
+    return this.script_name_ == script.nameOrSourceURL() &&
            script.line_offset <= this.line_  &&
            this.line_ < script.line_offset + script.lineCount();
   }
index 7ef6c73..de6a362 100644 (file)
@@ -433,6 +433,30 @@ Script.prototype.lineCount = function() {
 
 
 /**
+ * Returns the name of script if available, contents of sourceURL comment
+ * otherwise. See 
+ * http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt
+ * for details on using //@ sourceURL comment to identify scritps that don't
+ * have name.
+ * 
+ * @return {?string} script name if present, value for //@ sourceURL comment
+ * otherwise.
+ */
+Script.prototype.nameOrSourceURL = function() {
+  if (this.name)
+    return this.name;
+  // TODO(608): the spaces in a regexp below had to be escaped as \040 
+  // because this file is being processed by js2c whose handling of spaces
+  // in regexps is broken. Also, ['"] are excluded from allowed URLs to
+  // avoid matches against sources that invoke evals with sourceURL.
+  var sourceUrlPattern =
+    /\/\/@[\040\t]sourceURL=[\040\t]*([^\s'"]*)[\040\t]*$/m;
+  var match = sourceUrlPattern.exec(this.source);
+  return match ? match[1] : this.name;
+}
+
+
+/**
  * Class for source location. A source location is a position within some
  * source with the following properties:
  *   script   : script object for the source
index 6f8ebb4..29d0069 100644 (file)
@@ -1728,8 +1728,7 @@ ScriptMirror.prototype.value = function() {
 
 
 ScriptMirror.prototype.name = function() {
-  // If we have name, we trust it more than sourceURL from comments
-  return this.script_.name || this.sourceUrlFromComment_();
+  return this.script_.name || this.script_.nameOrSourceURL();
 };
 
 
@@ -1825,29 +1824,6 @@ ScriptMirror.prototype.toText = function() {
 
 
 /**
- * Returns a suggested script URL from comments in script code (if found),
- * undefined otherwise. Used primarily by debuggers for identifying eval()'ed
- * scripts. See
- * http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt
- * for details.
- *
- * @return {?string} value for //@ sourceURL comment
- */
-ScriptMirror.prototype.sourceUrlFromComment_ = function() {
-  if (!('sourceUrl_' in this) && this.source()) {
-    // TODO(608): the spaces in a regexp below had to be escaped as \040
-    // because this file is being processed by js2c whose handling of spaces
-    // in regexps is broken.
-    // We're not using \s here to prevent \n from matching.
-    var sourceUrlPattern = /\/\/@[\040\t]sourceURL=[\040\t]*(\S+)[\040\t]*$/m;
-    var match = sourceUrlPattern.exec(this.source());
-    this.sourceUrl_ = match ? match[1] : undefined;
-  }
-  return this.sourceUrl_;
-};
-
-
-/**
  * Mirror object for context.
  * @param {Object} data The context data
  * @constructor
index 08492b4..3981dc4 100644 (file)
@@ -116,6 +116,8 @@ function listener(event, exec_state, event_data, data) {
     mirror = debug.MakeMirror(o.a);
     testArguments(dcp, '{"type":"handle","target":' + mirror.handle() + '}', true, false);
 
+    testArguments(dcp, '{"type":"script","target":"sourceUrlScript","line":1}', true, true);
+
     // Indicate that all was processed.
     listenerComplete = true;
   }
@@ -136,6 +138,7 @@ function g() {
 };
 
 eval('function h(){}');
+eval('function sourceUrlFunc() { a = 2; }\n//@ sourceURL=sourceUrlScript');
 
 o = {a:function(){},b:function(){}}
 
@@ -143,9 +146,12 @@ o = {a:function(){},b:function(){}}
 f_script_id = Debug.findScript(f).id;
 g_script_id = Debug.findScript(g).id;
 h_script_id = Debug.findScript(h).id;
+sourceURL_script_id = Debug.findScript(sourceUrlFunc).id;
+
 assertTrue(f_script_id > 0, "invalid script id for f");
 assertTrue(g_script_id > 0, "invalid script id for g");
 assertTrue(h_script_id > 0, "invalid script id for h");
+assertTrue(sourceURL_script_id > 0, "invalid script id for sourceUrlFunc");
 assertEquals(f_script_id, g_script_id);
 
 // Get the source line for the test functions.
@@ -161,5 +167,20 @@ assertEquals(h_line, 0, "invalid line for h");
 Debug.setBreakPoint(g, 0, 0);
 g();
 
-// Make sure that the debug event listener vas invoked.
+// Make sure that the debug event listener was invoked.
 assertTrue(listenerComplete, "listener did not run to completion: " + exception);
+
+// Try setting breakpoint by url specified in sourceURL
+
+var breakListenerCalled = false;
+
+function breakListener(event) {
+  if (event == Debug.DebugEvent.Break)
+    breakListenerCalled = true;
+}
+
+Debug.setListener(breakListener);
+
+sourceUrlFunc();
+
+assertTrue(breakListenerCalled, "Break listener not called on breakpoint set by sourceURL");