-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(repl): use an inspector session
- Loading branch information
1 parent
2184cf5
commit 043ee12
Showing
9 changed files
with
87 additions
and
343 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(()) | ||
} |
Oops, something went wrong.