* Parse a single UpdateFileChunk from lines. * Returns the parsed chunk and number of lines consumed.
( lines: string[], lineNumber: number, allowMissingContext: boolean, )
| 105 | * Returns the parsed chunk and number of lines consumed. |
| 106 | */ |
| 107 | function parseUpdateFileChunk( |
| 108 | lines: string[], |
| 109 | lineNumber: number, |
| 110 | allowMissingContext: boolean, |
| 111 | ): { chunk: UpdateFileChunk; linesConsumed: number } { |
| 112 | if (lines.length === 0) { |
| 113 | throw new ParseError("Update hunk does not contain any lines", lineNumber) |
| 114 | } |
| 115 | |
| 116 | let changeContext: string | null = null |
| 117 | let startIndex = 0 |
| 118 | |
| 119 | // Check for context marker |
| 120 | if (lines[0] === EMPTY_CHANGE_CONTEXT_MARKER) { |
| 121 | changeContext = null |
| 122 | startIndex = 1 |
| 123 | } else if (lines[0]?.startsWith(CHANGE_CONTEXT_MARKER)) { |
| 124 | changeContext = lines[0].substring(CHANGE_CONTEXT_MARKER.length) |
| 125 | startIndex = 1 |
| 126 | } else if (!allowMissingContext) { |
| 127 | throw new ParseError(`Expected update hunk to start with a @@ context marker, got: '${lines[0]}'`, lineNumber) |
| 128 | } |
| 129 | |
| 130 | if (startIndex >= lines.length) { |
| 131 | throw new ParseError("Update hunk does not contain any lines", lineNumber + 1) |
| 132 | } |
| 133 | |
| 134 | const chunk: UpdateFileChunk = { |
| 135 | changeContext, |
| 136 | oldLines: [], |
| 137 | newLines: [], |
| 138 | isEndOfFile: false, |
| 139 | } |
| 140 | |
| 141 | let parsedLines = 0 |
| 142 | for (let i = startIndex; i < lines.length; i++) { |
| 143 | const line = lines[i] |
| 144 | |
| 145 | if (line === EOF_MARKER) { |
| 146 | if (parsedLines === 0) { |
| 147 | throw new ParseError("Update hunk does not contain any lines", lineNumber + 1) |
| 148 | } |
| 149 | chunk.isEndOfFile = true |
| 150 | parsedLines++ |
| 151 | break |
| 152 | } |
| 153 | |
| 154 | const firstChar = line.charAt(0) |
| 155 | |
| 156 | // Empty line is treated as context |
| 157 | if (line === "") { |
| 158 | chunk.oldLines.push("") |
| 159 | chunk.newLines.push("") |
| 160 | parsedLines++ |
| 161 | continue |
| 162 | } |
| 163 | |
| 164 | switch (firstChar) { |