Web Inspector: implement reverse mapping for compiler source maps.
authorpodivilov@chromium.org <podivilov@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Sep 2011 10:22:59 +0000 (10:22 +0000)
committerpodivilov@chromium.org <podivilov@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Sep 2011 10:22:59 +0000 (10:22 +0000)
https://bugs.webkit.org/show_bug.cgi?id=67850

Source/WebCore:

Implement the mapping from source code to compiled code. It will be used for
setting breakpoints on source code.

Reviewed by Pavel Feldman.

* inspector/front-end/CompilerSourceMapping.js:
(WebInspector.ClosureCompilerSourceMapping):
(WebInspector.ClosureCompilerSourceMapping.prototype.compiledLocationToSourceLocation):
(WebInspector.ClosureCompilerSourceMapping.prototype.sourceLocationToCompiledLocation):
(WebInspector.ClosureCompilerSourceMapping.prototype._parseMappings):

LayoutTests:

Reviewed by Pavel Feldman.

* inspector/debugger/compiler-source-mapping.html:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@95524 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/inspector/debugger/compiler-source-mapping.html
Source/WebCore/ChangeLog
Source/WebCore/inspector/front-end/CompilerSourceMapping.js
Source/WebCore/inspector/front-end/DebuggerPresentationModel.js

index 81bfbbf..5d5ee14 100644 (file)
@@ -1,3 +1,12 @@
+2011-09-09  Pavel Podivilov  <podivilov@chromium.org>
+
+        Web Inspector: implement reverse mapping for compiler source maps.
+        https://bugs.webkit.org/show_bug.cgi?id=67850
+
+        Reviewed by Pavel Feldman.
+
+        * inspector/debugger/compiler-source-mapping.html:
+
 2011-09-20  Renata Hodovan  <reni@webkit.org>
 
         [Qt] Add Qt specific expecteds to new tests introduced in r95461.
 2011-09-20  Renata Hodovan  <reni@webkit.org>
 
         [Qt] Add Qt specific expecteds to new tests introduced in r95461.
index 4a45f70..5e56486 100644 (file)
@@ -14,31 +14,52 @@ function test()
         InspectorTest.assertEquals(sourceColumnNumber, sourceLocation.columnNumber);
     }
 
         InspectorTest.assertEquals(sourceColumnNumber, sourceLocation.columnNumber);
     }
 
+    function checkReverseMapping(compiledLineNumber, compiledColumnNumber, sourceURL, sourceLineNumber, mapping)
+    {
+        var compiledLocation = mapping.sourceLocationToCompiledLocation(sourceURL, sourceLineNumber);
+        InspectorTest.assertEquals(compiledLineNumber, compiledLocation.lineNumber);
+        InspectorTest.assertEquals(compiledColumnNumber, compiledLocation.columnNumber);
+    }
+
     InspectorTest.runTestSuite([
         function testSimpleMapping(next)
         {
     InspectorTest.runTestSuite([
         function testSimpleMapping(next)
         {
-            // example.js:
-            // 0         1         2         3
-            // 012345678901234567890123456789012345
-            // function add(variable_x, variable_y)
-            // {
-            //     return variable_x + variable_y;
-            // }
-            // example-compiled.js:
-            // 0         1         2         3
-            // 012345678901234567890123456789012345
-            // function add(a,b){return a+b};
+            /*
+                example.js:
+                0         1         2         3
+                012345678901234567890123456789012345
+                function add(variable_x, variable_y)
+                {
+                    return variable_x + variable_y;
+                }
+
+                var global = "foo";
+                ----------------------------------------
+                example-compiled.js:
+                0         1         2         3
+                012345678901234567890123456789012345
+                function add(a,b){return a+b}var global="foo";
+            */
             var mappingPayload = {
             var mappingPayload = {
-                "mappings":"AAASA,QAAAA,IAAG,CAACC,CAAD,CAAaC,CAAb,CACZ,CACI,MAAOD,EAAP,CAAoBC,CADxB;",
+                "mappings":"AAASA,QAAAA,IAAG,CAACC,CAAD,CAAaC,CAAb,CACZ,CACI,MAAOD,EAAP,CAAoBC,CADxB,CAIA,IAAIC,OAAS;",
                 "sources":["example.js"]
             };
             var mapping = new WebInspector.ClosureCompilerSourceMapping(mappingPayload);
                 "sources":["example.js"]
             };
             var mapping = new WebInspector.ClosureCompilerSourceMapping(mappingPayload);
+
             checkMapping(0, 9, "example.js", 0, 9, mapping);
             checkMapping(0, 13, "example.js", 0, 13, mapping);
             checkMapping(0, 15, "example.js", 0, 25, mapping);
             checkMapping(0, 18, "example.js", 2, 4, mapping);
             checkMapping(0, 25, "example.js", 2, 11, mapping);
             checkMapping(0, 27, "example.js", 2, 24, mapping);
             checkMapping(0, 9, "example.js", 0, 9, mapping);
             checkMapping(0, 13, "example.js", 0, 13, mapping);
             checkMapping(0, 15, "example.js", 0, 25, mapping);
             checkMapping(0, 18, "example.js", 2, 4, mapping);
             checkMapping(0, 25, "example.js", 2, 11, mapping);
             checkMapping(0, 27, "example.js", 2, 24, mapping);
+
+            checkReverseMapping(0, 0, "example.js", 0, mapping);
+            checkReverseMapping(0, 17, "example.js", 1, mapping);
+            checkReverseMapping(0, 18, "example.js", 2, mapping);
+            checkReverseMapping(0, 29, "example.js", 4, mapping);
+            checkReverseMapping(0, 29, "example.js", 5, mapping);
+            InspectorTest.assertTrue(!mapping.sourceLocationToCompiledLocation("example.js", 6));
+
             next();
         }
     ]);
             next();
         }
     ]);
index 8f8201c..9bc6221 100644 (file)
@@ -1,3 +1,19 @@
+2011-09-09  Pavel Podivilov  <podivilov@chromium.org>
+
+        Web Inspector: implement reverse mapping for compiler source maps.
+        https://bugs.webkit.org/show_bug.cgi?id=67850
+
+        Implement the mapping from source code to compiled code. It will be used for
+        setting breakpoints on source code.
+
+        Reviewed by Pavel Feldman.
+
+        * inspector/front-end/CompilerSourceMapping.js:
+        (WebInspector.ClosureCompilerSourceMapping):
+        (WebInspector.ClosureCompilerSourceMapping.prototype.compiledLocationToSourceLocation):
+        (WebInspector.ClosureCompilerSourceMapping.prototype.sourceLocationToCompiledLocation):
+        (WebInspector.ClosureCompilerSourceMapping.prototype._parseMappings):
+
 2011-09-08  Pavel Podivilov  <podivilov@chromium.org>
 
         Web Inspector: extract RawSourceCode source mapping logic to helper classes.
 2011-09-08  Pavel Podivilov  <podivilov@chromium.org>
 
         Web Inspector: extract RawSourceCode source mapping logic to helper classes.
index 025031f..6d9dc6d 100644 (file)
@@ -68,19 +68,28 @@ WebInspector.ClosureCompilerSourceMapping = function(payload)
     }
 
     this._sources = payload.sources;
     }
 
     this._sources = payload.sources;
-    this._mappings = this._parsePayload(payload);
+    this._mappings = [];
+    this._reverseMappingsBySourceURL = {};
+    for (var i = 0; i < this._sources.length; ++i)
+        this._reverseMappingsBySourceURL[this._sources[i]] = [];
+    this._parseMappings(payload.mappings);
 }
 
 WebInspector.ClosureCompilerSourceMapping.prototype = {
     compiledLocationToSourceLocation: function(lineNumber, columnNumber)
     {
         var mapping = this._findMapping(lineNumber, columnNumber);
 }
 
 WebInspector.ClosureCompilerSourceMapping.prototype = {
     compiledLocationToSourceLocation: function(lineNumber, columnNumber)
     {
         var mapping = this._findMapping(lineNumber, columnNumber);
-        var sourceURL = this._sources[mapping[2]];
-        return { sourceURL: sourceURL, lineNumber: mapping[3], columnNumber: mapping[4] };
+        return { sourceURL: mapping[2], lineNumber: mapping[3], columnNumber: mapping[4] };
     },
 
     },
 
-    sourceLocationToCompiledLocation: function(sourceURL, lineNumber, columnNumber)
+    sourceLocationToCompiledLocation: function(sourceURL, lineNumber)
     {
     {
+        var mappings = this._reverseMappingsBySourceURL[sourceURL];
+        for ( ; lineNumber < mappings.length; ++lineNumber) {
+            var mapping = mappings[lineNumber];
+            if (mapping)
+                return { lineNumber: mapping[0], columnNumber: mapping[1] };
+        }
     },
 
     sources: function()
     },
 
     sources: function()
@@ -106,10 +115,9 @@ WebInspector.ClosureCompilerSourceMapping.prototype = {
         return this._mappings[first];
     },
 
         return this._mappings[first];
     },
 
-    _parsePayload: function(payload)
+    _parseMappings: function(mappingsPayload)
     {
     {
-        var mappings = [];
-        var stringCharIterator = new WebInspector.ClosureCompilerSourceMapping.StringCharIterator(payload.mappings);
+        var stringCharIterator = new WebInspector.ClosureCompilerSourceMapping.StringCharIterator(mappingsPayload);
 
         var lineNumber = 0;
         var columnNumber = 0;
 
         var lineNumber = 0;
         var columnNumber = 0;
@@ -117,25 +125,34 @@ WebInspector.ClosureCompilerSourceMapping.prototype = {
         var sourceLineNumber = 0;
         var sourceColumnNumber = 0;
         var nameIndex = 0;
         var sourceLineNumber = 0;
         var sourceColumnNumber = 0;
         var nameIndex = 0;
+
+        var sourceURL = this._sources[0];
+        var reverseMappings = this._reverseMappingsBySourceURL[sourceURL];
+
         do {
             columnNumber += this._decodeVLQ(stringCharIterator);
             if (this._isSeparator(stringCharIterator.peek()))
                 continue;
         do {
             columnNumber += this._decodeVLQ(stringCharIterator);
             if (this._isSeparator(stringCharIterator.peek()))
                 continue;
-            sourceIndex += this._decodeVLQ(stringCharIterator);
+            var sourceIndexDelta = this._decodeVLQ(stringCharIterator);
+            if (sourceIndexDelta) {
+                sourceIndex += sourceIndexDelta;
+                sourceURL = this._sources[sourceIndex];
+                reverseMappings = this._reverseMappingsBySourceURL[sourceURL];
+            }
             sourceLineNumber += this._decodeVLQ(stringCharIterator);
             sourceColumnNumber += this._decodeVLQ(stringCharIterator);
             sourceLineNumber += this._decodeVLQ(stringCharIterator);
             sourceColumnNumber += this._decodeVLQ(stringCharIterator);
-            var mapping = [lineNumber, columnNumber, sourceIndex, sourceLineNumber, sourceColumnNumber];
-            if (!this._isSeparator(stringCharIterator.peek())) {
+            if (!this._isSeparator(stringCharIterator.peek()))
                 nameIndex += this._decodeVLQ(stringCharIterator);
                 nameIndex += this._decodeVLQ(stringCharIterator);
-                mapping.push(nameIndex);
-            }
-            mappings.push(mapping);
+
+            this._mappings.push([lineNumber, columnNumber, sourceURL, sourceLineNumber, sourceColumnNumber]);
+            if (!reverseMappings[sourceLineNumber])
+                reverseMappings[sourceLineNumber] = [lineNumber, columnNumber];
+
             if (stringCharIterator.next() === ";") {
                 lineNumber += 1;
                 columnNumber = 0;
             }
         } while(stringCharIterator.hasNext());
             if (stringCharIterator.next() === ";") {
                 lineNumber += 1;
                 columnNumber = 0;
             }
         } while(stringCharIterator.hasNext());
-        return mappings;
     },
 
     _isSeparator: function(char)
     },
 
     _isSeparator: function(char)
index f6edd0c..0becb51 100644 (file)
@@ -173,7 +173,7 @@ WebInspector.DebuggerPresentationModel.prototype = {
             return false;
         var rawSourceCode = uiSourceCode.rawSourceCode;
         var script = this._scriptForRawSourceCode(rawSourceCode);
             return false;
         var rawSourceCode = uiSourceCode.rawSourceCode;
         var script = this._scriptForRawSourceCode(rawSourceCode);
-        return !script.lineOffset && !script.columnOffset;
+        return script && !script.lineOffset && !script.columnOffset;
     },
 
     setScriptSource: function(uiSourceCode, newSource, callback)
     },
 
     setScriptSource: function(uiSourceCode, newSource, callback)