Remove context_id from EditorHelper

This commit is contained in:
David Sherret 2022-12-14 10:43:58 -05:00
parent 302c2505bb
commit 14a8f8607c
3 changed files with 85 additions and 43 deletions

View File

@ -14,6 +14,8 @@ use tokio::sync::mpsc::UnboundedSender;
use crate::lsp::ReplCompletionItem;
use super::cdp;
/// Rustyline uses synchronous methods in its interfaces, but we need to call
/// async methods. To get around this, we communicate with async code by using
/// a channel and blocking on the result.
@ -35,6 +37,8 @@ pub fn rustyline_channel(
}
pub enum RustylineSyncMessage {
EvaluateExpression(String),
GetGlobalLexicalScopeNames,
PostMessage {
method: String,
params: Option<Value>,
@ -46,6 +50,8 @@ pub enum RustylineSyncMessage {
}
pub enum RustylineSyncResponse {
EvaluateExpression(Option<cdp::EvaluateResponse>),
GetGlobalLexicalScopeNames(Vec<String>),
PostMessage(Result<Value, AnyError>),
LspCompletions(Vec<ReplCompletionItem>),
}
@ -75,7 +81,40 @@ impl RustylineSyncMessageSender {
} else {
match self.response_rx.borrow_mut().blocking_recv().unwrap() {
RustylineSyncResponse::PostMessage(result) => result,
RustylineSyncResponse::LspCompletions(_) => unreachable!(),
_ => unreachable!(),
}
}
}
pub fn evaluate_expression(
&self,
expr: &str,
) -> Option<cdp::EvaluateResponse> {
if self
.message_tx
.blocking_send(RustylineSyncMessage::EvaluateExpression(expr.to_string()))
.is_err()
{
None
} else {
match self.response_rx.borrow_mut().blocking_recv().unwrap() {
RustylineSyncResponse::EvaluateExpression(response) => response,
_ => unreachable!(),
}
}
}
pub fn get_global_lexical_scope_names(&self) -> Vec<String> {
if self
.message_tx
.blocking_send(RustylineSyncMessage::GetGlobalLexicalScopeNames)
.is_err()
{
Vec::new()
} else {
match self.response_rx.borrow_mut().blocking_recv().unwrap() {
RustylineSyncResponse::GetGlobalLexicalScopeNames(response) => response,
_ => unreachable!(),
}
}
}
@ -97,7 +136,7 @@ impl RustylineSyncMessageSender {
} else {
match self.response_rx.borrow_mut().blocking_recv().unwrap() {
RustylineSyncResponse::LspCompletions(result) => result,
RustylineSyncResponse::PostMessage(_) => unreachable!(),
_ => unreachable!(),
}
}
}

View File

@ -38,24 +38,12 @@ use super::channel::RustylineSyncMessageSender;
// tab completion.
#[derive(Helper, Hinter)]
pub struct EditorHelper {
pub context_id: u64,
pub sync_sender: RustylineSyncMessageSender,
}
impl EditorHelper {
pub fn get_global_lexical_scope_names(&self) -> Vec<String> {
let evaluate_response = self
.sync_sender
.post_message(
"Runtime.globalLexicalScopeNames",
Some(cdp::GlobalLexicalScopeNamesArgs {
execution_context_id: Some(self.context_id),
}),
)
.unwrap();
let evaluate_response: cdp::GlobalLexicalScopeNamesResponse =
serde_json::from_value(evaluate_response).unwrap();
evaluate_response.names
self.sync_sender.get_global_lexical_scope_names()
}
pub fn get_expression_property_names(&self, expr: &str) -> Vec<String> {
@ -118,32 +106,7 @@ impl EditorHelper {
}
fn evaluate_expression(&self, expr: &str) -> Option<cdp::EvaluateResponse> {
let evaluate_response = self
.sync_sender
.post_message(
"Runtime.evaluate",
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()?;
let evaluate_response = self.sync_sender.evaluate_expression(expr)?;
if evaluate_response.exception_details.is_some() {
None
} else {

View File

@ -9,6 +9,7 @@ use deno_core::anyhow::Context;
use deno_core::error::AnyError;
use deno_core::op;
use deno_core::resolve_url_or_path;
use deno_core::serde_json;
use deno_core::Extension;
use deno_core::ModuleSpecifier;
use deno_core::OpState;
@ -57,6 +58,47 @@ async fn read_line_and_poll(
let result = repl_session.language_server.completions(&line_text, position).await;
message_handler.send(RustylineSyncResponse::LspCompletions(result)).unwrap();
}
Some(RustylineSyncMessage::EvaluateExpression(expr)) => {
let evaluate_response = repl_session
.post_message_with_event_loop(
"Runtime.evaluate",
Some(cdp::EvaluateArgs {
expression: expr.to_string(),
object_group: None,
include_command_line_api: None,
silent: None,
context_id: Some(repl_session.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,
}),
).await
.ok();
let evaluate_response: Option<cdp::EvaluateResponse> =
evaluate_response.and_then(|value| serde_json::from_value(value).ok());
message_handler.send(RustylineSyncResponse::EvaluateExpression(evaluate_response)).unwrap();
}
Some(RustylineSyncMessage::GetGlobalLexicalScopeNames) => {
let evaluate_response = repl_session
.post_message_with_event_loop(
"Runtime.globalLexicalScopeNames",
Some(cdp::GlobalLexicalScopeNamesArgs {
execution_context_id: Some(repl_session.context_id),
}),
)
.await
.unwrap();
let evaluate_response: cdp::GlobalLexicalScopeNamesResponse =
serde_json::from_value(evaluate_response).unwrap();
message_handler.send(RustylineSyncResponse::GetGlobalLexicalScopeNames(evaluate_response.names)).unwrap();
}
None => {}, // channel closed
}
@ -227,9 +269,7 @@ pub async fn run(flags: Flags, repl_flags: ReplFlags) -> Result<i32, AnyError> {
let mut rustyline_channel = rustyline_channel();
let mut should_exit_on_interrupt = false;
// TODO(bartlomieju): add helper to update `context_id` in the helper
let helper = EditorHelper {
context_id: repl_session.context_id,
sync_sender: rustyline_channel.0,
};