@@ -5,8 +5,12 @@ use serde::Serialize;
55
66use crate :: { errors:: HermesError , parse} ;
77
8- /// The entrypoint for running under the `ui_test` crate, which expects us to be
9- /// `rustc`. This is a bit of a hack, but it works.
8+ /// The entrypoint for running under the `ui_test` crate.
9+ ///
10+ /// `ui_test` expects us to behave like `rustc`:
11+ /// - Accept flags (we mostly ignore them).
12+ /// - Accept a single input file.
13+ /// - Emit JSON diagnostics to stderr.
1014pub fn run ( ) {
1115 let args: Vec < String > = env:: args ( ) . collect ( ) ;
1216
@@ -36,13 +40,13 @@ pub fn run() {
3640 // Run logic with JSON emitter
3741 let mut has_errors = false ;
3842
39- parse:: read_file_and_scan_compilation_unit ( & file_path, |source, res| {
43+ // Ignore the returned source and module list; we only care about errors.
44+ let _ = parse:: read_file_and_scan_compilation_unit ( & file_path, |source, res| {
4045 if let Err ( e) = res {
4146 has_errors = true ;
4247 emit_rustc_json ( & e, source, file_path. to_str ( ) . unwrap ( ) ) ;
4348 }
44- } )
45- . unwrap ( ) ;
49+ } ) ;
4650
4751 if has_errors {
4852 exit ( 1 ) ;
@@ -68,7 +72,7 @@ struct RustcSpan {
6872 column_start : usize ,
6973 column_end : usize ,
7074 is_primary : bool ,
71- text : Vec < RustcSpanLine > , // ui_test sometimes checks the snippet context
75+ text : Vec < RustcSpanLine > ,
7276}
7377
7478#[ derive( Serialize ) ]
@@ -78,7 +82,7 @@ struct RustcSpanLine {
7882 highlight_end : usize ,
7983}
8084
81- pub fn emit_rustc_json ( e : & HermesError , source : & str , file : & str ) {
85+ fn emit_rustc_json ( e : & HermesError , source : & str , file : & str ) {
8286 let msg = e. to_string ( ) ;
8387 // Use miette's span to get byte offsets.
8488 let span = e. labels ( ) . and_then ( |mut l| l. next ( ) ) ;
@@ -91,20 +95,23 @@ pub fn emit_rustc_json(e: &HermesError, source: &str, file: &str) {
9195 // Calculate lines/cols manually (miette makes this hard to extract
9296 // without a Report). This is isolated here now, so it's fine.
9397 let prefix = & source[ ..offset] ;
94- let line_start = prefix. lines ( ) . count ( ) . max ( 1 ) ;
95- let last_nl = prefix. rfind ( '\n' ) . map ( |i| i + 1 ) . unwrap_or ( 0 ) ;
96- let column_start = ( offset - last_nl) + 1 ;
98+ let line_idx = prefix. lines ( ) . count ( ) . max ( 1 ) - 1 ; // 0-indexed
99+ let line_start = line_idx + 1 ; // 1-indexed for rustc
97100
98- // Grab the line text for the snippet
99- let line_end_idx = source[ offset..] . find ( '\n' ) . map ( |i| offset + i) . unwrap_or ( source. len ( ) ) ;
100- let line_text = source[ last_nl..line_end_idx] . to_string ( ) ;
101+ let line_start_offset = prefix. rfind ( '\n' ) . map ( |i| i + 1 ) . unwrap_or ( 0 ) ;
102+ let column_start = ( offset - line_start_offset) + 1 ;
103+
104+ // Extract the full line text for context
105+ let line_end_offset =
106+ source[ offset..] . find ( '\n' ) . map ( |i| offset + i) . unwrap_or ( source. len ( ) ) ;
107+ let line_text = source[ line_start_offset..line_end_offset] . to_string ( ) ;
101108
102109 spans. push ( RustcSpan {
103110 file_name : file. to_string ( ) ,
104111 byte_start : offset,
105112 byte_end : offset + len,
106113 line_start,
107- line_end : line_start, // Assuming single line for simplicity
114+ line_end : line_start, // Assuming single- line span for simplicity
108115 column_start,
109116 column_end : column_start + len,
110117 is_primary : true ,
0 commit comments