( oldFile: string, newFile: string, lazyBlockReplacements: AstReplacements, )
| 21 | } |
| 22 | |
| 23 | function reconstructNewFile( |
| 24 | oldFile: string, |
| 25 | newFile: string, |
| 26 | lazyBlockReplacements: AstReplacements, |
| 27 | ): string { |
| 28 | // Sort acc by reverse line number |
| 29 | lazyBlockReplacements |
| 30 | .sort((a, b) => a.nodeToReplace.startIndex - b.nodeToReplace.startIndex) |
| 31 | .reverse(); |
| 32 | |
| 33 | // Reconstruct entire file by replacing lazy blocks with the replacement nodes |
| 34 | const oldFileLines = oldFile.split("\n"); |
| 35 | const newFileChars = newFile.split(""); |
| 36 | for (const { |
| 37 | nodeToReplace: lazyBlockNode, |
| 38 | replacementNodes, |
| 39 | } of lazyBlockReplacements) { |
| 40 | // Get the full string from the replacement nodes |
| 41 | let replacementText = ""; |
| 42 | if (replacementNodes.length > 0) { |
| 43 | const startPosition = replacementNodes[0].startPosition; |
| 44 | const endPosition = |
| 45 | replacementNodes[replacementNodes.length - 1].endPosition; |
| 46 | const replacementLines = oldFileLines.slice( |
| 47 | startPosition.row, |
| 48 | endPosition.row + 1, |
| 49 | ); |
| 50 | replacementLines[0] = replacementLines[0].slice(startPosition.column); |
| 51 | replacementLines[replacementLines.length - 1] = replacementLines[ |
| 52 | replacementLines.length - 1 |
| 53 | ].slice(0, endPosition.column); |
| 54 | replacementText = replacementLines.join("\n"); |
| 55 | |
| 56 | // Replace the lazy block |
| 57 | newFileChars.splice( |
| 58 | lazyBlockNode.startIndex, |
| 59 | lazyBlockNode.text.length, |
| 60 | replacementText, |
| 61 | ); |
| 62 | } else { |
| 63 | // If there are no replacements, then we want to strip the surrounding whitespace |
| 64 | // The example in calculator-exp.js.diff is a test where this is necessary |
| 65 | const lazyBlockStart = lazyBlockNode.startIndex; |
| 66 | const lazyBlockEnd = lazyBlockNode.endIndex - 1; |
| 67 | |
| 68 | // Remove leading whitespace up to two new lines |
| 69 | let startIndex = lazyBlockStart; |
| 70 | let newLinesFound = 0; |
| 71 | while ( |
| 72 | startIndex > 0 && |
| 73 | newFileChars[startIndex - 1]?.trim() === "" && |
| 74 | newLinesFound < 2 |
| 75 | ) { |
| 76 | startIndex--; |
| 77 | if (newFileChars[startIndex - 1] === "\n") { |
| 78 | newLinesFound++; |
| 79 | } |
| 80 | } |
no test coverage detected