(
chapters: Chapter[],
filteredFiles: {
path: string;
hunks: { oldStart: number; oldLines: number; newStart: number; newLines: number }[];
}[],
)
| 197 | } |
| 198 | |
| 199 | function sanitizeLineRefs( |
| 200 | chapters: Chapter[], |
| 201 | filteredFiles: { |
| 202 | path: string; |
| 203 | hunks: { oldStart: number; oldLines: number; newStart: number; newLines: number }[]; |
| 204 | }[], |
| 205 | ): Chapter[] { |
| 206 | const hunkSpanIndex = new Map<string, Map<number, HunkSpan>>(); |
| 207 | for (const file of filteredFiles) { |
| 208 | const spans = new Map<number, HunkSpan>(); |
| 209 | for (const hunk of file.hunks) { |
| 210 | spans.set(hunk.oldStart, { |
| 211 | oldStart: hunk.oldStart, |
| 212 | oldEnd: hunk.oldStart + hunk.oldLines - 1, |
| 213 | newStart: hunk.newStart, |
| 214 | newEnd: hunk.newStart + hunk.newLines - 1, |
| 215 | }); |
| 216 | } |
| 217 | if (spans.size > 0) { |
| 218 | hunkSpanIndex.set(file.path, spans); |
| 219 | } |
| 220 | } |
| 221 | |
| 222 | return chapters.map((chapter) => { |
| 223 | const chapterSpans = new Map<string, HunkSpan[]>(); |
| 224 | for (const ref of chapter.hunkRefs) { |
| 225 | const fileSpans = hunkSpanIndex.get(ref.filePath); |
| 226 | if (!fileSpans) continue; |
| 227 | const span = fileSpans.get(ref.oldStart); |
| 228 | if (!span) continue; |
| 229 | let spans = chapterSpans.get(ref.filePath); |
| 230 | if (!spans) { |
| 231 | spans = []; |
| 232 | chapterSpans.set(ref.filePath, spans); |
| 233 | } |
| 234 | spans.push(span); |
| 235 | } |
| 236 | |
| 237 | const keyChanges = chapter.keyChanges.flatMap((kc) => { |
| 238 | const validRefs = kc.lineRefs.filter((ref) => { |
| 239 | if (ref.startLine < 1 || ref.endLine < 1) return false; |
| 240 | if (ref.startLine > ref.endLine) return false; |
| 241 | |
| 242 | const spans = chapterSpans.get(ref.filePath); |
| 243 | if (!spans) return false; |
| 244 | |
| 245 | return spans.some((span) => { |
| 246 | const [rangeStart, rangeEnd] = |
| 247 | ref.side === DIFF_SIDE.ADDITIONS |
| 248 | ? [span.newStart, span.newEnd] |
| 249 | : [span.oldStart, span.oldEnd]; |
| 250 | if (rangeStart > rangeEnd) return false; |
| 251 | return ref.startLine >= rangeStart && ref.endLine <= rangeEnd; |
| 252 | }); |
| 253 | }); |
| 254 | |
| 255 | const uniqueRefs: typeof validRefs = []; |
| 256 | for (const ref of validRefs) { |
no outgoing calls
no test coverage detected