| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394 | 
							- /*
 
- 	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("./CompatSource").SourceLike} SourceLike */
 
- /** @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 */
 
- /** @typedef {string | Source | SourceLike} Child */
 
- const stringsAsRawSources = new WeakSet();
 
- class ConcatSource extends Source {
 
- 	/**
 
- 	 * @param {Child[]} args children
 
- 	 */
 
- 	constructor(...args) {
 
- 		super();
 
- 		/**
 
- 		 * @private
 
- 		 * @type {Child[]}
 
- 		 */
 
- 		this._children = [];
 
- 		for (const item of args) {
 
- 			if (item instanceof ConcatSource) {
 
- 				for (const child of item._children) {
 
- 					this._children.push(child);
 
- 				}
 
- 			} else {
 
- 				this._children.push(item);
 
- 			}
 
- 		}
 
- 		this._isOptimized = args.length === 0;
 
- 	}
 
- 	/**
 
- 	 * @returns {Source[]} children
 
- 	 */
 
- 	getChildren() {
 
- 		if (!this._isOptimized) this._optimize();
 
- 		return /** @type {Source[]} */ (this._children);
 
- 	}
 
- 	/**
 
- 	 * @param {Child} item item
 
- 	 * @returns {void}
 
- 	 */
 
- 	add(item) {
 
- 		if (item instanceof ConcatSource) {
 
- 			for (const child of item._children) {
 
- 				this._children.push(child);
 
- 			}
 
- 		} else {
 
- 			this._children.push(item);
 
- 		}
 
- 		this._isOptimized = false;
 
- 	}
 
- 	/**
 
- 	 * @param {Child[]} items items
 
- 	 * @returns {void}
 
- 	 */
 
- 	addAllSkipOptimizing(items) {
 
- 		for (const item of items) {
 
- 			this._children.push(item);
 
- 		}
 
- 	}
 
- 	buffer() {
 
- 		if (!this._isOptimized) this._optimize();
 
- 		/** @type {Buffer[]} */
 
- 		const buffers = [];
 
- 		for (const child of /** @type {SourceLike[]} */ (this._children)) {
 
- 			if (typeof child.buffer === "function") {
 
- 				buffers.push(child.buffer());
 
- 			} else {
 
- 				const bufferOrString = child.source();
 
- 				if (Buffer.isBuffer(bufferOrString)) {
 
- 					buffers.push(bufferOrString);
 
- 				} else {
 
- 					// This will not happen
 
- 					buffers.push(Buffer.from(bufferOrString, "utf8"));
 
- 				}
 
- 			}
 
- 		}
 
- 		return Buffer.concat(buffers);
 
- 	}
 
- 	/**
 
- 	 * @returns {SourceValue} source
 
- 	 */
 
- 	source() {
 
- 		if (!this._isOptimized) this._optimize();
 
- 		let source = "";
 
- 		for (const child of this._children) {
 
- 			source += /** @type {Source} */ (child).source();
 
- 		}
 
- 		return source;
 
- 	}
 
- 	size() {
 
- 		if (!this._isOptimized) this._optimize();
 
- 		let size = 0;
 
- 		for (const child of this._children) {
 
- 			size += /** @type {Source} */ (child).size();
 
- 		}
 
- 		return size;
 
- 	}
 
- 	/**
 
- 	 * @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._isOptimized) this._optimize();
 
- 		if (this._children.length === 1) {
 
- 			return /** @type {ConcatSource[]} */ (this._children)[0].streamChunks(
 
- 				options,
 
- 				onChunk,
 
- 				onSource,
 
- 				onName,
 
- 			);
 
- 		}
 
- 		let currentLineOffset = 0;
 
- 		let currentColumnOffset = 0;
 
- 		const sourceMapping = new Map();
 
- 		const nameMapping = new Map();
 
- 		const finalSource = Boolean(options && options.finalSource);
 
- 		let code = "";
 
- 		let needToCloseMapping = false;
 
- 		for (const item of /** @type {Source[]} */ (this._children)) {
 
- 			/** @type {number[]} */
 
- 			const sourceIndexMapping = [];
 
- 			/** @type {number[]} */
 
- 			const nameIndexMapping = [];
 
- 			let lastMappingLine = 0;
 
- 			const { generatedLine, generatedColumn, source } = streamChunks(
 
- 				item,
 
- 				options,
 
- 				// eslint-disable-next-line no-loop-func
 
- 				(
 
- 					chunk,
 
- 					generatedLine,
 
- 					generatedColumn,
 
- 					sourceIndex,
 
- 					originalLine,
 
- 					originalColumn,
 
- 					nameIndex,
 
- 				) => {
 
- 					const line = generatedLine + currentLineOffset;
 
- 					const column =
 
- 						generatedLine === 1
 
- 							? generatedColumn + currentColumnOffset
 
- 							: generatedColumn;
 
- 					if (needToCloseMapping) {
 
- 						if (generatedLine !== 1 || generatedColumn !== 0) {
 
- 							onChunk(
 
- 								undefined,
 
- 								currentLineOffset + 1,
 
- 								currentColumnOffset,
 
- 								-1,
 
- 								-1,
 
- 								-1,
 
- 								-1,
 
- 							);
 
- 						}
 
- 						needToCloseMapping = false;
 
- 					}
 
- 					const resultSourceIndex =
 
- 						sourceIndex < 0 || sourceIndex >= sourceIndexMapping.length
 
- 							? -1
 
- 							: sourceIndexMapping[sourceIndex];
 
- 					const resultNameIndex =
 
- 						nameIndex < 0 || nameIndex >= nameIndexMapping.length
 
- 							? -1
 
- 							: nameIndexMapping[nameIndex];
 
- 					lastMappingLine = resultSourceIndex < 0 ? 0 : generatedLine;
 
- 					let _chunk;
 
- 					// When using finalSource, we process the entire source code at once at the end, rather than chunk by chunk
 
- 					if (finalSource) {
 
- 						if (chunk !== undefined) code += chunk;
 
- 					} else {
 
- 						_chunk = chunk;
 
- 					}
 
- 					if (resultSourceIndex < 0) {
 
- 						onChunk(_chunk, line, column, -1, -1, -1, -1);
 
- 					} else {
 
- 						onChunk(
 
- 							_chunk,
 
- 							line,
 
- 							column,
 
- 							resultSourceIndex,
 
- 							originalLine,
 
- 							originalColumn,
 
- 							resultNameIndex,
 
- 						);
 
- 					}
 
- 				},
 
- 				(i, source, sourceContent) => {
 
- 					let globalIndex = sourceMapping.get(source);
 
- 					if (globalIndex === undefined) {
 
- 						sourceMapping.set(source, (globalIndex = sourceMapping.size));
 
- 						onSource(globalIndex, source, sourceContent);
 
- 					}
 
- 					sourceIndexMapping[i] = globalIndex;
 
- 				},
 
- 				(i, name) => {
 
- 					let globalIndex = nameMapping.get(name);
 
- 					if (globalIndex === undefined) {
 
- 						nameMapping.set(name, (globalIndex = nameMapping.size));
 
- 						onName(globalIndex, name);
 
- 					}
 
- 					nameIndexMapping[i] = globalIndex;
 
- 				},
 
- 			);
 
- 			if (source !== undefined) code += source;
 
- 			if (
 
- 				needToCloseMapping &&
 
- 				(generatedLine !== 1 || generatedColumn !== 0)
 
- 			) {
 
- 				onChunk(
 
- 					undefined,
 
- 					currentLineOffset + 1,
 
- 					currentColumnOffset,
 
- 					-1,
 
- 					-1,
 
- 					-1,
 
- 					-1,
 
- 				);
 
- 				needToCloseMapping = false;
 
- 			}
 
- 			if (/** @type {number} */ (generatedLine) > 1) {
 
- 				currentColumnOffset = /** @type {number} */ (generatedColumn);
 
- 			} else {
 
- 				currentColumnOffset += /** @type {number} */ (generatedColumn);
 
- 			}
 
- 			needToCloseMapping =
 
- 				needToCloseMapping ||
 
- 				(finalSource && lastMappingLine === generatedLine);
 
- 			currentLineOffset += /** @type {number} */ (generatedLine) - 1;
 
- 		}
 
- 		return {
 
- 			generatedLine: currentLineOffset + 1,
 
- 			generatedColumn: currentColumnOffset,
 
- 			source: finalSource ? code : undefined,
 
- 		};
 
- 	}
 
- 	/**
 
- 	 * @param {HashLike} hash hash
 
- 	 * @returns {void}
 
- 	 */
 
- 	updateHash(hash) {
 
- 		if (!this._isOptimized) this._optimize();
 
- 		hash.update("ConcatSource");
 
- 		for (const item of this._children) {
 
- 			/** @type {Source} */
 
- 			(item).updateHash(hash);
 
- 		}
 
- 	}
 
- 	_optimize() {
 
- 		const newChildren = [];
 
- 		let currentString;
 
- 		/** @type {undefined | string | [string, string] | SourceLike} */
 
- 		let currentRawSources;
 
- 		/**
 
- 		 * @param {string} string string
 
- 		 * @returns {void}
 
- 		 */
 
- 		const addStringToRawSources = (string) => {
 
- 			if (currentRawSources === undefined) {
 
- 				currentRawSources = string;
 
- 			} else if (Array.isArray(currentRawSources)) {
 
- 				currentRawSources.push(string);
 
- 			} else {
 
- 				currentRawSources = [
 
- 					typeof currentRawSources === "string"
 
- 						? currentRawSources
 
- 						: /** @type {string} */ (currentRawSources.source()),
 
- 					string,
 
- 				];
 
- 			}
 
- 		};
 
- 		/**
 
- 		 * @param {SourceLike} source source
 
- 		 * @returns {void}
 
- 		 */
 
- 		const addSourceToRawSources = (source) => {
 
- 			if (currentRawSources === undefined) {
 
- 				currentRawSources = source;
 
- 			} else if (Array.isArray(currentRawSources)) {
 
- 				currentRawSources.push(
 
- 					/** @type {string} */
 
- 					(source.source()),
 
- 				);
 
- 			} else {
 
- 				currentRawSources = [
 
- 					typeof currentRawSources === "string"
 
- 						? currentRawSources
 
- 						: /** @type {string} */ (currentRawSources.source()),
 
- 					/** @type {string} */
 
- 					(source.source()),
 
- 				];
 
- 			}
 
- 		};
 
- 		const mergeRawSources = () => {
 
- 			if (Array.isArray(currentRawSources)) {
 
- 				const rawSource = new RawSource(currentRawSources.join(""));
 
- 				stringsAsRawSources.add(rawSource);
 
- 				newChildren.push(rawSource);
 
- 			} else if (typeof currentRawSources === "string") {
 
- 				const rawSource = new RawSource(currentRawSources);
 
- 				stringsAsRawSources.add(rawSource);
 
- 				newChildren.push(rawSource);
 
- 			} else {
 
- 				newChildren.push(currentRawSources);
 
- 			}
 
- 		};
 
- 		for (const child of this._children) {
 
- 			if (typeof child === "string") {
 
- 				if (currentString === undefined) {
 
- 					currentString = child;
 
- 				} else {
 
- 					currentString += child;
 
- 				}
 
- 			} else {
 
- 				if (currentString !== undefined) {
 
- 					addStringToRawSources(currentString);
 
- 					currentString = undefined;
 
- 				}
 
- 				if (stringsAsRawSources.has(child)) {
 
- 					addSourceToRawSources(
 
- 						/** @type {SourceLike} */
 
- 						(child),
 
- 					);
 
- 				} else {
 
- 					if (currentRawSources !== undefined) {
 
- 						mergeRawSources();
 
- 						currentRawSources = undefined;
 
- 					}
 
- 					newChildren.push(child);
 
- 				}
 
- 			}
 
- 		}
 
- 		if (currentString !== undefined) {
 
- 			addStringToRawSources(currentString);
 
- 		}
 
- 		if (currentRawSources !== undefined) {
 
- 			mergeRawSources();
 
- 		}
 
- 		this._children = newChildren;
 
- 		this._isOptimized = true;
 
- 	}
 
- }
 
- module.exports = ConcatSource;
 
 
  |