streamChunksOfRawSource.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const getGeneratedSourceInfo = require("./getGeneratedSourceInfo");
  7. /** @typedef {import("./getGeneratedSourceInfo").GeneratedSourceInfo} GeneratedSourceInfo */
  8. /** @typedef {import("./streamChunks").OnChunk} OnChunk */
  9. /** @typedef {import("./streamChunks").OnName} OnName */
  10. /** @typedef {import("./streamChunks").OnSource} OnSource */
  11. /**
  12. * @param {string} source source
  13. * @param {OnChunk} onChunk on chunk
  14. * @param {OnSource} _onSource on source
  15. * @param {OnName} _onName on name
  16. * @returns {GeneratedSourceInfo} source info
  17. *
  18. * Single-pass equivalent of `splitIntoLines(source).forEach(emit)` — emits
  19. * each line via onChunk while scanning for newlines, so we never allocate
  20. * the intermediate array of lines.
  21. */
  22. const streamChunksOfRawSource = (source, onChunk, _onSource, _onName) => {
  23. const len = source.length;
  24. if (len === 0) {
  25. return { generatedLine: 1, generatedColumn: 0 };
  26. }
  27. let line = 1;
  28. let i = 0;
  29. while (i < len) {
  30. const n = source.indexOf("\n", i);
  31. if (n === -1) {
  32. // Trailing partial line (no \n). Emit and return its length as the
  33. // final column.
  34. const lastLine = i === 0 ? source : source.slice(i);
  35. onChunk(lastLine, line, 0, -1, -1, -1, -1);
  36. return { generatedLine: line, generatedColumn: lastLine.length };
  37. }
  38. const chunk = n === i ? "\n" : source.slice(i, n + 1);
  39. onChunk(chunk, line, 0, -1, -1, -1, -1);
  40. line++;
  41. i = n + 1;
  42. }
  43. // Source ended with a newline — the next "logical" line is empty.
  44. return { generatedLine: line, generatedColumn: 0 };
  45. };
  46. /**
  47. * @param {string} source source
  48. * @param {OnChunk} onChunk on chunk
  49. * @param {OnSource} onSource on source
  50. * @param {OnName} onName on name
  51. * @param {boolean} finalSource is final source
  52. * @returns {GeneratedSourceInfo} source info
  53. */
  54. module.exports = (source, onChunk, onSource, onName, finalSource) =>
  55. finalSource
  56. ? getGeneratedSourceInfo(source)
  57. : streamChunksOfRawSource(source, onChunk, onSource, onName);