PrefixSource.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const Source = require("./Source");
  7. const RawSource = require("./RawSource");
  8. const streamChunks = require("./helpers/streamChunks");
  9. const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks");
  10. const REPLACE_REGEX = /\n(?=.|\s)/g;
  11. class PrefixSource extends Source {
  12. constructor(prefix, source) {
  13. super();
  14. this._source =
  15. typeof source === "string" || Buffer.isBuffer(source)
  16. ? new RawSource(source, true)
  17. : source;
  18. this._prefix = prefix;
  19. }
  20. getPrefix() {
  21. return this._prefix;
  22. }
  23. original() {
  24. return this._source;
  25. }
  26. source() {
  27. const node = this._source.source();
  28. const prefix = this._prefix;
  29. return prefix + node.replace(REPLACE_REGEX, "\n" + prefix);
  30. }
  31. // TODO efficient buffer() implementation
  32. map(options) {
  33. return getMap(this, options);
  34. }
  35. sourceAndMap(options) {
  36. return getSourceAndMap(this, options);
  37. }
  38. streamChunks(options, onChunk, onSource, onName) {
  39. const prefix = this._prefix;
  40. const prefixOffset = prefix.length;
  41. const linesOnly = !!(options && options.columns === false);
  42. const { generatedLine, generatedColumn, source } = streamChunks(
  43. this._source,
  44. options,
  45. (
  46. chunk,
  47. generatedLine,
  48. generatedColumn,
  49. sourceIndex,
  50. originalLine,
  51. originalColumn,
  52. nameIndex
  53. ) => {
  54. if (generatedColumn !== 0) {
  55. // In the middle of the line, we just adject the column
  56. generatedColumn += prefixOffset;
  57. } else if (chunk !== undefined) {
  58. // At the start of the line, when we have source content
  59. // add the prefix as generated mapping
  60. // (in lines only mode we just add it to the original mapping
  61. // for performance reasons)
  62. if (linesOnly || sourceIndex < 0) {
  63. chunk = prefix + chunk;
  64. } else if (prefixOffset > 0) {
  65. onChunk(prefix, generatedLine, generatedColumn, -1, -1, -1, -1);
  66. generatedColumn += prefixOffset;
  67. }
  68. } else if (!linesOnly) {
  69. // Without source content, we only need to adject the column info
  70. // expect in lines only mode where prefix is added to original mapping
  71. generatedColumn += prefixOffset;
  72. }
  73. onChunk(
  74. chunk,
  75. generatedLine,
  76. generatedColumn,
  77. sourceIndex,
  78. originalLine,
  79. originalColumn,
  80. nameIndex
  81. );
  82. },
  83. onSource,
  84. onName
  85. );
  86. return {
  87. generatedLine,
  88. generatedColumn:
  89. generatedColumn === 0 ? 0 : prefixOffset + generatedColumn,
  90. source:
  91. source !== undefined
  92. ? prefix + source.replace(REPLACE_REGEX, "\n" + prefix)
  93. : undefined
  94. };
  95. }
  96. updateHash(hash) {
  97. hash.update("PrefixSource");
  98. this._source.updateHash(hash);
  99. hash.update(this._prefix);
  100. }
  101. }
  102. module.exports = PrefixSource;