Skip to content

Commit 729994c

Browse files
authored
feat: allow overwriting used file extension (#660)
1 parent 4283426 commit 729994c

File tree

4 files changed

+29
-18
lines changed

4 files changed

+29
-18
lines changed

src/format_text.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,18 @@ use super::swc::parse_swc_ast;
3535
/// // now format many files (it is recommended to parallelize this)
3636
/// let files_to_format = vec![(PathBuf::from("path/to/file.ts"), "const t = 5 ;")];
3737
/// for (file_path, file_text) in files_to_format {
38-
/// let result = format_text(&file_path, file_text.into(), &config);
38+
/// let result = format_text(&file_path, None, file_text.into(), &config);
3939
/// // save result here...
4040
/// }
4141
/// ```
42-
pub fn format_text(file_path: &Path, file_text: String, config: &Configuration) -> Result<Option<String>> {
42+
pub fn format_text(file_path: &Path, file_extension: Option<&str>, file_text: String, config: &Configuration) -> Result<Option<String>> {
4343
if super::utils::file_text_has_ignore_comment(&file_text, &config.ignore_file_comment_text) {
4444
Ok(None)
4545
} else {
4646
let had_bom = file_text.starts_with("\u{FEFF}");
4747
let file_text = if had_bom { file_text[3..].to_string() } else { file_text };
4848
let file_text: Arc<str> = file_text.into();
49-
let parsed_source = parse_swc_ast(file_path, file_text)?;
49+
let parsed_source = parse_swc_ast(file_path, file_extension, file_text)?;
5050
match inner_format(&parsed_source, config)? {
5151
Some(new_text) => Ok(Some(new_text)),
5252
None => {
@@ -89,7 +89,7 @@ fn inner_format(parsed_source: &ParsedSource, config: &Configuration) -> Result<
8989

9090
#[cfg(feature = "tracing")]
9191
pub fn trace_file(file_path: &Path, file_text: &str, config: &Configuration) -> dprint_core::formatting::TracingResult {
92-
let parsed_source = parse_swc_ast(file_path, file_text.into()).unwrap();
92+
let parsed_source = parse_swc_ast(file_path, None, file_text.into()).unwrap();
9393
ensure_no_specific_syntax_errors(&parsed_source).unwrap();
9494
dprint_core::formatting::trace_printing(|| generate(&parsed_source, config), config_to_print_options(file_text, config))
9595
}
@@ -111,7 +111,7 @@ mod test {
111111
fn strips_bom() {
112112
for input_text in ["\u{FEFF}const t = 5;\n", "\u{FEFF}const t = 5;"] {
113113
let config = crate::configuration::ConfigurationBuilder::new().build();
114-
let result = format_text(&std::path::PathBuf::from("test.ts"), input_text.into(), &config).unwrap().unwrap();
114+
let result = format_text(&std::path::PathBuf::from("test.ts"), None, input_text.into(), &config).unwrap().unwrap();
115115
assert_eq!(result, "const t = 5;\n");
116116
}
117117
}

src/swc.rs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,38 @@ use deno_ast::ParsedSource;
88
use std::path::Path;
99
use std::sync::Arc;
1010

11-
pub fn parse_swc_ast(file_path: &Path, file_text: Arc<str>) -> Result<ParsedSource> {
12-
match parse_inner(file_path, file_text.clone()) {
11+
pub fn parse_swc_ast(file_path: &Path, file_extension: Option<&str>, file_text: Arc<str>) -> Result<ParsedSource> {
12+
match parse_inner(file_path, file_extension, file_text.clone()) {
1313
Ok(result) => Ok(result),
1414
Err(err) => {
15-
let lowercase_ext = get_lowercase_extension(file_path);
15+
let lowercase_ext = file_extension.map(|ext| ext.to_string()).or_else(|| get_lowercase_extension(file_path));
1616
let new_file_path = match lowercase_ext.as_deref() {
1717
Some("ts") | Some("cts") | Some("mts") => file_path.with_extension("tsx"),
1818
Some("js") | Some("cjs") | Some("mjs") => file_path.with_extension("jsx"),
1919
_ => return Err(err),
2020
};
2121
// try to parse as jsx
22-
match parse_inner(&new_file_path, file_text) {
22+
match parse_inner(&new_file_path, None, file_text) {
2323
Ok(result) => Ok(result),
2424
Err(_) => Err(err), // return the original error
2525
}
2626
}
2727
}
2828
}
2929

30-
fn parse_inner(file_path: &Path, text: Arc<str>) -> Result<ParsedSource> {
31-
let parsed_source = parse_inner_no_diagnostic_check(file_path, text)?;
30+
fn parse_inner(file_path: &Path, file_extension: Option<&str>, text: Arc<str>) -> Result<ParsedSource> {
31+
let parsed_source = parse_inner_no_diagnostic_check(file_path, file_extension, text)?;
3232
ensure_no_specific_syntax_errors(&parsed_source)?;
3333
Ok(parsed_source)
3434
}
3535

36-
fn parse_inner_no_diagnostic_check(file_path: &Path, text: Arc<str>) -> Result<ParsedSource> {
37-
let media_type = deno_ast::MediaType::from_path(file_path);
36+
fn parse_inner_no_diagnostic_check(file_path: &Path, file_extension: Option<&str>, text: Arc<str>) -> Result<ParsedSource> {
37+
let media_type = if let Some(file_extension) = file_extension {
38+
deno_ast::MediaType::from_path(&file_path.with_extension(file_extension))
39+
} else {
40+
deno_ast::MediaType::from_path(file_path)
41+
};
42+
3843
let mut syntax = deno_ast::get_syntax(media_type);
3944
if let Syntax::Es(es) = &mut syntax {
4045
// support decorators in js
@@ -260,7 +265,7 @@ mod tests {
260265

261266
fn run_fatal_diagnostic_test(file_path: &str, text: &str, expected: &str) {
262267
let file_path = PathBuf::from(file_path);
263-
assert_eq!(parse_swc_ast(&file_path, text.into()).err().unwrap().to_string(), expected);
268+
assert_eq!(parse_swc_ast(&file_path, None, text.into()).err().unwrap().to_string(), expected);
264269
}
265270

266271
#[test]
@@ -286,6 +291,12 @@ mod tests {
286291
);
287292
}
288293

294+
#[test]
295+
fn file_extension_overwrite() {
296+
let file_path = PathBuf::from("./test.js");
297+
assert!(parse_swc_ast(&file_path, Some("ts"), "const foo: string = 'bar';".into()).is_ok());
298+
}
299+
289300
#[test]
290301
fn it_should_error_for_exected_close_brace() {
291302
// swc can parse this, but we explicitly fail formatting
@@ -342,11 +353,11 @@ Merge conflict marker encountered. at file:///test.ts:6:1
342353

343354
fn run_non_fatal_diagnostic_test(file_path: &str, text: &str, expected: &str) {
344355
let file_path = PathBuf::from(file_path);
345-
assert_eq!(format!("{}", parse_swc_ast(&file_path, text.into()).err().unwrap()), expected);
356+
assert_eq!(format!("{}", parse_swc_ast(&file_path, None, text.into()).err().unwrap()), expected);
346357

347358
// this error should also be surfaced in `format_parsed_source` if someone provides
348359
// a source file that had a non-fatal diagnostic
349-
let parsed_source = parse_inner_no_diagnostic_check(&file_path, text.into()).unwrap();
360+
let parsed_source = parse_inner_no_diagnostic_check(&file_path, None, text.into()).unwrap();
350361
let config = ConfigurationBuilder::new().build();
351362
assert_eq!(crate::format_parsed_source(&parsed_source, &config).err().unwrap().to_string(), expected);
352363
}

src/wasm_plugin.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ impl SyncPluginHandler<Configuration> for TypeScriptPluginHandler {
5858
_format_with_host: impl FnMut(&Path, Vec<u8>, &ConfigKeyMap) -> FormatResult,
5959
) -> FormatResult {
6060
let file_text = String::from_utf8(file_bytes)?;
61-
super::format_text(file_path, file_text, config).map(|maybe_text| maybe_text.map(|t| t.into_bytes()))
61+
super::format_text(file_path, None, file_text, config).map(|maybe_text| maybe_text.map(|t| t.into_bytes()))
6262
}
6363
}
6464

tests/spec_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ fn main() {
2828
let config_result = resolve_config(spec_config, &global_config);
2929
ensure_no_diagnostics(&config_result.diagnostics);
3030

31-
format_text(file_name, file_text.into(), &config_result.config)
31+
format_text(file_name, None, file_text.into(), &config_result.config)
3232
})
3333
},
3434
Arc::new(move |_file_name, _file_text, _spec_config| {

0 commit comments

Comments
 (0)