Skip to content

Commit 45de419

Browse files
committed
Improve Request::parse
1 parent 84df719 commit 45de419

File tree

2 files changed

+93
-6
lines changed

2 files changed

+93
-6
lines changed

turbopack/crates/turbopack-core/src/resolve/parse.rs

Lines changed: 84 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub enum Request {
2323
fragment: RcStr,
2424
},
2525
Module {
26-
module: RcStr,
26+
module: Pattern,
2727
path: Pattern,
2828
query: RcStr,
2929
fragment: RcStr,
@@ -236,7 +236,7 @@ impl Request {
236236
let (path, query, fragment) = split_off_query_fragment(path.as_str());
237237

238238
return Request::Module {
239-
module: module.as_str().into(),
239+
module: RcStr::from(module.as_str()).into(),
240240
path,
241241
query,
242242
fragment,
@@ -255,6 +255,12 @@ impl Request {
255255

256256
let mut result = Self::parse_ref(list[0].clone());
257257

258+
let mut was_module_name_terminated = if let Request::Module { path, .. } = &result {
259+
!path.is_empty()
260+
} else {
261+
false
262+
};
263+
258264
for item in list.into_iter().skip(1) {
259265
match &mut result {
260266
Request::Raw { path, .. } => {
@@ -263,8 +269,22 @@ impl Request {
263269
Request::Relative { path, .. } => {
264270
path.push(item);
265271
}
266-
Request::Module { path, .. } => {
267-
path.push(item);
272+
Request::Module { module, path, .. } => {
273+
if !was_module_name_terminated && matches!(item, Pattern::Dynamic) {
274+
// TODO ideally this would be more general (i.e. support also
275+
// `module-part<dynamic>more-module/subpath`) and not just handle
276+
// Pattern::Dynamic, but this covers the common case of
277+
// `require('@img/sharp-' + arch + '/sharp.node')`
278+
279+
// Insert dynamic between module and path (by adding it to both of them,
280+
// because both could happen). Note that path is empty at this
281+
// point anyway.
282+
module.push(Pattern::Dynamic);
283+
path.push(item);
284+
} else {
285+
path.push(item);
286+
was_module_name_terminated = true;
287+
}
268288
}
269289
Request::ServerRelative { path, .. } => {
270290
path.push(item);
@@ -358,7 +378,7 @@ impl Request {
358378
}
359379

360380
#[turbo_tasks::function]
361-
pub fn module(module: RcStr, path: Pattern, query: RcStr, fragment: RcStr) -> Vc<Self> {
381+
pub fn module(module: Pattern, path: Pattern, query: RcStr, fragment: RcStr) -> Vc<Self> {
362382
Self::cell(Request::Module {
363383
module,
364384
path,
@@ -692,7 +712,7 @@ impl Request {
692712
Request::Relative { path, .. } => path.clone(),
693713
Request::Module { module, path, .. } => {
694714
let mut path = path.clone();
695-
path.push_front(Pattern::Constant(module.clone()));
715+
path.push_front(module.clone());
696716
path.normalize();
697717
path
698718
}
@@ -811,6 +831,64 @@ pub async fn stringify_data_uri(
811831
mod tests {
812832
use super::*;
813833

834+
#[test]
835+
fn test_parse_module() {
836+
assert_eq!(
837+
Request::Module {
838+
module: rcstr!("foo").into(),
839+
path: rcstr!("").into(),
840+
query: rcstr!(""),
841+
fragment: rcstr!(""),
842+
},
843+
Request::parse_ref(rcstr!("foo").into())
844+
);
845+
assert_eq!(
846+
Request::Module {
847+
module: rcstr!("@org/foo").into(),
848+
path: rcstr!("").into(),
849+
query: rcstr!(""),
850+
fragment: rcstr!(""),
851+
},
852+
Request::parse_ref(rcstr!("@org/foo").into())
853+
);
854+
855+
assert_eq!(
856+
Request::Module {
857+
module: Pattern::Concatenation(vec![
858+
Pattern::Constant(rcstr!("foo-")),
859+
Pattern::Dynamic,
860+
]),
861+
path: Pattern::Dynamic,
862+
query: rcstr!(""),
863+
fragment: rcstr!(""),
864+
},
865+
Request::parse_ref(Pattern::Concatenation(vec![
866+
Pattern::Constant(rcstr!("foo-")),
867+
Pattern::Dynamic,
868+
]))
869+
);
870+
871+
assert_eq!(
872+
Request::Module {
873+
module: Pattern::Concatenation(vec![
874+
Pattern::Constant(rcstr!("foo-")),
875+
Pattern::Dynamic,
876+
]),
877+
path: Pattern::Concatenation(vec![
878+
Pattern::Dynamic,
879+
Pattern::Constant(rcstr!("/file")),
880+
]),
881+
query: rcstr!(""),
882+
fragment: rcstr!(""),
883+
},
884+
Request::parse_ref(Pattern::Concatenation(vec![
885+
Pattern::Constant(rcstr!("foo-")),
886+
Pattern::Dynamic,
887+
Pattern::Constant(rcstr!("/file")),
888+
]))
889+
);
890+
}
891+
814892
#[test]
815893
fn test_split_query_fragment() {
816894
assert_eq!(

turbopack/crates/turbopack-core/src/resolve/pattern.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,15 @@ impl Pattern {
676676
}
677677
}
678678

679+
pub fn is_empty(&self) -> bool {
680+
match self {
681+
Pattern::Constant(s) => s.is_empty(),
682+
Pattern::Dynamic => false,
683+
Pattern::Concatenation(parts) => parts.iter().all(|p| p.is_empty()),
684+
Pattern::Alternatives(parts) => parts.iter().all(|p| p.is_empty()),
685+
}
686+
}
687+
679688
pub fn filter_could_match(&self, value: &str) -> Option<Pattern> {
680689
if let Pattern::Alternatives(list) = self {
681690
let new_list = list

0 commit comments

Comments
 (0)