@@ -292,91 +292,61 @@ impl TsGoLintState {
292292 drop ( stdin) ;
293293
294294 // Stream diagnostics as they are emitted, rather than waiting for all output
295- let mut stdout = child. stdout . take ( ) . expect ( "Failed to open tsgolint stdout" ) ;
295+ let stdout = child. stdout . take ( ) . expect ( "Failed to open tsgolint stdout" ) ;
296296
297297 let stdout_handler =
298298 std:: thread:: spawn ( move || -> Result < Vec < MessageWithPosition < ' _ > > , String > {
299- let mut buffer = Vec :: with_capacity ( 8192 ) ;
300- let mut read_buf = [ 0u8 ; 8192 ] ;
299+ let msg_iter = TsGoLintMessageStream :: new ( stdout) ;
301300
302301 let mut result = vec ! [ ] ;
303302
304- loop {
305- match stdout. read ( & mut read_buf) {
306- Ok ( 0 ) => break , // EOF
307- Ok ( n) => {
308- buffer. extend_from_slice ( & read_buf[ ..n] ) ;
309-
310- // Try to parse complete messages from buffer
311- let mut cursor = std:: io:: Cursor :: new ( buffer. as_slice ( ) ) ;
312- let mut processed_up_to: u64 = 0 ;
313-
314- while cursor. position ( ) < buffer. len ( ) as u64 {
315- let start_pos = cursor. position ( ) ;
316- match parse_single_message ( & mut cursor) {
317- Ok ( TsGoLintMessage :: Error ( err) ) => {
318- return Err ( err. error ) ;
319- }
320- Ok ( TsGoLintMessage :: Diagnostic ( tsgolint_diagnostic) ) => {
321- processed_up_to = cursor. position ( ) ;
322-
323- let path = tsgolint_diagnostic. file_path . clone ( ) ;
324- let Some ( resolved_config) = resolved_configs. get ( & path)
325- else {
326- // If we don't have a resolved config for this path, skip it. We should always
327- // have a resolved config though, since we processed them already above.
328- continue ;
329- } ;
330-
331- let severity = resolved_config. rules . iter ( ) . find_map (
332- |( rule, status) | {
333- if rule. name ( ) == tsgolint_diagnostic. rule {
334- Some ( * status)
335- } else {
336- None
337- }
338- } ,
339- ) ;
340- let Some ( severity) = severity else {
341- // If the severity is not found, we should not report the diagnostic
342- continue ;
343- } ;
344-
345- let mut message_with_position: MessageWithPosition < ' _ > =
346- message_to_message_with_position (
347- Message :: from_tsgo_lint_diagnostic (
348- tsgolint_diagnostic,
349- & source_text,
350- ) ,
351- & source_text,
352- & Rope :: from_str ( & source_text) ,
353- ) ;
354-
355- message_with_position. severity =
356- if severity == AllowWarnDeny :: Deny {
357- Severity :: Error
358- } else {
359- Severity :: Warning
360- } ;
361-
362- result. push ( message_with_position) ;
363- }
364- Err ( _) => {
365- // Could not parse a complete message, break and keep remaining data
366- cursor. set_position ( start_pos) ;
367- break ;
303+ for msg in msg_iter {
304+ match msg {
305+ Ok ( TsGoLintMessage :: Error ( err) ) => {
306+ return Err ( err. error ) ;
307+ }
308+ Ok ( TsGoLintMessage :: Diagnostic ( tsgolint_diagnostic) ) => {
309+ let path = tsgolint_diagnostic. file_path . clone ( ) ;
310+ let Some ( resolved_config) = resolved_configs. get ( & path) else {
311+ // If we don't have a resolved config for this path, skip it. We should always
312+ // have a resolved config though, since we processed them already above.
313+ continue ;
314+ } ;
315+
316+ let severity =
317+ resolved_config. rules . iter ( ) . find_map ( |( rule, status) | {
318+ if rule. name ( ) == tsgolint_diagnostic. rule {
319+ Some ( * status)
320+ } else {
321+ None
368322 }
369- }
370- }
323+ } ) ;
324+ let Some ( severity) = severity else {
325+ // If the severity is not found, we should not report the diagnostic
326+ continue ;
327+ } ;
328+
329+ let mut message_with_position: MessageWithPosition < ' _ > =
330+ message_to_message_with_position (
331+ Message :: from_tsgo_lint_diagnostic (
332+ tsgolint_diagnostic,
333+ & source_text,
334+ ) ,
335+ & source_text,
336+ & Rope :: from_str ( & source_text) ,
337+ ) ;
338+
339+ message_with_position. severity = if severity == AllowWarnDeny :: Deny
340+ {
341+ Severity :: Error
342+ } else {
343+ Severity :: Warning
344+ } ;
371345
372- // Keep unprocessed data for next iteration
373- if processed_up_to > 0 {
374- #[ expect( clippy:: cast_possible_truncation) ]
375- buffer. drain ( ..processed_up_to as usize ) ;
376- }
346+ result. push ( message_with_position) ;
377347 }
378348 Err ( e) => {
379- return Err ( format ! ( "Failed to read from tsgolint stdout: {e}" ) ) ;
349+ return Err ( e ) ;
380350 }
381351 }
382352 }
0 commit comments