export function mergeFileLists()

in server/aws-lsp-codewhisperer/src/language-server/agenticChat/context/contextUtils.ts [133:189]


export function mergeFileLists(fileList1: FileList, fileList2: FileList): FileList {
    // Handle empty lists
    if (!fileList1.filePaths?.length) {
        return fileList2
    }
    if (!fileList2.filePaths?.length) {
        return fileList1
    }

    // Initialize the result
    const mergedFilePaths: string[] = []
    const mergedDetails: Record<string, FileDetails> = {}

    // Process all files from fileList1
    fileList1.filePaths?.forEach(filePath => {
        mergedFilePaths.push(filePath)
        mergedDetails[filePath] = { ...fileList1.details?.[filePath] }
    })

    // Process all files from fileList2
    fileList2.filePaths?.forEach(filePath => {
        // If the file already exists in the merged result, merge the line ranges
        if (mergedDetails[filePath]) {
            const existingRanges = mergedDetails[filePath].lineRanges || []
            const newRanges = fileList2.details?.[filePath].lineRanges || []

            // Combine and sort all ranges
            const combinedRanges = [...existingRanges, ...newRanges].sort((a, b) => a.first - b.first)

            // Merge overlapping ranges
            const mergedRanges: Array<{ first: number; second: number }> = []
            for (const range of combinedRanges) {
                if (mergedRanges.length === 0 || mergedRanges[mergedRanges.length - 1].second < range.first - 1) {
                    // No overlap, add new range
                    mergedRanges.push({ ...range })
                } else {
                    // Merge overlapping or consecutive ranges
                    mergedRanges[mergedRanges.length - 1].second = Math.max(
                        mergedRanges[mergedRanges.length - 1].second,
                        range.second
                    )
                }
            }

            mergedDetails[filePath].lineRanges = mergedRanges
        } else {
            // If the file doesn't exist in the merged result, add it
            mergedFilePaths.push(filePath)
            mergedDetails[filePath] = { ...fileList2.details?.[filePath] }
        }
    })

    return {
        filePaths: mergedFilePaths,
        details: mergedDetails,
    }
}