Browse Source

Make it possible to evaluate an expression in a non-top call frame

Fix github #167.

* indium-client.el (indium-client-evaluate): Add a FRAME parameter to
  specify which context to evaluate an expression in.
* indium-debugger.el (indium-debugger-evaluate): Add an optional FRAME
  parameter that is the current frame by default.
* indium-interaction.el (indium-eval): Use the current debugger frame
  to evaluate the passed expression.
* indium-repl.el (indium-repl-inspect): (indium-repl-evaluate): Use
  the current debugger frame to inspect and evaluate expressions.
* server/README.md: Describe the frameId parameter that the server now
  accepts for evaluation.
* server/adapters/cdp/index.js (evaluate): Accept an optional frameId
  parameter.
* server/server/runtime.js (evaluate): Accept an optional frameId
  parameter.
run-to-here
Damien Cassou 2 years ago
committed by Nicolas Petton
parent
commit
5ef09dfe96
7 changed files with 40 additions and 30 deletions
  1. +4
    -3
      indium-client.el
  2. +13
    -11
      indium-debugger.el
  3. +4
    -2
      indium-interaction.el
  4. +5
    -3
      indium-repl.el
  5. +10
    -7
      server/README.md
  6. +2
    -2
      server/adapters/cdp/index.js
  7. +2
    -2
      server/server/runtime.js

+ 4
- 3
indium-client.el View File

@ -159,14 +159,15 @@ Once the client is connected, run the hook `indium-client-connected-hook'."
(lambda (&rest _)
(run-hooks 'indium-client-connected-hook))))
(defun indium-client-evaluate (expression &optional callback)
"Evaluate EXPRESSION.
(defun indium-client-evaluate (expression &optional frame callback)
"Evaluate EXPRESSION in the context of FRAME.
When non-nil, evaluate CALLBACK with the result."
(indium-client-send
`((type . "runtime")
(payload . ((action . "evaluate")
(expression . ,expression))))
(expression . ,expression)
(frameId . ,(when frame (indium-frame-id frame))))))
(lambda (obj)
(when callback
(funcall callback (indium-remote-object-from-alist obj))))))


+ 13
- 11
indium-debugger.el View File

@ -334,9 +334,9 @@ If there is no debugging session, signal an error."
(user-error "No debugger to switch to"))
(indium-debugger-select-frame indium-debugger-current-frame))
(defun indium-debugger-evaluate (expression)
"Prompt for EXPRESSION to be evaluated.
Evaluation happens in the context of the current call frame.
(defun indium-debugger-evaluate (expression &optional frame)
"Prompt for EXPRESSION to be evaluated in the context of FRAME.
When called interactively, FRAME is the current frame.
When called with a prefix argument, or when
`indium-debugger-inspect-when-eval' is non-nil, inspect the
@ -346,15 +346,17 @@ result of the evaluation if possible."
(buffer-substring-no-properties (mark) (point))
(thing-at-point 'symbol))))
(read-string (format "Evaluate on frame: (%s): " default)
nil nil default))))
nil nil default))
indium-debugger-current-frame))
(indium-client-evaluate expression
(lambda (value)
(let ((inspect (and (or indium-debugger-inspect-when-eval
current-prefix-arg)
(map-elt value 'objectid))))
(if inspect
(indium-inspector-inspect value)
(message "%s" (indium-render-remote-object-to-string value)))))))
frame
(lambda (value)
(let ((inspect (and (or indium-debugger-inspect-when-eval
current-prefix-arg)
(map-elt value 'objectid))))
(if inspect
(indium-inspector-inspect value)
(message "%s" (indium-render-remote-object-to-string value)))))))
;; Debugging context


+ 4
- 2
indium-interaction.el View File

@ -115,9 +115,11 @@ active connection."
When CALLBACK is non-nil, evaluate CALLBACK with the result.
When called interactively, prompt the user for the string to be
evaluated."
evaluated.
Evaluation happens in the context of the current debugger frame if any."
(interactive "sEvaluate JavaScript: ")
(indium-client-evaluate string callback))
(indium-client-evaluate string indium-debugger-current-frame callback))
(defun indium-eval-buffer ()
"Evaluate the accessible portion of current buffer."


+ 5
- 3
indium-repl.el View File

@ -27,6 +27,7 @@
(require 'indium-render)
(require 'indium-faces)
(require 'indium-client)
(require 'indium-debugger)
(require 'company)
(require 'easymenu)
@ -166,8 +167,9 @@ connected to the process.
"Inspect the result of the evaluation of the input at point."
(interactive)
(indium-client-evaluate (indium-repl--input-content)
(lambda (result)
(indium-inspector-inspect result))))
indium-debugger-current-frame
(lambda (result)
(indium-inspector-inspect result))))
(defun indium-repl--input-content ()
"Return the content of the current input."
@ -180,7 +182,7 @@ connected to the process.
(defun indium-repl-evaluate (string)
"Evaluate STRING in the browser tab and emit the output."
(push string indium-repl-history)
(indium-client-evaluate string #'indium-repl-emit-value)
(indium-client-evaluate string indium-debugger-current-frame #'indium-repl-emit-value)
;; move the output markers so that output is put after the current prompt
(save-excursion
(goto-char (point-max))


+ 10
- 7
server/README.md View File

@ -136,16 +136,19 @@ inspection and debugging is done through runtime requests.
#### evaluate
Evaluation is context-sensitive. During a debugging session when the runtime is
paused, evaluation is done in the context of the current stack frame, with full
access to all locals.
Evaluate an expression and send the result back. If `frameId` is in
the payload, evaluation occurs within the context of the associated
call frame. If `frameId` is not provided but there is an active
debugging session, the expression is evaluated within the context of
the top frame.
*Request payload:*
| Key | Type or value | Description |
|:-----------|:--------------|:-----------------------|
| action | `"evaluate"` | Action type |
| expression | `<string>` | Expression to evaluate |
| Key | Type or value | Description |
|:-----------|:------------------------|:-----------------------|
| action | `"evaluate"` | Action type |
| expression | `<string>` | Expression to evaluate |
| frameId | `<string>` *(optional)* | Call frame id |
*Successful response payload:*


+ 2
- 2
server/adapters/cdp/index.js View File

@ -71,7 +71,7 @@ const disconnect = async () => {
}
};
const evaluate = async expression => {
const evaluate = async ({expression, frameId}) => {
ensureConnected();
let method = state.currentCallFrameId
? state.client.Debugger.evaluateOnCallFrame
@ -79,7 +79,7 @@ const evaluate = async expression => {
let response = await method({
generatePreview: true,
expression,
callFrameId: state.currentCallFrameId
callFrameId: frameId || state.currentCallFrameId
});
return convertRemoteObject(response.result);


+ 2
- 2
server/server/runtime.js View File

@ -37,13 +37,13 @@ const runtime = (data = {}, { success, error, stop }) => {
}
};
const evaluate = async ({ expression } = {}, { success, error }) => {
const evaluate = async ({ expression, frameId } = {}, { success, error }) => {
if (!expression) {
error("No expression to evaluate");
}
try {
let result = await adapter.evaluate(expression);
let result = await adapter.evaluate({expression, frameId});
success(result);
} catch(e) {
error(e.message);


Loading…
Cancel
Save