You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
3.0 KiB

4 years ago
  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. function addCode(generatedCode) {
  21. if(currentNode && currentNode instanceof CodeNode) {
  22. currentNode.addGeneratedCode(generatedCode);
  23. } else if(currentNode && currentNode instanceof SourceNode && !generatedCode.trim()) {
  24. currentNode.addGeneratedCode(generatedCode);
  25. currentSourceNodeLine++;
  26. } else {
  27. currentNode = new CodeNode(generatedCode);
  28. nodes.push(currentNode);
  29. }
  30. }
  31. function addSource(generatedCode, source, originalSource, linePosition) {
  32. if(currentNode && currentNode instanceof SourceNode &&
  33. currentNode.source === source &&
  34. currentSourceNodeLine === linePosition
  35. ) {
  36. currentNode.addGeneratedCode(generatedCode);
  37. currentSourceNodeLine++;
  38. } else {
  39. currentNode = new SourceNode(generatedCode, source, originalSource, linePosition);
  40. currentSourceNodeLine = linePosition + 1;
  41. nodes.push(currentNode);
  42. }
  43. }
  44. mappings.forEach(function(mapping, idx) {
  45. let line = lines[idx];
  46. if(typeof line === 'undefined') return;
  47. if(idx !== lines.length - 1) line += "\n";
  48. if(!mapping)
  49. return addCode(line);
  50. mapping = { value: 0, rest: mapping };
  51. let lineAdded = false;
  52. while(mapping.rest)
  53. lineAdded = processMapping(mapping, line, lineAdded) || lineAdded;
  54. if(!lineAdded)
  55. addCode(line);
  56. });
  57. if(mappings.length < lines.length) {
  58. let idx = mappings.length;
  59. while(!lines[idx].trim() && idx < lines.length-1) {
  60. addCode(lines[idx] + "\n");
  61. idx++;
  62. }
  63. addCode(lines.slice(idx).join("\n"));
  64. }
  65. return new SourceListMap(nodes);
  66. function processMapping(mapping, line, ignore) {
  67. if(mapping.rest && mapping.rest[0] !== ",") {
  68. base64VLQ.decode(mapping.rest, mapping);
  69. }
  70. if(!mapping.rest)
  71. return false;
  72. if(mapping.rest[0] === ",") {
  73. mapping.rest = mapping.rest.substr(1);
  74. return false;
  75. }
  76. base64VLQ.decode(mapping.rest, mapping);
  77. const sourceIdx = mapping.value + currentSourceIdx;
  78. currentSourceIdx = sourceIdx;
  79. let linePosition;
  80. if(mapping.rest && mapping.rest[0] !== ",") {
  81. base64VLQ.decode(mapping.rest, mapping);
  82. linePosition = mapping.value + currentLine;
  83. currentLine = linePosition;
  84. } else {
  85. linePosition = currentLine;
  86. }
  87. if(mapping.rest) {
  88. const next = mapping.rest.indexOf(",");
  89. mapping.rest = next === -1 ? "" : mapping.rest.substr(next);
  90. }
  91. if(!ignore) {
  92. addSource(line, sources ? sources[sourceIdx] : null, sourcesContent ? sourcesContent[sourceIdx] : null, linePosition)
  93. return true;
  94. }
  95. }
  96. };