summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/cdp.rs414
-rw-r--r--cli/main.rs1
-rw-r--r--cli/tests/integration/repl_tests.rs17
-rw-r--r--cli/tools/coverage/mod.rs29
-rw-r--r--cli/tools/repl/channel.rs9
-rw-r--r--cli/tools/repl/editor.rs81
-rw-r--r--cli/tools/repl/mod.rs5
-rw-r--r--cli/tools/repl/session.rs148
-rw-r--r--core/inspector.rs4
-rw-r--r--test_util/src/pty.rs2
10 files changed, 599 insertions, 111 deletions
diff --git a/cli/cdp.rs b/cli/cdp.rs
new file mode 100644
index 000000000..55229947d
--- /dev/null
+++ b/cli/cdp.rs
@@ -0,0 +1,414 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/
+use deno_core::serde_json;
+use deno_core::serde_json::Value;
+use serde::Deserialize;
+use serde::Serialize;
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-awaitPromise
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct AwaitPromiseArgs {
+ pub promise_object_id: RemoteObjectId,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub return_by_value: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub generate_preview: Option<bool>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-awaitPromise
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct AwaitPromiseResponse {
+ pub result: RemoteObject,
+ pub exception_details: Option<ExceptionDetails>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-callFunctionOn
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct CallFunctionOnArgs {
+ pub function_declaration: String,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub object_id: Option<RemoteObjectId>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub arguments: Option<Vec<CallArgument>>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub silent: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub return_by_value: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub generate_preview: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub user_gesture: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub await_promise: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub execution_context_id: Option<ExecutionContextId>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub object_group: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub throw_on_side_effect: Option<bool>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-callFunctionOn
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct CallFunctionOnResponse {
+ pub result: RemoteObject,
+ pub exception_details: Option<ExceptionDetails>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-compileScript
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct CompileScriptArgs {
+ pub expression: String,
+ #[serde(rename = "sourceURL")]
+ pub source_url: String,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub execution_context_id: Option<ExecutionContextId>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-compileScript
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct CompileScriptResponse {
+ pub script_id: Option<ScriptId>,
+ pub exception_details: Option<ExceptionDetails>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-evaluate
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct EvaluateArgs {
+ pub expression: String,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub object_group: Option<String>,
+ #[serde(
+ rename = "includeCommandLineAPI",
+ skip_serializing_if = "Option::is_none"
+ )]
+ pub include_command_line_api: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub silent: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub context_id: Option<ExecutionContextId>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub return_by_value: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub generate_preview: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub user_gesture: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub await_promise: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub throw_on_side_effect: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub timeout: Option<TimeDelta>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub disable_breaks: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub repl_mode: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ #[serde(rename = "allowUnsafeEvalBlockedByCSP")]
+ pub allow_unsafe_eval_blocked_by_csp: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub unique_context_id: Option<String>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-evaluate
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct EvaluateResponse {
+ pub result: RemoteObject,
+ pub exception_details: Option<ExceptionDetails>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-getProperties
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct GetPropertiesArgs {
+ pub object_id: RemoteObjectId,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub own_properties: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub accessor_properties_only: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub generate_preview: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub non_indexed_properties_only: Option<bool>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-getProperties
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct GetPropertiesResponse {
+ pub result: Vec<PropertyDescriptor>,
+ pub internal_properties: Option<Vec<InternalPropertyDescriptor>>,
+ pub private_properties: Option<Vec<PrivatePropertyDescriptor>>,
+ pub exception_details: Option<ExceptionDetails>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-globalLexicalScopeNames
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct GlobalLexicalScopeNamesArgs {
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub execution_context_id: Option<ExecutionContextId>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-globalLexicalScopeNames
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct GlobalLexicalScopeNamesResponse {
+ pub names: Vec<String>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-queryObjects
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct QueryObjectsArgs {
+ pub prototype_object_id: RemoteObjectId,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub object_group: Option<String>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-queryObjects
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct QueryObjectsResponse {
+ pub objects: RemoteObject,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-releaseObject
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct ReleaseObjectArgs {
+ pub object_id: RemoteObjectId,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-releaseObjectGroup
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct ReleaseObjectGroupArgs {
+ pub object_group: String,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-runScript
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct RunScriptArgs {
+ pub script_id: ScriptId,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub execution_context_id: Option<ExecutionContextId>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub object_group: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub silent: Option<bool>,
+ #[serde(
+ rename = "includeCommandLineAPI",
+ skip_serializing_if = "Option::is_none"
+ )]
+ pub include_command_line_api: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub return_by_value: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub generate_preview: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub await_promise: Option<bool>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-runScript
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct RunScriptResponse {
+ pub result: RemoteObject,
+ pub exception_details: Option<ExceptionDetails>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-setAsyncCallStackDepth
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct SetAsyncCallStackDepthArgs {
+ pub max_depth: u64,
+}
+
+// types
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-RemoteObject
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct RemoteObject {
+ #[serde(rename = "type")]
+ pub kind: String,
+ pub subtype: Option<String>,
+ pub class_name: Option<String>,
+ pub value: Option<Value>,
+ pub unserializable_value: Option<UnserializableValue>,
+ pub description: Option<String>,
+ pub object_id: Option<RemoteObjectId>,
+ pub preview: Option<ObjectPreview>,
+ pub custom_preview: Option<CustomPreview>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-ObjectPreview
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct ObjectPreview {
+ #[serde(rename = "type")]
+ pub kind: String,
+ pub subtype: Option<String>,
+ pub description: Option<String>,
+ pub overflow: bool,
+ pub properties: Vec<PropertyPreview>,
+ pub entries: Option<Vec<EntryPreview>>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-PropertyPreview
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct PropertyPreview {
+ pub name: String,
+ #[serde(rename = "type")]
+ pub kind: String,
+ pub value: Option<String>,
+ pub value_preview: Option<ObjectPreview>,
+ pub subtype: Option<String>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-EntryPreview
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct EntryPreview {
+ pub key: Option<ObjectPreview>,
+ pub value: ObjectPreview,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-CustomPreview
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct CustomPreview {
+ pub header: String,
+ pub body_getter_id: RemoteObjectId,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-ExceptionDetails
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct ExceptionDetails {
+ pub exception_id: u64,
+ pub text: String,
+ pub line_number: u64,
+ pub column_number: u64,
+ pub script_id: Option<ScriptId>,
+ pub url: Option<String>,
+ pub stack_trace: Option<StackTrace>,
+ pub exception: Option<RemoteObject>,
+ pub execution_context_id: Option<ExecutionContextId>,
+ pub exception_meta_data: Option<serde_json::Map<String, Value>>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-StackTrace
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct StackTrace {
+ pub description: Option<String>,
+ pub call_frames: Vec<CallFrame>,
+ pub parent: Option<Box<StackTrace>>,
+ pub parent_id: Option<StackTraceId>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-CallFrame
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct CallFrame {
+ pub function_name: String,
+ pub script_id: ScriptId,
+ pub url: String,
+ pub line_number: u64,
+ pub column_number: u64,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-StackTraceId
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct StackTraceId {
+ pub id: String,
+ pub debugger_id: Option<UniqueDebuggerId>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-CallArgument
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct CallArgument {
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub value: Option<Value>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub unserializable_value: Option<UnserializableValue>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub object_id: Option<RemoteObjectId>,
+}
+
+impl From<&RemoteObject> for CallArgument {
+ fn from(obj: &RemoteObject) -> Self {
+ Self {
+ value: obj.value.clone(),
+ unserializable_value: obj.unserializable_value.clone(),
+ object_id: obj.object_id.clone(),
+ }
+ }
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-InternalPropertyDescriptor
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct PropertyDescriptor {
+ pub name: String,
+ pub value: Option<RemoteObject>,
+ pub writable: Option<bool>,
+ pub get: Option<RemoteObject>,
+ pub set: Option<RemoteObject>,
+ pub configurable: bool,
+ pub enumerable: bool,
+ pub was_thrown: Option<bool>,
+ pub is_own: Option<bool>,
+ pub symbol: Option<RemoteObject>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-InternalPropertyDescriptor
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct InternalPropertyDescriptor {
+ pub name: String,
+ pub value: Option<RemoteObject>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-PrivatePropertyDescriptor
+#[derive(Debug, Clone, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct PrivatePropertyDescriptor {
+ pub name: String,
+ pub value: Option<RemoteObject>,
+ pub get: Option<RemoteObject>,
+ pub set: Option<RemoteObject>,
+}
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-RemoteObjectId
+pub type RemoteObjectId = String;
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-ExecutionContextId
+pub type ExecutionContextId = u64;
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-ScriptId
+pub type ScriptId = String;
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-TimeDelta
+pub type TimeDelta = u64;
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-UnserializableValue
+pub type UnserializableValue = String;
+
+/// https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-UniqueDebuggerId
+pub type UniqueDebuggerId = String;
diff --git a/cli/main.rs b/cli/main.rs
index 0e9a57382..ecadf65bd 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -2,6 +2,7 @@
mod auth_tokens;
mod cache;
+mod cdp;
mod checksum;
mod compat;
mod config_file;
diff --git a/cli/tests/integration/repl_tests.rs b/cli/tests/integration/repl_tests.rs
index 68379c695..571b65fa2 100644
--- a/cli/tests/integration/repl_tests.rs
+++ b/cli/tests/integration/repl_tests.rs
@@ -123,6 +123,23 @@ fn pty_complete_primitives() {
}
#[test]
+fn pty_complete_expression() {
+ util::with_pty(&["repl"], |mut console| {
+ console.write_text("Deno.\t\t");
+ console.write_text("y");
+ console.write_line("");
+ console.write_line("close();");
+ let output = console.read_all_output();
+ assert!(output.contains("Display all"));
+ assert!(output.contains("core"));
+ assert!(output.contains("args"));
+ assert!(output.contains("exit"));
+ assert!(output.contains("symlink"));
+ assert!(output.contains("permissions"));
+ });
+}
+
+#[test]
fn pty_complete_imports() {
util::with_pty(&["repl"], |mut console| {
// single quotes
diff --git a/cli/tools/coverage/mod.rs b/cli/tools/coverage/mod.rs
index 1c14859ea..6177295a6 100644
--- a/cli/tools/coverage/mod.rs
+++ b/cli/tools/coverage/mod.rs
@@ -43,22 +43,34 @@ impl CoverageCollector {
}
async fn enable_debugger(&mut self) -> Result<(), AnyError> {
- self.session.post_message("Debugger.enable", None).await?;
+ self
+ .session
+ .post_message::<()>("Debugger.enable", None)
+ .await?;
Ok(())
}
async fn enable_profiler(&mut self) -> Result<(), AnyError> {
- self.session.post_message("Profiler.enable", None).await?;
+ self
+ .session
+ .post_message::<()>("Profiler.enable", None)
+ .await?;
Ok(())
}
async fn disable_debugger(&mut self) -> Result<(), AnyError> {
- self.session.post_message("Debugger.disable", None).await?;
+ self
+ .session
+ .post_message::<()>("Debugger.disable", None)
+ .await?;
Ok(())
}
async fn disable_profiler(&mut self) -> Result<(), AnyError> {
- self.session.post_message("Profiler.disable", None).await?;
+ self
+ .session
+ .post_message::<()>("Profiler.disable", None)
+ .await?;
Ok(())
}
@@ -66,10 +78,9 @@ impl CoverageCollector {
&mut self,
parameters: StartPreciseCoverageParameters,
) -> Result<StartPreciseCoverageReturnObject, AnyError> {
- let parameters_value = serde_json::to_value(parameters)?;
let return_value = self
.session
- .post_message("Profiler.startPreciseCoverage", Some(parameters_value))
+ .post_message("Profiler.startPreciseCoverage", Some(parameters))
.await?;
let return_object = serde_json::from_value(return_value)?;
@@ -82,7 +93,7 @@ impl CoverageCollector {
) -> Result<TakePreciseCoverageReturnObject, AnyError> {
let return_value = self
.session
- .post_message("Profiler.takePreciseCoverage", None)
+ .post_message::<()>("Profiler.takePreciseCoverage", None)
.await?;
let return_object = serde_json::from_value(return_value)?;
@@ -592,8 +603,8 @@ pub async fn cover_files(
})?
};
let file = maybe_file.ok_or_else(|| {
- anyhow!("Failed to fetch \"{}\" from cache.
- Before generating coverage report, run `deno test --coverage` to ensure consistent state.",
+ anyhow!("Failed to fetch \"{}\" from cache.
+ Before generating coverage report, run `deno test --coverage` to ensure consistent state.",
module_specifier
)
})?;
diff --git a/cli/tools/repl/channel.rs b/cli/tools/repl/channel.rs
index 7cc802905..4f2086fb5 100644
--- a/cli/tools/repl/channel.rs
+++ b/cli/tools/repl/channel.rs
@@ -2,6 +2,7 @@
use deno_core::anyhow::anyhow;
use deno_core::error::AnyError;
+use deno_core::serde_json;
use deno_core::serde_json::Value;
use std::cell::RefCell;
use tokio::sync::mpsc::channel;
@@ -55,17 +56,19 @@ pub struct RustylineSyncMessageSender {
}
impl RustylineSyncMessageSender {
- pub fn post_message(
+ pub fn post_message<T: serde::Serialize>(
&self,
method: &str,
- params: Option<Value>,
+ params: Option<T>,
) -> Result<Value, AnyError> {
if let Err(err) =
self
.message_tx
.blocking_send(RustylineSyncMessage::PostMessage {
method: method.to_string(),
- params,
+ params: params
+ .map(|params| serde_json::to_value(params))
+ .transpose()?,
})
{
Err(anyhow!("{}", err))
diff --git a/cli/tools/repl/editor.rs b/cli/tools/repl/editor.rs
index 30b9fba87..ea62bd49f 100644
--- a/cli/tools/repl/editor.rs
+++ b/cli/tools/repl/editor.rs
@@ -1,13 +1,13 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+use crate::cdp;
use crate::colors;
use deno_ast::swc::parser::error::SyntaxError;
use deno_ast::swc::parser::token::Token;
use deno_ast::swc::parser::token::Word;
use deno_core::error::AnyError;
use deno_core::parking_lot::Mutex;
-use deno_core::serde_json::json;
-use deno_core::serde_json::Value;
+use deno_core::serde_json;
use rustyline::completion::Completer;
use rustyline::error::ReadlineError;
use rustyline::highlight::Highlighter;
@@ -39,20 +39,14 @@ impl EditorHelper {
.sync_sender
.post_message(
"Runtime.globalLexicalScopeNames",
- Some(json!({
- "executionContextId": self.context_id,
- })),
+ Some(cdp::GlobalLexicalScopeNamesArgs {
+ execution_context_id: Some(self.context_id),
+ }),
)
.unwrap();
-
- evaluate_response
- .get("names")
- .unwrap()
- .as_array()
- .unwrap()
- .iter()
- .map(|n| n.as_str().unwrap().to_string())
- .collect()
+ let evaluate_response: cdp::GlobalLexicalScopeNamesResponse =
+ serde_json::from_value(evaluate_response).unwrap();
+ evaluate_response.names
}
pub fn get_expression_property_names(&self, expr: &str) -> Vec<String> {
@@ -80,12 +74,7 @@ impl EditorHelper {
}
fn get_expression_type(&self, expr: &str) -> Option<String> {
- self
- .evaluate_expression(expr)?
- .get("result")?
- .get("type")?
- .as_str()
- .map(|s| s.to_string())
+ self.evaluate_expression(expr).map(|res| res.result.kind)
}
fn get_object_expr_properties(
@@ -93,44 +82,60 @@ impl EditorHelper {
object_expr: &str,
) -> Option<Vec<String>> {
let evaluate_result = self.evaluate_expression(object_expr)?;
- let object_id = evaluate_result.get("result")?.get("objectId")?;
+ let object_id = evaluate_result.result.object_id?;
let get_properties_response = self
.sync_sender
.post_message(
"Runtime.getProperties",
- Some(json!({
- "objectId": object_id,
- })),
+ Some(cdp::GetPropertiesArgs {
+ object_id,
+ own_properties: None,
+ accessor_properties_only: None,
+ generate_preview: None,
+ non_indexed_properties_only: None,
+ }),
)
.ok()?;
-
+ let get_properties_response: cdp::GetPropertiesResponse =
+ serde_json::from_value(get_properties_response).ok()?;
Some(
get_properties_response
- .get("result")?
- .as_array()
- .unwrap()
- .iter()
- .map(|r| r.get("name").unwrap().as_str().unwrap().to_string())
+ .result
+ .into_iter()
+ .map(|prop| prop.name)
.collect(),
)
}
- fn evaluate_expression(&self, expr: &str) -> Option<Value> {
+ fn evaluate_expression(&self, expr: &str) -> Option<cdp::EvaluateResponse> {
let evaluate_response = self
.sync_sender
.post_message(
"Runtime.evaluate",
- Some(json!({
- "contextId": self.context_id,
- "expression": expr,
- "throwOnSideEffect": true,
- "timeout": 200,
- })),
+ Some(cdp::EvaluateArgs {
+ expression: expr.to_string(),
+ object_group: None,
+ include_command_line_api: None,
+ silent: None,
+ context_id: Some(self.context_id),
+ return_by_value: None,
+ generate_preview: None,
+ user_gesture: None,
+ await_promise: None,
+ throw_on_side_effect: Some(true),
+ timeout: Some(200),
+ disable_breaks: None,
+ repl_mode: None,
+ allow_unsafe_eval_blocked_by_csp: None,
+ unique_context_id: None,
+ }),
)
.ok()?;
+ let evaluate_response: cdp::EvaluateResponse =
+ serde_json::from_value(evaluate_response).ok()?;
- if evaluate_response.get("exceptionDetails").is_some() {
+ if evaluate_response.exception_details.is_some() {
None
} else {
Some(evaluate_response)
diff --git a/cli/tools/repl/mod.rs b/cli/tools/repl/mod.rs
index 0c9fdbfb0..b49c641c4 100644
--- a/cli/tools/repl/mod.rs
+++ b/cli/tools/repl/mod.rs
@@ -33,10 +33,7 @@ async fn read_line_and_poll(
}
result = message_handler.recv() => {
match result {
- Some(RustylineSyncMessage::PostMessage {
- method,
- params
- }) => {
+ Some(RustylineSyncMessage::PostMessage { method, params }) => {
let result = repl_session
.post_message_with_event_loop(&method, params)
.await;
diff --git a/cli/tools/repl/session.rs b/cli/tools/repl/session.rs
index 5d458189f..57109eb1d 100644
--- a/cli/tools/repl/session.rs
+++ b/cli/tools/repl/session.rs
@@ -1,12 +1,13 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+use crate::cdp;
use crate::colors;
use crate::lsp::ReplLanguageServer;
use deno_ast::DiagnosticsError;
use deno_ast::ImportsNotUsedAsValues;
use deno_core::error::AnyError;
use deno_core::futures::FutureExt;
-use deno_core::serde_json::json;
+use deno_core::serde_json;
use deno_core::serde_json::Value;
use deno_core::LocalInspectorSession;
use deno_runtime::worker::MainWorker;
@@ -58,7 +59,7 @@ impl std::fmt::Display for EvaluationOutput {
struct TsEvaluateResponse {
ts_code: String,
- value: Value,
+ value: cdp::EvaluateResponse,
}
pub struct ReplSession {
@@ -75,7 +76,9 @@ impl ReplSession {
worker
.with_event_loop(
- session.post_message("Runtime.enable", None).boxed_local(),
+ session
+ .post_message::<()>("Runtime.enable", None)
+ .boxed_local(),
)
.await?;
@@ -115,9 +118,8 @@ impl ReplSession {
let closed = self
.evaluate_expression("(this.closed)")
.await?
- .get("result")
- .unwrap()
- .get("value")
+ .result
+ .value
.unwrap()
.as_bool()
.unwrap();
@@ -125,10 +127,10 @@ impl ReplSession {
Ok(closed)
}
- pub async fn post_message_with_event_loop(
+ pub async fn post_message_with_event_loop<T: serde::Serialize>(
&mut self,
method: &str,
- params: Option<Value>,
+ params: Option<T>,
) -> Result<Value, AnyError> {
self
.worker
@@ -156,23 +158,24 @@ impl ReplSession {
match self.evaluate_line_with_object_wrapping(line).await {
Ok(evaluate_response) => {
- let evaluate_result = evaluate_response.value.get("result").unwrap();
- let evaluate_exception_details =
- evaluate_response.value.get("exceptionDetails");
+ let cdp::EvaluateResponse {
+ result,
+ exception_details,
+ } = evaluate_response.value;
- if evaluate_exception_details.is_some() {
- self.set_last_thrown_error(evaluate_result).await?;
+ if exception_details.is_some() {
+ self.set_last_thrown_error(&result).await?;
} else {
self
.language_server
.commit_text(&evaluate_response.ts_code)
.await;
- self.set_last_eval_result(evaluate_result).await?;
+ self.set_last_eval_result(&result).await?;
}
- let value = self.get_eval_value(evaluate_result).await?;
- Ok(match evaluate_exception_details {
+ let value = self.get_eval_value(&result).await?;
+ Ok(match exception_details {
Some(_) => EvaluationOutput::Error(format!("Uncaught {}", value)),
None => EvaluationOutput::Value(value),
})
@@ -224,7 +227,7 @@ impl ReplSession {
.as_ref()
.unwrap()
.value
- .get("exceptionDetails")
+ .exception_details
.is_some())
{
self.evaluate_ts_expression(line).await
@@ -235,66 +238,90 @@ impl ReplSession {
async fn set_last_thrown_error(
&mut self,
- error: &Value,
+ error: &cdp::RemoteObject,
) -> Result<(), AnyError> {
self.post_message_with_event_loop(
"Runtime.callFunctionOn",
- Some(json!({
- "executionContextId": self.context_id,
- "functionDeclaration": "function (object) { Deno[Deno.internal].lastThrownError = object; }",
- "arguments": [
- error,
- ],
- })),
+ Some(cdp::CallFunctionOnArgs {
+ function_declaration: "function (object) { Deno[Deno.internal].lastThrownError = object; }".to_string(),
+ object_id: None,
+ arguments: Some(vec![error.into()]),
+ silent: None,
+ return_by_value: None,
+ generate_preview: None,
+ user_gesture: None,
+ await_promise: None,
+ execution_context_id: Some(self.context_id),
+ object_group: None,
+ throw_on_side_effect: None
+ }),
).await?;
Ok(())
}
async fn set_last_eval_result(
&mut self,
- evaluate_result: &Value,
+ evaluate_result: &cdp::RemoteObject,
) -> Result<(), AnyError> {
- self.post_message_with_event_loop(
- "Runtime.callFunctionOn",
- Some(json!({
- "executionContextId": self.context_id,
- "functionDeclaration": "function (object) { Deno[Deno.internal].lastEvalResult = object; }",
- "arguments": [
- evaluate_result,
- ],
- })),
- ).await?;
+ self
+ .post_message_with_event_loop(
+ "Runtime.callFunctionOn",
+ Some(cdp::CallFunctionOnArgs {
+ function_declaration:
+ "function (object) { Deno[Deno.internal].lastEvalResult = object; }"
+ .to_string(),
+ object_id: None,
+ arguments: Some(vec![evaluate_result.into()]),
+ silent: None,
+ return_by_value: None,
+ generate_preview: None,
+ user_gesture: None,
+ await_promise: None,
+ execution_context_id: Some(self.context_id),
+ object_group: None,
+ throw_on_side_effect: None,
+ }),
+ )
+ .await?;
Ok(())
}
pub async fn get_eval_value(
&mut self,
- evaluate_result: &Value,
+ evaluate_result: &cdp::RemoteObject,
) -> Result<String, AnyError> {
// TODO(caspervonb) we should investigate using previews here but to keep things
// consistent with the previous implementation we just get the preview result from
// Deno.inspectArgs.
let inspect_response = self.post_message_with_event_loop(
"Runtime.callFunctionOn",
- Some(json!({
- "executionContextId": self.context_id,
- "functionDeclaration": r#"function (object) {
+ Some(cdp::CallFunctionOnArgs {
+ function_declaration: r#"function (object) {
try {
return Deno[Deno.internal].inspectArgs(["%o", object], { colors: !Deno.noColor });
} catch (err) {
return Deno[Deno.internal].inspectArgs(["%o", err]);
}
- }"#,
- "arguments": [
- evaluate_result,
- ],
- })),
+ }"#.to_string(),
+ object_id: None,
+ arguments: Some(vec![evaluate_result.into()]),
+ silent: None,
+ return_by_value: None,
+ generate_preview: None,
+ user_gesture: None,
+ await_promise: None,
+ execution_context_id: Some(self.context_id),
+ object_group: None,
+ throw_on_side_effect: None
+ }),
).await?;
- let inspect_result = inspect_response.get("result").unwrap();
- let value = inspect_result.get("value").unwrap().as_str().unwrap();
+ let response: cdp::CallFunctionOnResponse =
+ serde_json::from_value(inspect_response)?;
+ let value = response.result.value.unwrap();
+ let s = value.as_str().unwrap();
- Ok(value.to_string())
+ Ok(s.to_string())
}
async fn evaluate_ts_expression(
@@ -344,16 +371,29 @@ impl ReplSession {
async fn evaluate_expression(
&mut self,
expression: &str,
- ) -> Result<Value, AnyError> {
+ ) -> Result<cdp::EvaluateResponse, AnyError> {
self
.post_message_with_event_loop(
"Runtime.evaluate",
- Some(json!({
- "expression": expression,
- "contextId": self.context_id,
- "replMode": true,
- })),
+ Some(cdp::EvaluateArgs {
+ expression: expression.to_string(),
+ object_group: None,
+ include_command_line_api: None,
+ silent: None,
+ context_id: Some(self.context_id),
+ return_by_value: None,
+ generate_preview: None,
+ user_gesture: None,
+ await_promise: None,
+ throw_on_side_effect: None,
+ timeout: None,
+ disable_breaks: None,
+ repl_mode: Some(true),
+ allow_unsafe_eval_blocked_by_csp: None,
+ unique_context_id: None,
+ }),
)
.await
+ .and_then(|res| serde_json::from_value(res).map_err(|e| e.into()))
}
}
diff --git a/core/inspector.rs b/core/inspector.rs
index 97a04407d..b6c86fb79 100644
--- a/core/inspector.rs
+++ b/core/inspector.rs
@@ -649,10 +649,10 @@ impl LocalInspectorSession {
self.notification_queue.split_off(0)
}
- pub async fn post_message(
+ pub async fn post_message<T: serde::Serialize>(
&mut self,
method: &str,
- params: Option<serde_json::Value>,
+ params: Option<T>,
) -> Result<serde_json::Value, Error> {
let id = self.next_message_id;
self.next_message_id += 1;
diff --git a/test_util/src/pty.rs b/test_util/src/pty.rs
index a8298d7a5..9ca02f857 100644
--- a/test_util/src/pty.rs
+++ b/test_util/src/pty.rs
@@ -36,7 +36,7 @@ pub fn create_pty(
.unwrap()
.wait()
.unwrap();
- unreachable!();
+ std::process::exit(0);
}
}