Skip to content

Commit

Permalink
refactor(repl): use an inspector session
Browse files Browse the repository at this point in the history
  • Loading branch information
caspervonb committed Sep 30, 2020
1 parent 2184cf5 commit 043ee12
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 343 deletions.
2 changes: 2 additions & 0 deletions cli/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ pub struct Flags {
pub no_remote: bool,
pub read_allowlist: Vec<PathBuf>,
pub reload: bool,
pub repl: bool,
pub seed: Option<u64>,
pub unstable: bool,
pub v8_flags: Option<Vec<String>>,
Expand Down Expand Up @@ -447,6 +448,7 @@ fn completions_parse(flags: &mut Flags, matches: &clap::ArgMatches) {

fn repl_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
runtime_args_parse(flags, matches, false);
flags.repl = true;
flags.subcommand = DenoSubcommand::Repl;
flags.allow_net = true;
flags.allow_env = true;
Expand Down
1 change: 1 addition & 0 deletions cli/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,7 @@ impl v8::inspector::ChannelImpl for InspectorSession {
) {
let raw_message = message.unwrap().string().to_string();
let message = serde_json::from_str(&raw_message).unwrap();

self
.response_tx_map
.remove(&call_id)
Expand Down
22 changes: 20 additions & 2 deletions cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ use crate::file_fetcher::SourceFileFetcher;
use crate::file_fetcher::TextDocument;
use crate::fs as deno_fs;
use crate::global_state::GlobalState;
use crate::inspector::InspectorSession;
use crate::media_type::MediaType;
use crate::permissions::Permissions;
use crate::worker::MainWorker;
Expand Down Expand Up @@ -428,9 +429,26 @@ async fn run_repl(flags: Flags) -> Result<(), AnyError> {
let main_module =
ModuleSpecifier::resolve_url_or_path("./$deno$repl.ts").unwrap();
let global_state = GlobalState::new(flags)?;
let mut worker = MainWorker::new(&global_state, main_module);
let mut worker = MainWorker::new(&global_state, main_module.clone());
(&mut *worker).await?;

let inspector = worker
.inspector
.as_mut()
.expect("Inspector is not created.");

let inspector_session = InspectorSession::new(&mut **inspector);
let repl = repl::run(&global_state, inspector_session);

tokio::pin!(repl);

loop {
(&mut *worker).await?;
tokio::select! {
result = &mut repl => {
return result;
}
_ = &mut *worker => {}
}
}
}

Expand Down
1 change: 0 additions & 1 deletion cli/ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ pub mod permissions;
pub mod plugin;
pub mod process;
pub mod random;
pub mod repl;
pub mod runtime;
pub mod runtime_compiler;
pub mod signal;
Expand Down
78 changes: 0 additions & 78 deletions cli/ops/repl.rs

This file was deleted.

121 changes: 63 additions & 58 deletions cli/repl.rs
Original file line number Diff line number Diff line change
@@ -1,73 +1,78 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.

use crate::deno_dir::DenoDir;
use crate::global_state::GlobalState;
use crate::inspector::InspectorSession;
use deno_core::error::AnyError;
use deno_core::serde_json::json;
use rustyline::error::ReadlineError;
use rustyline::Editor;
use std::fs;
use std::path::PathBuf;

pub struct Repl {
editor: Editor<()>,
history_file: PathBuf,
}
pub async fn run(
_global_state: &GlobalState,
mut session: Box<InspectorSession>,
) -> Result<(), AnyError> {
// Our inspector is unable to default to the default context id so we have to specify it here.
let context_id: u32 = 1;

impl Repl {
pub fn new(history_file: PathBuf) -> Self {
let mut repl = Self {
editor: Editor::<()>::new(),
history_file,
};
session
.post_message("Runtime.enable".to_string(), None)
.await?;

repl.load_history();
repl
}
let mut editor = Editor::<()>::new();

fn load_history(&mut self) {
debug!("Loading REPL history: {:?}", self.history_file);
self
.editor
.load_history(&self.history_file.to_str().unwrap())
.map_err(|e| {
debug!("Unable to load history file: {:?} {}", self.history_file, e)
})
// ignore this error (e.g. it occurs on first load)
.unwrap_or(())
}
println!("Deno {}", crate::version::DENO);
println!("exit using ctrl+d or close()");

fn save_history(&mut self) -> Result<(), AnyError> {
fs::create_dir_all(self.history_file.parent().unwrap())?;
self
.editor
.save_history(&self.history_file.to_str().unwrap())
.map(|_| debug!("Saved REPL history to: {:?}", self.history_file))
.map_err(|e| {
eprintln!("Unable to save REPL history: {:?} {}", self.history_file, e);
e.into()
})
}
loop {
let line = editor.readline("> ");
match line {
Ok(line) => {
let evaluate_response = session
.post_message(
"Runtime.evaluate".to_string(),
Some(json!({
"expression": line,
"contextId": context_id,
// Set repl mode to true to enable const redeclarations and top level await
"replMode": false,
})),
)
.await?;

pub fn readline(&mut self, prompt: &str) -> Result<String, AnyError> {
self
.editor
.readline(&prompt)
.map(|line| {
self.editor.add_history_entry(line.clone());
line
})
.map_err(AnyError::from)
let evaluate_result = evaluate_response.get("result").unwrap();

// Forward error to TS side for processing
}
}
// 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 = session.post_message("Runtime.callFunctionOn".to_string(), Some(json!({
"executionContextId": context_id,
"functionDeclaration": "function (object) { return Deno[Deno.internal].inspectArgs(['%o', object]); }",
"arguments": [
evaluate_result,
],
}))).await?;

let inspect_result = inspect_response.get("result").unwrap();
println!("{}", inspect_result.get("value").unwrap().as_str().unwrap());

impl Drop for Repl {
fn drop(&mut self) {
self.save_history().unwrap();
editor.add_history_entry(line.as_str());
}
Err(ReadlineError::Interrupted) => {
println!("ctrl-c");
break;
}
Err(ReadlineError::Eof) => {
println!("ctrl-d");
break;
}
Err(err) => {
println!("Error: {:?}", err);
break;
}
}
}
}

pub fn history_path(dir: &DenoDir, history_file: &str) -> PathBuf {
let mut p: PathBuf = dir.root.clone();
p.push(history_file);
p
// TODO(caspervonb) save history file

Ok(())
}
Loading

0 comments on commit 043ee12

Please sign in to comment.