Skip to content

Commit

Permalink
Properly rewrite the pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
mischnic committed Jul 17, 2024
1 parent 847081e commit 8c02b98
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 15 deletions.
45 changes: 30 additions & 15 deletions crates/turbopack-core/src/resolve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1920,21 +1920,6 @@ async fn resolve_relative_request(
let mut new_path = path_pattern.clone();

let fragment_val = fragment.await?;

if !options_value.fully_specified && options_value.enable_js_ts_rewriting {
// TODO path_pattern might not be a constant?
// TODO extension might be empty, or dots in filepath
if let Pattern::Constant(s) = path_pattern {
if let Some((base, ext)) = s.rsplit_once(".") {
if ext == "js" {
new_path = Pattern::Alternatives(vec![Pattern::Constant(base.into()), new_path])
}
}
} else {
todo!("enable_js_ts_rewriting");
}
}

if !fragment_val.is_empty() {
new_path.push(Pattern::Alternatives(
once(Pattern::Constant("".into()))
Expand All @@ -1957,6 +1942,36 @@ async fn resolve_relative_request(
.collect(),
));

if options_value.enable_js_ts_rewriting {
let mut rewritten_path = path_pattern.clone();
let rewritten_path_modified =
rewritten_path.replace_final_constants(&|c: &RcStr| -> Option<Pattern> {
let result = match c.rsplit_once(".") {
Some((base, "js")) => Some((
base,
vec![
Pattern::Constant(".ts".into()),
Pattern::Constant(".tsx".into()),
],
)),
Some((base, "mjs")) => Some((base, vec![Pattern::Constant(".mts".into())])),
Some((base, "cjs")) => Some((base, vec![Pattern::Constant(".cts".into())])),
_ => None,
};
result.map(|(base, replacement)| {
Pattern::Concatenation(vec![
Pattern::Constant(base.into()),
Pattern::Alternatives(replacement),
])
})
});

if rewritten_path_modified {
// Prepend the rewritten pattern to give it higher priority
new_path = Pattern::Alternatives(vec![rewritten_path, new_path])
}
}

new_path.normalize();
};

Expand Down
92 changes: 92 additions & 0 deletions crates/turbopack-core/src/resolve/pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,33 @@ impl Pattern {
new.normalize();
Pattern::alternatives([self.clone(), new])
}

/// Calls `cb` on all constants that are at the end of the pattern and
/// replaces the given final constant with the returned pattern. Returns
/// true if replacements were performed.
pub fn replace_final_constants(&mut self, cb: &impl Fn(&RcStr) -> Option<Pattern>) -> bool {
let mut replaced = false;
match self {
Pattern::Constant(c) => {
if let Some(replacement) = cb(c) {
*self = replacement;
replaced = true;
}
}
Pattern::Dynamic => {}
Pattern::Alternatives(list) => {
for i in list {
replaced = i.replace_final_constants(cb) || replaced;
}
}
Pattern::Concatenation(list) => {
if let Some(c @ Pattern::Constant(_)) = list.last_mut() {
replaced = c.replace_final_constants(cb) || replaced;
}
}
}
replaced
}
}

impl Pattern {
Expand Down Expand Up @@ -1097,6 +1124,7 @@ pub async fn read_matches(
#[cfg(test)]
mod tests {
use rstest::*;
use turbo_tasks::RcStr;

use super::Pattern;

Expand Down Expand Up @@ -1344,4 +1372,68 @@ mod tests {
) {
assert_eq!(pat.next_constants(value), expected);
}

#[test]
fn replace_final_constants() {
fn f(mut p: Pattern, cb: &impl Fn(&RcStr) -> Option<Pattern>) -> Pattern {
p.replace_final_constants(cb);
p
}

let js_to_ts_tsx = |c: &RcStr| -> Option<Pattern> {
c.strip_suffix(".js").map(|rest| {
let new_ending = Pattern::Alternatives(vec![
Pattern::Constant(".ts".into()),
Pattern::Constant(".tsx".into()),
]);
if !rest.is_empty() {
Pattern::Concatenation(vec![Pattern::Constant(rest.into()), new_ending])
} else {
new_ending
}
})
};

assert_eq!(
f(
Pattern::Concatenation(vec![
Pattern::Constant(".".into()),
Pattern::Constant("/".into()),
Pattern::Dynamic,
Pattern::Constant(".js".into()),
]),
&js_to_ts_tsx
),
Pattern::Concatenation(vec![
Pattern::Constant(".".into()),
Pattern::Constant("/".into()),
Pattern::Dynamic,
Pattern::Alternatives(vec![
Pattern::Constant(".ts".into()),
Pattern::Constant(".tsx".into()),
]),
])
);
assert_eq!(
f(
Pattern::Concatenation(vec![
Pattern::Constant(".".into()),
Pattern::Constant("/".into()),
Pattern::Constant("abc.js".into()),
]),
&js_to_ts_tsx
),
Pattern::Concatenation(vec![
Pattern::Constant(".".into()),
Pattern::Constant("/".into()),
Pattern::Concatenation(vec![
Pattern::Constant("abc".into()),
Pattern::Alternatives(vec![
Pattern::Constant(".ts".into()),
Pattern::Constant(".tsx".into()),
])
]),
])
);
}
}

0 comments on commit 8c02b98

Please sign in to comment.