Skip to content

Commit e7a5f7a

Browse files
committed
Refactor compiler arg collection
1 parent 2b48e3e commit e7a5f7a

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
@@ -469,6 +469,18 @@ pub fn get_runtime_path_args(
469469
])
470470
}
471471

472+
/// Output mode for compiler arguments.
473+
/// Controls whether bsc writes to files or outputs to stdout.
474+
pub enum OutputMode {
475+
/// Normal mode: write JS to files based on package-specs configuration.
476+
/// Includes -bs-package-name, -bs-package-output, -bs-suffix, -bs-module-system for each spec.
477+
ToFile,
478+
/// Stdout mode: output JS to stdout for one-shot compilation.
479+
/// Only includes -bs-module-system with the specified format.
480+
/// Omits -bs-package-name (which triggers file output) and -bs-package-output.
481+
ToStdout { module_format: String },
482+
}
483+
472484
pub fn compiler_args(
473485
config: &config::Config,
474486
ast_path: &Path,
@@ -485,6 +497,8 @@ pub fn compiler_args(
485497
is_local_dep: bool,
486498
// Command-line --warn-error flag override (takes precedence over rescript.json config)
487499
warn_error_override: Option<String>,
500+
// Output mode: ToFile for normal compilation, ToStdout for one-shot compilation
501+
output_mode: OutputMode,
488502
) -> Result<Vec<String>> {
489503
let bsc_flags = config::flatten_flags(&config.compiler_flags);
490504
let dependency_paths = get_dependency_paths(config, project_context, packages, is_type_dev);
@@ -531,40 +545,52 @@ pub fn compiler_args(
531545
false => vec![],
532546
};
533547

534-
let package_name_arg = vec!["-bs-package-name".to_string(), config.name.to_owned()];
535-
536-
let implementation_args = if is_interface {
537-
debug!("Compiling interface file: {}", &module_name);
538-
vec![]
539-
} else {
540-
debug!("Compiling file: {}", &module_name);
541-
let specs = root_config.get_package_specs();
548+
// Package name and implementation args depend on output mode
549+
let (package_name_arg, implementation_args) = match &output_mode {
550+
OutputMode::ToFile => {
551+
let package_name = vec!["-bs-package-name".to_string(), config.name.to_owned()];
552+
let impl_args = if is_interface {
553+
debug!("Compiling interface file: {}", &module_name);
554+
vec![]
555+
} else {
556+
debug!("Compiling file: {}", &module_name);
557+
let specs = root_config.get_package_specs();
542558

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

570596
let runtime_path_args = get_runtime_path_args(config, project_context)?;
@@ -603,11 +629,7 @@ pub fn compiler_args(
603629
}
604630

605631
/// Generate compiler arguments for stdout output (no file write).
606-
///
607-
/// Calls `compiler_args` and then filters out flags that would cause file output:
608-
/// - Removes `-bs-package-name` (triggers file output mode)
609-
/// - Removes `-bs-package-output` and `-bs-suffix` (file output config)
610-
/// - Keeps only a single `-bs-module-system` for the requested format
632+
/// This is a convenience wrapper around `compiler_args` with `OutputMode::ToStdout`.
611633
pub fn compiler_args_for_stdout(
612634
config: &config::Config,
613635
ast_path: &Path,
@@ -620,8 +642,7 @@ pub fn compiler_args_for_stdout(
620642
warn_error_override: Option<String>,
621643
module_format: &str,
622644
) -> Result<Vec<String>> {
623-
// Get the base compiler args
624-
let base_args = compiler_args(
645+
compiler_args(
625646
config,
626647
ast_path,
627648
file_path,
@@ -632,48 +653,10 @@ pub fn compiler_args_for_stdout(
632653
is_type_dev,
633654
is_local_dep,
634655
warn_error_override,
635-
)?;
636-
637-
// Filter out flags that trigger file output, keeping track of what to skip
638-
let mut result = Vec::new();
639-
let mut skip_next = false;
640-
let mut seen_module_system = false;
641-
642-
for arg in base_args {
643-
if skip_next {
644-
skip_next = false;
645-
continue;
646-
}
647-
648-
match arg.as_str() {
649-
// Skip -bs-package-name and its value (triggers file output)
650-
"-bs-package-name" => {
651-
skip_next = true;
652-
}
653-
// Skip -bs-package-output and its value (file path)
654-
"-bs-package-output" => {
655-
skip_next = true;
656-
}
657-
// Skip -bs-suffix and its value (not needed for stdout)
658-
"-bs-suffix" => {
659-
skip_next = true;
660-
}
661-
// Keep only one -bs-module-system with our chosen format
662-
"-bs-module-system" => {
663-
if !seen_module_system {
664-
result.push("-bs-module-system".to_string());
665-
result.push(module_format.to_string());
666-
seen_module_system = true;
667-
}
668-
skip_next = true; // skip the original value
669-
}
670-
_ => {
671-
result.push(arg);
672-
}
673-
}
674-
}
675-
676-
Ok(result)
656+
OutputMode::ToStdout {
657+
module_format: module_format.to_string(),
658+
},
659+
)
677660
}
678661

679662
/// Compile a single file and return its JavaScript output on stdout.
@@ -875,6 +858,7 @@ fn compile_file(
875858
is_type_dev,
876859
package.is_local_dep,
877860
warn_error_override,
861+
OutputMode::ToFile,
878862
)?;
879863

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

0 commit comments

Comments
 (0)