fromStringWithSourceMap.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const base64VLQ = require("./base64-vlq");
  7. const SourceNode = require("./SourceNode");
  8. const CodeNode = require("./CodeNode");
  9. const SourceListMap = require("./SourceListMap");
  10. module.exports = function fromStringWithSourceMap(code, map) {
  11. const sources = map.sources;
  12. const sourcesContent = map.sourcesContent;
  13. const mappings = map.mappings.split(";");
  14. const lines = code.split("\n");
  15. const nodes = [];
  16. let currentNode = null;
  17. let currentLine = 1;
  18. let currentSourceIdx = 0;
  19. let currentSourceNodeLine;
  20. mappings.forEach(function(mapping, idx) {
  21. let line = lines[idx];
  22. if(typeof line === 'undefined') return;
  23. if(idx !== lines.length - 1) line += "\n";
  24. if(!mapping)
  25. return addCode(line);
  26. mapping = { value: 0, rest: mapping };
  27. let lineAdded = false;
  28. while(mapping.rest)
  29. lineAdded = processMapping(mapping, line, lineAdded) || lineAdded;
  30. if(!lineAdded)
  31. addCode(line);
  32. });
  33. if(mappings.length < lines.length) {
  34. let idx = mappings.length;
  35. while(!lines[idx].trim() && idx < lines.length-1) {
  36. addCode(lines[idx] + "\n");
  37. idx++;
  38. }
  39. addCode(lines.slice(idx).join("\n"));
  40. }
  41. return new SourceListMap(nodes);
  42. function processMapping(mapping, line, ignore) {
  43. if(mapping.rest && mapping.rest[0] !== ",") {
  44. base64VLQ.decode(mapping.rest, mapping);
  45. }
  46. if(!mapping.rest)
  47. return false;
  48. if(mapping.rest[0] === ",") {
  49. mapping.rest = mapping.rest.substr(1);
  50. return false;
  51. }
  52. base64VLQ.decode(mapping.rest, mapping);
  53. const sourceIdx = mapping.value + currentSourceIdx;
  54. currentSourceIdx = sourceIdx;
  55. let linePosition;
  56. if(mapping.rest && mapping.rest[0] !== ",") {
  57. base64VLQ.decode(mapping.rest, mapping);
  58. linePosition = mapping.value + currentLine;
  59. currentLine = linePosition;
  60. } else {
  61. linePosition = currentLine;
  62. }
  63. if(mapping.rest) {
  64. const next = mapping.rest.indexOf(",");
  65. mapping.rest = next === -1 ? "" : mapping.rest.substr(next);
  66. }
  67. if(!ignore) {
  68. addSource(line, sources ? sources[sourceIdx] : null, sourcesContent ? sourcesContent[sourceIdx] : null, linePosition)
  69. return true;
  70. }
  71. }
  72. function addCode(generatedCode) {
  73. if(currentNode && currentNode instanceof CodeNode) {
  74. currentNode.addGeneratedCode(generatedCode);
  75. } else if(currentNode && currentNode instanceof SourceNode && !generatedCode.trim()) {
  76. currentNode.addGeneratedCode(generatedCode);
  77. currentSourceNodeLine++;
  78. } else {
  79. currentNode = new CodeNode(generatedCode);
  80. nodes.push(currentNode);
  81. }
  82. }
  83. function addSource(generatedCode, source, originalSource, linePosition) {
  84. if(currentNode && currentNode instanceof SourceNode &&
  85. currentNode.source === source &&
  86. currentSourceNodeLine === linePosition
  87. ) {
  88. currentNode.addGeneratedCode(generatedCode);
  89. currentSourceNodeLine++;
  90. } else {
  91. currentNode = new SourceNode(generatedCode, source, originalSource, linePosition);
  92. currentSourceNodeLine = linePosition + 1;
  93. nodes.push(currentNode);
  94. }
  95. }
  96. };