Skip to content

Commit 2a53300

Browse files
committed
Refactor compiler arg collection
1 parent 800a423 commit 2a53300

2 files changed

Lines changed: 67 additions & 82 deletions

File tree

rewatch/src/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ pub fn get_compiler_args(rescript_file_path: &Path) -> Result<String> {
103103
is_type_dev,
104104
true,
105105
None, // No warn_error_override for compiler-args command
106+
compile::OutputMode::ToFile,
106107
)?;
107108

108109
let result = serde_json::to_string_pretty(&CompilerArgs {

rewatch/src/build/compile.rs

Lines changed: 66 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,18 @@ pub fn get_runtime_path_args(
458458
])
459459
}
460460

461+
/// Output mode for compiler arguments.
462+
/// Controls whether bsc writes to files or outputs to stdout.
463+
pub enum OutputMode {
464+
/// Normal mode: write JS to files based on package-specs configuration.
465+
/// Includes -bs-package-name, -bs-package-output, -bs-suffix, -bs-module-system for each spec.
466+
ToFile,
467+
/// Stdout mode: output JS to stdout for one-shot compilation.
468+
/// Only includes -bs-module-system with the specified format.
469+
/// Omits -bs-package-name (which triggers file output) and -bs-package-output.
470+
ToStdout { module_format: String },
471+
}
472+
461473
pub fn compiler_args(
462474
config: &config::Config,
463475
ast_path: &Path,
@@ -474,6 +486,8 @@ pub fn compiler_args(
474486
is_local_dep: bool,
475487
// Command-line --warn-error flag override (takes precedence over rescript.json config)
476488
warn_error_override: Option<String>,
489+
// Output mode: ToFile for normal compilation, ToStdout for one-shot compilation
490+
output_mode: OutputMode,
477491
) -> Result<Vec<String>> {
478492
let bsc_flags = config::flatten_flags(&config.compiler_flags);
479493
let dependency_paths = get_dependency_paths(config, project_context, packages, is_type_dev);
@@ -520,40 +534,52 @@ pub fn compiler_args(
520534
false => vec![],
521535
};
522536

523-
let package_name_arg = vec!["-bs-package-name".to_string(), config.name.to_owned()];
524-
525-
let implementation_args = if is_interface {
526-
debug!("Compiling interface file: {}", &module_name);
527-
vec![]
528-
} else {
529-
debug!("Compiling file: {}", &module_name);
530-
let specs = root_config.get_package_specs();
537+
// Package name and implementation args depend on output mode
538+
let (package_name_arg, implementation_args) = match &output_mode {
539+
OutputMode::ToFile => {
540+
let package_name = vec!["-bs-package-name".to_string(), config.name.to_owned()];
541+
let impl_args = if is_interface {
542+
debug!("Compiling interface file: {}", &module_name);
543+
vec![]
544+
} else {
545+
debug!("Compiling file: {}", &module_name);
546+
let specs = root_config.get_package_specs();
531547

532-
specs
533-
.iter()
534-
.flat_map(|spec| {
535-
// Pass module system, suffix, and output path as separate flags
536-
vec![
537-
"-bs-module-system".to_string(),
538-
spec.module.clone(),
539-
"-bs-suffix".to_string(),
540-
root_config.get_suffix(spec),
541-
"-bs-package-output".to_string(),
542-
if spec.in_source {
543-
file_path.parent().unwrap().to_str().unwrap().to_string()
544-
} else {
545-
Path::new("lib")
546-
.join(Path::join(
547-
Path::new(&spec.get_out_of_source_dir()),
548-
file_path.parent().unwrap(),
549-
))
550-
.to_str()
551-
.unwrap()
552-
.to_string()
553-
},
554-
]
555-
})
556-
.collect()
548+
specs
549+
.iter()
550+
.flat_map(|spec| {
551+
// Pass module system, suffix, and output path as separate flags
552+
vec![
553+
"-bs-module-system".to_string(),
554+
spec.module.clone(),
555+
"-bs-suffix".to_string(),
556+
root_config.get_suffix(spec),
557+
"-bs-package-output".to_string(),
558+
if spec.in_source {
559+
file_path.parent().unwrap().to_str().unwrap().to_string()
560+
} else {
561+
Path::new("lib")
562+
.join(Path::join(
563+
Path::new(&spec.get_out_of_source_dir()),
564+
file_path.parent().unwrap(),
565+
))
566+
.to_str()
567+
.unwrap()
568+
.to_string()
569+
},
570+
]
571+
})
572+
.collect()
573+
};
574+
(package_name, impl_args)
575+
}
576+
OutputMode::ToStdout { module_format } => {
577+
// For stdout mode: no -bs-package-name (triggers file output),
578+
// only -bs-module-system with the chosen format
579+
debug!("Compiling file to stdout: {}", &module_name);
580+
let impl_args = vec!["-bs-module-system".to_string(), module_format.clone()];
581+
(vec![], impl_args)
582+
}
557583
};
558584

559585
let runtime_path_args = get_runtime_path_args(config, project_context)?;
@@ -592,11 +618,7 @@ pub fn compiler_args(
592618
}
593619

594620
/// Generate compiler arguments for stdout output (no file write).
595-
///
596-
/// Calls `compiler_args` and then filters out flags that would cause file output:
597-
/// - Removes `-bs-package-name` (triggers file output mode)
598-
/// - Removes `-bs-package-output` and `-bs-suffix` (file output config)
599-
/// - Keeps only a single `-bs-module-system` for the requested format
621+
/// This is a convenience wrapper around `compiler_args` with `OutputMode::ToStdout`.
600622
pub fn compiler_args_for_stdout(
601623
config: &config::Config,
602624
ast_path: &Path,
@@ -609,8 +631,7 @@ pub fn compiler_args_for_stdout(
609631
warn_error_override: Option<String>,
610632
module_format: &str,
611633
) -> Result<Vec<String>> {
612-
// Get the base compiler args
613-
let base_args = compiler_args(
634+
compiler_args(
614635
config,
615636
ast_path,
616637
file_path,
@@ -621,48 +642,10 @@ pub fn compiler_args_for_stdout(
621642
is_type_dev,
622643
is_local_dep,
623644
warn_error_override,
624-
)?;
625-
626-
// Filter out flags that trigger file output, keeping track of what to skip
627-
let mut result = Vec::new();
628-
let mut skip_next = false;
629-
let mut seen_module_system = false;
630-
631-
for arg in base_args {
632-
if skip_next {
633-
skip_next = false;
634-
continue;
635-
}
636-
637-
match arg.as_str() {
638-
// Skip -bs-package-name and its value (triggers file output)
639-
"-bs-package-name" => {
640-
skip_next = true;
641-
}
642-
// Skip -bs-package-output and its value (file path)
643-
"-bs-package-output" => {
644-
skip_next = true;
645-
}
646-
// Skip -bs-suffix and its value (not needed for stdout)
647-
"-bs-suffix" => {
648-
skip_next = true;
649-
}
650-
// Keep only one -bs-module-system with our chosen format
651-
"-bs-module-system" => {
652-
if !seen_module_system {
653-
result.push("-bs-module-system".to_string());
654-
result.push(module_format.to_string());
655-
seen_module_system = true;
656-
}
657-
skip_next = true; // skip the original value
658-
}
659-
_ => {
660-
result.push(arg);
661-
}
662-
}
663-
}
664-
665-
Ok(result)
645+
OutputMode::ToStdout {
646+
module_format: module_format.to_string(),
647+
},
648+
)
666649
}
667650

668651
/// Compile a single file and return its JavaScript output on stdout.
@@ -864,6 +847,7 @@ fn compile_file(
864847
is_type_dev,
865848
package.is_local_dep,
866849
warn_error_override,
850+
OutputMode::ToFile,
867851
)?;
868852

869853
let to_mjs = Command::new(&compiler_info.bsc_path)

0 commit comments

Comments
 (0)