@@ -294,8 +294,19 @@ async function getPullRequestEditedDiffRanges(
294294 headLabel : string ,
295295 logger : Logger ,
296296) : Promise < DiffThunkRange [ ] | undefined > {
297- await getFileDiffsWithBasehead ( baseRef , headLabel , logger ) ;
298- return undefined ;
297+ const fileDiffs = await getFileDiffsWithBasehead ( baseRef , headLabel , logger ) ;
298+ if ( fileDiffs === undefined ) {
299+ return undefined ;
300+ }
301+ const results : DiffThunkRange [ ] = [ ] ;
302+ for ( const filediff of fileDiffs ) {
303+ const diffRanges = getDiffRanges ( filediff , logger ) ;
304+ if ( diffRanges === undefined ) {
305+ return undefined ;
306+ }
307+ results . push ( ...diffRanges ) ;
308+ }
309+ return results ;
299310}
300311
301312/**
@@ -348,6 +359,76 @@ async function getFileDiffsWithBasehead(
348359 }
349360}
350361
362+ function getDiffRanges (
363+ fileDiff : FileDiff ,
364+ logger : Logger ,
365+ ) : DiffThunkRange [ ] | undefined {
366+ if ( fileDiff . patch === undefined ) {
367+ return undefined ;
368+ }
369+
370+ // Diff-informed queries expect the file path to be absolute. CodeQL always
371+ // uses forward slashes as the path separator, so on Windows we need to
372+ // replace any backslashes with forward slashes.
373+ const filename = path
374+ . join ( actionsUtil . getRequiredInput ( "checkout_path" ) , fileDiff . filename )
375+ . replaceAll ( path . sep , "/" ) ;
376+
377+ // The 1-based file line number of the current line
378+ let currentLine = 0 ;
379+ // The 1-based file line number that starts the current range of added lines
380+ let additionRangeStartLine : number | undefined = undefined ;
381+ const diffRanges : DiffThunkRange [ ] = [ ] ;
382+
383+ const diffLines = fileDiff . patch . split ( "\n" ) ;
384+ // Adding a fake context line at the end ensures that the following loop will
385+ // always terminate the last range of added lines.
386+ diffLines . push ( " " ) ;
387+
388+ for ( const diffLine of diffLines ) {
389+ if ( diffLine . startsWith ( "-" ) ) {
390+ // Ignore deletions completely -- we do not even want to consider them when
391+ // calculating consecutive ranges of added lines.
392+ continue ;
393+ }
394+ if ( diffLine . startsWith ( "+" ) ) {
395+ if ( additionRangeStartLine === undefined ) {
396+ additionRangeStartLine = currentLine ;
397+ }
398+ currentLine ++ ;
399+ continue ;
400+ }
401+ if ( additionRangeStartLine !== undefined ) {
402+ // Any line that does not start with a "+" or "-" terminates the current
403+ // range of added lines.
404+ diffRanges . push ( {
405+ path : filename ,
406+ startLine : additionRangeStartLine ,
407+ endLine : currentLine - 1 ,
408+ } ) ;
409+ additionRangeStartLine = undefined ;
410+ }
411+ if ( diffLine . startsWith ( "@@ " ) ) {
412+ // A new hunk header line resets the current line number.
413+ const match = diffLine . match ( / ^ @ @ - \d + (?: , \d + ) ? \+ ( \d + ) (?: , \d + ) ? @ @ / ) ;
414+ if ( match === null ) {
415+ logger . warning (
416+ `Cannot parse diff hunk header for ${ fileDiff . filename } : ${ diffLine } ` ,
417+ ) ;
418+ return undefined ;
419+ }
420+ currentLine = parseInt ( match [ 1 ] , 10 ) ;
421+ continue ;
422+ }
423+ if ( diffLine . startsWith ( " " ) ) {
424+ // An unchanged context line advances the current line number.
425+ currentLine ++ ;
426+ continue ;
427+ }
428+ }
429+ return diffRanges ;
430+ }
431+
351432/**
352433 * Create an extension pack in the temporary directory that contains the file
353434 * line ranges that were added or modified in the pull request.
0 commit comments