Skip to content

Commit bc0af36

Browse files
committed
chore: ensure source maps are cached
1 parent decafab commit bc0af36

File tree

3 files changed

+86
-0
lines changed

3 files changed

+86
-0
lines changed

src/analysis.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,9 @@ pub struct ModuleInfo {
276276
/// or `@import { SomeType } from "npm:some-module"`.
277277
#[serde(skip_serializing_if = "Vec::is_empty", default)]
278278
pub jsdoc_imports: Vec<JsDocImportInfo>,
279+
/// Source map URL extracted from sourceMappingURL comment
280+
#[serde(skip_serializing_if = "Option::is_none", default)]
281+
pub source_map_url: Option<SpecifierWithRange>,
279282
}
280283

281284
fn is_false(v: &bool) -> bool {
@@ -442,6 +445,14 @@ pub fn find_jsx_import_source_types(text: &str) -> Option<regex::Match<'_>> {
442445
.and_then(|c| c.get(1))
443446
}
444447

448+
/// Matches the `sourceMappingURL` comment.
449+
pub fn find_source_mapping_url(text: &str) -> Option<regex::Match<'_>> {
450+
static SOURCE_MAPPING_URL_RE: Lazy<Regex> = Lazy::new(|| {
451+
Regex::new(r"(?i)^[#@]\s*sourceMappingURL\s*=\s*(\S+)").unwrap()
452+
});
453+
SOURCE_MAPPING_URL_RE.captures(text).and_then(|c| c.get(1))
454+
}
455+
445456
/// Matches the `@ts-self-types` pragma.
446457
pub fn find_ts_self_types(text: &str) -> Option<regex::Match<'_>> {
447458
static TS_SELF_TYPES_RE: Lazy<Regex> = Lazy::new(|| {
@@ -505,6 +516,7 @@ mod test {
505516
jsx_import_source: None,
506517
jsx_import_source_types: None,
507518
jsdoc_imports: Vec::new(),
519+
source_map_url: None,
508520
};
509521
run_serialization_test(&module_info, json!({}));
510522
}
@@ -574,6 +586,7 @@ mod test {
574586
jsx_import_source: None,
575587
jsx_import_source_types: None,
576588
jsdoc_imports: Vec::new(),
589+
source_map_url: None,
577590
};
578591
run_serialization_test(
579592
&module_info,
@@ -659,6 +672,7 @@ mod test {
659672
jsx_import_source: None,
660673
jsx_import_source_types: None,
661674
jsdoc_imports: Vec::new(),
675+
source_map_url: None,
662676
};
663677
run_serialization_test(
664678
&module_info,
@@ -704,6 +718,7 @@ mod test {
704718
jsx_import_source: None,
705719
jsx_import_source_types: None,
706720
jsdoc_imports: Vec::new(),
721+
source_map_url: None,
707722
};
708723
run_serialization_test(
709724
&module_info,
@@ -734,6 +749,7 @@ mod test {
734749
}),
735750
jsx_import_source_types: None,
736751
jsdoc_imports: Vec::new(),
752+
source_map_url: None,
737753
};
738754
run_serialization_test(
739755
&module_info,
@@ -764,6 +780,7 @@ mod test {
764780
},
765781
}),
766782
jsdoc_imports: Vec::new(),
783+
source_map_url: None,
767784
};
768785
run_serialization_test(
769786
&module_info,
@@ -819,6 +836,7 @@ mod test {
819836
resolution_mode: Some(TypeScriptTypesResolutionMode::Require),
820837
},
821838
]),
839+
source_map_url: None,
822840
};
823841
run_serialization_test(
824842
&module_info,
@@ -1053,6 +1071,7 @@ mod test {
10531071
jsx_import_source: None,
10541072
jsx_import_source_types: None,
10551073
jsdoc_imports: Vec::new(),
1074+
source_map_url: None,
10561075
};
10571076
let json = json!({
10581077
"dependencies": [{
@@ -1097,6 +1116,7 @@ mod test {
10971116
jsx_import_source: None,
10981117
jsx_import_source_types: None,
10991118
jsdoc_imports: Vec::new(),
1119+
source_map_url: None,
11001120
};
11011121
let json = json!({
11021122
"dependencies": [{

src/ast/mod.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use crate::analysis::find_jsx_import_source;
1616
use crate::analysis::find_jsx_import_source_types;
1717
use crate::analysis::find_path_reference;
1818
use crate::analysis::find_resolution_mode;
19+
use crate::analysis::find_source_mapping_url;
1920
use crate::analysis::find_ts_self_types;
2021
use crate::analysis::find_ts_types;
2122
use crate::analysis::find_types_reference;
@@ -268,6 +269,9 @@ impl<'a> ParserModuleAnalyzer<'a> {
268269
None => comments.get_leading(program.start()),
269270
},
270271
};
272+
// Get trailing comments from the program end to extract sourceMappingURL
273+
// which is typically at the very end of the file
274+
let trailing_comments = comments.get_trailing(program.end());
271275
ModuleInfo {
272276
is_script: program.compute_is_script(),
273277
dependencies: analyze_dependencies(program, text_info, comments),
@@ -288,6 +292,7 @@ impl<'a> ParserModuleAnalyzer<'a> {
288292
leading_comments,
289293
),
290294
jsdoc_imports: analyze_jsdoc_imports(media_type, text_info, comments),
295+
source_map_url: analyze_source_map_url(text_info, trailing_comments),
291296
}
292297
}
293298

@@ -608,6 +613,27 @@ fn analyze_ts_self_types(
608613
})
609614
}
610615

616+
// Search source map URL from trailing comments
617+
fn analyze_source_map_url(
618+
text_info: &SourceTextInfo,
619+
trailing_comments: Option<&Vec<deno_ast::swc::common::comments::Comment>>,
620+
) -> Option<SpecifierWithRange> {
621+
trailing_comments.and_then(|c| {
622+
c.iter().rev().find_map(|comment| {
623+
let source_mapping_url = find_source_mapping_url(&comment.text)?;
624+
Some(SpecifierWithRange {
625+
text: source_mapping_url.as_str().to_string(),
626+
range: comment_source_to_position_range(
627+
comment.start(),
628+
source_mapping_url.range(),
629+
text_info,
630+
true,
631+
),
632+
})
633+
})
634+
})
635+
}
636+
611637
/// Searches comments for any `@ts-types` or `@deno-types` compiler hints.
612638
pub fn analyze_ts_or_deno_types(
613639
text_info: &SourceTextInfo,
@@ -1459,6 +1485,7 @@ export {};
14591485
}),
14601486
jsx_import_source_types: None,
14611487
jsdoc_imports: vec![],
1488+
source_map_url: None,
14621489
},
14631490
);
14641491
}

src/graph.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,6 +1439,8 @@ pub struct JsModule {
14391439
#[serde(skip_serializing_if = "is_media_type_unknown")]
14401440
pub media_type: MediaType,
14411441
pub specifier: ModuleSpecifier,
1442+
#[serde(skip_serializing_if = "Option::is_none")]
1443+
pub maybe_source_map_dependency: Option<TypesDependency>,
14421444
#[cfg(feature = "fast_check")]
14431445
#[serde(skip_serializing)]
14441446
pub fast_check: Option<FastCheckTypeModuleSlot>,
@@ -3145,10 +3147,30 @@ pub(crate) fn parse_js_module_from_module_info(
31453147
maybe_types_dependency: None,
31463148
media_type,
31473149
specifier,
3150+
maybe_source_map_dependency: None,
31483151
#[cfg(feature = "fast_check")]
31493152
fast_check: None,
31503153
};
31513154

3155+
// Resolve source map dependency if source_map_url is present
3156+
if let Some(source_map_specifier) = module_info.source_map_url.as_ref() {
3157+
let range = Range {
3158+
specifier: module.specifier.clone(),
3159+
range: source_map_specifier.range,
3160+
resolution_mode: None,
3161+
};
3162+
module.maybe_source_map_dependency = Some(TypesDependency {
3163+
specifier: source_map_specifier.text.clone(),
3164+
dependency: resolve(
3165+
&source_map_specifier.text,
3166+
range.clone(),
3167+
ResolutionKind::Execution,
3168+
jsr_url_provider,
3169+
maybe_resolver,
3170+
),
3171+
});
3172+
}
3173+
31523174
// Analyze the TypeScript triple-slash references and self types specifier
31533175
if graph_kind.include_types() {
31543176
if let Some(specifier) = module_info.self_types_specifier.as_ref() {
@@ -6000,6 +6022,23 @@ impl<'a, 'graph> Builder<'a, 'graph> {
60006022
if matches!(self.graph.graph_kind, GraphKind::All | GraphKind::CodeOnly)
60016023
|| module.maybe_types_dependency.is_none()
60026024
{
6025+
// Load source map as an external module if it exists
6026+
if let Some(Resolution::Ok(resolved)) = module
6027+
.maybe_source_map_dependency
6028+
.as_ref()
6029+
.map(|d| &d.dependency)
6030+
{
6031+
self.load(LoadOptionsRef {
6032+
specifier: &resolved.specifier,
6033+
maybe_range: Some(&resolved.range),
6034+
is_asset: true,
6035+
in_dynamic_branch: self.in_dynamic_branch,
6036+
is_root: self.resolved_roots.contains(&resolved.specifier),
6037+
maybe_attribute_type: None,
6038+
maybe_version_info,
6039+
});
6040+
}
6041+
60036042
self.visit_module_dependencies(
60046043
&mut module.dependencies,
60056044
maybe_version_info,

0 commit comments

Comments
 (0)