@@ -16,8 +16,8 @@ use rspack_core::{
1616 diagnostics:: ModuleParseError ,
1717 rspack_sources:: { BoxSource , RawStringSource , Source , SourceExt } ,
1818 BuildMetaDefaultObject , BuildMetaExportsType , ChunkGraph , CompilerOptions , ExportsInfo ,
19- GenerateContext , Module , ModuleGraph , ParserAndGenerator , Plugin , RuntimeGlobals , RuntimeSpec ,
20- SourceType , UsageState , NAMESPACE_OBJECT_EXPORT ,
19+ GenerateContext , Module , ModuleGraph , ParseOption , ParserAndGenerator , Plugin , RuntimeGlobals ,
20+ RuntimeSpec , SourceType , UsageState , NAMESPACE_OBJECT_EXPORT ,
2121} ;
2222use rspack_error:: {
2323 miette:: diagnostic, DiagnosticExt , DiagnosticKind , IntoTWithDiagnosticArray , Result ,
@@ -34,6 +34,7 @@ mod utils;
3434#[ derive( Debug ) ]
3535struct JsonParserAndGenerator {
3636 pub exports_depth : u32 ,
37+ pub parse : ParseOption ,
3738}
3839
3940#[ cacheable_dyn]
@@ -55,54 +56,68 @@ impl ParserAndGenerator for JsonParserAndGenerator {
5556 build_info,
5657 build_meta,
5758 loaders,
59+ module_parser_options,
5860 ..
5961 } = parse_context;
6062 let source = box_source. source ( ) ;
6163 let strip_bom_source = source. strip_prefix ( '\u{feff}' ) ;
6264 let need_strip_bom = strip_bom_source. is_some ( ) ;
65+ let strip_bom_source = strip_bom_source. unwrap_or ( & source) ;
6366
64- let parse_result = json:: parse ( strip_bom_source. unwrap_or ( & source) ) . map_err ( |e| {
65- match e {
66- UnexpectedCharacter { ch, line, column } => {
67- let rope = ropey:: Rope :: from_str ( & source) ;
68- let line_offset = rope. try_line_to_byte ( line - 1 ) . expect ( "TODO:" ) ;
69- let start_offset = source[ line_offset..]
70- . chars ( )
71- . take ( column)
72- . fold ( line_offset, |acc, cur| acc + cur. len_utf8 ( ) ) ;
73- let start_offset = if need_strip_bom {
74- start_offset + 1
75- } else {
76- start_offset
77- } ;
78- TraceableError :: from_file (
79- source. into_owned ( ) ,
80- // one character offset
81- start_offset,
82- start_offset + 1 ,
83- "Json parsing error" . to_string ( ) ,
84- format ! ( "Unexpected character {ch}" ) ,
85- )
86- . with_kind ( DiagnosticKind :: Json )
87- . boxed ( )
67+ // If there is a custom parse, execute it to obtain the returned string.
68+ let parse_result_str = module_parser_options
69+ . and_then ( |p| p. get_json ( ) )
70+ . and_then ( |p| match & p. parse {
71+ ParseOption :: Func ( p) => {
72+ let parse_result = p ( strip_bom_source. to_string ( ) ) ;
73+ parse_result. ok ( )
8874 }
89- ExceededDepthLimit | WrongType ( _) | FailedUtf8Parsing => diagnostic ! ( "{e}" ) . boxed ( ) ,
90- UnexpectedEndOfJson => {
91- // End offset of json file
92- let length = source. len ( ) ;
93- let offset = if length > 0 { length - 1 } else { length } ;
94- TraceableError :: from_file (
95- source. into_owned ( ) ,
96- offset,
97- offset,
98- "Json parsing error" . to_string ( ) ,
99- format ! ( "{e}" ) ,
100- )
101- . with_kind ( DiagnosticKind :: Json )
102- . boxed ( )
75+ _ => None ,
76+ } ) ;
77+
78+ let parse_result = json:: parse ( parse_result_str. as_deref ( ) . unwrap_or ( strip_bom_source) )
79+ . map_err ( |e| {
80+ match e {
81+ UnexpectedCharacter { ch, line, column } => {
82+ let rope = ropey:: Rope :: from_str ( & source) ;
83+ let line_offset = rope. try_line_to_byte ( line - 1 ) . expect ( "TODO:" ) ;
84+ let start_offset = source[ line_offset..]
85+ . chars ( )
86+ . take ( column)
87+ . fold ( line_offset, |acc, cur| acc + cur. len_utf8 ( ) ) ;
88+ let start_offset = if need_strip_bom {
89+ start_offset + 1
90+ } else {
91+ start_offset
92+ } ;
93+ TraceableError :: from_file (
94+ source. into_owned ( ) ,
95+ // one character offset
96+ start_offset,
97+ start_offset + 1 ,
98+ "Json parsing error" . to_string ( ) ,
99+ format ! ( "Unexpected character {ch}" ) ,
100+ )
101+ . with_kind ( DiagnosticKind :: Json )
102+ . boxed ( )
103+ }
104+ ExceededDepthLimit | WrongType ( _) | FailedUtf8Parsing => diagnostic ! ( "{e}" ) . boxed ( ) ,
105+ UnexpectedEndOfJson => {
106+ // End offset of json file
107+ let length = source. len ( ) ;
108+ let offset = if length > 0 { length - 1 } else { length } ;
109+ TraceableError :: from_file (
110+ source. into_owned ( ) ,
111+ offset,
112+ offset,
113+ "Json parsing error" . to_string ( ) ,
114+ format ! ( "{e}" ) ,
115+ )
116+ . with_kind ( DiagnosticKind :: Json )
117+ . boxed ( )
118+ }
103119 }
104- }
105- } ) ;
120+ } ) ;
106121
107122 let ( diagnostics, data) = match parse_result {
108123 Ok ( data) => ( vec ! [ ] , Some ( data) ) ,
@@ -236,6 +251,7 @@ impl Plugin for JsonPlugin {
236251
237252 Box :: new ( JsonParserAndGenerator {
238253 exports_depth : p. exports_depth . expect ( "should have exports_depth" ) ,
254+ parse : p. parse . clone ( ) ,
239255 } )
240256 } ) ,
241257 ) ;
0 commit comments