diff options
Diffstat (limited to 'cli/node')
-rw-r--r-- | cli/node/analyze.rs | 40 | ||||
-rw-r--r-- | cli/node/mod.rs | 22 |
2 files changed, 50 insertions, 12 deletions
diff --git a/cli/node/analyze.rs b/cli/node/analyze.rs index ed2536390..9b449f675 100644 --- a/cli/node/analyze.rs +++ b/cli/node/analyze.rs @@ -12,6 +12,8 @@ use deno_core::error::AnyError; use deno_runtime::deno_node::NODE_GLOBAL_THIS_NAME; use std::fmt::Write; +use crate::cache::NodeAnalysisCache; + static NODE_GLOBALS: &[&str] = &[ "Buffer", "clearImmediate", @@ -32,18 +34,34 @@ static NODE_GLOBALS: &[&str] = &[ // `var` decls are taken into consideration. pub fn esm_code_with_node_globals( + analysis_cache: &NodeAnalysisCache, specifier: &ModuleSpecifier, code: String, ) -> Result<String, AnyError> { - let parsed_source = deno_ast::parse_program(deno_ast::ParseParams { - specifier: specifier.to_string(), - text_info: deno_ast::SourceTextInfo::from_string(code), - media_type: deno_ast::MediaType::from(specifier), - capture_tokens: true, - scope_analysis: true, - maybe_syntax: None, - })?; - let top_level_decls = analyze_top_level_decls(&parsed_source)?; + let source_hash = NodeAnalysisCache::compute_source_hash(&code); + let text_info = deno_ast::SourceTextInfo::from_string(code); + let top_level_decls = if let Some(decls) = + analysis_cache.get_esm_analysis(specifier.as_str(), &source_hash) + { + HashSet::from_iter(decls) + } else { + let parsed_source = deno_ast::parse_program(deno_ast::ParseParams { + specifier: specifier.to_string(), + text_info: text_info.clone(), + media_type: deno_ast::MediaType::from(specifier), + capture_tokens: true, + scope_analysis: true, + maybe_syntax: None, + })?; + let top_level_decls = analyze_top_level_decls(&parsed_source)?; + analysis_cache.set_esm_analysis( + specifier.as_str(), + &source_hash, + &top_level_decls.clone().into_iter().collect(), + ); + top_level_decls + }; + let mut globals = Vec::with_capacity(NODE_GLOBALS.len()); let has_global_this = top_level_decls.contains("globalThis"); for global in NODE_GLOBALS.iter() { @@ -64,7 +82,7 @@ pub fn esm_code_with_node_globals( write!(result, "var {0} = {1}.{0};", global, global_this_expr).unwrap(); } - let file_text = parsed_source.text_info().text_str(); + let file_text = text_info.text_str(); // strip the shebang let file_text = if file_text.starts_with("#!/") { let start_index = file_text.find('\n').unwrap_or(file_text.len()); @@ -148,6 +166,7 @@ mod tests { #[test] fn test_esm_code_with_node_globals() { let r = esm_code_with_node_globals( + &NodeAnalysisCache::new(None), &ModuleSpecifier::parse("https://example.com/foo/bar.js").unwrap(), "export const x = 1;".to_string(), ) @@ -163,6 +182,7 @@ mod tests { #[test] fn test_esm_code_with_node_globals_with_shebang() { let r = esm_code_with_node_globals( + &NodeAnalysisCache::new(None), &ModuleSpecifier::parse("https://example.com/foo/bar.js").unwrap(), "#!/usr/bin/env node\nexport const x = 1;".to_string(), ) diff --git a/cli/node/mod.rs b/cli/node/mod.rs index 3ea263b04..2e431eaa0 100644 --- a/cli/node/mod.rs +++ b/cli/node/mod.rs @@ -5,6 +5,7 @@ use std::collections::VecDeque; use std::path::Path; use std::path::PathBuf; +use crate::cache::NodeAnalysisCache; use crate::deno_std::CURRENT_STD_URL; use deno_ast::CjsAnalysis; use deno_ast::MediaType; @@ -734,12 +735,20 @@ pub fn translate_cjs_to_esm( code: String, media_type: MediaType, npm_resolver: &NpmPackageResolver, + node_analysis_cache: &NodeAnalysisCache, ) -> Result<String, AnyError> { fn perform_cjs_analysis( + analysis_cache: &NodeAnalysisCache, specifier: &str, media_type: MediaType, code: String, ) -> Result<CjsAnalysis, AnyError> { + let source_hash = NodeAnalysisCache::compute_source_hash(&code); + if let Some(analysis) = + analysis_cache.get_cjs_analysis(specifier, &source_hash) + { + return Ok(analysis); + } let parsed_source = deno_ast::parse_script(deno_ast::ParseParams { specifier: specifier.to_string(), text_info: deno_ast::SourceTextInfo::new(code.into()), @@ -748,7 +757,10 @@ pub fn translate_cjs_to_esm( scope_analysis: false, maybe_syntax: None, })?; - Ok(parsed_source.analyze_cjs()) + let analysis = parsed_source.analyze_cjs(); + analysis_cache.set_cjs_analysis(specifier, &source_hash, &analysis); + + Ok(analysis) } let mut temp_var_count = 0; @@ -758,7 +770,12 @@ pub fn translate_cjs_to_esm( r#"const require = Deno[Deno.internal].require.Module.createRequire(import.meta.url);"#.to_string(), ]; - let analysis = perform_cjs_analysis(specifier.as_str(), media_type, code)?; + let analysis = perform_cjs_analysis( + node_analysis_cache, + specifier.as_str(), + media_type, + code, + )?; let mut all_exports = analysis .exports @@ -804,6 +821,7 @@ pub fn translate_cjs_to_esm( { let analysis = perform_cjs_analysis( + node_analysis_cache, reexport_specifier.as_str(), reexport_file.media_type, reexport_file.source.to_string(), |