@@ -29,10 +29,13 @@ fn missing_super_some(span: Span) -> OxcDiagnostic {
2929 . with_label ( span)
3030}
3131
32- fn duplicate_super ( span : Span ) -> OxcDiagnostic {
32+ fn duplicate_super ( span : Span , first_super_span : Span ) -> OxcDiagnostic {
3333 OxcDiagnostic :: warn ( "Unexpected duplicate `super()`." )
3434 . with_help ( "Remove the duplicate `super()` call" )
35- . with_label ( span)
35+ . with_labels ( [
36+ span. primary_label ( "This path may call `super()` after it was already called." ) ,
37+ first_super_span. label ( "`super()` was first called here." ) ,
38+ ] )
3639}
3740
3841#[ derive( Clone , Copy ) ]
@@ -273,9 +276,10 @@ impl Rule for ConstructorSuper {
273276 if super_call_spans. len ( ) > 1 {
274277 let mut sorted_spans = super_call_spans;
275278 sorted_spans. sort_by_key ( |s| s. start ) ;
279+ let first_super_span = sorted_spans[ 0 ] ;
276280
277281 for & span in sorted_spans. iter ( ) . skip ( 1 ) {
278- ctx. diagnostic ( duplicate_super ( span) ) ;
282+ ctx. diagnostic ( duplicate_super ( span, first_super_span ) ) ;
279283 }
280284 }
281285 } else {
@@ -307,9 +311,10 @@ impl Rule for ConstructorSuper {
307311 if has_duplicate && super_call_spans. len ( ) > 1 {
308312 let mut sorted_spans = super_call_spans;
309313 sorted_spans. sort_by_key ( |s| s. start ) ;
314+ let first_super_span = sorted_spans[ 0 ] ;
310315
311316 for & span in sorted_spans. iter ( ) . skip ( 1 ) {
312- ctx. diagnostic ( duplicate_super ( span) ) ;
317+ ctx. diagnostic ( duplicate_super ( span, first_super_span ) ) ;
313318 }
314319 }
315320 }
@@ -432,13 +437,13 @@ impl ConstructorSuper {
432437 record_super ( span) ;
433438 }
434439 }
435- // Special case: `super() || super()` - report both as duplicate.
440+ // Special case: `super() || super()` - report the RHS as duplicate.
436441 //
437442 // Technically, `super()` returns the constructed instance (truthy),
438443 // so the RHS of `||` won't execute at runtime. However:
439- // 1. ESLint reports this as duplicate for compatibility
444+ // 1. ESLint reports the RHS as a duplicate for compatibility
440445 // 2. This code pattern is almost certainly a mistake
441- // 3. The CFG doesn't catch this because it sees only LHS as reachable
446+ // 3. The CFG records the reachable LHS, but not the short-circuited RHS
442447 //
443448 // We intentionally match ESLint's behavior here.
444449 Expression :: LogicalExpression ( logical)
@@ -457,14 +462,13 @@ impl ConstructorSuper {
457462 let left_span = check_super ( & logical. left ) ;
458463 let right_span = check_super ( & logical. right ) ;
459464
460- // Report both super() calls as duplicates if both exist
461- if left_span. is_some ( ) && right_span. is_some ( ) {
462- if let Some ( span) = left_span {
463- record_super ( span) ;
464- }
465- if let Some ( span) = right_span {
466- record_super ( span) ;
467- }
465+ // The CFG records the reachable left `super()` call. Add the
466+ // right call so `super() || super()` still matches ESLint's
467+ // duplicate-super behavior.
468+ if left_span. is_some ( )
469+ && let Some ( span) = right_span
470+ {
471+ record_super ( span) ;
468472 }
469473 }
470474 _ => { }
0 commit comments