@@ -12,7 +12,7 @@ const TS_EXTS = new Set(["ts", "tsx", "mts", "cts"]);
1212
1313const CAST_RE = / \b a s \s + a n y \b / ;
1414const ASSERTION_RE = / < \s * a n y \s * > / ;
15- const ANNOTATION_RE = / : \s * a n y \b (? ! \s * \} ) / ;
15+ const ANNOTATION_RE = / : \s * a n y \b (? ! \s * [ , } ] ) / ;
1616
1717function isTypeScriptPath ( path : string ) : boolean {
1818 const ext = / \. ( [ ^ . ] + ) $ / . exec ( path ) ?. [ 1 ] ?. toLowerCase ( ) ;
@@ -31,6 +31,31 @@ function isFullLineComment(line: string): boolean {
3131 return / ^ \s * \/ \* [ \s \S ] * \* \/ \s * $ / . test ( line ) ;
3232}
3333
34+ type BlockCommentState = { open : boolean } ;
35+
36+ /** Remove block-comment spans from one added line, tracking multi-line comment state. Pure aside from state. */
37+ export function stripBlockCommentsFromAddedLine ( line : string , state : BlockCommentState ) : string | null {
38+ let scanLine = line ;
39+ if ( state . open ) {
40+ const end = scanLine . indexOf ( "*/" ) ;
41+ if ( end < 0 ) return null ;
42+ state . open = false ;
43+ scanLine = scanLine . slice ( end + 2 ) ;
44+ }
45+ while ( true ) {
46+ const start = scanLine . indexOf ( "/*" ) ;
47+ if ( start < 0 ) break ;
48+ const end = scanLine . indexOf ( "*/" , start + 2 ) ;
49+ if ( end < 0 ) {
50+ scanLine = scanLine . slice ( 0 , start ) ;
51+ state . open = true ;
52+ break ;
53+ }
54+ scanLine = `${ scanLine . slice ( 0 , start ) } ${ scanLine . slice ( end + 2 ) } ` ;
55+ }
56+ return scanLine ;
57+ }
58+
3459/** Classify one added TS line for an unsafe-`any` pattern, or null. Pure. */
3560export function detectUnsafeAny ( line : string ) : UnsafeAnyFinding [ "kind" ] | null {
3661 if ( isFullLineComment ( line ) ) return null ;
@@ -57,27 +82,35 @@ export function scanPatchForUnsafeAny(
5782 const findings : UnsafeAnyFinding [ ] = [ ] ;
5883 let newLine = 0 ;
5984 let inHunk = false ;
85+ const blockComment : BlockCommentState = { open : false } ;
6086 for ( const line of patch . split ( "\n" ) ) {
6187 if ( limits . signal ?. aborted ) throw new Error ( "analyzer_aborted" ) ;
6288 const hunk = / ^ @ @ - \d + (?: , \d + ) ? \+ ( \d + ) (?: , \d + ) ? @ @ / . exec ( line ) ;
6389 if ( hunk ) {
6490 newLine = Number ( hunk [ 1 ] ) ;
6591 inHunk = true ;
92+ blockComment . open = false ;
6693 continue ;
6794 }
6895 if ( ! inHunk ) continue ;
6996 if ( line . startsWith ( "+" ) ) {
7097 const body = line . slice ( 1 ) ;
7198 if ( body . length <= MAX_LINE_CHARS ) {
72- const kind = detectUnsafeAny ( body ) ;
73- if ( kind ) {
74- findings . push ( { file : path , line : newLine , kind } ) ;
75- if ( findings . length >= maxFindings ) return findings ;
99+ const scanLine = stripBlockCommentsFromAddedLine ( body , blockComment ) ;
100+ if ( scanLine !== null ) {
101+ const kind = detectUnsafeAny ( scanLine ) ;
102+ if ( kind ) {
103+ findings . push ( { file : path , line : newLine , kind } ) ;
104+ if ( findings . length >= maxFindings ) return findings ;
105+ }
76106 }
77107 }
78108 newLine ++ ;
79- } else if ( ! line . startsWith ( "-" ) && ! line . startsWith ( "\\" ) ) {
80- newLine ++ ;
109+ } else {
110+ blockComment . open = false ;
111+ if ( ! line . startsWith ( "-" ) && ! line . startsWith ( "\\" ) ) {
112+ newLine ++ ;
113+ }
81114 }
82115 }
83116 return findings ;
0 commit comments