UNPKG

webpack-sources

Version:

Source code handling classes for webpack

159 lines (144 loc) 4.23 kB
/* MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ "use strict"; const RawSource = require("./RawSource"); const Source = require("./Source"); const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks"); const streamChunks = require("./helpers/streamChunks"); /** @typedef {import("./Source").HashLike} HashLike */ /** @typedef {import("./Source").MapOptions} MapOptions */ /** @typedef {import("./Source").RawSourceMap} RawSourceMap */ /** @typedef {import("./Source").SourceAndMap} SourceAndMap */ /** @typedef {import("./Source").SourceValue} SourceValue */ /** @typedef {import("./helpers/getGeneratedSourceInfo").GeneratedSourceInfo} GeneratedSourceInfo */ /** @typedef {import("./helpers/streamChunks").OnChunk} OnChunk */ /** @typedef {import("./helpers/streamChunks").OnName} OnName */ /** @typedef {import("./helpers/streamChunks").OnSource} OnSource */ /** @typedef {import("./helpers/streamChunks").Options} Options */ const REPLACE_REGEX = /\n(?=.|\s)/g; class PrefixSource extends Source { /** * @param {string} prefix prefix * @param {string | Buffer | Source} source source */ constructor(prefix, source) { super(); /** * @private * @type {Source} */ this._source = typeof source === "string" || Buffer.isBuffer(source) ? new RawSource(source, true) : source; this._prefix = prefix; } getPrefix() { return this._prefix; } original() { return this._source; } /** * @returns {SourceValue} source */ source() { const node = /** @type {string} */ (this._source.source()); const prefix = this._prefix; return prefix + node.replace(REPLACE_REGEX, "\n" + prefix); } // TODO efficient buffer() implementation /** * @param {MapOptions=} options map options * @returns {RawSourceMap | null} map */ map(options) { return getMap(this, options); } /** * @param {MapOptions=} options map options * @returns {SourceAndMap} source and map */ sourceAndMap(options) { return getSourceAndMap(this, options); } /** * @param {Options} options options * @param {OnChunk} onChunk called for each chunk of code * @param {OnSource} onSource called for each source * @param {OnName} onName called for each name * @returns {GeneratedSourceInfo} generated source info */ streamChunks(options, onChunk, onSource, onName) { const prefix = this._prefix; const prefixOffset = prefix.length; const linesOnly = !!(options && options.columns === false); const { generatedLine, generatedColumn, source } = streamChunks( this._source, options, ( chunk, generatedLine, generatedColumn, sourceIndex, originalLine, originalColumn, nameIndex ) => { if (generatedColumn !== 0) { // In the middle of the line, we just adject the column generatedColumn += prefixOffset; } else if (chunk !== undefined) { // At the start of the line, when we have source content // add the prefix as generated mapping // (in lines only mode we just add it to the original mapping // for performance reasons) if (linesOnly || sourceIndex < 0) { chunk = prefix + chunk; } else if (prefixOffset > 0) { onChunk(prefix, generatedLine, generatedColumn, -1, -1, -1, -1); generatedColumn += prefixOffset; } } else if (!linesOnly) { // Without source content, we only need to adject the column info // expect in lines only mode where prefix is added to original mapping generatedColumn += prefixOffset; } onChunk( chunk, generatedLine, generatedColumn, sourceIndex, originalLine, originalColumn, nameIndex ); }, onSource, onName ); return { generatedLine, generatedColumn: generatedColumn === 0 ? 0 : prefixOffset + /** @type {number} */ (generatedColumn), source: source !== undefined ? prefix + source.replace(REPLACE_REGEX, "\n" + prefix) : undefined }; } /** * @param {HashLike} hash hash * @returns {void} */ updateHash(hash) { hash.update("PrefixSource"); this._source.updateHash(hash); hash.update(this._prefix); } } module.exports = PrefixSource;