UNPKG

4.04 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5"use strict";
6
7const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks");
8const getGeneratedSourceInfo = require("./helpers/getGeneratedSourceInfo");
9const Source = require("./Source");
10
11const SPLIT_REGEX = /[^\n;{}]+[;{} \r\t]*\n?|[;{} \r\t]+\n?|\n/g;
12const SPLIT_LINES_REGEX = /[^\n]+\n?|\n/g;
13
14class OriginalSource extends Source {
15 constructor(value, name) {
16 super();
17 const isBuffer = Buffer.isBuffer(value);
18 this._value = isBuffer ? undefined : value;
19 this._valueAsBuffer = isBuffer ? value : undefined;
20 this._name = name;
21 }
22
23 getName() {
24 return this._name;
25 }
26
27 source() {
28 if (this._value === undefined) {
29 this._value = this._valueAsBuffer.toString("utf-8");
30 }
31 return this._value;
32 }
33
34 buffer() {
35 if (this._valueAsBuffer === undefined) {
36 this._valueAsBuffer = Buffer.from(this._value, "utf-8");
37 }
38 return this._valueAsBuffer;
39 }
40
41 map(options) {
42 return getMap(this, options);
43 }
44
45 sourceAndMap(options) {
46 return getSourceAndMap(this, options);
47 }
48
49 /**
50 * @param {object} options options
51 * @param {function(string, number, number, number, number, number, number): void} onChunk called for each chunk of code
52 * @param {function(number, string, string)} onSource called for each source
53 * @param {function(number, string)} onName called for each name
54 * @returns {void}
55 */
56 streamChunks(options, onChunk, onSource, onName) {
57 if (this._value === undefined) {
58 this._value = this._valueAsBuffer.toString("utf-8");
59 }
60 onSource(0, this._name, this._value);
61 const finalSource = !!(options && options.finalSource);
62 if (!options || options.columns !== false) {
63 // With column info we need to read all lines and split them
64 const matches = this._value.match(SPLIT_REGEX);
65 let line = 1;
66 let column = 0;
67 if (matches !== null) {
68 for (const match of matches) {
69 const isEndOfLine = match.endsWith("\n");
70 if (isEndOfLine && match.length === 1) {
71 if (!finalSource) onChunk(match, line, column, -1, -1, -1, -1);
72 } else {
73 const chunk = finalSource ? undefined : match;
74 onChunk(chunk, line, column, 0, line, column, -1);
75 }
76 if (isEndOfLine) {
77 line++;
78 column = 0;
79 } else {
80 column += match.length;
81 }
82 }
83 }
84 return {
85 generatedLine: line,
86 generatedColumn: column,
87 source: finalSource ? this._value : undefined
88 };
89 } else if (finalSource) {
90 // Without column info and with final source we only
91 // need meta info to generate mapping
92 const result = getGeneratedSourceInfo(this._value);
93 const { generatedLine, generatedColumn } = result;
94 if (generatedColumn === 0) {
95 for (let line = 1; line < generatedLine; line++)
96 onChunk(undefined, line, 0, 0, line, 0, -1);
97 } else {
98 for (let line = 1; line <= generatedLine; line++)
99 onChunk(undefined, line, 0, 0, line, 0, -1);
100 }
101 return result;
102 } else {
103 // Without column info, but also without final source
104 // we need to split source by lines
105 let line = 1;
106 const matches = this._value.match(SPLIT_LINES_REGEX);
107 if (matches !== null) {
108 let match;
109 for (match of matches) {
110 onChunk(finalSource ? undefined : match, line, 0, 0, line, 0, -1);
111 line++;
112 }
113 return match.endsWith("\n")
114 ? {
115 generatedLine: matches.length + 1,
116 generatedColumn: 0,
117 source: finalSource ? this._value : undefined
118 }
119 : {
120 generatedLine: matches.length,
121 generatedColumn: match.length,
122 source: finalSource ? this._value : undefined
123 };
124 }
125 return {
126 generatedLine: 1,
127 generatedColumn: 0,
128 source: finalSource ? this._value : undefined
129 };
130 }
131 }
132
133 updateHash(hash) {
134 if (this._valueAsBuffer === undefined) {
135 this._valueAsBuffer = Buffer.from(this._value, "utf-8");
136 }
137 hash.update("OriginalSource");
138 hash.update(this._valueAsBuffer);
139 hash.update(this._name || "");
140 }
141}
142
143module.exports = OriginalSource;