Title: [260113] trunk
Revision
260113
Author
[email protected]
Date
2020-04-14 19:35:04 -0700 (Tue, 14 Apr 2020)

Log Message

Web Inspector: Debugger: add a Step next that steps by _expression_
https://bugs.webkit.org/show_bug.cgi?id=210324

Reviewed by Timothy Hatcher.

Source/_javascript_Core:

Step next is a hybrid of Step over and Step into which continues execution to the next pause
opportunity within the current (or ancestor) call frame. It is especially useful when trying
to debug minified code, such as trying to continue to `c()` in `a() && b() && c();`, where
Step over would continue to the next statement (i.e. after the `;`) and Step in would
continue to the first line inside `a()` (and would require a Step out to get back).

* inspector/protocol/Debugger.json:
* inspector/agents/InspectorDebuggerAgent.h:
* inspector/agents/InspectorDebuggerAgent.cpp:
(Inspector::InspectorDebuggerAgent::stepNext): Added.

* debugger/Debugger.h:
* debugger/Debugger.cpp:
(JSC::Debugger::stepNextExpression): Added.
(JSC::Debugger::atExpression):
(JSC::Debugger::clearNextPauseState):

Source/WebInspectorUI:

Step next is a hybrid of Step over and Step into which continues execution to the next pause
opportunity within the current (or ancestor) call frame. It is especially useful when trying
to debug minified code, such as trying to continue to `c()` in `a() && b() && c();`, where
Step over would continue to the next statement (i.e. after the `;`) and Step in would
continue to the first line inside `a()` (and would require a Step out to get back).

* UserInterface/Controllers/DebuggerManager.js:
(WI.DebuggerManager.prototype.stepNext): Added.

* UserInterface/Base/Main.js:
(WI.contentLoaded):
(WI.debuggerStepNext): Added.
* UserInterface/Views/SourcesNavigationSidebarPanel.js:
(WI.SourcesNavigationSidebarPanel):
(WI.SourcesNavigationSidebarPanel.prototype._handleDebuggerPaused):
(WI.SourcesNavigationSidebarPanel.prototype._handleDebuggerResumed):

* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Images/StepNext.svg: Added.

LayoutTests:

* inspector/debugger/stepping/stepNext.html: Added.
* inspector/debugger/stepping/stepNext-expected.txt: Added.

* inspector/debugger/stepping/stepInto.html:
* inspector/debugger/stepping/stepInto-expected.txt:
* inspector/debugger/stepping/stepOut.html:
* inspector/debugger/stepping/stepOut-expected.txt:
* inspector/debugger/stepping/stepOver.html:
* inspector/debugger/stepping/stepOver-expected.txt:
Renamed functions for clarity and added additional test cases from other commands.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (260112 => 260113)


--- trunk/LayoutTests/ChangeLog	2020-04-15 01:24:30 UTC (rev 260112)
+++ trunk/LayoutTests/ChangeLog	2020-04-15 02:35:04 UTC (rev 260113)
@@ -1,3 +1,21 @@
+2020-04-14  Devin Rousso  <[email protected]>
+
+        Web Inspector: Debugger: add a Step next that steps by _expression_
+        https://bugs.webkit.org/show_bug.cgi?id=210324
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/debugger/stepping/stepNext.html: Added.
+        * inspector/debugger/stepping/stepNext-expected.txt: Added.
+
+        * inspector/debugger/stepping/stepInto.html:
+        * inspector/debugger/stepping/stepInto-expected.txt:
+        * inspector/debugger/stepping/stepOut.html:
+        * inspector/debugger/stepping/stepOut-expected.txt:
+        * inspector/debugger/stepping/stepOver.html:
+        * inspector/debugger/stepping/stepOver-expected.txt:
+        Renamed functions for clarity and added additional test cases from other commands.
+
 2020-04-14  Diego Pino Garcia  <[email protected]>
 
         [GTK] Gardening, update expectations after r260062

Modified: trunk/LayoutTests/inspector/debugger/stepping/stepInto-expected.txt (260112 => 260113)


--- trunk/LayoutTests/inspector/debugger/stepping/stepInto-expected.txt	2020-04-15 01:24:30 UTC (rev 260112)
+++ trunk/LayoutTests/inspector/debugger/stepping/stepInto-expected.txt	2020-04-15 02:35:04 UTC (rev 260113)
@@ -1,4 +1,3 @@
-ALERT: log 1
 Checking pause locations when stepping with "stepInto".
 
 
@@ -5,18 +4,18 @@
 == Running test suite: Debugger.stepInto
 -- Running test case: Debugger.stepInto.statements
 PAUSED (debugger-statement)
-PAUSE AT entry1:12:5
-      8    }
+PAUSE AT testStatements:12:5
+      8    function c() { return "c"; }
       9    
-     10    function entry1() {
+     10    function testStatements() {
  ->  11        |debugger;
      12        let x = 1;
      13        let y = 2;
      14    }
 
-PAUSE AT entry1:13:5
+PAUSE AT testStatements:13:5
       9    
-     10    function entry1() {
+     10    function testStatements() {
      11        debugger;
  ->  12        |let x = 1;
      13        let y = 2;
@@ -23,22 +22,22 @@
      14    }
      15    
 
-PAUSE AT entry1:14:5
-     10    function entry1() {
+PAUSE AT testStatements:14:5
+     10    function testStatements() {
      11        debugger;
      12        let x = 1;
  ->  13        |let y = 2;
      14    }
      15    
-     16    function entry2() {
+     16    function testFunctions() {
 
-PAUSE AT entry1:15:2
+PAUSE AT testStatements:15:2
      11        debugger;
      12        let x = 1;
      13        let y = 2;
  ->  14    }|
      15    
-     16    function entry2() {
+     16    function testFunctions() {
      17        debugger;
 
 RESUMED
@@ -45,67 +44,67 @@
 
 -- Running test case: Debugger.stepInto.function
 PAUSED (debugger-statement)
-PAUSE AT entry2:18:5
+PAUSE AT testFunctions:18:5
      14    }
      15    
-     16    function entry2() {
+     16    function testFunctions() {
  ->  17        |debugger;
      18        let before = 1;
-     19        testAlert("log 1");
+     19        a();
      20        let after = 2;
 
-PAUSE AT entry2:19:5
+PAUSE AT testFunctions:19:5
      15    
-     16    function entry2() {
+     16    function testFunctions() {
      17        debugger;
  ->  18        |let before = 1;
-     19        testAlert("log 1");
+     19        a();
      20        let after = 2;
      21    }
 
-PAUSE AT entry2:20:5
-     16    function entry2() {
+PAUSE AT testFunctions:20:5
+     16    function testFunctions() {
      17        debugger;
      18        let before = 1;
- ->  19        |testAlert("log 1");
+ ->  19        |a();
      20        let after = 2;
      21    }
      22    
 
-PAUSE AT testAlert:8:5
+PAUSE AT a:7:16
+      3    <script src=""
       4    <script src=""
       5    <script>
-      6    function testAlert(str) {
- ->   7        |alert(str);
-      8    }
+ ->   6    function a() { |return "a"; }
+      7    function b() { return "b"; }
+      8    function c() { return "c"; }
       9    
-     10    function entry1() {
 
-PAUSE AT testAlert:9:2
+PAUSE AT a:7:29
+      3    <script src=""
+      4    <script src=""
       5    <script>
-      6    function testAlert(str) {
-      7        alert(str);
- ->   8    }|
+ ->   6    function a() { return "a"; }|
+      7    function b() { return "b"; }
+      8    function c() { return "c"; }
       9    
-     10    function entry1() {
-     11        debugger;
 
-PAUSE AT entry2:21:5
+PAUSE AT testFunctions:21:5
      17        debugger;
      18        let before = 1;
-     19        testAlert("log 1");
+     19        a();
  ->  20        |let after = 2;
      21    }
      22    
-     23    function entry3() {
+     23    function testEval() {
 
-PAUSE AT entry2:22:2
+PAUSE AT testFunctions:22:2
      18        let before = 1;
-     19        testAlert("log 1");
+     19        a();
      20        let after = 2;
  ->  21    }|
      22    
-     23    function entry3() {
+     23    function testEval() {
      24        debugger;
 
 RESUMED
@@ -112,18 +111,18 @@
 
 -- Running test case: Debugger.stepInto.eval
 PAUSED (debugger-statement)
-PAUSE AT entry3:25:5
+PAUSE AT testEval:25:5
      21    }
      22    
-     23    function entry3() {
+     23    function testEval() {
  ->  24        |debugger;
      25        let before = 1;
      26        eval("1 + 1");
      27        let after = 2;
 
-PAUSE AT entry3:26:5
+PAUSE AT testEval:26:5
      22    
-     23    function entry3() {
+     23    function testEval() {
      24        debugger;
  ->  25        |let before = 1;
      26        eval("1 + 1");
@@ -130,8 +129,8 @@
      27        let after = 2;
      28    }
 
-PAUSE AT entry3:27:5
-     23    function entry3() {
+PAUSE AT testEval:27:5
+     23    function testEval() {
      24        debugger;
      25        let before = 1;
  ->  26        |eval("1 + 1");
@@ -145,7 +144,7 @@
 PAUSE AT Eval Code:1:6
 --- Source Unavailable ---
 
-PAUSE AT entry3:28:5
+PAUSE AT testEval:28:5
      24        debugger;
      25        let before = 1;
      26        eval("1 + 1");
@@ -152,15 +151,15 @@
  ->  27        |let after = 2;
      28    }
      29    
-     30    function entry4() {
+     30    function testInnerFunction() {
 
-PAUSE AT entry3:29:2
+PAUSE AT testEval:29:2
      25        let before = 1;
      26        eval("1 + 1");
      27        let after = 2;
  ->  28    }|
      29    
-     30    function entry4() {
+     30    function testInnerFunction() {
      31        (function() {
 
 RESUMED
@@ -169,7 +168,7 @@
 PAUSED (debugger-statement)
 PAUSE AT <anonymous>:33:9
      29    
-     30    function entry4() {
+     30    function testInnerFunction() {
      31        (function() {
  ->  32            |debugger;
      33            let inner = 1;
@@ -177,7 +176,7 @@
      35        let outer = 2;
 
 PAUSE AT <anonymous>:34:9
-     30    function entry4() {
+     30    function testInnerFunction() {
      31        (function() {
      32            debugger;
  ->  33            |let inner = 1;
@@ -194,7 +193,7 @@
      36    }
      37    
 
-PAUSE AT entry4:36:5
+PAUSE AT testInnerFunction:36:5
      32            debugger;
      33            let inner = 1;
      34        })();
@@ -201,16 +200,339 @@
  ->  35        |let outer = 2;
      36    }
      37    
-     38    // ---------
+     38    function testCommas() {
 
-PAUSE AT entry4:37:2
+PAUSE AT testInnerFunction:37:2
      33            let inner = 1;
      34        })();
      35        let outer = 2;
  ->  36    }|
      37    
-     38    // ---------
-     39    
+     38    function testCommas() {
+     39        debugger;
 
 RESUMED
 
+-- Running test case: Debugger.stepInto.commas
+PAUSED (debugger-statement)
+PAUSE AT testCommas:40:5
+     36    }
+     37    
+     38    function testCommas() {
+ ->  39        |debugger;
+     40        let x = 1,
+     41            y = 2,
+     42            z = 3;
+
+PAUSE AT testCommas:41:5
+     37    
+     38    function testCommas() {
+     39        debugger;
+ ->  40        |let x = 1,
+     41            y = 2,
+     42            z = 3;
+     43        a(), b(), c();
+
+PAUSE AT testCommas:42:9
+     38    function testCommas() {
+     39        debugger;
+     40        let x = 1,
+ ->  41            |y = 2,
+     42            z = 3;
+     43        a(), b(), c();
+     44        true && (a(), b(), c());
+
+PAUSE AT testCommas:43:9
+     39        debugger;
+     40        let x = 1,
+     41            y = 2,
+ ->  42            |z = 3;
+     43        a(), b(), c();
+     44        true && (a(), b(), c());
+     45    }
+
+PAUSE AT testCommas:44:5
+     40        let x = 1,
+     41            y = 2,
+     42            z = 3;
+ ->  43        |a(), b(), c();
+     44        true && (a(), b(), c());
+     45    }
+     46    
+
+PAUSE AT a:7:16
+      3    <script src=""
+      4    <script src=""
+      5    <script>
+ ->   6    function a() { |return "a"; }
+      7    function b() { return "b"; }
+      8    function c() { return "c"; }
+      9    
+
+PAUSE AT a:7:29
+      3    <script src=""
+      4    <script src=""
+      5    <script>
+ ->   6    function a() { return "a"; }|
+      7    function b() { return "b"; }
+      8    function c() { return "c"; }
+      9    
+
+PAUSE AT testCommas:44:10
+     40        let x = 1,
+     41            y = 2,
+     42            z = 3;
+ ->  43        a(), |b(), c();
+     44        true && (a(), b(), c());
+     45    }
+     46    
+
+PAUSE AT b:8:16
+      4    <script src=""
+      5    <script>
+      6    function a() { return "a"; }
+ ->   7    function b() { |return "b"; }
+      8    function c() { return "c"; }
+      9    
+     10    function testStatements() {
+
+PAUSE AT b:8:29
+      4    <script src=""
+      5    <script>
+      6    function a() { return "a"; }
+ ->   7    function b() { return "b"; }|
+      8    function c() { return "c"; }
+      9    
+     10    function testStatements() {
+
+PAUSE AT testCommas:44:15
+     40        let x = 1,
+     41            y = 2,
+     42            z = 3;
+ ->  43        a(), b(), |c();
+     44        true && (a(), b(), c());
+     45    }
+     46    
+
+PAUSE AT c:9:16
+      5    <script>
+      6    function a() { return "a"; }
+      7    function b() { return "b"; }
+ ->   8    function c() { |return "c"; }
+      9    
+     10    function testStatements() {
+     11        debugger;
+
+PAUSE AT c:9:29
+      5    <script>
+      6    function a() { return "a"; }
+      7    function b() { return "b"; }
+ ->   8    function c() { return "c"; }|
+      9    
+     10    function testStatements() {
+     11        debugger;
+
+PAUSE AT testCommas:45:5
+     41            y = 2,
+     42            z = 3;
+     43        a(), b(), c();
+ ->  44        |true && (a(), b(), c());
+     45    }
+     46    
+     47    function testChainedExpressions() {
+
+PAUSE AT testCommas:45:14
+     41            y = 2,
+     42            z = 3;
+     43        a(), b(), c();
+ ->  44        true && (|a(), b(), c());
+     45    }
+     46    
+     47    function testChainedExpressions() {
+
+PAUSE AT a:7:16
+      3    <script src=""
+      4    <script src=""
+      5    <script>
+ ->   6    function a() { |return "a"; }
+      7    function b() { return "b"; }
+      8    function c() { return "c"; }
+      9    
+
+PAUSE AT a:7:29
+      3    <script src=""
+      4    <script src=""
+      5    <script>
+ ->   6    function a() { return "a"; }|
+      7    function b() { return "b"; }
+      8    function c() { return "c"; }
+      9    
+
+PAUSE AT testCommas:45:19
+     41            y = 2,
+     42            z = 3;
+     43        a(), b(), c();
+ ->  44        true && (a(), |b(), c());
+     45    }
+     46    
+     47    function testChainedExpressions() {
+
+PAUSE AT b:8:16
+      4    <script src=""
+      5    <script>
+      6    function a() { return "a"; }
+ ->   7    function b() { |return "b"; }
+      8    function c() { return "c"; }
+      9    
+     10    function testStatements() {
+
+PAUSE AT b:8:29
+      4    <script src=""
+      5    <script>
+      6    function a() { return "a"; }
+ ->   7    function b() { return "b"; }|
+      8    function c() { return "c"; }
+      9    
+     10    function testStatements() {
+
+PAUSE AT testCommas:45:24
+     41            y = 2,
+     42            z = 3;
+     43        a(), b(), c();
+ ->  44        true && (a(), b(), |c());
+     45    }
+     46    
+     47    function testChainedExpressions() {
+
+PAUSE AT c:9:16
+      5    <script>
+      6    function a() { return "a"; }
+      7    function b() { return "b"; }
+ ->   8    function c() { |return "c"; }
+      9    
+     10    function testStatements() {
+     11        debugger;
+
+PAUSE AT c:9:29
+      5    <script>
+      6    function a() { return "a"; }
+      7    function b() { return "b"; }
+ ->   8    function c() { return "c"; }|
+      9    
+     10    function testStatements() {
+     11        debugger;
+
+PAUSE AT testCommas:46:2
+     42            z = 3;
+     43        a(), b(), c();
+     44        true && (a(), b(), c());
+ ->  45    }|
+     46    
+     47    function testChainedExpressions() {
+     48        debugger;
+
+RESUMED
+
+-- Running test case: Debugger.stepInto.chainedExpressions
+PAUSED (debugger-statement)
+PAUSE AT testChainedExpressions:49:5
+     45    }
+     46    
+     47    function testChainedExpressions() {
+ ->  48        |debugger;
+     49        a() && b() && c();
+     50    }
+     51    
+
+PAUSE AT testChainedExpressions:50:5
+     46    
+     47    function testChainedExpressions() {
+     48        debugger;
+ ->  49        |a() && b() && c();
+     50    }
+     51    
+     52    // ---------
+
+PAUSE AT a:7:16
+      3    <script src=""
+      4    <script src=""
+      5    <script>
+ ->   6    function a() { |return "a"; }
+      7    function b() { return "b"; }
+      8    function c() { return "c"; }
+      9    
+
+PAUSE AT a:7:29
+      3    <script src=""
+      4    <script src=""
+      5    <script>
+ ->   6    function a() { return "a"; }|
+      7    function b() { return "b"; }
+      8    function c() { return "c"; }
+      9    
+
+PAUSE AT testChainedExpressions:50:12
+     46    
+     47    function testChainedExpressions() {
+     48        debugger;
+ ->  49        a() && |b() && c();
+     50    }
+     51    
+     52    // ---------
+
+PAUSE AT b:8:16
+      4    <script src=""
+      5    <script>
+      6    function a() { return "a"; }
+ ->   7    function b() { |return "b"; }
+      8    function c() { return "c"; }
+      9    
+     10    function testStatements() {
+
+PAUSE AT b:8:29
+      4    <script src=""
+      5    <script>
+      6    function a() { return "a"; }
+ ->   7    function b() { return "b"; }|
+      8    function c() { return "c"; }
+      9    
+     10    function testStatements() {
+
+PAUSE AT testChainedExpressions:50:19
+     46    
+     47    function testChainedExpressions() {
+     48        debugger;
+ ->  49        a() && b() && |c();
+     50    }
+     51    
+     52    // ---------
+
+PAUSE AT c:9:16
+      5    <script>
+      6    function a() { return "a"; }
+      7    function b() { return "b"; }
+ ->   8    function c() { |return "c"; }
+      9    
+     10    function testStatements() {
+     11        debugger;
+
+PAUSE AT c:9:29
+      5    <script>
+      6    function a() { return "a"; }
+      7    function b() { return "b"; }
+ ->   8    function c() { return "c"; }|
+      9    
+     10    function testStatements() {
+     11        debugger;
+
+PAUSE AT testChainedExpressions:51:2
+     47    function testChainedExpressions() {
+     48        debugger;
+     49        a() && b() && c();
+ ->  50    }|
+     51    
+     52    // ---------
+     53    
+
+RESUMED
+

Modified: trunk/LayoutTests/inspector/debugger/stepping/stepInto.html (260112 => 260113)


--- trunk/LayoutTests/inspector/debugger/stepping/stepInto.html	2020-04-15 01:24:30 UTC (rev 260112)
+++ trunk/LayoutTests/inspector/debugger/stepping/stepInto.html	2020-04-15 02:35:04 UTC (rev 260113)
@@ -4,24 +4,24 @@
 <script src=""
 <script src=""
 <script>
-function testAlert(str) {
-    alert(str);
-}
+function a() { return "a"; }
+function b() { return "b"; }
+function c() { return "c"; }
 
-function entry1() {
+function testStatements() {
     debugger;
     let x = 1;
     let y = 2;
 }
 
-function entry2() {
+function testFunctions() {
     debugger;
     let before = 1;
-    testAlert("log 1");
+    a();
     let after = 2;
 }
 
-function entry3() {
+function testEval() {
     debugger;
     let before = 1;
     eval("1 + 1");
@@ -28,7 +28,7 @@
     let after = 2;
 }
 
-function entry4() {
+function testInnerFunction() {
     (function() {
         debugger;
         let inner = 1;
@@ -36,6 +36,20 @@
     let outer = 2;
 }
 
+function testCommas() {
+    debugger;
+    let x = 1,
+        y = 2,
+        z = 3;
+    a(), b(), c();
+    true && (a(), b(), c());
+}
+
+function testChainedExpressions() {
+    debugger;
+    a() && b() && c();
+}
+
 // ---------
 
 function test()
@@ -69,27 +83,39 @@
     addTestCase({
         name: "Debugger.stepInto.statements",
         description: "step-into should step over statements.",
-        _expression_: "setTimeout(entry1)",
+        _expression_: "setTimeout(testStatements)",
     });
 
     addTestCase({
         name: "Debugger.stepInto.function",
         description: "step-into should step into function calls.",
-        _expression_: "setTimeout(entry2)",
+        _expression_: "setTimeout(testFunctions)",
     });
 
     addTestCase({
         name: "Debugger.stepInto.eval",
         description: "step-into should step into an eval program.",
-        _expression_: "setTimeout(entry3)",
+        _expression_: "setTimeout(testEval)",
     });
 
     addTestCase({
         name: "Debugger.stepInto.innerFunction",
         description: "step-into should step out of a function to its caller.",
-        _expression_: "setTimeout(entry4)",
+        _expression_: "setTimeout(testInnerFunction)",
     });
 
+    addTestCase({
+        name: "Debugger.stepInto.commas",
+        description: "step-into should step into each sub-_expression_ within comma expressions.",
+        _expression_: "setTimeout(testCommas)",
+    });
+
+    addTestCase({
+        name: "Debugger.stepInto.chainedExpressions",
+        description: "step-into should step into each sub-_expression_ within chained expressions.",
+        _expression_: "setTimeout(testChainedExpressions)",
+    });
+
     loadMainPageContent().then(() => {
         suite.runTestCasesAndFinish();
     });

Copied: trunk/LayoutTests/inspector/debugger/stepping/stepNext-expected.txt (from rev 260112, trunk/LayoutTests/inspector/debugger/stepping/stepOver-expected.txt) (0 => 260113)


--- trunk/LayoutTests/inspector/debugger/stepping/stepNext-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/debugger/stepping/stepNext-expected.txt	2020-04-15 02:35:04 UTC (rev 260113)
@@ -0,0 +1,352 @@
+Checking pause locations when stepping with "stepNext".
+
+
+== Running test suite: Debugger.stepNext
+-- Running test case: Debugger.stepNext.statements
+PAUSED (debugger-statement)
+PAUSE AT testStatements:12:5
+      8    function c() { return "c"; }
+      9    
+     10    function testStatements() {
+ ->  11        |debugger;
+     12        let x = 1;
+     13        let y = 2;
+     14    }
+
+PAUSE AT testStatements:13:5
+      9    
+     10    function testStatements() {
+     11        debugger;
+ ->  12        |let x = 1;
+     13        let y = 2;
+     14    }
+     15    
+
+PAUSE AT testStatements:14:5
+     10    function testStatements() {
+     11        debugger;
+     12        let x = 1;
+ ->  13        |let y = 2;
+     14    }
+     15    
+     16    function testFunctions() {
+
+PAUSE AT testStatements:15:2
+     11        debugger;
+     12        let x = 1;
+     13        let y = 2;
+ ->  14    }|
+     15    
+     16    function testFunctions() {
+     17        debugger;
+
+RESUMED
+
+-- Running test case: Debugger.stepNext.function
+PAUSED (debugger-statement)
+PAUSE AT testFunctions:18:5
+     14    }
+     15    
+     16    function testFunctions() {
+ ->  17        |debugger;
+     18        let before = 1;
+     19        a();
+     20        let after = 2;
+
+PAUSE AT testFunctions:19:5
+     15    
+     16    function testFunctions() {
+     17        debugger;
+ ->  18        |let before = 1;
+     19        a();
+     20        let after = 2;
+     21    }
+
+PAUSE AT testFunctions:20:5
+     16    function testFunctions() {
+     17        debugger;
+     18        let before = 1;
+ ->  19        |a();
+     20        let after = 2;
+     21    }
+     22    
+
+PAUSE AT testFunctions:21:5
+     17        debugger;
+     18        let before = 1;
+     19        a();
+ ->  20        |let after = 2;
+     21    }
+     22    
+     23    function testEval() {
+
+PAUSE AT testFunctions:22:2
+     18        let before = 1;
+     19        a();
+     20        let after = 2;
+ ->  21    }|
+     22    
+     23    function testEval() {
+     24        debugger;
+
+RESUMED
+
+-- Running test case: Debugger.stepNext.eval
+PAUSED (debugger-statement)
+PAUSE AT testEval:25:5
+     21    }
+     22    
+     23    function testEval() {
+ ->  24        |debugger;
+     25        let before = 1;
+     26        eval("1 + 1");
+     27        let after = 2;
+
+PAUSE AT testEval:26:5
+     22    
+     23    function testEval() {
+     24        debugger;
+ ->  25        |let before = 1;
+     26        eval("1 + 1");
+     27        let after = 2;
+     28    }
+
+PAUSE AT testEval:27:5
+     23    function testEval() {
+     24        debugger;
+     25        let before = 1;
+ ->  26        |eval("1 + 1");
+     27        let after = 2;
+     28    }
+     29    
+
+PAUSE AT testEval:28:5
+     24        debugger;
+     25        let before = 1;
+     26        eval("1 + 1");
+ ->  27        |let after = 2;
+     28    }
+     29    
+     30    function testInnerFunction() {
+
+PAUSE AT testEval:29:2
+     25        let before = 1;
+     26        eval("1 + 1");
+     27        let after = 2;
+ ->  28    }|
+     29    
+     30    function testInnerFunction() {
+     31        (function() {
+
+RESUMED
+
+-- Running test case: Debugger.stepNext.innerFunction
+PAUSED (debugger-statement)
+PAUSE AT <anonymous>:33:9
+     29    
+     30    function testInnerFunction() {
+     31        (function() {
+ ->  32            |debugger;
+     33            let inner = 1;
+     34        })();
+     35        let outer = 2;
+
+PAUSE AT <anonymous>:34:9
+     30    function testInnerFunction() {
+     31        (function() {
+     32            debugger;
+ ->  33            |let inner = 1;
+     34        })();
+     35        let outer = 2;
+     36    }
+
+PAUSE AT <anonymous>:35:6
+     31        (function() {
+     32            debugger;
+     33            let inner = 1;
+ ->  34        }|)();
+     35        let outer = 2;
+     36    }
+     37    
+
+PAUSE AT testInnerFunction:36:5
+     32            debugger;
+     33            let inner = 1;
+     34        })();
+ ->  35        |let outer = 2;
+     36    }
+     37    
+     38    function testCommas() {
+
+PAUSE AT testInnerFunction:37:2
+     33            let inner = 1;
+     34        })();
+     35        let outer = 2;
+ ->  36    }|
+     37    
+     38    function testCommas() {
+     39        debugger;
+
+RESUMED
+
+-- Running test case: Debugger.stepNext.commas
+PAUSED (debugger-statement)
+PAUSE AT testCommas:40:5
+     36    }
+     37    
+     38    function testCommas() {
+ ->  39        |debugger;
+     40        let x = 1,
+     41            y = 2,
+     42            z = 3;
+
+PAUSE AT testCommas:41:5
+     37    
+     38    function testCommas() {
+     39        debugger;
+ ->  40        |let x = 1,
+     41            y = 2,
+     42            z = 3;
+     43        a(), b(), c();
+
+PAUSE AT testCommas:42:9
+     38    function testCommas() {
+     39        debugger;
+     40        let x = 1,
+ ->  41            |y = 2,
+     42            z = 3;
+     43        a(), b(), c();
+     44        true && (a(), b(), c());
+
+PAUSE AT testCommas:43:9
+     39        debugger;
+     40        let x = 1,
+     41            y = 2,
+ ->  42            |z = 3;
+     43        a(), b(), c();
+     44        true && (a(), b(), c());
+     45    }
+
+PAUSE AT testCommas:44:5
+     40        let x = 1,
+     41            y = 2,
+     42            z = 3;
+ ->  43        |a(), b(), c();
+     44        true && (a(), b(), c());
+     45    }
+     46    
+
+PAUSE AT testCommas:44:10
+     40        let x = 1,
+     41            y = 2,
+     42            z = 3;
+ ->  43        a(), |b(), c();
+     44        true && (a(), b(), c());
+     45    }
+     46    
+
+PAUSE AT testCommas:44:15
+     40        let x = 1,
+     41            y = 2,
+     42            z = 3;
+ ->  43        a(), b(), |c();
+     44        true && (a(), b(), c());
+     45    }
+     46    
+
+PAUSE AT testCommas:45:5
+     41            y = 2,
+     42            z = 3;
+     43        a(), b(), c();
+ ->  44        |true && (a(), b(), c());
+     45    }
+     46    
+     47    function testChainedExpressions() {
+
+PAUSE AT testCommas:45:14
+     41            y = 2,
+     42            z = 3;
+     43        a(), b(), c();
+ ->  44        true && (|a(), b(), c());
+     45    }
+     46    
+     47    function testChainedExpressions() {
+
+PAUSE AT testCommas:45:19
+     41            y = 2,
+     42            z = 3;
+     43        a(), b(), c();
+ ->  44        true && (a(), |b(), c());
+     45    }
+     46    
+     47    function testChainedExpressions() {
+
+PAUSE AT testCommas:45:24
+     41            y = 2,
+     42            z = 3;
+     43        a(), b(), c();
+ ->  44        true && (a(), b(), |c());
+     45    }
+     46    
+     47    function testChainedExpressions() {
+
+PAUSE AT testCommas:46:2
+     42            z = 3;
+     43        a(), b(), c();
+     44        true && (a(), b(), c());
+ ->  45    }|
+     46    
+     47    function testChainedExpressions() {
+     48        debugger;
+
+RESUMED
+
+-- Running test case: Debugger.stepNext.chainedExpressions
+PAUSED (debugger-statement)
+PAUSE AT testChainedExpressions:49:5
+     45    }
+     46    
+     47    function testChainedExpressions() {
+ ->  48        |debugger;
+     49        a() && b() && c();
+     50    }
+     51    
+
+PAUSE AT testChainedExpressions:50:5
+     46    
+     47    function testChainedExpressions() {
+     48        debugger;
+ ->  49        |a() && b() && c();
+     50    }
+     51    
+     52    // ---------
+
+PAUSE AT testChainedExpressions:50:12
+     46    
+     47    function testChainedExpressions() {
+     48        debugger;
+ ->  49        a() && |b() && c();
+     50    }
+     51    
+     52    // ---------
+
+PAUSE AT testChainedExpressions:50:19
+     46    
+     47    function testChainedExpressions() {
+     48        debugger;
+ ->  49        a() && b() && |c();
+     50    }
+     51    
+     52    // ---------
+
+PAUSE AT testChainedExpressions:51:2
+     47    function testChainedExpressions() {
+     48        debugger;
+     49        a() && b() && c();
+ ->  50    }|
+     51    
+     52    // ---------
+     53    
+
+RESUMED
+

Copied: trunk/LayoutTests/inspector/debugger/stepping/stepNext.html (from rev 260112, trunk/LayoutTests/inspector/debugger/stepping/stepOver.html) (0 => 260113)


--- trunk/LayoutTests/inspector/debugger/stepping/stepNext.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/debugger/stepping/stepNext.html	2020-04-15 02:35:04 UTC (rev 260113)
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+<script>
+function a() { return "a"; }
+function b() { return "b"; }
+function c() { return "c"; }
+
+function testStatements() {
+    debugger;
+    let x = 1;
+    let y = 2;
+}
+
+function testFunctions() {
+    debugger;
+    let before = 1;
+    a();
+    let after = 2;
+}
+
+function testEval() {
+    debugger;
+    let before = 1;
+    eval("1 + 1");
+    let after = 2;
+}
+
+function testInnerFunction() {
+    (function() {
+        debugger;
+        let inner = 1;
+    })();
+    let outer = 2;
+}
+
+function testCommas() {
+    debugger;
+    let x = 1,
+        y = 2,
+        z = 3;
+    a(), b(), c();
+    true && (a(), b(), c());
+}
+
+function testChainedExpressions() {
+    debugger;
+    a() && b() && c();
+}
+
+// ---------
+
+function test()
+{
+    let suite = InspectorTest.createAsyncSuite("Debugger.stepNext");
+
+    // Always step-next when call frames change.
+    WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.CallFramesDidChange, (event) => {
+        if (!WI.debuggerManager.activeCallFrame)
+            return;
+        logPauseLocation();
+        WI.debuggerManager.stepNext();
+    });
+
+    function addTestCase({name, description, _expression_}) {
+        suite.addTestCase({
+            name, description,
+            test(resolve, reject) {
+                InspectorTest.evaluateInPage(_expression_);
+                WI.debuggerManager.singleFireEventListener(WI.DebuggerManager.Event.Paused, (event) => {
+                    InspectorTest.log(`PAUSED (${WI.debuggerManager.dataForTarget(WI.debuggerManager.activeCallFrame.target).pauseReason})`);
+                });
+                WI.debuggerManager.singleFireEventListener(WI.DebuggerManager.Event.Resumed, (event) => {
+                    InspectorTest.log("RESUMED");
+                    resolve();
+                });
+            }
+        });
+    }
+
+    addTestCase({
+        name: "Debugger.stepNext.statements",
+        description: "step-next should step over statements.",
+        _expression_: "setTimeout(testStatements)",
+    });
+
+    addTestCase({
+        name: "Debugger.stepNext.function",
+        description: "step-next should step over function calls.",
+        _expression_: "setTimeout(testFunctions)",
+    });
+
+    addTestCase({
+        name: "Debugger.stepNext.eval",
+        description: "step-next should step over an eval program.",
+        _expression_: "setTimeout(testEval)",
+    });
+
+    addTestCase({
+        name: "Debugger.stepNext.innerFunction",
+        description: "step-next should step out of a function to its caller.",
+        _expression_: "setTimeout(testInnerFunction)",
+    });
+
+    addTestCase({
+        name: "Debugger.stepNext.commas",
+        description: "step-next should step to each sub-_expression_ within comma expressions.",
+        _expression_: "setTimeout(testCommas)",
+    });
+
+    addTestCase({
+        name: "Debugger.stepNext.chainedExpressions",
+        description: "step-next should step to each sub-_expression_ within chained expressions.",
+        _expression_: "setTimeout(testChainedExpressions)",
+    });
+
+    loadMainPageContent().then(() => {
+        suite.runTestCasesAndFinish();
+    });
+}
+</script>
+</head>
+<body _onload_="runTest()">
+<p>Checking pause locations when stepping with "stepNext".</p>
+</body>
+</html>

Modified: trunk/LayoutTests/inspector/debugger/stepping/stepOut-expected.txt (260112 => 260113)


--- trunk/LayoutTests/inspector/debugger/stepping/stepOut-expected.txt	2020-04-15 01:24:30 UTC (rev 260112)
+++ trunk/LayoutTests/inspector/debugger/stepping/stepOut-expected.txt	2020-04-15 02:35:04 UTC (rev 260113)
@@ -4,14 +4,14 @@
 == Running test suite: Debugger.stepOut
 -- Running test case: Debugger.stepOut.function
 PAUSED (debugger-statement)
-PAUSE AT entry1:8:5
-      4    <script src=""
-      5    <script>
-      6    function entry1() {
- ->   7        |debugger;
-      8        let x = 1;
-      9        let y = 2;
-     10    }
+PAUSE AT testFunctions:12:5
+      8    function c() { return "c"; }
+      9    
+     10    function testFunctions() {
+ ->  11        |debugger;
+     12        let x = 1;
+     13        let y = 2;
+     14    }
 
 RESUMED
 
@@ -24,54 +24,80 @@
 
 -- Running test case: Debugger.stepOut.innerFunction
 PAUSED (debugger-statement)
-PAUSE AT beta:24:9
-     20            beta();
-     21        }
-     22        function beta() {
- ->  23            |debugger;
-     24        }
-     25        alpha();
-     26    }
+PAUSE AT beta:28:9
+     24            beta();
+     25        }
+     26        function beta() {
+ ->  27            |debugger;
+     28        }
+     29        alpha();
+     30    }
 
-PAUSE AT alpha:22:6
-     18    function entry3() {
-     19        function alpha() {
-     20            beta();
- ->  21        }|
-     22        function beta() {
-     23            debugger;
-     24        }
+PAUSE AT alpha:26:6
+     22    function testInnerFunction() {
+     23        function alpha() {
+     24            beta();
+ ->  25        }|
+     26        function beta() {
+     27            debugger;
+     28        }
 
-PAUSE AT entry3:27:2
-     23            debugger;
-     24        }
-     25        alpha();
- ->  26    }|
-     27    
-     28    function entry4() {
-     29        (function() {
+PAUSE AT testInnerFunction:31:2
+     27            debugger;
+     28        }
+     29        alpha();
+ ->  30    }|
+     31    
+     32    function testAnonymousFunction() {
+     33        (function() {
 
 RESUMED
 
 -- Running test case: Debugger.stepOut.anonymousFunction
 PAUSED (debugger-statement)
-PAUSE AT <anonymous>:31:9
-     27    
-     28    function entry4() {
-     29        (function() {
- ->  30            |debugger;
-     31            let inner = 1;
-     32        })();
-     33        let outer = 2;
+PAUSE AT <anonymous>:35:9
+     31    
+     32    function testAnonymousFunction() {
+     33        (function() {
+ ->  34            |debugger;
+     35            let inner = 1;
+     36        })();
+     37        let outer = 2;
 
-PAUSE AT entry4:34:5
-     30            debugger;
-     31            let inner = 1;
-     32        })();
- ->  33        |let outer = 2;
-     34    }
-     35    
-     36    // ---------
+PAUSE AT testAnonymousFunction:38:5
+     34            debugger;
+     35            let inner = 1;
+     36        })();
+ ->  37        |let outer = 2;
+     38    }
+     39    
+     40    function testCommas() {
 
 RESUMED
 
+-- Running test case: Debugger.stepOut.commas
+PAUSED (debugger-statement)
+PAUSE AT testCommas:42:5
+     38    }
+     39    
+     40    function testCommas() {
+ ->  41        |debugger;
+     42        let x = 1,
+     43            y = 2,
+     44            z = 3;
+
+RESUMED
+
+-- Running test case: Debugger.stepOut.chainedExpressions
+PAUSED (debugger-statement)
+PAUSE AT testChainedExpressions:51:5
+     47    }
+     48    
+     49    function testChainedExpressions() {
+ ->  50        |debugger;
+     51        a() && b() && c();
+     52    }
+     53    
+
+RESUMED
+

Modified: trunk/LayoutTests/inspector/debugger/stepping/stepOut.html (260112 => 260113)


--- trunk/LayoutTests/inspector/debugger/stepping/stepOut.html	2020-04-15 01:24:30 UTC (rev 260112)
+++ trunk/LayoutTests/inspector/debugger/stepping/stepOut.html	2020-04-15 02:35:04 UTC (rev 260113)
@@ -4,19 +4,23 @@
 <script src=""
 <script src=""
 <script>
-function entry1() {
+function a() { return "a"; }
+function b() { return "b"; }
+function c() { return "c"; }
+
+function testFunctions() {
     debugger;
     let x = 1;
     let y = 2;
 }
 
-function entry2() {
+function testEval() {
     let before = 1;
     eval("debugger");
     let after = 2;
 }
 
-function entry3() {
+function testInnerFunction() {
     function alpha() {
         beta();
     }
@@ -26,7 +30,7 @@
     alpha();
 }
 
-function entry4() {
+function testAnonymousFunction() {
     (function() {
         debugger;
         let inner = 1;
@@ -34,6 +38,20 @@
     let outer = 2;
 }
 
+function testCommas() {
+    debugger;
+    let x = 1,
+        y = 2,
+        z = 3;
+    a(), b(), c();
+    true && (a(), b(), c());
+}
+
+function testChainedExpressions() {
+    debugger;
+    a() && b() && c();
+}
+
 // ---------
 
 function test()
@@ -67,27 +85,39 @@
     addTestCase({
         name: "Debugger.stepOut.function",
         description: "step-out should leave a function.",
-        _expression_: "setTimeout(entry1)",
+        _expression_: "setTimeout(testFunctions)",
     });
 
     addTestCase({
         name: "Debugger.stepOut.eval",
         description: "step-out should step leave an eval program.",
-        _expression_: "setTimeout(entry2)",
+        _expression_: "setTimeout(testEval)",
     });
 
     addTestCase({
         name: "Debugger.stepOut.innerFunction",
         description: "step-out should leave a function and end up after its callsite.",
-        _expression_: "setTimeout(entry3)",
+        _expression_: "setTimeout(testInnerFunction)",
     });
 
     addTestCase({
         name: "Debugger.stepOut.anonymousFunction",
         description: "step-out should leave an anonymous function and end up after its callsite.",
-        _expression_: "setTimeout(entry4)",
+        _expression_: "setTimeout(testAnonymousFunction)",
     });
 
+    addTestCase({
+        name: "Debugger.stepOut.commas",
+        description: "step-out should not enter any comma separated function calls.",
+        _expression_: "setTimeout(testCommas)",
+    });
+
+    addTestCase({
+        name: "Debugger.stepOut.chainedExpressions",
+        description: "step-out should not enter any function calls in a chained _expression_.",
+        _expression_: "setTimeout(testChainedExpressions)",
+    });
+
     loadMainPageContent().then(() => {
         suite.runTestCasesAndFinish();
     });

Modified: trunk/LayoutTests/inspector/debugger/stepping/stepOver-expected.txt (260112 => 260113)


--- trunk/LayoutTests/inspector/debugger/stepping/stepOver-expected.txt	2020-04-15 01:24:30 UTC (rev 260112)
+++ trunk/LayoutTests/inspector/debugger/stepping/stepOver-expected.txt	2020-04-15 02:35:04 UTC (rev 260113)
@@ -5,7 +5,7 @@
 -- Running test case: Debugger.stepOver.statements
 PAUSED (debugger-statement)
 PAUSE AT testStatements:12:5
-      8    }
+      8    function c() { return "c"; }
       9    
      10    function testStatements() {
  ->  11        |debugger;
@@ -127,7 +127,7 @@
  ->  27        |let after = 2;
      28    }
      29    
-     30    function testLocalFunction() {
+     30    function testInnerFunction() {
 
 PAUSE AT testEval:29:2
      25        let before = 1;
@@ -135,7 +135,7 @@
      27        let after = 2;
  ->  28    }|
      29    
-     30    function testLocalFunction() {
+     30    function testInnerFunction() {
      31        (function() {
 
 RESUMED
@@ -144,7 +144,7 @@
 PAUSED (debugger-statement)
 PAUSE AT <anonymous>:33:9
      29    
-     30    function testLocalFunction() {
+     30    function testInnerFunction() {
      31        (function() {
  ->  32            |debugger;
      33            let inner = 1;
@@ -152,7 +152,7 @@
      35        let outer = 2;
 
 PAUSE AT <anonymous>:34:9
-     30    function testLocalFunction() {
+     30    function testInnerFunction() {
      31        (function() {
      32            debugger;
  ->  33            |let inner = 1;
@@ -169,7 +169,7 @@
      36    }
      37    
 
-PAUSE AT testLocalFunction:36:5
+PAUSE AT testInnerFunction:36:5
      32            debugger;
      33            let inner = 1;
      34        })();
@@ -178,7 +178,7 @@
      37    
      38    function testCommas() {
 
-PAUSE AT testLocalFunction:37:2
+PAUSE AT testInnerFunction:37:2
      33            let inner = 1;
      34        })();
      35        let outer = 2;
@@ -261,7 +261,7 @@
  ->  44        |true && (a(), b(), c());
      45    }
      46    
-     47    function a() { }
+     47    function testChainedExpressions() {
 
 PAUSE AT testCommas:45:14
      41            y = 2,
@@ -270,7 +270,7 @@
  ->  44        true && (|a(), b(), c());
      45    }
      46    
-     47    function a() { }
+     47    function testChainedExpressions() {
 
 PAUSE AT testCommas:45:19
      41            y = 2,
@@ -279,7 +279,7 @@
  ->  44        true && (a(), |b(), c());
      45    }
      46    
-     47    function a() { }
+     47    function testChainedExpressions() {
 
 PAUSE AT testCommas:45:24
      41            y = 2,
@@ -288,7 +288,7 @@
  ->  44        true && (a(), b(), |c());
      45    }
      46    
-     47    function a() { }
+     47    function testChainedExpressions() {
 
 PAUSE AT testCommas:46:2
      42            z = 3;
@@ -296,8 +296,39 @@
      44        true && (a(), b(), c());
  ->  45    }|
      46    
-     47    function a() { }
-     48    function b() { }
+     47    function testChainedExpressions() {
+     48        debugger;
 
 RESUMED
 
+-- Running test case: Debugger.stepOver.chainedExpressions
+PAUSED (debugger-statement)
+PAUSE AT testChainedExpressions:49:5
+     45    }
+     46    
+     47    function testChainedExpressions() {
+ ->  48        |debugger;
+     49        a() && b() && c();
+     50    }
+     51    
+
+PAUSE AT testChainedExpressions:50:5
+     46    
+     47    function testChainedExpressions() {
+     48        debugger;
+ ->  49        |a() && b() && c();
+     50    }
+     51    
+     52    // ---------
+
+PAUSE AT testChainedExpressions:51:2
+     47    function testChainedExpressions() {
+     48        debugger;
+     49        a() && b() && c();
+ ->  50    }|
+     51    
+     52    // ---------
+     53    
+
+RESUMED
+

Modified: trunk/LayoutTests/inspector/debugger/stepping/stepOver.html (260112 => 260113)


--- trunk/LayoutTests/inspector/debugger/stepping/stepOver.html	2020-04-15 01:24:30 UTC (rev 260112)
+++ trunk/LayoutTests/inspector/debugger/stepping/stepOver.html	2020-04-15 02:35:04 UTC (rev 260113)
@@ -4,9 +4,9 @@
 <script src=""
 <script src=""
 <script>
-function testAlert(str) {
-    alert(str);
-}
+function a() { return "a"; }
+function b() { return "b"; }
+function c() { return "c"; }
 
 function testStatements() {
     debugger;
@@ -28,7 +28,7 @@
     let after = 2;
 }
 
-function testLocalFunction() {
+function testInnerFunction() {
     (function() {
         debugger;
         let inner = 1;
@@ -45,9 +45,10 @@
     true && (a(), b(), c());
 }
 
-function a() { }
-function b() { }
-function c() { }
+function testChainedExpressions() {
+    debugger;
+    a() && b() && c();
+}
 
 // ---------
 
@@ -100,7 +101,7 @@
     addTestCase({
         name: "Debugger.stepOver.innerFunction",
         description: "step-over should step out of a function to its caller.",
-        _expression_: "setTimeout(testLocalFunction)",
+        _expression_: "setTimeout(testInnerFunction)",
     });
 
     addTestCase({
@@ -109,6 +110,12 @@
         _expression_: "setTimeout(testCommas)",
     });
 
+    addTestCase({
+        name: "Debugger.stepOver.chainedExpressions",
+        description: "step-over should step over chained expressions as a single statement.",
+        _expression_: "setTimeout(testChainedExpressions)",
+    });
+
     loadMainPageContent().then(() => {
         suite.runTestCasesAndFinish();
     });

Modified: trunk/Source/_javascript_Core/ChangeLog (260112 => 260113)


--- trunk/Source/_javascript_Core/ChangeLog	2020-04-15 01:24:30 UTC (rev 260112)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-04-15 02:35:04 UTC (rev 260113)
@@ -1,3 +1,27 @@
+2020-04-14  Devin Rousso  <[email protected]>
+
+        Web Inspector: Debugger: add a Step next that steps by _expression_
+        https://bugs.webkit.org/show_bug.cgi?id=210324
+
+        Reviewed by Timothy Hatcher.
+
+        Step next is a hybrid of Step over and Step into which continues execution to the next pause
+        opportunity within the current (or ancestor) call frame. It is especially useful when trying
+        to debug minified code, such as trying to continue to `c()` in `a() && b() && c();`, where
+        Step over would continue to the next statement (i.e. after the `;`) and Step in would
+        continue to the first line inside `a()` (and would require a Step out to get back).
+
+        * inspector/protocol/Debugger.json:
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::stepNext): Added.
+
+        * debugger/Debugger.h:
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::stepNextExpression): Added.
+        (JSC::Debugger::atExpression):
+        (JSC::Debugger::clearNextPauseState):
+
 2020-04-13  Alexey Shvayka  <[email protected]>
 
         REGRESSION (r259587): bterlson/eshost throws during init in strict mode

Modified: trunk/Source/_javascript_Core/debugger/Debugger.cpp (260112 => 260113)


--- trunk/Source/_javascript_Core/debugger/Debugger.cpp	2020-04-15 01:24:30 UTC (rev 260112)
+++ trunk/Source/_javascript_Core/debugger/Debugger.cpp	2020-04-15 02:35:04 UTC (rev 260113)
@@ -609,6 +609,17 @@
     notifyDoneProcessingDebuggerEvents();
 }
 
+void Debugger::stepNextExpression()
+{
+    if (!m_isPaused)
+        return;
+
+    m_pauseOnCallFrame = m_currentCallFrame;
+    m_pauseOnStepNext = true;
+    setSteppingMode(SteppingModeEnabled);
+    notifyDoneProcessingDebuggerEvents();
+}
+
 void Debugger::stepIntoStatement()
 {
     if (!m_isPaused)
@@ -803,8 +814,8 @@
         return;
     }
 
-    // Only pause at the next _expression_ with step-in and step-out, not step-over.
-    bool shouldAttemptPause = m_pauseAtNextOpportunity || m_pauseOnStepOut;
+    // Only pause at the next _expression_ with step-in, step-next, and step-out.
+    bool shouldAttemptPause = m_pauseAtNextOpportunity || m_pauseOnStepNext || m_pauseOnStepOut;
 
     PauseReasonDeclaration reason(*this, PausedAtExpression);
     updateCallFrame(lexicalGlobalObjectForCallFrame(m_vm, callFrame), callFrame, shouldAttemptPause ? AttemptPause : NoPause);
@@ -910,6 +921,7 @@
 {
     m_pauseOnCallFrame = nullptr;
     m_pauseAtNextOpportunity = false;
+    m_pauseOnStepNext = false;
     m_pauseOnStepOut = false;
     m_afterBlackboxedScript = false;
 }

Modified: trunk/Source/_javascript_Core/debugger/Debugger.h (260112 => 260113)


--- trunk/Source/_javascript_Core/debugger/Debugger.h	2020-04-15 01:24:30 UTC (rev 260112)
+++ trunk/Source/_javascript_Core/debugger/Debugger.h	2020-04-15 02:35:04 UTC (rev 260113)
@@ -108,6 +108,7 @@
     void setPauseOnNextStatement(bool);
     void breakProgram();
     void continueProgram();
+    void stepNextExpression();
     void stepIntoStatement();
     void stepOverStatement();
     void stepOutOfFunction();
@@ -230,6 +231,7 @@
     PauseOnExceptionsState m_pauseOnExceptionsState;
     bool m_pauseOnDebuggerStatements : 1;
     bool m_pauseAtNextOpportunity : 1;
+    bool m_pauseOnStepNext : 1;
     bool m_pauseOnStepOut : 1;
     bool m_pastFirstExpressionInStatement : 1;
     bool m_isPaused : 1;

Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp (260112 => 260113)


--- trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp	2020-04-15 01:24:30 UTC (rev 260112)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp	2020-04-15 02:35:04 UTC (rev 260113)
@@ -767,6 +767,15 @@
     m_conditionToDispatchResumed = ShouldDispatchResumed::WhenContinued;
 }
 
+void InspectorDebuggerAgent::stepNext(ErrorString& errorString)
+{
+    if (!assertPaused(errorString))
+        return;
+
+    willStepAndMayBecomeIdle();
+    m_scriptDebugServer.stepNextExpression();
+}
+
 void InspectorDebuggerAgent::stepOver(ErrorString& errorString)
 {
     if (!assertPaused(errorString))

Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h (260112 => 260113)


--- trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h	2020-04-15 01:24:30 UTC (rev 260112)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h	2020-04-15 02:35:04 UTC (rev 260113)
@@ -72,6 +72,7 @@
     void removeBreakpoint(ErrorString&, const String& breakpointIdentifier) final;
     void continueUntilNextRunLoop(ErrorString&) final;
     void continueToLocation(ErrorString&, const JSON::Object& location) final;
+    void stepNext(ErrorString&) final;
     void stepOver(ErrorString&) final;
     void stepInto(ErrorString&) final;
     void stepOut(ErrorString&) final;

Modified: trunk/Source/_javascript_Core/inspector/protocol/Debugger.json (260112 => 260113)


--- trunk/Source/_javascript_Core/inspector/protocol/Debugger.json	2020-04-15 01:24:30 UTC (rev 260112)
+++ trunk/Source/_javascript_Core/inspector/protocol/Debugger.json	2020-04-15 02:35:04 UTC (rev 260113)
@@ -196,6 +196,10 @@
             ]
         },
         {
+            "name": "stepNext",
+            "description": "Steps over the _expression_. This will trigger either a Debugger.paused or Debugger.resumed event."
+        },
+        {
             "name": "stepOver",
             "description": "Steps over the statement. This will trigger either a Debugger.paused or Debugger.resumed event."
         },

Modified: trunk/Source/WebInspectorUI/ChangeLog (260112 => 260113)


--- trunk/Source/WebInspectorUI/ChangeLog	2020-04-15 01:24:30 UTC (rev 260112)
+++ trunk/Source/WebInspectorUI/ChangeLog	2020-04-15 02:35:04 UTC (rev 260113)
@@ -1,3 +1,30 @@
+2020-04-14  Devin Rousso  <[email protected]>
+
+        Web Inspector: Debugger: add a Step next that steps by _expression_
+        https://bugs.webkit.org/show_bug.cgi?id=210324
+
+        Reviewed by Timothy Hatcher.
+
+        Step next is a hybrid of Step over and Step into which continues execution to the next pause
+        opportunity within the current (or ancestor) call frame. It is especially useful when trying
+        to debug minified code, such as trying to continue to `c()` in `a() && b() && c();`, where
+        Step over would continue to the next statement (i.e. after the `;`) and Step in would
+        continue to the first line inside `a()` (and would require a Step out to get back).
+
+        * UserInterface/Controllers/DebuggerManager.js:
+        (WI.DebuggerManager.prototype.stepNext): Added.
+
+        * UserInterface/Base/Main.js:
+        (WI.contentLoaded):
+        (WI.debuggerStepNext): Added.
+        * UserInterface/Views/SourcesNavigationSidebarPanel.js:
+        (WI.SourcesNavigationSidebarPanel):
+        (WI.SourcesNavigationSidebarPanel.prototype._handleDebuggerPaused):
+        (WI.SourcesNavigationSidebarPanel.prototype._handleDebuggerResumed):
+
+        * Localizations/en.lproj/localizedStrings.js:
+        * UserInterface/Images/StepNext.svg: Added.
+
 2020-04-14  Nikita Vasilyev  <[email protected]>
 
         Web Inspector: Don't show tooltips for tabs

Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (260112 => 260113)


--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2020-04-15 01:24:30 UTC (rev 260112)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2020-04-15 02:35:04 UTC (rev 260113)
@@ -1179,6 +1179,7 @@
 localizedStrings["Statistics"] = "Statistics";
 localizedStrings["Status"] = "Status";
 localizedStrings["Step"] = "Step";
+localizedStrings["Step (%s or %s)"] = "Step (%s or %s)";
 localizedStrings["Step into (%s or %s)"] = "Step into (%s or %s)";
 localizedStrings["Step out (%s or %s)"] = "Step out (%s or %s)";
 localizedStrings["Step over (%s or %s)"] = "Step over (%s or %s)";

Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Main.js (260112 => 260113)


--- trunk/Source/WebInspectorUI/UserInterface/Base/Main.js	2020-04-15 01:24:30 UTC (rev 260112)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Main.js	2020-04-15 02:35:04 UTC (rev 260113)
@@ -362,6 +362,12 @@
     WI.stepIntoAlternateKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, WI.KeyboardShortcut.Key.Semicolon, WI.debuggerStepInto);
     WI.stepOutAlternateKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.Shift | WI.KeyboardShortcut.Modifier.CommandOrControl, WI.KeyboardShortcut.Key.Semicolon, WI.debuggerStepOut);
 
+    // COMPATIBILITY (iOS 13.4): Debugger.stepNext did not exist yet.
+    if (InspectorBackend.hasCommand("Debugger.stepNext")) {
+        WI.stepNextKeyboardShortcut = new WI.KeyboardShortcut(null, WI.KeyboardShortcut.Key.F9, WI.debuggerStepNext);
+        WI.stepNextAlternateKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.Shift | WI.KeyboardShortcut.Modifier.CommandOrControl, WI.KeyboardShortcut.Key.SingleQuote, WI.debuggerStepNext);
+    }
+
     WI.settingsKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, WI.KeyboardShortcut.Key.Comma, WI._handleSettingsKeyboardShortcut);
 
     WI._togglePreviousDockConfigurationKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Shift, "D", WI._togglePreviousDockConfiguration);
@@ -1525,6 +1531,11 @@
         WI.debuggerManager.pause();
 };
 
+WI.debuggerStepNext = function(event)
+{
+    WI.debuggerManager.stepNext();
+};
+
 WI.debuggerStepOver = function(event)
 {
     WI.debuggerManager.stepOver();

Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js (260112 => 260113)


--- trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js	2020-04-15 01:24:30 UTC (rev 260112)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js	2020-04-15 02:35:04 UTC (rev 260113)
@@ -568,6 +568,27 @@
         return Promise.all([managerResult, ...promises]);
     }
 
+    stepNext()
+    {
+        if (!this.paused)
+            return Promise.reject(new Error("Cannot step next because debugger is not paused."));
+
+        let listener = new WI.EventListener(this, true);
+
+        let managerResult = new Promise(function(resolve, reject) {
+            listener.connect(WI.debuggerManager, WI.DebuggerManager.Event.ActiveCallFrameDidChange, resolve);
+        });
+
+        let protocolResult = this._activeCallFrame.target.DebuggerAgent.stepNext()
+            .catch(function(error) {
+                listener.disconnect();
+                console.error("DebuggerManager.stepNext failed: ", error);
+                throw error;
+            });
+
+        return Promise.all([managerResult, protocolResult]);
+    }
+
     stepOver()
     {
         if (!this.paused)

Added: trunk/Source/WebInspectorUI/UserInterface/Images/StepNext.svg (0 => 260113)


--- trunk/Source/WebInspectorUI/UserInterface/Images/StepNext.svg	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Images/StepNext.svg	2020-04-15 02:35:04 UTC (rev 260113)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2020 Apple Inc. All rights reserved. -->
+<svg xmlns="http://www.w3.org/2000/svg" id="root" version="1.1" viewBox="0 0 15 15">
+    <rect fill="none" stroke="currentColor" x="3.5" y="10.5" width="8" height="2"/>
+    <path fill="none" stroke="currentColor" d="M 2 5 L 13 5"/>
+    <path fill="none" stroke="currentColor" d="M 10 2 L 13 5 L 10 8"/>
+</svg>

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js (260112 => 260113)


--- trunk/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js	2020-04-15 01:24:30 UTC (rev 260112)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js	2020-04-15 02:35:04 UTC (rev 260113)
@@ -106,6 +106,17 @@
         this._debuggerStepOutButtonItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI.debuggerStepOut, this);
         this._debuggerStepOutButtonItem.enabled = false;
 
+        // COMPATIBILITY (iOS 13.4): Debugger.stepNext did not exist yet.
+        if (InspectorBackend.hasCommand("Debugger.stepNext")) {
+            this._debuggerStepNextButtonItem = createButtonNavigationitem({
+                identifier: "debugger-step-next",
+                toolTipOrLabel: WI.UIString("Step (%s or %s)").format(WI.stepNextKeyboardShortcut.displayName, WI.stepNextAlternateKeyboardShortcut.displayName),
+                image: "Images/StepNext.svg",
+            });
+            this._debuggerStepNextButtonItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI.debuggerStepNext, this);
+            this._debuggerStepNextButtonItem.enabled = false;
+        }
+
         this._timelineRecordingWarningElement = null;
         this._auditTestWarningElement = null;
         this._breakpointsDisabledWarningElement = null;
@@ -2345,6 +2356,8 @@
         this._debuggerStepOverButtonItem.enabled = true;
         this._debuggerStepIntoButtonItem.enabled = true;
         this._debuggerStepOutButtonItem.enabled = true;
+        if (this._debuggerStepNextButtonItem)
+            this._debuggerStepNextButtonItem.enabled = true;
 
         this.element.classList.add("paused");
     }
@@ -2360,6 +2373,8 @@
         this._debuggerStepOverButtonItem.enabled = false;
         this._debuggerStepIntoButtonItem.enabled = false;
         this._debuggerStepOutButtonItem.enabled = false;
+        if (this._debuggerStepNextButtonItem)
+            this._debuggerStepNextButtonItem.enabled = false;
 
         this.element.classList.remove("paused");
     }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to