Title: [118685] trunk
Revision
118685
Author
commit-qu...@webkit.org
Date
2012-05-28 08:52:05 -0700 (Mon, 28 May 2012)

Log Message

Web Inspector: Expose function (closure) scopes in remote protocol
https://bugs.webkit.org/show_bug.cgi?id=86861

Patch by Peter Rybin <peter.ry...@gmail.com> on 2012-05-28
Reviewed by Yury Semikhatsky.

Source/WebCore:

A data transfer from V8's FunctionMirror via DebuggerScript.js via InjectedScriptHost is built.
Scope field is added to protocol declaration similar to scopes of stack call frame.
Test for function details is extended.
JSC code binging got fixme for implemting the corresponding feature.

* bindings/js/JSInjectedScriptHostCustom.cpp:
(WebCore::JSInjectedScriptHost::functionDetails):
* bindings/v8/DebuggerScript.js:
* bindings/v8/ScriptDebugServer.cpp:
(WebCore::ScriptDebugServer::functionScopes):
(WebCore):
* bindings/v8/ScriptDebugServer.h:
(ScriptDebugServer):
* bindings/v8/custom/V8InjectedScriptHostCustom.cpp:
(WebCore::V8InjectedScriptHost::functionDetailsCallback):
* inspector/InjectedScriptHost.cpp:
(WebCore):
(WebCore::InjectedScriptHost::scriptDebugServer):
* inspector/InjectedScriptHost.h:
(WebCore):
(WebCore::InjectedScriptHost::init):
(InjectedScriptHost):
* inspector/InjectedScriptSource.js:
(.):
* inspector/Inspector.json:
* inspector/InspectorController.cpp:
(WebCore::InspectorController::InspectorController):
* inspector/WorkerInspectorController.cpp:
(WebCore::WorkerInspectorController::WorkerInspectorController):

LayoutTests:

Test for function details now checks scopes.

* inspector/debugger/function-details-expected.txt:
* inspector/debugger/function-details.html:
* platform/chromium/inspector/debugger/function-details-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (118684 => 118685)


--- trunk/LayoutTests/ChangeLog	2012-05-28 15:45:59 UTC (rev 118684)
+++ trunk/LayoutTests/ChangeLog	2012-05-28 15:52:05 UTC (rev 118685)
@@ -1,3 +1,16 @@
+2012-05-28  Peter Rybin  <peter.ry...@gmail.com>
+
+        Web Inspector: Expose function (closure) scopes in remote protocol
+        https://bugs.webkit.org/show_bug.cgi?id=86861
+
+        Reviewed by Yury Semikhatsky.
+
+        Test for function details now checks scopes.
+
+        * inspector/debugger/function-details-expected.txt:
+        * inspector/debugger/function-details.html:
+        * platform/chromium/inspector/debugger/function-details-expected.txt:
+
 2012-05-28  Marcus Bulach  <bul...@chromium.org>
 
         [chromium] Rebaseline following r118598

Modified: trunk/LayoutTests/inspector/debugger/function-details-expected.txt (118684 => 118685)


--- trunk/LayoutTests/inspector/debugger/function-details-expected.txt	2012-05-28 15:45:59 UTC (rev 118684)
+++ trunk/LayoutTests/inspector/debugger/function-details-expected.txt	2012-05-28 15:52:05 UTC (rev 118685)
@@ -11,9 +11,10 @@
 name: firstLineFunction
 displayName: undefined
 inferredName: undefined
+scopeChain: n/a
 
 Running: testGetNonFirstLineFunctionDetails
-nonFirstLineFunction type = function
+notFirstLineFunction type = function
 Function details: 
 lineNumber: 12
 columnNumber: undefined
@@ -21,6 +22,7 @@
 name: notFirstLineFunction
 displayName: undefined
 inferredName: undefined
+scopeChain: n/a
 
 Running: testGetDetailsOfFunctionWithInferredName
 obj.m type = function
@@ -31,6 +33,7 @@
 name: undefined
 displayName: undefined
 inferredName: undefined
+scopeChain: n/a
 
 Running: testGetDetailsOfFunctionWithDisplayName
 functionWithDisplayName type = function
@@ -41,5 +44,28 @@
 name: functionWithDisplayName
 displayName: user-friendly name
 inferredName: undefined
+scopeChain: n/a
+
+Running: testSmallClosure
+smallClosure type = function
+Function details: 
+lineNumber: 22
+columnNumber: undefined
+scriptId is valid: true
+name: undefined
+displayName: undefined
+inferredName: undefined
+scopeChain: n/a
+
+Running: testBigClosure
+bigClosure type = function
+Function details: 
+lineNumber: 35
+columnNumber: undefined
+scriptId is valid: true
+name: undefined
+displayName: undefined
+inferredName: undefined
+scopeChain: n/a
 Debugger was disabled.
 

Modified: trunk/LayoutTests/inspector/debugger/function-details.html (118684 => 118685)


--- trunk/LayoutTests/inspector/debugger/function-details.html	2012-05-28 15:45:59 UTC (rev 118684)
+++ trunk/LayoutTests/inspector/debugger/function-details.html	2012-05-28 15:52:05 UTC (rev 118685)
@@ -20,6 +20,26 @@
 function functionWithDisplayName() {}
 functionWithDisplayName.displayName = "user-friendly name";
 
+var smallClosure = (function(p) { return function() { return p; }; })("Capybara");
+
+var bigClosure = (function(p) {
+    var o = {
+       e: 7,
+       f: 5,
+       get u() { return 3; },
+       set v(value) { }
+    };
+    with (o) {
+        try {
+            throw Error("Test");
+        } catch (ex) {
+            return function() {
+                return String(p) + String(ex) + u + e;
+            };
+        }
+    }
+})({});
+
 function test()
 {
     function dumpFunctionDetails(details)
@@ -33,69 +53,101 @@
         InspectorTest.addResult("inferredName: " + details.inferredName);
     }
 
+    function dumpFunctionNoScopes()
+    {
+        InspectorTest.addResult("scopeChain: n/a");
+    }
 
-    InspectorTest.runDebuggerTestSuite([
-        function testGetFirstLineFunctionDetails(next)
-        {
-            InspectorTest.evaluateInPage("firstLineFunction", didEvaluate);
 
-            function didEvaluate(remote)
-            {
-                InspectorTest.addResult("firstLineFunction type = " + remote.type);
-                DebuggerAgent.getFunctionDetails(remote.objectId, didGetDetails);
+    function dumpFunctionScope(pos, type, propertyDescriptors)
+    {
+        var variables;
+        if (type == "global") {
+            variables = "<global object properties omitted>";
+        } else {
+            var varArray = [];
+            for (var i = 0; i < propertyDescriptors.length; i++) {
+                var d = propertyDescriptors[i];
+                var valueStr;
+                if (d.value) {
+                    if (d.value.value)
+                        valueStr = JSON.stringify(d.value.value);
+                    else
+                        valueStr = "<no string representation>";
+                } else {
+                    valueStr = "<no value>";
+                }
+                varArray.push(d.name + ": " + valueStr);
             }
-            function didGetDetails(error, response)
-            {
-                dumpFunctionDetails(response);
+            varArray.sort();
+            variables = varArray.join();
+        }
+        InspectorTest.addResult("scopeChain #" + pos + ": " + type + "; " + variables);
+    }
+
+    function loadAndDumpScopeObjects(scopeChain, end) {
+        function loadScopeObject(pos, next) {
+            if (pos >= scopeChain.length) {
                 next();
+                return;
             }
+            var scopeJson = scopeChain[pos];
+            RuntimeAgent.getProperties(scopeJson.object.objectId, true, didGetProperties);
+
+            function didGetProperties(error, propertyDescriptors) {
+                dumpFunctionScope(pos, scopeJson.type, propertyDescriptors);
+                loadScopeObject(pos + 1, next);
+            }
+        }
+
+        if (scopeChain) {
+            loadScopeObject(0, end);
+        } else {
+            dumpFunctionNoScopes();
+            end();
+        }
+    }
+
+    function performStandardTestCase(pageExpression, next) {
+        InspectorTest.evaluateInPage(pageExpression, didEvaluate);
+
+        function didEvaluate(remote)
+        {
+            InspectorTest.addResult(pageExpression + " type = " + remote.type);
+            DebuggerAgent.getFunctionDetails(remote.objectId, didGetDetails);
+        }
+        function didGetDetails(error, response)
+        {
+            dumpFunctionDetails(response);
+            loadAndDumpScopeObjects(response.scopeChain, next);
+        }
+    }
+
+    InspectorTest.runDebuggerTestSuite([
+        function testGetFirstLineFunctionDetails(next)
+        {
+            performStandardTestCase("firstLineFunction", next);
         },
         function testGetNonFirstLineFunctionDetails(next)
         {
-            InspectorTest.evaluateInPage("notFirstLineFunction", didEvaluate);
-
-            function didEvaluate(remote)
-            {
-                InspectorTest.addResult("nonFirstLineFunction type = " + remote.type);
-                DebuggerAgent.getFunctionDetails(remote.objectId, didGetDetails);
-            }
-            function didGetDetails(error, response)
-            {
-                dumpFunctionDetails(response);
-                next();
-            }
+            performStandardTestCase("notFirstLineFunction", next);
         },
         function testGetDetailsOfFunctionWithInferredName(next)
         {
-            InspectorTest.evaluateInPage("obj.m", didEvaluate);
-
-            function didEvaluate(remote)
-            {
-                InspectorTest.addResult("obj.m type = " + remote.type);
-                DebuggerAgent.getFunctionDetails(remote.objectId, didGetDetails);
-            }
-            function didGetDetails(error, response)
-            {
-                dumpFunctionDetails(response);
-                next();
-            }
+            performStandardTestCase("obj.m", next);
         },
         function testGetDetailsOfFunctionWithDisplayName(next)
         {
-            InspectorTest.evaluateInPage("functionWithDisplayName", didEvaluate);
-
-            function didEvaluate(remote)
-            {
-                InspectorTest.addResult("functionWithDisplayName type = " + remote.type);
-                DebuggerAgent.getFunctionDetails(remote.objectId, didGetDetails);
-            }
-            function didGetDetails(error, response)
-            {
-                dumpFunctionDetails(response);
-                next();
-            }
+            performStandardTestCase("functionWithDisplayName", next);
+        },
+        function testSmallClosure(next)
+        {
+            performStandardTestCase("smallClosure", next);
+        },
+        function testBigClosure(next)
+        {
+            performStandardTestCase("bigClosure", next);
         }
-
     ]);
 };
 

Modified: trunk/LayoutTests/platform/chromium/inspector/debugger/function-details-expected.txt (118684 => 118685)


--- trunk/LayoutTests/platform/chromium/inspector/debugger/function-details-expected.txt	2012-05-28 15:45:59 UTC (rev 118684)
+++ trunk/LayoutTests/platform/chromium/inspector/debugger/function-details-expected.txt	2012-05-28 15:52:05 UTC (rev 118685)
@@ -11,9 +11,10 @@
 name: firstLineFunction
 displayName: undefined
 inferredName: undefined
+scopeChain #0: global; <global object properties omitted>
 
 Running: testGetNonFirstLineFunctionDetails
-nonFirstLineFunction type = function
+notFirstLineFunction type = function
 Function details: 
 lineNumber: 10
 columnNumber: 32
@@ -21,6 +22,7 @@
 name: notFirstLineFunction
 displayName: undefined
 inferredName: undefined
+scopeChain #0: global; <global object properties omitted>
 
 Running: testGetDetailsOfFunctionWithInferredName
 obj.m type = function
@@ -31,6 +33,7 @@
 name: undefined
 displayName: undefined
 inferredName: obj.m
+scopeChain #0: global; <global object properties omitted>
 
 Running: testGetDetailsOfFunctionWithDisplayName
 functionWithDisplayName type = function
@@ -41,5 +44,32 @@
 name: functionWithDisplayName
 displayName: undefined
 inferredName: undefined
+scopeChain #0: global; <global object properties omitted>
+
+Running: testSmallClosure
+smallClosure type = function
+Function details: 
+lineNumber: 22
+columnNumber: 49
+scriptId is valid: true
+name: undefined
+displayName: undefined
+inferredName: undefined
+scopeChain #0: closure; p: "Capybara"
+scopeChain #1: global; <global object properties omitted>
+
+Running: testBigClosure
+bigClosure type = function
+Function details: 
+lineNumber: 35
+columnNumber: 27
+scriptId is valid: true
+name: undefined
+displayName: undefined
+inferredName: undefined
+scopeChain #0: catch; ex: <no string representation>
+scopeChain #1: with; __proto__: <no string representation>,e: 7,f: 5,u: <no value>,v: <no value>
+scopeChain #2: closure; arguments: <no string representation>,o: <no string representation>,p: <no string representation>
+scopeChain #3: global; <global object properties omitted>
 Debugger was disabled.
 

Modified: trunk/Source/WebCore/ChangeLog (118684 => 118685)


--- trunk/Source/WebCore/ChangeLog	2012-05-28 15:45:59 UTC (rev 118684)
+++ trunk/Source/WebCore/ChangeLog	2012-05-28 15:52:05 UTC (rev 118685)
@@ -1,3 +1,40 @@
+2012-05-28  Peter Rybin  <peter.ry...@gmail.com>
+
+        Web Inspector: Expose function (closure) scopes in remote protocol
+        https://bugs.webkit.org/show_bug.cgi?id=86861
+
+        Reviewed by Yury Semikhatsky.
+
+        A data transfer from V8's FunctionMirror via DebuggerScript.js via InjectedScriptHost is built.
+        Scope field is added to protocol declaration similar to scopes of stack call frame.
+        Test for function details is extended.
+        JSC code binging got fixme for implemting the corresponding feature.
+
+        * bindings/js/JSInjectedScriptHostCustom.cpp:
+        (WebCore::JSInjectedScriptHost::functionDetails):
+        * bindings/v8/DebuggerScript.js:
+        * bindings/v8/ScriptDebugServer.cpp:
+        (WebCore::ScriptDebugServer::functionScopes):
+        (WebCore):
+        * bindings/v8/ScriptDebugServer.h:
+        (ScriptDebugServer):
+        * bindings/v8/custom/V8InjectedScriptHostCustom.cpp:
+        (WebCore::V8InjectedScriptHost::functionDetailsCallback):
+        * inspector/InjectedScriptHost.cpp:
+        (WebCore):
+        (WebCore::InjectedScriptHost::scriptDebugServer):
+        * inspector/InjectedScriptHost.h:
+        (WebCore):
+        (WebCore::InjectedScriptHost::init):
+        (InjectedScriptHost):
+        * inspector/InjectedScriptSource.js:
+        (.):
+        * inspector/Inspector.json:
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::InspectorController):
+        * inspector/WorkerInspectorController.cpp:
+        (WebCore::WorkerInspectorController::WorkerInspectorController):
+
 2012-05-28  Arvid Nilsson  <anils...@rim.com>
 
         [BlackBerry] Add a constructor to create a Path from an SkPath

Modified: trunk/Source/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp (118684 => 118685)


--- trunk/Source/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp	2012-05-28 15:45:59 UTC (rev 118684)
+++ trunk/Source/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp	2012-05-28 15:52:05 UTC (rev 118685)
@@ -184,6 +184,8 @@
     UString displayName = function->displayName(exec);
     if (!displayName.isEmpty())
         result->putDirect(exec->globalData(), Identifier(exec, "displayName"), jsString(exec, displayName));
+    // FIXME: provide function scope data in "scopesRaw" property when JSC supports it.
+    //     https://bugs.webkit.org/show_bug.cgi?id=87192
     return result;
 }
 

Modified: trunk/Source/WebCore/bindings/v8/DebuggerScript.js (118684 => 118685)


--- trunk/Source/WebCore/bindings/v8/DebuggerScript.js	2012-05-28 15:45:59 UTC (rev 118684)
+++ trunk/Source/WebCore/bindings/v8/DebuggerScript.js	2012-05-28 15:52:05 UTC (rev 118685)
@@ -62,6 +62,23 @@
     return result;
 }
 
+DebuggerScript.getFunctionScopes = function(fun)
+{
+    var mirror = MakeMirror(fun);
+    var count = mirror.scopeCount();
+    if (count == 0)
+        return null;
+    var result = [];
+    for (var i = 0; i < count; i++) {
+        var scopeMirror = mirror.scope(i);
+        result[i] = {
+            type: scopeMirror.scopeType(),
+            object: DebuggerScript._buildScopeObject(scopeMirror)
+        };
+    }
+    return result;
+}
+
 DebuggerScript.getScripts = function(contextData)
 {
     var result = [];
@@ -233,35 +250,8 @@
     var scopeType = [];
     for (var i = 0; i < frameMirror.scopeCount(); i++) {
         var scopeMirror = frameMirror.scope(i);
-        var scopeObjectMirror = scopeMirror.scopeObject();
-
-        var scopeObject;
-        switch (scopeMirror.scopeType()) {
-        case ScopeType.Local:
-        case ScopeType.Closure:
-        case ScopeType.Catch:
-            // For transient objects we create a "persistent" copy that contains
-            // the same properties.
-            scopeObject = {};
-            // Reset scope object prototype to null so that the proto properties
-            // don't appear in the local scope section.
-            scopeObject.__proto__ = null;
-            var properties = scopeObjectMirror.properties();
-            for (var j = 0; j < properties.length; j++) {
-                var name = properties[j].name();
-                if (name.charAt(0) === ".")
-                    continue; // Skip internal variables like ".arguments"
-                scopeObject[name] = properties[j].value_;
-            }
-            break;
-        case ScopeType.Global:
-        case ScopeType.With:
-            scopeObject = scopeMirror.details_.object();
-            break;
-        }
-
         scopeType.push(scopeMirror.scopeType());
-        scopeChain.push(scopeObject);
+        scopeChain.push(DebuggerScript._buildScopeObject(scopeMirror));
     }
 
     function evaluate(_expression_) {
@@ -281,5 +271,37 @@
     };
 }
 
+DebuggerScript._buildScopeObject = function(scopeMirror) {
+    var scopeObject;
+    switch (scopeMirror.scopeType()) {
+    case ScopeType.Local:
+    case ScopeType.Closure:
+    case ScopeType.Catch:
+        // For transient objects we create a "persistent" copy that contains
+        // the same properties.
+        scopeObject = {};
+        // Reset scope object prototype to null so that the proto properties
+        // don't appear in the local scope section.
+        scopeObject.__proto__ = null;
+        var scopeObjectMirror = scopeMirror.scopeObject();
+        var properties = scopeObjectMirror.properties();
+        for (var j = 0; j < properties.length; j++) {
+            var name = properties[j].name();
+            if (name.charAt(0) === ".")
+                continue; // Skip internal variables like ".arguments"
+            scopeObject[name] = properties[j].value_;
+        }
+        break;
+    case ScopeType.Global:
+    case ScopeType.With:
+        scopeObject = scopeMirror.details_.object();
+        break;
+    case ScopeType.Block:
+        // Unsupported yet. Mustn't be reachable.
+        break;
+    }
+    return scopeObject;
+}
+
 return DebuggerScript;
 })();

Modified: trunk/Source/WebCore/bindings/v8/ScriptDebugServer.cpp (118684 => 118685)


--- trunk/Source/WebCore/bindings/v8/ScriptDebugServer.cpp	2012-05-28 15:45:59 UTC (rev 118684)
+++ trunk/Source/WebCore/bindings/v8/ScriptDebugServer.cpp	2012-05-28 15:52:05 UTC (rev 118685)
@@ -396,6 +396,14 @@
     }
 }
 
+v8::Local<v8::Value> ScriptDebugServer::functionScopes(v8::Handle<v8::Function> function)
+{
+    ensureDebuggerScriptCompiled();
+
+    v8::Handle<v8::Value> argv[] = { function };
+    return callDebuggerMethod("getFunctionScopes", 1, argv);
+}
+
 bool ScriptDebugServer::isPaused()
 {
     return !m_executionState.get().IsEmpty();

Modified: trunk/Source/WebCore/bindings/v8/ScriptDebugServer.h (118684 => 118685)


--- trunk/Source/WebCore/bindings/v8/ScriptDebugServer.h	2012-05-28 15:45:59 UTC (rev 118684)
+++ trunk/Source/WebCore/bindings/v8/ScriptDebugServer.h	2012-05-28 15:52:05 UTC (rev 118685)
@@ -94,6 +94,8 @@
 
     bool isPaused();
 
+    v8::Local<v8::Value> functionScopes(v8::Handle<v8::Function>);
+
 protected:
     ScriptDebugServer();
     ~ScriptDebugServer() { }

Modified: trunk/Source/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp (118684 => 118685)


--- trunk/Source/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp	2012-05-28 15:45:59 UTC (rev 118684)
+++ trunk/Source/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp	2012-05-28 15:52:05 UTC (rev 118685)
@@ -37,6 +37,7 @@
 #include "InjectedScriptHost.h"
 #include "InspectorDOMAgent.h"
 #include "InspectorValues.h"
+#include "ScriptDebugServer.h"
 #include "ScriptValue.h"
 #include "V8Binding.h"
 #include "V8BindingState.h"
@@ -181,6 +182,13 @@
     v8::Handle<v8::Value> inferredName = function->GetInferredName();
     if (inferredName->IsString() && v8::Handle<v8::String>::Cast(inferredName)->Length())
         result->Set(v8::String::New("inferredName"), inferredName);
+
+    InjectedScriptHost* host = V8InjectedScriptHost::toNative(args.Holder());
+    ScriptDebugServer& debugServer = host->scriptDebugServer();
+    v8::Handle<v8::Value> scopes = debugServer.functionScopes(function);
+    if (!scopes.IsEmpty() && scopes->IsArray())
+        result->Set(v8::String::New("rawScopes"), scopes);
+
     return result;
 }
 

Modified: trunk/Source/WebCore/inspector/InjectedScriptHost.cpp (118684 => 118685)


--- trunk/Source/WebCore/inspector/InjectedScriptHost.cpp	2012-05-28 15:45:59 UTC (rev 118684)
+++ trunk/Source/WebCore/inspector/InjectedScriptHost.cpp	2012-05-28 15:52:05 UTC (rev 118685)
@@ -45,6 +45,7 @@
 #include "InspectorDOMAgent.h"
 #include "InspectorDOMStorageAgent.h"
 #include "InspectorDatabaseAgent.h"
+#include "InspectorDebuggerAgent.h"
 #include "InspectorFrontend.h"
 #include "InspectorValues.h"
 #include "Pasteboard.h"
@@ -182,6 +183,14 @@
 }
 #endif // ENABLE(WORKERS)
 
+#if ENABLE(_javascript__DEBUGGER)
+ScriptDebugServer& InjectedScriptHost::scriptDebugServer()
+{
+    return m_debuggerAgent->scriptDebugServer();
+}
+#endif
+
+
 } // namespace WebCore
 
 #endif // ENABLE(INSPECTOR)

Modified: trunk/Source/WebCore/inspector/InjectedScriptHost.h (118684 => 118685)


--- trunk/Source/WebCore/inspector/InjectedScriptHost.h	2012-05-28 15:45:59 UTC (rev 118684)
+++ trunk/Source/WebCore/inspector/InjectedScriptHost.h	2012-05-28 15:52:05 UTC (rev 118685)
@@ -45,10 +45,12 @@
 class InspectorDOMAgent;
 class InspectorDOMStorageAgent;
 class InspectorDatabaseAgent;
+class InspectorDebuggerAgent;
 class InspectorFrontend;
 class InspectorObject;
 class InspectorValue;
 class Node;
+class ScriptDebugServer;
 class ScriptObject;
 class ScriptValue;
 class Storage;
@@ -67,6 +69,9 @@
 #endif
             , InspectorDOMStorageAgent* domStorageAgent
             , InspectorDOMAgent* domAgent
+#if ENABLE(_javascript__DEBUGGER)
+            , InspectorDebuggerAgent* debuggerAgent
+#endif
         )
     {
         m_inspectorAgent = inspectorAgent;
@@ -76,6 +81,9 @@
 #endif
         m_domStorageAgent = domStorageAgent;
         m_domAgent = domAgent;
+#if ENABLE(_javascript__DEBUGGER)
+        m_debuggerAgent = debuggerAgent;
+#endif
     }
 
     static Node* scriptValueAsNode(ScriptValue);
@@ -107,6 +115,10 @@
     void didDestroyWorker(long id);
 #endif
 
+#if ENABLE(_javascript__DEBUGGER)
+    ScriptDebugServer& scriptDebugServer();
+#endif
+
 private:
     InjectedScriptHost();
 
@@ -117,6 +129,9 @@
 #endif
     InspectorDOMStorageAgent* m_domStorageAgent;
     InspectorDOMAgent* m_domAgent;
+#if ENABLE(_javascript__DEBUGGER)
+    InspectorDebuggerAgent* m_debuggerAgent;
+#endif
     long m_lastWorkerId;
     Vector<OwnPtr<InspectableObject> > m_inspectedObjects;
     OwnPtr<InspectableObject> m_defaultInspectableObject;

Modified: trunk/Source/WebCore/inspector/InjectedScriptSource.js (118684 => 118685)


--- trunk/Source/WebCore/inspector/InjectedScriptSource.js	2012-05-28 15:45:59 UTC (rev 118684)
+++ trunk/Source/WebCore/inspector/InjectedScriptSource.js	2012-05-28 15:52:05 UTC (rev 118685)
@@ -197,7 +197,17 @@
         var func = this._objectForId(parsedFunctionId);
         if (typeof func !== "function")
             return "Cannot resolve function by id.";
-        return InjectedScriptHost.functionDetails(func);
+        var details = InjectedScriptHost.functionDetails(func);
+        if ("rawScopes" in details) {
+            var objectGroupName = this._idToObjectGroupName[parsedFunctionId.id];
+            var rawScopes = details.rawScopes;
+            var scopes = [];
+            delete details.rawScopes;
+            for (var i = 0; i < rawScopes.length; i++)
+                scopes.push(InjectedScript.CallFrameProxy._createScopeJson(rawScopes[i].type, rawScopes[i].object, objectGroupName));
+            details.scopeChain = scopes;
+        }
+        return details;
     },
 
     releaseObject: function(objectId)
@@ -522,34 +532,36 @@
 InjectedScript.CallFrameProxy.prototype = {
     _wrapScopeChain: function(callFrame)
     {
-        const GLOBAL_SCOPE = 0;
-        const LOCAL_SCOPE = 1;
-        const WITH_SCOPE = 2;
-        const CLOSURE_SCOPE = 3;
-        const CATCH_SCOPE = 4;
-
-        var scopeTypeNames = {};
-        scopeTypeNames[GLOBAL_SCOPE] = "global";
-        scopeTypeNames[LOCAL_SCOPE] = "local";
-        scopeTypeNames[WITH_SCOPE] = "with";
-        scopeTypeNames[CLOSURE_SCOPE] = "closure";
-        scopeTypeNames[CATCH_SCOPE] = "catch";
-
         var scopeChain = callFrame.scopeChain;
         var scopeChainProxy = [];
-        var foundLocalScope = false;
         for (var i = 0; i < scopeChain.length; i++) {
-            var scope = {};
-            scope.object = injectedScript._wrapObject(scopeChain[i], "backtrace");
-
-            var scopeType = callFrame.scopeType(i);
-            scope.type = scopeTypeNames[scopeType];
+            var scope = InjectedScript.CallFrameProxy._createScopeJson(callFrame.scopeType(i), scopeChain[i], "backtrace");
             scopeChainProxy.push(scope);
         }
         return scopeChainProxy;
     }
 }
 
+InjectedScript.CallFrameProxy._createScopeJson = function(scopeTypeCode, scopeObject, groupId) {
+    const GLOBAL_SCOPE = 0;
+    const LOCAL_SCOPE = 1;
+    const WITH_SCOPE = 2;
+    const CLOSURE_SCOPE = 3;
+    const CATCH_SCOPE = 4;
+
+    var scopeTypeNames = {};
+    scopeTypeNames[GLOBAL_SCOPE] = "global";
+    scopeTypeNames[LOCAL_SCOPE] = "local";
+    scopeTypeNames[WITH_SCOPE] = "with";
+    scopeTypeNames[CLOSURE_SCOPE] = "closure";
+    scopeTypeNames[CATCH_SCOPE] = "catch";
+
+    return {
+        object: injectedScript._wrapObject(scopeObject, groupId),
+        type: scopeTypeNames[scopeTypeCode]
+    };
+}
+
 /**
  * @constructor
  */

Modified: trunk/Source/WebCore/inspector/Inspector.json (118684 => 118685)


--- trunk/Source/WebCore/inspector/Inspector.json	2012-05-28 15:45:59 UTC (rev 118684)
+++ trunk/Source/WebCore/inspector/Inspector.json	2012-05-28 15:52:05 UTC (rev 118685)
@@ -2272,7 +2272,8 @@
                     { "name": "location", "$ref": "Location", "description": "Location of the function." },
                     { "name": "name", "type": "string", "optional": true, "description": "Name of the function. Not present for anonymous functions." },
                     { "name": "displayName", "type": "string", "optional": true, "description": "Display name of the function(specified in 'displayName' property on the function object)." },
-                    { "name": "inferredName", "type": "string", "optional": true, "description": "Name of the function inferred from its initial assignment." }
+                    { "name": "inferredName", "type": "string", "optional": true, "description": "Name of the function inferred from its initial assignment." },
+                    { "name": "scopeChain", "type": "array", "optional": true, "items": { "$ref": "Scope" }, "description": "Scope chain for this closure." }
                 ],
                 "description": "Information about the function."
             },

Modified: trunk/Source/WebCore/inspector/InspectorController.cpp (118684 => 118685)


--- trunk/Source/WebCore/inspector/InspectorController.cpp	2012-05-28 15:45:59 UTC (rev 118684)
+++ trunk/Source/WebCore/inspector/InspectorController.cpp	2012-05-28 15:52:05 UTC (rev 118685)
@@ -152,6 +152,7 @@
 #endif
         , domStorageAgent
         , m_domAgent
+        , m_debuggerAgent
     );
 
 #if ENABLE(_javascript__DEBUGGER)

Modified: trunk/Source/WebCore/inspector/WorkerInspectorController.cpp (118684 => 118685)


--- trunk/Source/WebCore/inspector/WorkerInspectorController.cpp	2012-05-28 15:45:59 UTC (rev 118684)
+++ trunk/Source/WebCore/inspector/WorkerInspectorController.cpp	2012-05-28 15:52:05 UTC (rev 118685)
@@ -111,6 +111,7 @@
 #endif
         , 0
         , 0
+        , 0
     );
 
 #if ENABLE(_javascript__DEBUGGER)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to