computeSourceMap.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import {GenMapping, maybeAddSegment, toEncodedMap} from "@jridgewell/gen-mapping";
  2. import {charCodes} from "./parser/util/charcodes";
  3. /**
  4. * Generate a source map indicating that each line maps directly to the original line,
  5. * with the tokens in their new positions.
  6. */
  7. export default function computeSourceMap(
  8. {code: generatedCode, mappings: rawMappings},
  9. filePath,
  10. options,
  11. source,
  12. tokens,
  13. ) {
  14. const sourceColumns = computeSourceColumns(source, tokens);
  15. const map = new GenMapping({file: options.compiledFilename});
  16. let tokenIndex = 0;
  17. // currentMapping is the output source index for the current input token being
  18. // considered.
  19. let currentMapping = rawMappings[0];
  20. while (currentMapping === undefined && tokenIndex < rawMappings.length - 1) {
  21. tokenIndex++;
  22. currentMapping = rawMappings[tokenIndex];
  23. }
  24. let line = 0;
  25. let lineStart = 0;
  26. if (currentMapping !== lineStart) {
  27. maybeAddSegment(map, line, 0, filePath, line, 0);
  28. }
  29. for (let i = 0; i < generatedCode.length; i++) {
  30. if (i === currentMapping) {
  31. const genColumn = currentMapping - lineStart;
  32. const sourceColumn = sourceColumns[tokenIndex];
  33. maybeAddSegment(map, line, genColumn, filePath, line, sourceColumn);
  34. while (
  35. (currentMapping === i || currentMapping === undefined) &&
  36. tokenIndex < rawMappings.length - 1
  37. ) {
  38. tokenIndex++;
  39. currentMapping = rawMappings[tokenIndex];
  40. }
  41. }
  42. if (generatedCode.charCodeAt(i) === charCodes.lineFeed) {
  43. line++;
  44. lineStart = i + 1;
  45. if (currentMapping !== lineStart) {
  46. maybeAddSegment(map, line, 0, filePath, line, 0);
  47. }
  48. }
  49. }
  50. const {sourceRoot, sourcesContent, ...sourceMap} = toEncodedMap(map);
  51. return sourceMap ;
  52. }
  53. /**
  54. * Create an array mapping each token index to the 0-based column of the start
  55. * position of the token.
  56. */
  57. function computeSourceColumns(code, tokens) {
  58. const sourceColumns = new Array(tokens.length);
  59. let tokenIndex = 0;
  60. let currentMapping = tokens[tokenIndex].start;
  61. let lineStart = 0;
  62. for (let i = 0; i < code.length; i++) {
  63. if (i === currentMapping) {
  64. sourceColumns[tokenIndex] = currentMapping - lineStart;
  65. tokenIndex++;
  66. currentMapping = tokens[tokenIndex].start;
  67. }
  68. if (code.charCodeAt(i) === charCodes.lineFeed) {
  69. lineStart = i + 1;
  70. }
  71. }
  72. return sourceColumns;
  73. }