use swc_common::{GLOBALS, Globals, BytePos, comments::{Comment}};
use dprint_core::*;
use dprint_core::configuration::{resolve_new_line_kind};
use super::*;
use super::configuration::Configuration;
pub struct Formatter<'a> {
globals: Globals,
config: &'a Configuration,
}
impl<'a> Formatter<'a> {
pub fn new(config: &'a Configuration) -> Self {
Formatter {
globals: Globals::new(),
config,
}
}
pub fn format_text(&self, file_path: &str, file_text: &str) -> Result<Option<String>, String> {
return self.run(|| {
let mut parsed_source_file = parse_swc_ast(&file_path, &file_text)?;
if !should_format_file(&mut parsed_source_file) {
return Ok(None);
}
let print_items = parse(parsed_source_file, &self.config);
println!("{}", print_items.get_as_text());
Ok(Some(print(print_items, PrintOptions {
indent_width: self.config.indent_width,
max_width: self.config.line_width,
use_tabs: self.config.use_tabs,
new_line_text: resolve_new_line_kind(file_text, self.config.new_line_kind),
})))
});
fn should_format_file(file: &mut ParsedSourceFile) -> bool {
return if file.module.body.is_empty() {
should_format_based_on_comments(file.trailing_comments.get(&BytePos(0)))
} else {
should_format_based_on_comments(file.leading_comments.get(&get_search_position(&file)))
};
fn should_format_based_on_comments(comments: Option<&Vec<Comment>>) -> bool {
if let Some(comments) = comments {
for comment in comments.iter() {
if comment.text.contains("dprint-ignore-file") {
return false;
}
}
}
return true;
}
fn get_search_position(file: &ParsedSourceFile) -> BytePos {
if let Some(first_statement) = file.module.body.get(0) {
first_statement.lo()
} else {
BytePos(0)
}
}
}
}
fn run<F, TReturn>(&self, action: F) -> TReturn where F: FnOnce() -> TReturn {
GLOBALS.set(&self.globals, action)
}
}