* Checks if the hunk can be made to fit at the provided location with at most `maxErrors` * insertions, substitutions, or deletions, while ensuring also that: * - lines deleted in the hunk match exactly, and * - wherever an insertion operation or block of insertion operations appears in the
(
hunkLines: string[],
toPos: number,
maxErrors: number,
hunkLinesI: number = 0,
lastContextLineMatched: boolean = true,
patchedLines: string[] = [],
patchedLinesLength: number = 0
)
| 154 | * `replacementLines`. Otherwise, returns null. |
| 155 | */ |
| 156 | function applyHunk( |
| 157 | hunkLines: string[], |
| 158 | toPos: number, |
| 159 | maxErrors: number, |
| 160 | hunkLinesI: number = 0, |
| 161 | lastContextLineMatched: boolean = true, |
| 162 | patchedLines: string[] = [], |
| 163 | patchedLinesLength: number = 0 |
| 164 | ): ApplyHunkReturnType | null { |
| 165 | let nConsecutiveOldContextLines = 0; |
| 166 | let nextContextLineMustMatch = false; |
| 167 | for (; hunkLinesI < hunkLines.length; hunkLinesI++) { |
| 168 | const hunkLine = hunkLines[hunkLinesI], |
| 169 | operation = (hunkLine.length > 0 ? hunkLine[0] : ' '), |
| 170 | content = (hunkLine.length > 0 ? hunkLine.substr(1) : hunkLine); |
| 171 | |
| 172 | if (operation === '-') { |
| 173 | if (compareLine(toPos + 1, lines[toPos], operation, content)) { |
| 174 | toPos++; |
| 175 | nConsecutiveOldContextLines = 0; |
| 176 | } else { |
| 177 | if (!maxErrors || lines[toPos] == null) { |
| 178 | return null; |
| 179 | } |
| 180 | patchedLines[patchedLinesLength] = lines[toPos]; |
| 181 | return applyHunk( |
| 182 | hunkLines, |
| 183 | toPos + 1, |
| 184 | maxErrors - 1, |
| 185 | hunkLinesI, |
| 186 | false, |
| 187 | patchedLines, |
| 188 | patchedLinesLength + 1 |
| 189 | ); |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | if (operation === '+') { |
| 194 | if (!lastContextLineMatched) { |
| 195 | return null; |
| 196 | } |
| 197 | patchedLines[patchedLinesLength] = content; |
| 198 | patchedLinesLength++; |
| 199 | nConsecutiveOldContextLines = 0; |
| 200 | nextContextLineMustMatch = true; |
| 201 | } |
| 202 | |
| 203 | if (operation === ' ') { |
| 204 | nConsecutiveOldContextLines++; |
| 205 | patchedLines[patchedLinesLength] = lines[toPos]; |
| 206 | if (compareLine(toPos + 1, lines[toPos], operation, content)) { |
| 207 | patchedLinesLength++; |
| 208 | lastContextLineMatched = true; |
| 209 | nextContextLineMustMatch = false; |
| 210 | toPos++; |
| 211 | } else { |
| 212 | if (nextContextLineMustMatch || !maxErrors) { |
| 213 | return null; |
no test coverage detected