perf: do not clone swc Program when transpiling (#23365)

This commit is contained in:
David Sherret 2024-04-14 17:15:17 -04:00 committed by GitHub
parent 76df7d7c9b
commit e277490c82
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 68 additions and 39 deletions

View file

@ -8,8 +8,10 @@ use deno_ast::ModuleSpecifier;
use deno_ast::ParsedSource;
use deno_core::parking_lot::Mutex;
use deno_graph::CapturingModuleParser;
use deno_graph::DefaultModuleParser;
use deno_graph::ModuleParser;
use deno_graph::ParseOptions;
use deno_graph::ParsedSourceStore;
/// Lazily parses JS/TS sources from a `deno_graph::ModuleGraph` given
/// a `ParsedSourceCache`. Note that deno_graph doesn't necessarily cause
@ -54,30 +56,38 @@ impl ParsedSourceCache {
&self,
module: &deno_graph::JsModule,
) -> Result<ParsedSource, deno_ast::ParseDiagnostic> {
self.get_or_parse_module(
&module.specifier,
module.source.clone(),
module.media_type,
)
}
/// Gets the matching `ParsedSource` from the cache
/// or parses a new one and stores that in the cache.
pub fn get_or_parse_module(
&self,
specifier: &deno_graph::ModuleSpecifier,
source: Arc<str>,
media_type: MediaType,
) -> deno_core::anyhow::Result<ParsedSource, deno_ast::ParseDiagnostic> {
let parser = self.as_capturing_parser();
// this will conditionally parse because it's using a CapturingModuleParser
parser.parse_module(ParseOptions {
specifier: &module.specifier,
source: module.source.clone(),
media_type: module.media_type,
// don't bother enabling because this method is currently only used for vendoring
scope_analysis: false,
})
}
pub fn remove_or_parse_module(
&self,
specifier: &ModuleSpecifier,
source: Arc<str>,
media_type: MediaType,
) -> Result<ParsedSource, deno_ast::ParseDiagnostic> {
if let Some(parsed_source) = self.remove_parsed_source(specifier) {
if parsed_source.media_type() == media_type
&& parsed_source.text_info().text_str() == source.as_ref()
{
return Ok(parsed_source);
}
}
let options = ParseOptions {
specifier,
source,
media_type,
// don't bother enabling because this method is currently only used for emitting
scope_analysis: false,
})
};
DefaultModuleParser.parse_module(options)
}
/// Frees the parsed source from memory.
@ -100,7 +110,7 @@ impl ParsedSourceCache {
impl deno_graph::ParsedSourceStore for ParsedSourceCache {
fn set_parsed_source(
&self,
specifier: deno_graph::ModuleSpecifier,
specifier: ModuleSpecifier,
parsed_source: ParsedSource,
) -> Option<ParsedSource> {
self.sources.lock().insert(specifier, parsed_source)
@ -108,14 +118,21 @@ impl deno_graph::ParsedSourceStore for ParsedSourceCache {
fn get_parsed_source(
&self,
specifier: &deno_graph::ModuleSpecifier,
specifier: &ModuleSpecifier,
) -> Option<ParsedSource> {
self.sources.lock().get(specifier).cloned()
}
fn remove_parsed_source(
&self,
specifier: &ModuleSpecifier,
) -> Option<ParsedSource> {
self.sources.lock().remove(specifier)
}
fn get_scope_analysis_parsed_source(
&self,
specifier: &deno_graph::ModuleSpecifier,
specifier: &ModuleSpecifier,
) -> Option<ParsedSource> {
let mut sources = self.sources.lock();
let parsed_source = sources.get(specifier)?;