@@ -29,7 +29,11 @@ use oxc::{
2929 syntax:: reference:: ReferenceFlags ,
3030 transformer:: { TransformOptions , Transformer } ,
3131} ;
32- use oxc_formatter:: { FormatOptions , Formatter } ;
32+ use oxc_formatter:: {
33+ ArrowParentheses , AttributePosition , BracketSameLine , BracketSpacing , Expand , FormatOptions ,
34+ Formatter , IndentStyle , IndentWidth , LineEnding , LineWidth , OperatorPosition , QuoteProperties ,
35+ QuoteStyle , Semicolons , SortImports , SortOrder , TrailingCommas ,
36+ } ;
3337use oxc_linter:: {
3438 ConfigStore , ConfigStoreBuilder , ContextSubHost , ExternalPluginStore , LintOptions , Linter ,
3539 ModuleRecord , Oxlintrc ,
@@ -41,8 +45,9 @@ use oxc_transformer_plugins::{
4145} ;
4246
4347use crate :: options:: {
44- OxcControlFlowOptions , OxcDefineOptions , OxcInjectOptions , OxcIsolatedDeclarationsOptions ,
45- OxcLinterOptions , OxcOptions , OxcParserOptions , OxcRunOptions , OxcTransformerOptions ,
48+ OxcControlFlowOptions , OxcDefineOptions , OxcFormatterOptions , OxcInjectOptions ,
49+ OxcIsolatedDeclarationsOptions , OxcLinterOptions , OxcOptions , OxcParserOptions , OxcRunOptions ,
50+ OxcTransformerOptions ,
4651} ;
4752
4853mod options;
@@ -100,6 +105,7 @@ impl Oxc {
100105 run : ref run_options,
101106 parser : ref parser_options,
102107 linter : ref linter_options,
108+ formatter : ref formatter_options,
103109 transformer : ref transform_options,
104110 control_flow : ref control_flow_options,
105111 isolated_declarations : ref isolated_declarations_options,
@@ -109,6 +115,7 @@ impl Oxc {
109115 ..
110116 } = options;
111117 let linter_options = linter_options. clone ( ) . unwrap_or_default ( ) ;
118+ let formatter_options = formatter_options. clone ( ) . unwrap_or_default ( ) ;
112119 let transform_options = transform_options. clone ( ) . unwrap_or_default ( ) ;
113120 let control_flow_options = control_flow_options. clone ( ) . unwrap_or_default ( ) ;
114121 let codegen_options = codegen_options. clone ( ) . unwrap_or_default ( ) ;
@@ -142,14 +149,7 @@ impl Oxc {
142149 & allocator,
143150 ) ;
144151
145- // Phase 4: Run formatter
146- let parse_options = ParseOptions {
147- parse_regular_expression : true ,
148- allow_return_outside_function : parser_options. allow_return_outside_function ,
149- preserve_parens : parser_options. preserve_parens ,
150- allow_v8_intrinsics : parser_options. allow_v8_intrinsics ,
151- } ;
152- self . run_formatter ( run_options, parse_options, & source_text, source_type) ;
152+ self . run_formatter ( run_options, & source_text, source_type, & formatter_options) ;
153153
154154 let mut scoping = semantic. into_scoping ( ) ;
155155
@@ -414,30 +414,148 @@ impl Oxc {
414414 }
415415 }
416416
417+ fn convert_formatter_options ( options : & OxcFormatterOptions ) -> FormatOptions {
418+ let mut format_options = FormatOptions :: default ( ) ;
419+
420+ if let Some ( use_tabs) = options. use_tabs {
421+ format_options. indent_style =
422+ if use_tabs { IndentStyle :: Tab } else { IndentStyle :: Space } ;
423+ }
424+
425+ if let Some ( tab_width) = options. tab_width
426+ && let Ok ( width) = IndentWidth :: try_from ( tab_width)
427+ {
428+ format_options. indent_width = width;
429+ }
430+
431+ if let Some ( ref end_of_line) = options. end_of_line
432+ && let Ok ( ending) = end_of_line. parse :: < LineEnding > ( )
433+ {
434+ format_options. line_ending = ending;
435+ }
436+
437+ if let Some ( print_width) = options. print_width
438+ && let Ok ( width) = LineWidth :: try_from ( print_width)
439+ {
440+ format_options. line_width = width;
441+ }
442+
443+ if let Some ( single_quote) = options. single_quote {
444+ format_options. quote_style =
445+ if single_quote { QuoteStyle :: Single } else { QuoteStyle :: Double } ;
446+ }
447+
448+ if let Some ( jsx_single_quote) = options. jsx_single_quote {
449+ format_options. jsx_quote_style =
450+ if jsx_single_quote { QuoteStyle :: Single } else { QuoteStyle :: Double } ;
451+ }
452+
453+ if let Some ( ref quote_props) = options. quote_props
454+ && let Ok ( props) = quote_props. parse :: < QuoteProperties > ( )
455+ {
456+ format_options. quote_properties = props;
457+ }
458+
459+ if let Some ( ref trailing_comma) = options. trailing_comma
460+ && let Ok ( commas) = trailing_comma. parse :: < TrailingCommas > ( )
461+ {
462+ format_options. trailing_commas = commas;
463+ }
464+
465+ if let Some ( semi) = options. semi {
466+ format_options. semicolons =
467+ if semi { Semicolons :: Always } else { Semicolons :: AsNeeded } ;
468+ }
469+
470+ if let Some ( ref arrow_parens) = options. arrow_parens {
471+ let normalized =
472+ if arrow_parens == "avoid" { "as-needed" } else { arrow_parens. as_str ( ) } ;
473+ if let Ok ( parens) = normalized. parse :: < ArrowParentheses > ( ) {
474+ format_options. arrow_parentheses = parens;
475+ }
476+ }
477+
478+ if let Some ( bracket_spacing) = options. bracket_spacing {
479+ format_options. bracket_spacing = BracketSpacing :: from ( bracket_spacing) ;
480+ }
481+
482+ if let Some ( bracket_same_line) = options. bracket_same_line {
483+ format_options. bracket_same_line = BracketSameLine :: from ( bracket_same_line) ;
484+ }
485+
486+ if let Some ( single_attribute_per_line) = options. single_attribute_per_line {
487+ format_options. attribute_position = if single_attribute_per_line {
488+ AttributePosition :: Multiline
489+ } else {
490+ AttributePosition :: Auto
491+ } ;
492+ }
493+
494+ if let Some ( ref object_wrap) = options. object_wrap {
495+ let normalized = match object_wrap. as_str ( ) {
496+ "preserve" => "auto" ,
497+ "collapse" => "never" ,
498+ _ => object_wrap. as_str ( ) ,
499+ } ;
500+ if let Ok ( expand) = normalized. parse :: < Expand > ( ) {
501+ format_options. expand = expand;
502+ }
503+ }
504+
505+ if let Some ( ref position) = options. experimental_operator_position
506+ && let Ok ( op_position) = position. parse :: < OperatorPosition > ( )
507+ {
508+ format_options. experimental_operator_position = op_position;
509+ }
510+
511+ if let Some ( ref sort_imports_config) = options. experimental_sort_imports {
512+ let order = sort_imports_config
513+ . order
514+ . as_ref ( )
515+ . and_then ( |o| o. parse :: < SortOrder > ( ) . ok ( ) )
516+ . unwrap_or_default ( ) ;
517+
518+ format_options. experimental_sort_imports = Some ( SortImports {
519+ partition_by_newline : sort_imports_config. partition_by_newline . unwrap_or ( false ) ,
520+ partition_by_comment : sort_imports_config. partition_by_comment . unwrap_or ( false ) ,
521+ sort_side_effects : sort_imports_config. sort_side_effects . unwrap_or ( false ) ,
522+ order,
523+ ignore_case : sort_imports_config. ignore_case . unwrap_or ( true ) ,
524+ } ) ;
525+ }
526+
527+ format_options
528+ }
529+
417530 fn run_formatter (
418531 & mut self ,
419532 run_options : & OxcRunOptions ,
420- parser_options : ParseOptions ,
421533 source_text : & str ,
422534 source_type : SourceType ,
535+ formatter_options : & OxcFormatterOptions ,
423536 ) {
424537 let allocator = Allocator :: default ( ) ;
425- if run_options. formatter || run_options . formatter_ir {
538+ if run_options. formatter {
426539 let ret = Parser :: new ( & allocator, source_text, source_type)
427- . with_options ( ParseOptions { preserve_parens : false , ..parser_options } )
540+ . with_options ( ParseOptions {
541+ preserve_parens : false ,
542+ allow_return_outside_function : true ,
543+ allow_v8_intrinsics : true ,
544+ parse_regular_expression : false ,
545+ } )
428546 . parse ( ) ;
429547
430- let formatter = Formatter :: new ( & allocator , FormatOptions :: default ( ) ) ;
431- self . formatter_formatted_text = formatter . build ( & ret . program ) ;
432-
433- // if run_options.formatter_ir.unwrap_or_default() {
434- // let formatter_doc = formatter.doc(&ret.program).to_string();
435- // self.formatter_ir_text = {
436- // let ret =
437- // Parser::new(&allocator, &formatter_doc, SourceType::default()).parse() ;
438- // Formatter::new(&allocator, FormatOptions::default()).build(&ret.program)
439- // } ;
440- // }
548+ let format_options = Self :: convert_formatter_options ( formatter_options ) ;
549+ let formatter = Formatter :: new ( & allocator , format_options ) ;
550+ let formatted = formatter . format ( & ret . program ) ;
551+ if run_options. formatter {
552+ self . formatter_formatted_text = match formatted . print ( ) {
553+ Ok ( printer ) => printer . into_code ( ) ,
554+ Err ( err ) => err . to_string ( ) ,
555+ } ;
556+
557+ self . formatter_ir_text = formatted . into_document ( ) . to_string ( ) ;
558+ }
441559 }
442560 }
443561
0 commit comments