| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 | /*	MIT License http://www.opensource.org/licenses/mit-license.php	Author Tobias Koppers @sokra*/"use strict";const Source = require("./Source");const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks");const getGeneratedSourceInfo = require("./helpers/getGeneratedSourceInfo");const splitIntoLines = require("./helpers/splitIntoLines");const splitIntoPotentialTokens = require("./helpers/splitIntoPotentialTokens");const {	isDualStringBufferCachingEnabled,} = require("./helpers/stringBufferUtils");/** @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 */class OriginalSource extends Source {	/**	 * @param {string | Buffer} value value	 * @param {string} name name	 */	constructor(value, name) {		super();		const isBuffer = Buffer.isBuffer(value);		/**		 * @private		 * @type {undefined | string}		 */		this._value = isBuffer ? undefined : value;		/**		 * @private		 * @type {undefined | Buffer}		 */		this._valueAsBuffer = isBuffer ? value : undefined;		this._name = name;	}	getName() {		return this._name;	}	/**	 * @returns {SourceValue} source	 */	source() {		if (this._value === undefined) {			const value =				/** @type {Buffer} */				(this._valueAsBuffer).toString("utf8");			if (isDualStringBufferCachingEnabled()) {				this._value = value;			}			return value;		}		return this._value;	}	buffer() {		if (this._valueAsBuffer === undefined) {			const value = Buffer.from(/** @type {string} */ (this._value), "utf8");			if (isDualStringBufferCachingEnabled()) {				this._valueAsBuffer = value;			}			return value;		}		return this._valueAsBuffer;	}	/**	 * @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) {		if (this._value === undefined) {			this._value =				/** @type {Buffer} */				(this._valueAsBuffer).toString("utf8");		}		onSource(0, this._name, this._value);		const finalSource = Boolean(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 < /** @type {number} */ (generatedLine);					line++				) {					onChunk(undefined, line, 0, 0, line, 0, -1);				}			} else {				for (					let line = 1;					line <= /** @type {number} */ (generatedLine);					line++				) {					onChunk(undefined, line, 0, 0, line, 0, -1);				}			}			return result;		}		// Without column info, but also without final source		// we need to split source by lines		let line = 1;		const matches = splitIntoLines(this._value);		/** @type {string | undefined} */		let match;		for (match of matches) {			onChunk(finalSource ? undefined : match, line, 0, 0, line, 0, -1);			line++;		}		return matches.length === 0 || /** @type {string} */ (match).endsWith("\n")			? {					generatedLine: matches.length + 1,					generatedColumn: 0,					source: finalSource ? this._value : undefined,				}			: {					generatedLine: matches.length,					generatedColumn: /** @type {string} */ (match).length,					source: finalSource ? this._value : undefined,				};	}	/**	 * @param {HashLike} hash hash	 * @returns {void}	 */	updateHash(hash) {		hash.update("OriginalSource");		hash.update(this.buffer());		hash.update(this._name || "");	}}module.exports = OriginalSource;
 |