diff --git a/cli/tools/repl/cdp.rs b/cli/cdp.rs similarity index 86% rename from cli/tools/repl/cdp.rs rename to cli/cdp.rs index f90a1875e3..cb9933a033 100644 --- a/cli/tools/repl/cdp.rs +++ b/cli/cdp.rs @@ -424,3 +424,81 @@ pub type UnserializableValue = String; /// pub type UniqueDebuggerId = String; + +/// +#[derive(Debug, Deserialize)] +pub struct SetScriptSourceResponse { + pub status: Status, +} + +#[derive(Debug, Deserialize)] +pub enum Status { + Ok, + CompileError, + BlockedByActiveGenerator, + BlockedByActiveFunction, + BlockedByTopLevelEsModuleChange, +} + +/// +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ScriptParsed { + pub script_id: String, + pub url: String, +} + +/// +#[derive(Debug, Eq, PartialEq, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct CoverageRange { + /// Start character index. + #[serde(rename = "startOffset")] + pub start_char_offset: usize, + /// End character index. + #[serde(rename = "endOffset")] + pub end_char_offset: usize, + pub count: i64, +} + +/// +#[derive(Debug, Eq, PartialEq, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct FunctionCoverage { + pub function_name: String, + pub ranges: Vec, + pub is_block_coverage: bool, +} + +/// +#[derive(Debug, Eq, PartialEq, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct ScriptCoverage { + pub script_id: String, + pub url: String, + pub functions: Vec, +} + +/// +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct StartPreciseCoverageArgs { + pub call_count: bool, + pub detailed: bool, + pub allow_triggered_updates: bool, +} + +/// +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct StartPreciseCoverageResponse { + pub timestamp: f64, +} + +/// +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TakePreciseCoverageResponse { + pub result: Vec, + pub timestamp: f64, +} diff --git a/cli/main.rs b/cli/main.rs index 18b0fe8277..6c5a78e617 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -3,6 +3,7 @@ mod args; mod auth_tokens; mod cache; +mod cdp; mod deno_std; mod emit; mod errors; diff --git a/cli/tools/coverage/json_types.rs b/cli/tools/coverage/json_types.rs deleted file mode 100644 index d5c6591f72..0000000000 --- a/cli/tools/coverage/json_types.rs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -use serde::Deserialize; -use serde::Serialize; - -#[derive(Debug, Eq, PartialEq, Serialize, Deserialize, Clone)] -#[serde(rename_all = "camelCase")] -pub struct CoverageRange { - /// Start character index. - #[serde(rename = "startOffset")] - pub start_char_offset: usize, - /// End character index. - #[serde(rename = "endOffset")] - pub end_char_offset: usize, - pub count: i64, -} - -#[derive(Debug, Eq, PartialEq, Serialize, Deserialize, Clone)] -#[serde(rename_all = "camelCase")] -pub struct FunctionCoverage { - pub function_name: String, - pub ranges: Vec, - pub is_block_coverage: bool, -} - -#[derive(Debug, Eq, PartialEq, Serialize, Deserialize, Clone)] -#[serde(rename_all = "camelCase")] -pub struct ScriptCoverage { - pub script_id: String, - pub url: String, - pub functions: Vec, -} - -#[derive(Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct StartPreciseCoverageParameters { - pub call_count: bool, - pub detailed: bool, - pub allow_triggered_updates: bool, -} - -#[derive(Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct StartPreciseCoverageReturnObject { - pub timestamp: f64, -} - -#[derive(Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct TakePreciseCoverageReturnObject { - pub result: Vec, - pub timestamp: f64, -} - -// TODO(bartlomieju): remove me -#[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ProcessCoverage { - pub result: Vec, -} diff --git a/cli/tools/coverage/merge.rs b/cli/tools/coverage/merge.rs index c7f9b15244..a15f4b552a 100644 --- a/cli/tools/coverage/merge.rs +++ b/cli/tools/coverage/merge.rs @@ -3,24 +3,26 @@ // Forked from https://github.com/demurgos/v8-coverage/tree/d0ca18da8740198681e0bc68971b0a6cdb11db3e/rust // Copyright 2021 Charles Samborski. All rights reserved. MIT license. -use super::json_types::CoverageRange; -use super::json_types::FunctionCoverage; -use super::json_types::ProcessCoverage; -use super::json_types::ScriptCoverage; use super::range_tree::RangeTree; use super::range_tree::RangeTreeArena; +use crate::cdp; use std::collections::BTreeMap; use std::collections::BTreeSet; use std::collections::HashMap; use std::iter::Peekable; +#[derive(Eq, PartialEq, Clone, Debug)] +pub struct ProcessCoverage { + pub result: Vec, +} + pub fn merge_processes( mut processes: Vec, ) -> Option { if processes.len() <= 1 { return processes.pop(); } - let mut url_to_scripts: BTreeMap> = + let mut url_to_scripts: BTreeMap> = BTreeMap::new(); for process_cov in processes { for script_cov in process_cov.result { @@ -31,12 +33,13 @@ pub fn merge_processes( } } - let result: Vec = url_to_scripts + let result: Vec = url_to_scripts .into_iter() .enumerate() .map(|(script_id, (_, scripts))| (script_id, scripts)) .map(|(script_id, scripts)| { - let mut merged: ScriptCoverage = merge_scripts(scripts.to_vec()).unwrap(); + let mut merged: cdp::ScriptCoverage = + merge_scripts(scripts.to_vec()).unwrap(); merged.script_id = script_id.to_string(); merged }) @@ -46,21 +49,21 @@ pub fn merge_processes( } pub fn merge_scripts( - mut scripts: Vec, -) -> Option { + mut scripts: Vec, +) -> Option { if scripts.len() <= 1 { return scripts.pop(); } let (script_id, url) = { - let first: &ScriptCoverage = &scripts[0]; + let first: &cdp::ScriptCoverage = &scripts[0]; (first.script_id.clone(), first.url.clone()) }; - let mut range_to_funcs: BTreeMap> = + let mut range_to_funcs: BTreeMap> = BTreeMap::new(); for script_cov in scripts { for func_cov in script_cov.functions { let root_range = { - let root_range_cov: &CoverageRange = &func_cov.ranges[0]; + let root_range_cov: &cdp::CoverageRange = &func_cov.ranges[0]; CharRange { start: root_range_cov.start_char_offset, end: root_range_cov.end_char_offset, @@ -70,12 +73,12 @@ pub fn merge_scripts( } } - let functions: Vec = range_to_funcs + let functions: Vec = range_to_funcs .into_values() .map(|funcs| merge_functions(funcs).unwrap()) .collect(); - Some(ScriptCoverage { + Some(cdp::ScriptCoverage { script_id, url, functions, @@ -105,8 +108,8 @@ impl PartialOrd for CharRange { } pub fn merge_functions( - mut funcs: Vec, -) -> Option { + mut funcs: Vec, +) -> Option { if funcs.len() <= 1 { return funcs.pop(); } @@ -124,7 +127,7 @@ pub fn merge_functions( let ranges = merged.to_ranges(); let is_block_coverage: bool = !(ranges.len() == 1 && ranges[0].count == 0); - Some(FunctionCoverage { + Some(cdp::FunctionCoverage { function_name, ranges, is_block_coverage, @@ -439,13 +442,13 @@ mod tests { fn two_flat_trees() { let inputs: Vec = vec![ ProcessCoverage { - result: vec![ScriptCoverage { + result: vec![cdp::ScriptCoverage { script_id: String::from("0"), url: String::from("/lib.js"), - functions: vec![FunctionCoverage { + functions: vec![cdp::FunctionCoverage { function_name: String::from("lib"), is_block_coverage: true, - ranges: vec![CoverageRange { + ranges: vec![cdp::CoverageRange { start_char_offset: 0, end_char_offset: 9, count: 1, @@ -454,13 +457,13 @@ mod tests { }], }, ProcessCoverage { - result: vec![ScriptCoverage { + result: vec![cdp::ScriptCoverage { script_id: String::from("0"), url: String::from("/lib.js"), - functions: vec![FunctionCoverage { + functions: vec![cdp::FunctionCoverage { function_name: String::from("lib"), is_block_coverage: true, - ranges: vec![CoverageRange { + ranges: vec![cdp::CoverageRange { start_char_offset: 0, end_char_offset: 9, count: 2, @@ -470,13 +473,13 @@ mod tests { }, ]; let expected: Option = Some(ProcessCoverage { - result: vec![ScriptCoverage { + result: vec![cdp::ScriptCoverage { script_id: String::from("0"), url: String::from("/lib.js"), - functions: vec![FunctionCoverage { + functions: vec![cdp::FunctionCoverage { function_name: String::from("lib"), is_block_coverage: true, - ranges: vec![CoverageRange { + ranges: vec![cdp::CoverageRange { start_char_offset: 0, end_char_offset: 9, count: 3, @@ -492,19 +495,19 @@ mod tests { fn two_trees_with_matching_children() { let inputs: Vec = vec![ ProcessCoverage { - result: vec![ScriptCoverage { + result: vec![cdp::ScriptCoverage { script_id: String::from("0"), url: String::from("/lib.js"), - functions: vec![FunctionCoverage { + functions: vec![cdp::FunctionCoverage { function_name: String::from("lib"), is_block_coverage: true, ranges: vec![ - CoverageRange { + cdp::CoverageRange { start_char_offset: 0, end_char_offset: 9, count: 10, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 3, end_char_offset: 6, count: 1, @@ -514,19 +517,19 @@ mod tests { }], }, ProcessCoverage { - result: vec![ScriptCoverage { + result: vec![cdp::ScriptCoverage { script_id: String::from("0"), url: String::from("/lib.js"), - functions: vec![FunctionCoverage { + functions: vec![cdp::FunctionCoverage { function_name: String::from("lib"), is_block_coverage: true, ranges: vec![ - CoverageRange { + cdp::CoverageRange { start_char_offset: 0, end_char_offset: 9, count: 20, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 3, end_char_offset: 6, count: 2, @@ -537,19 +540,19 @@ mod tests { }, ]; let expected: Option = Some(ProcessCoverage { - result: vec![ScriptCoverage { + result: vec![cdp::ScriptCoverage { script_id: String::from("0"), url: String::from("/lib.js"), - functions: vec![FunctionCoverage { + functions: vec![cdp::FunctionCoverage { function_name: String::from("lib"), is_block_coverage: true, ranges: vec![ - CoverageRange { + cdp::CoverageRange { start_char_offset: 0, end_char_offset: 9, count: 30, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 3, end_char_offset: 6, count: 3, @@ -566,19 +569,19 @@ mod tests { fn two_trees_with_partially_overlapping_children() { let inputs: Vec = vec![ ProcessCoverage { - result: vec![ScriptCoverage { + result: vec![cdp::ScriptCoverage { script_id: String::from("0"), url: String::from("/lib.js"), - functions: vec![FunctionCoverage { + functions: vec![cdp::FunctionCoverage { function_name: String::from("lib"), is_block_coverage: true, ranges: vec![ - CoverageRange { + cdp::CoverageRange { start_char_offset: 0, end_char_offset: 9, count: 10, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 2, end_char_offset: 5, count: 1, @@ -588,19 +591,19 @@ mod tests { }], }, ProcessCoverage { - result: vec![ScriptCoverage { + result: vec![cdp::ScriptCoverage { script_id: String::from("0"), url: String::from("/lib.js"), - functions: vec![FunctionCoverage { + functions: vec![cdp::FunctionCoverage { function_name: String::from("lib"), is_block_coverage: true, ranges: vec![ - CoverageRange { + cdp::CoverageRange { start_char_offset: 0, end_char_offset: 9, count: 20, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 4, end_char_offset: 7, count: 2, @@ -611,29 +614,29 @@ mod tests { }, ]; let expected: Option = Some(ProcessCoverage { - result: vec![ScriptCoverage { + result: vec![cdp::ScriptCoverage { script_id: String::from("0"), url: String::from("/lib.js"), - functions: vec![FunctionCoverage { + functions: vec![cdp::FunctionCoverage { function_name: String::from("lib"), is_block_coverage: true, ranges: vec![ - CoverageRange { + cdp::CoverageRange { start_char_offset: 0, end_char_offset: 9, count: 30, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 2, end_char_offset: 5, count: 21, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 4, end_char_offset: 5, count: 3, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 5, end_char_offset: 7, count: 12, @@ -650,29 +653,29 @@ mod tests { fn two_trees_with_with_complementary_children_summing_to_the_same_count() { let inputs: Vec = vec![ ProcessCoverage { - result: vec![ScriptCoverage { + result: vec![cdp::ScriptCoverage { script_id: String::from("0"), url: String::from("/lib.js"), - functions: vec![FunctionCoverage { + functions: vec![cdp::FunctionCoverage { function_name: String::from("lib"), is_block_coverage: true, ranges: vec![ - CoverageRange { + cdp::CoverageRange { start_char_offset: 0, end_char_offset: 9, count: 1, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 1, end_char_offset: 8, count: 6, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 1, end_char_offset: 5, count: 5, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 5, end_char_offset: 8, count: 7, @@ -682,29 +685,29 @@ mod tests { }], }, ProcessCoverage { - result: vec![ScriptCoverage { + result: vec![cdp::ScriptCoverage { script_id: String::from("0"), url: String::from("/lib.js"), - functions: vec![FunctionCoverage { + functions: vec![cdp::FunctionCoverage { function_name: String::from("lib"), is_block_coverage: true, ranges: vec![ - CoverageRange { + cdp::CoverageRange { start_char_offset: 0, end_char_offset: 9, count: 4, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 1, end_char_offset: 8, count: 8, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 1, end_char_offset: 5, count: 9, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 5, end_char_offset: 8, count: 7, @@ -715,19 +718,19 @@ mod tests { }, ]; let expected: Option = Some(ProcessCoverage { - result: vec![ScriptCoverage { + result: vec![cdp::ScriptCoverage { script_id: String::from("0"), url: String::from("/lib.js"), - functions: vec![FunctionCoverage { + functions: vec![cdp::FunctionCoverage { function_name: String::from("lib"), is_block_coverage: true, ranges: vec![ - CoverageRange { + cdp::CoverageRange { start_char_offset: 0, end_char_offset: 9, count: 5, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 1, end_char_offset: 8, count: 14, @@ -744,19 +747,19 @@ mod tests { fn merges_a_similar_sliding_chain_a_bc() { let inputs: Vec = vec![ ProcessCoverage { - result: vec![ScriptCoverage { + result: vec![cdp::ScriptCoverage { script_id: String::from("0"), url: String::from("/lib.js"), - functions: vec![FunctionCoverage { + functions: vec![cdp::FunctionCoverage { function_name: String::from("lib"), is_block_coverage: true, ranges: vec![ - CoverageRange { + cdp::CoverageRange { start_char_offset: 0, end_char_offset: 7, count: 10, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 0, end_char_offset: 4, count: 1, @@ -766,24 +769,24 @@ mod tests { }], }, ProcessCoverage { - result: vec![ScriptCoverage { + result: vec![cdp::ScriptCoverage { script_id: String::from("0"), url: String::from("/lib.js"), - functions: vec![FunctionCoverage { + functions: vec![cdp::FunctionCoverage { function_name: String::from("lib"), is_block_coverage: true, ranges: vec![ - CoverageRange { + cdp::CoverageRange { start_char_offset: 0, end_char_offset: 7, count: 20, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 1, end_char_offset: 6, count: 11, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 2, end_char_offset: 5, count: 2, @@ -794,29 +797,29 @@ mod tests { }, ]; let expected: Option = Some(ProcessCoverage { - result: vec![ScriptCoverage { + result: vec![cdp::ScriptCoverage { script_id: String::from("0"), url: String::from("/lib.js"), - functions: vec![FunctionCoverage { + functions: vec![cdp::FunctionCoverage { function_name: String::from("lib"), is_block_coverage: true, ranges: vec![ - CoverageRange { + cdp::CoverageRange { start_char_offset: 0, end_char_offset: 7, count: 30, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 0, end_char_offset: 6, count: 21, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 1, end_char_offset: 5, count: 12, }, - CoverageRange { + cdp::CoverageRange { start_char_offset: 2, end_char_offset: 4, count: 3, diff --git a/cli/tools/coverage/mod.rs b/cli/tools/coverage/mod.rs index 67566d811a..cd4afe360a 100644 --- a/cli/tools/coverage/mod.rs +++ b/cli/tools/coverage/mod.rs @@ -3,6 +3,7 @@ use crate::args::CoverageFlags; use crate::args::FileFlags; use crate::args::Flags; +use crate::cdp; use crate::colors; use crate::factory::CliFactory; use crate::npm::CliNpmResolver; @@ -34,11 +35,9 @@ use std::path::PathBuf; use text_lines::TextLines; use uuid::Uuid; -mod json_types; mod merge; mod range_tree; - -use json_types::*; +use merge::ProcessCoverage; pub struct CoverageCollector { pub dir: PathBuf, @@ -84,8 +83,8 @@ impl CoverageCollector { async fn start_precise_coverage( &mut self, - parameters: StartPreciseCoverageParameters, - ) -> Result { + parameters: cdp::StartPreciseCoverageArgs, + ) -> Result { let return_value = self .session .post_message("Profiler.startPreciseCoverage", Some(parameters)) @@ -98,7 +97,7 @@ impl CoverageCollector { async fn take_precise_coverage( &mut self, - ) -> Result { + ) -> Result { let return_value = self .session .post_message::<()>("Profiler.takePreciseCoverage", None) @@ -113,7 +112,7 @@ impl CoverageCollector { self.enable_debugger().await?; self.enable_profiler().await?; self - .start_precise_coverage(StartPreciseCoverageParameters { + .start_precise_coverage(cdp::StartPreciseCoverageArgs { call_count: true, detailed: true, allow_triggered_updates: false, @@ -180,7 +179,7 @@ struct CoverageReport { } fn generate_coverage_report( - script_coverage: &ScriptCoverage, + script_coverage: &cdp::ScriptCoverage, script_source: String, maybe_source_map: &Option>, output: &Option, @@ -570,8 +569,8 @@ impl CoverageReporter for PrettyCoverageReporter { fn collect_coverages( files: FileFlags, -) -> Result, AnyError> { - let mut coverages: Vec = Vec::new(); +) -> Result, AnyError> { + let mut coverages: Vec = Vec::new(); let file_paths = FileCollector::new(|file_path| { file_path .extension() @@ -590,7 +589,7 @@ fn collect_coverages( for file_path in file_paths { let json = fs::read_to_string(file_path.as_path())?; - let new_coverage: ScriptCoverage = serde_json::from_str(&json)?; + let new_coverage: cdp::ScriptCoverage = serde_json::from_str(&json)?; coverages.push(new_coverage); } @@ -600,11 +599,11 @@ fn collect_coverages( } fn filter_coverages( - coverages: Vec, + coverages: Vec, include: Vec, exclude: Vec, npm_resolver: &dyn CliNpmResolver, -) -> Vec { +) -> Vec { let include: Vec = include.iter().map(|e| Regex::new(e).unwrap()).collect(); @@ -629,7 +628,7 @@ fn filter_coverages( (include.is_empty() || is_included) && !is_excluded && !is_internal }) - .collect::>() + .collect::>() } pub async fn cover_files( diff --git a/cli/tools/coverage/range_tree.rs b/cli/tools/coverage/range_tree.rs index c3bba79429..c873b2f8e0 100644 --- a/cli/tools/coverage/range_tree.rs +++ b/cli/tools/coverage/range_tree.rs @@ -3,7 +3,7 @@ // Forked from https://github.com/demurgos/v8-coverage/tree/d0ca18da8740198681e0bc68971b0a6cdb11db3e/rust // Copyright 2021 Charles Samborski. All rights reserved. MIT license. -use super::json_types::CoverageRange; +use crate::cdp; use std::iter::Peekable; use typed_arena::Arena; @@ -126,12 +126,12 @@ impl<'rt> RangeTree<'rt> { tree } - pub fn to_ranges(&self) -> Vec { - let mut ranges: Vec = Vec::new(); + pub fn to_ranges(&self) -> Vec { + let mut ranges: Vec = Vec::new(); let mut stack: Vec<(&RangeTree, i64)> = vec![(self, 0)]; while let Some((cur, parent_count)) = stack.pop() { let count: i64 = parent_count + cur.delta; - ranges.push(CoverageRange { + ranges.push(cdp::CoverageRange { start_char_offset: cur.start, end_char_offset: cur.end, count, @@ -145,7 +145,7 @@ impl<'rt> RangeTree<'rt> { pub fn from_sorted_ranges<'a>( rta: &'a RangeTreeArena<'a>, - ranges: &[CoverageRange], + ranges: &[cdp::CoverageRange], ) -> Option<&'a mut RangeTree<'a>> { Self::from_sorted_ranges_inner( rta, @@ -157,7 +157,7 @@ impl<'rt> RangeTree<'rt> { fn from_sorted_ranges_inner<'a, 'b, 'c: 'b>( rta: &'a RangeTreeArena<'a>, - ranges: &'b mut Peekable>, + ranges: &'b mut Peekable>, parent_end: usize, parent_count: i64, ) -> Option<&'a mut RangeTree<'a>> { @@ -190,7 +190,7 @@ mod tests { #[test] fn from_sorted_ranges_empty() { let rta = RangeTreeArena::new(); - let inputs: Vec = vec![CoverageRange { + let inputs: Vec = vec![cdp::CoverageRange { start_char_offset: 0, end_char_offset: 9, count: 1, diff --git a/cli/tools/jupyter/server.rs b/cli/tools/jupyter/server.rs index 6175a33e9f..7a44fab64e 100644 --- a/cli/tools/jupyter/server.rs +++ b/cli/tools/jupyter/server.rs @@ -8,8 +8,8 @@ use std::collections::HashMap; use std::rc::Rc; use std::sync::Arc; +use crate::cdp; use crate::tools::repl; -use crate::tools::repl::cdp; use deno_core::error::AnyError; use deno_core::futures; use deno_core::serde_json; @@ -382,7 +382,7 @@ impl JupyterServer { } }; - let repl::cdp::EvaluateResponse { + let cdp::EvaluateResponse { result, exception_details, } = evaluate_response.value; diff --git a/cli/tools/repl/editor.rs b/cli/tools/repl/editor.rs index 52fad4759d..0bf2da7c8f 100644 --- a/cli/tools/repl/editor.rs +++ b/cli/tools/repl/editor.rs @@ -1,5 +1,6 @@ // Copyright 2018-2023 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::BinOpToken; @@ -37,7 +38,6 @@ use std::sync::atomic::AtomicBool; use std::sync::atomic::Ordering::Relaxed; use std::sync::Arc; -use super::cdp; use super::channel::RustylineSyncMessageSender; use super::session::REPL_INTERNALS_NAME; diff --git a/cli/tools/repl/mod.rs b/cli/tools/repl/mod.rs index c25dc00c6c..3700911d62 100644 --- a/cli/tools/repl/mod.rs +++ b/cli/tools/repl/mod.rs @@ -14,7 +14,6 @@ use deno_runtime::permissions::PermissionsContainer; use rustyline::error::ReadlineError; use tokio::sync::mpsc::unbounded_channel; -pub(crate) mod cdp; mod channel; mod editor; mod session; diff --git a/cli/tools/repl/session.rs b/cli/tools/repl/session.rs index df9a63772c..b46f73d5ac 100644 --- a/cli/tools/repl/session.rs +++ b/cli/tools/repl/session.rs @@ -5,6 +5,7 @@ use std::rc::Rc; use std::sync::Arc; use crate::args::CliOptions; +use crate::cdp; use crate::colors; use crate::lsp::ReplLanguageServer; use crate::npm::CliNpmResolver; @@ -48,8 +49,6 @@ use once_cell::sync::Lazy; use regex::Match; use regex::Regex; -use super::cdp; - fn comment_source_to_position_range( comment_start: SourcePos, m: &Match, diff --git a/cli/tools/run/hmr/mod.rs b/cli/tools/run/hmr.rs similarity index 84% rename from cli/tools/run/hmr/mod.rs rename to cli/tools/run/hmr.rs index 1a57723070..fb6651fed9 100644 --- a/cli/tools/run/hmr/mod.rs +++ b/cli/tools/run/hmr.rs @@ -1,5 +1,6 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. +use crate::cdp; use crate::emit::Emitter; use crate::util::file_watcher::WatcherCommunicator; use crate::util::file_watcher::WatcherRestartMode; @@ -7,21 +8,45 @@ use deno_core::error::generic_error; use deno_core::error::AnyError; use deno_core::futures::StreamExt; use deno_core::serde_json::json; +use deno_core::serde_json::Value; use deno_core::serde_json::{self}; use deno_core::url::Url; use deno_core::LocalInspectorSession; use deno_runtime::colors; +use serde::Deserialize; use std::collections::HashMap; use std::path::PathBuf; use std::sync::Arc; use tokio::select; -mod json_types; +// TODO(bartlomieju): the same thing is used in the REPL. Deduplicate. +#[derive(Debug, Deserialize)] +pub struct RpcNotification { + pub method: String, + pub params: Value, +} -use json_types::RpcNotification; -use json_types::ScriptParsed; -use json_types::SetScriptSourceReturnObject; -use json_types::Status; +fn explain(status: &cdp::Status) -> &'static str { + match status { + cdp::Status::Ok => "OK", + cdp::Status::CompileError => "compile error", + cdp::Status::BlockedByActiveGenerator => "blocked by active generator", + cdp::Status::BlockedByActiveFunction => "blocked by active function", + cdp::Status::BlockedByTopLevelEsModuleChange => { + "blocked by top-level ES module change" + } + } +} + +fn should_retry(status: &cdp::Status) -> bool { + match status { + cdp::Status::Ok => false, + cdp::Status::CompileError => false, + cdp::Status::BlockedByActiveGenerator => true, + cdp::Status::BlockedByActiveFunction => true, + cdp::Status::BlockedByTopLevelEsModuleChange => false, + } +} /// This structure is responsible for providing Hot Module Replacement /// functionality. @@ -102,7 +127,7 @@ impl HmrRunner { &mut self, script_id: &str, source: &str, - ) -> Result { + ) -> Result { let result = self .session .post_message( @@ -115,7 +140,7 @@ impl HmrRunner { ) .await?; - Ok(serde_json::from_value::( + Ok(serde_json::from_value::( result, )?) } @@ -162,7 +187,7 @@ impl HmrRunner { let description = exception.get("description").and_then(|d| d.as_str()).unwrap_or("undefined"); break Err(generic_error(format!("{text} {description}"))); } else if notification.method == "Debugger.scriptParsed" { - let params = serde_json::from_value::(notification.params)?; + let params = serde_json::from_value::(notification.params)?; if params.url.starts_with("file://") { let file_url = Url::parse(¶ms.url).unwrap(); let file_path = file_url.to_file_path().unwrap(); @@ -217,14 +242,14 @@ impl HmrRunner { loop { let result = self.set_script_source(&id, source_code.as_str()).await?; - if matches!(result.status, Status::Ok) { + if matches!(result.status, cdp::Status::Ok) { self.dispatch_hmr_event(module_url.as_str()).await?; self.watcher_communicator.print(format!("Replaced changed module {}", module_url.as_str())); break; } - self.watcher_communicator.print(format!("Failed to reload module {}: {}.", module_url, colors::gray(result.status.explain()))); - if result.status.should_retry() && tries <= 2 { + self.watcher_communicator.print(format!("Failed to reload module {}: {}.", module_url, colors::gray(explain(&result.status)))); + if should_retry(&result.status) && tries <= 2 { tries += 1; tokio::time::sleep(std::time::Duration::from_millis(100)).await; continue; diff --git a/cli/tools/run/hmr/json_types.rs b/cli/tools/run/hmr/json_types.rs deleted file mode 100644 index 3ac80344b6..0000000000 --- a/cli/tools/run/hmr/json_types.rs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. - -// TODO(bartlomieju): this code should be factored out to `cli/cdp.rs` along -// with code in `cli/tools/repl/` and `cli/tools/coverage/`. These are all -// Chrome Devtools Protocol message types. - -use deno_core::serde_json::Value; -use serde::Deserialize; - -#[derive(Debug, Deserialize)] -pub struct RpcNotification { - pub method: String, - pub params: Value, -} - -#[derive(Debug, Deserialize)] -pub struct SetScriptSourceReturnObject { - pub status: Status, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ScriptParsed { - pub script_id: String, - pub url: String, -} - -#[derive(Debug, Deserialize)] -pub enum Status { - Ok, - CompileError, - BlockedByActiveGenerator, - BlockedByActiveFunction, - BlockedByTopLevelEsModuleChange, -} - -impl Status { - pub(crate) fn explain(&self) -> &'static str { - match self { - Status::Ok => "OK", - Status::CompileError => "compile error", - Status::BlockedByActiveGenerator => "blocked by active generator", - Status::BlockedByActiveFunction => "blocked by active function", - Status::BlockedByTopLevelEsModuleChange => { - "blocked by top-level ES module change" - } - } - } - - pub(crate) fn should_retry(&self) -> bool { - match self { - Status::Ok => false, - Status::CompileError => false, - Status::BlockedByActiveGenerator => true, - Status::BlockedByActiveFunction => true, - Status::BlockedByTopLevelEsModuleChange => false, - } - } -}