136 lines
3.8 KiB
JavaScript
136 lines
3.8 KiB
JavaScript
|
/*
|
||
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
||
|
Author Tobias Koppers @sokra
|
||
|
*/
|
||
|
"use strict";
|
||
|
|
||
|
const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks");
|
||
|
const splitIntoLines = require("./helpers/splitIntoLines");
|
||
|
const getGeneratedSourceInfo = require("./helpers/getGeneratedSourceInfo");
|
||
|
const Source = require("./Source");
|
||
|
const splitIntoPotentialTokens = require("./helpers/splitIntoPotentialTokens");
|
||
|
|
||
|
class OriginalSource extends Source {
|
||
|
constructor(value, name) {
|
||
|
super();
|
||
|
const isBuffer = Buffer.isBuffer(value);
|
||
|
this._value = isBuffer ? undefined : value;
|
||
|
this._valueAsBuffer = isBuffer ? value : undefined;
|
||
|
this._name = name;
|
||
|
}
|
||
|
|
||
|
getName() {
|
||
|
return this._name;
|
||
|
}
|
||
|
|
||
|
source() {
|
||
|
if (this._value === undefined) {
|
||
|
this._value = this._valueAsBuffer.toString("utf-8");
|
||
|
}
|
||
|
return this._value;
|
||
|
}
|
||
|
|
||
|
buffer() {
|
||
|
if (this._valueAsBuffer === undefined) {
|
||
|
this._valueAsBuffer = Buffer.from(this._value, "utf-8");
|
||
|
}
|
||
|
return this._valueAsBuffer;
|
||
|
}
|
||
|
|
||
|
map(options) {
|
||
|
return getMap(this, options);
|
||
|
}
|
||
|
|
||
|
sourceAndMap(options) {
|
||
|
return getSourceAndMap(this, options);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param {object} options options
|
||
|
* @param {function(string, number, number, number, number, number, number): void} onChunk called for each chunk of code
|
||
|
* @param {function(number, string, string)} onSource called for each source
|
||
|
* @param {function(number, string)} onName called for each name
|
||
|
* @returns {void}
|
||
|
*/
|
||
|
streamChunks(options, onChunk, onSource, onName) {
|
||
|
if (this._value === undefined) {
|
||
|
this._value = this._valueAsBuffer.toString("utf-8");
|
||
|
}
|
||
|
onSource(0, this._name, this._value);
|
||
|
const finalSource = !!(options && options.finalSource);
|
||
|
if (!options || options.columns !== false) {
|
||
|
// With column info we need to read all lines and split them
|
||
|
const matches = splitIntoPotentialTokens(this._value);
|
||
|
let line = 1;
|
||
|
let column = 0;
|
||
|
if (matches !== null) {
|
||
|
for (const match of matches) {
|
||
|
const isEndOfLine = match.endsWith("\n");
|
||
|
if (isEndOfLine && match.length === 1) {
|
||
|
if (!finalSource) onChunk(match, line, column, -1, -1, -1, -1);
|
||
|
} else {
|
||
|
const chunk = finalSource ? undefined : match;
|
||
|
onChunk(chunk, line, column, 0, line, column, -1);
|
||
|
}
|
||
|
if (isEndOfLine) {
|
||
|
line++;
|
||
|
column = 0;
|
||
|
} else {
|
||
|
column += match.length;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return {
|
||
|
generatedLine: line,
|
||
|
generatedColumn: column,
|
||
|
source: finalSource ? this._value : undefined
|
||
|
};
|
||
|
} else if (finalSource) {
|
||
|
// Without column info and with final source we only
|
||
|
// need meta info to generate mapping
|
||
|
const result = getGeneratedSourceInfo(this._value);
|
||
|
const { generatedLine, generatedColumn } = result;
|
||
|
if (generatedColumn === 0) {
|
||
|
for (let line = 1; line < generatedLine; line++)
|
||
|
onChunk(undefined, line, 0, 0, line, 0, -1);
|
||
|
} else {
|
||
|
for (let line = 1; line <= generatedLine; line++)
|
||
|
onChunk(undefined, line, 0, 0, line, 0, -1);
|
||
|
}
|
||
|
return result;
|
||
|
} else {
|
||
|
// Without column info, but also without final source
|
||
|
// we need to split source by lines
|
||
|
let line = 1;
|
||
|
const matches = splitIntoLines(this._value);
|
||
|
let match;
|
||
|
for (match of matches) {
|
||
|
onChunk(finalSource ? undefined : match, line, 0, 0, line, 0, -1);
|
||
|
line++;
|
||
|
}
|
||
|
return matches.length === 0 || match.endsWith("\n")
|
||
|
? {
|
||
|
generatedLine: matches.length + 1,
|
||
|
generatedColumn: 0,
|
||
|
source: finalSource ? this._value : undefined
|
||
|
}
|
||
|
: {
|
||
|
generatedLine: matches.length,
|
||
|
generatedColumn: match.length,
|
||
|
source: finalSource ? this._value : undefined
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
updateHash(hash) {
|
||
|
if (this._valueAsBuffer === undefined) {
|
||
|
this._valueAsBuffer = Buffer.from(this._value, "utf-8");
|
||
|
}
|
||
|
hash.update("OriginalSource");
|
||
|
hash.update(this._valueAsBuffer);
|
||
|
hash.update(this._name || "");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module.exports = OriginalSource;
|