| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 | /*	MIT License http://www.opensource.org/licenses/mit-license.php	Author Tobias Koppers @sokra*/"use strict";const splitIntoLines = require("./splitIntoLines");const streamChunksOfSourceMap = require("./streamChunksOfSourceMap");/** @typedef {import("../Source").RawSourceMap} RawSourceMap *//** @typedef {import("./getGeneratedSourceInfo").GeneratedSourceInfo} GeneratedSourceInfo *//** @typedef {import("./streamChunks").OnChunk} onChunk *//** @typedef {import("./streamChunks").OnName} OnName *//** @typedef {import("./streamChunks").OnSource} OnSource *//** * @param {string} source source * @param {RawSourceMap} sourceMap source map * @param {string} innerSourceName inner source name * @param {string} innerSource inner source * @param {RawSourceMap} innerSourceMap inner source map * @param {boolean | undefined} removeInnerSource do remove inner source * @param {onChunk} onChunk on chunk * @param {OnSource} onSource on source * @param {OnName} onName on name * @param {boolean} finalSource finalSource * @param {boolean} columns columns * @returns {GeneratedSourceInfo} generated source info */const streamChunksOfCombinedSourceMap = (	source,	sourceMap,	innerSourceName,	innerSource,	innerSourceMap,	removeInnerSource,	onChunk,	onSource,	onName,	finalSource,	columns,) => {	/** @type {Map<string | null, number>} */	const sourceMapping = new Map();	/** @type {Map<string, number>} */	const nameMapping = new Map();	/** @type {number[]} */	const sourceIndexMapping = [];	/** @type {number[]} */	const nameIndexMapping = [];	/** @type {string[]} */	const nameIndexValueMapping = [];	let outerSourceIndex = -2;	/** @type {number[]} */	const innerSourceIndexMapping = [];	/** @type {[string | null, string | undefined][]} */	const innerSourceIndexValueMapping = [];	/** @type {(string | undefined)[]} */	const innerSourceContents = [];	/** @type {(null | undefined | string[])[]} */	const innerSourceContentLines = [];	/** @type {number[]} */	const innerNameIndexMapping = [];	/** @type {string[]} */	const innerNameIndexValueMapping = [];	/** @typedef {[number, number, number, number, number] | number[]} MappingsData */	/** @type {{ chunks: string[], mappingsData: MappingsData }[]} */	const innerSourceMapLineData = [];	/**	 * @param {number} line line	 * @param {number} column column	 * @returns {number} result	 */	const findInnerMapping = (line, column) => {		if (line > innerSourceMapLineData.length) return -1;		const { mappingsData } = innerSourceMapLineData[line - 1];		let l = 0;		let r = mappingsData.length / 5;		while (l < r) {			const m = (l + r) >> 1;			if (mappingsData[m * 5] <= column) {				l = m + 1;			} else {				r = m;			}		}		if (l === 0) return -1;		return l - 1;	};	return streamChunksOfSourceMap(		source,		sourceMap,		(			chunk,			generatedLine,			generatedColumn,			sourceIndex,			originalLine,			originalColumn,			nameIndex,		) => {			// Check if this is a mapping to the inner source			if (sourceIndex === outerSourceIndex) {				// Check if there is a mapping in the inner source				const idx = findInnerMapping(originalLine, originalColumn);				if (idx !== -1) {					const { chunks, mappingsData } =						innerSourceMapLineData[originalLine - 1];					const mi = idx * 5;					const innerSourceIndex = mappingsData[mi + 1];					const innerOriginalLine = mappingsData[mi + 2];					let innerOriginalColumn = mappingsData[mi + 3];					let innerNameIndex = mappingsData[mi + 4];					if (innerSourceIndex >= 0) {						// Check for an identity mapping						// where we are allowed to adjust the original column						const innerChunk = chunks[idx];						const innerGeneratedColumn = mappingsData[mi];						const locationInChunk = originalColumn - innerGeneratedColumn;						if (locationInChunk > 0) {							let originalSourceLines =								innerSourceIndex < innerSourceContentLines.length									? innerSourceContentLines[innerSourceIndex]									: null;							if (originalSourceLines === undefined) {								const originalSource = innerSourceContents[innerSourceIndex];								originalSourceLines = originalSource									? splitIntoLines(originalSource)									: null;								innerSourceContentLines[innerSourceIndex] = originalSourceLines;							}							if (originalSourceLines !== null) {								const originalChunk =									innerOriginalLine <= originalSourceLines.length										? originalSourceLines[innerOriginalLine - 1].slice(												innerOriginalColumn,												innerOriginalColumn + locationInChunk,											)										: "";								if (innerChunk.slice(0, locationInChunk) === originalChunk) {									innerOriginalColumn += locationInChunk;									innerNameIndex = -1;								}							}						}						// We have a inner mapping to original source						// emit source when needed and compute global source index						let sourceIndex =							innerSourceIndex < innerSourceIndexMapping.length								? innerSourceIndexMapping[innerSourceIndex]								: -2;						if (sourceIndex === -2) {							const [source, sourceContent] =								innerSourceIndex < innerSourceIndexValueMapping.length									? innerSourceIndexValueMapping[innerSourceIndex]									: [null, undefined];							let globalIndex = sourceMapping.get(source);							if (globalIndex === undefined) {								sourceMapping.set(source, (globalIndex = sourceMapping.size));								onSource(globalIndex, source, sourceContent);							}							sourceIndex = globalIndex;							innerSourceIndexMapping[innerSourceIndex] = sourceIndex;						}						// emit name when needed and compute global name index						let finalNameIndex = -1;						if (innerNameIndex >= 0) {							// when we have a inner name							finalNameIndex =								innerNameIndex < innerNameIndexMapping.length									? innerNameIndexMapping[innerNameIndex]									: -2;							if (finalNameIndex === -2) {								const name =									innerNameIndex < innerNameIndexValueMapping.length										? innerNameIndexValueMapping[innerNameIndex]										: undefined;								if (name) {									let globalIndex = nameMapping.get(name);									if (globalIndex === undefined) {										nameMapping.set(name, (globalIndex = nameMapping.size));										onName(globalIndex, name);									}									finalNameIndex = globalIndex;								} else {									finalNameIndex = -1;								}								innerNameIndexMapping[innerNameIndex] = finalNameIndex;							}						} else if (nameIndex >= 0) {							// when we don't have an inner name,							// but we have an outer name							// it can be used when inner original code equals to the name							let originalSourceLines =								innerSourceContentLines[innerSourceIndex];							if (originalSourceLines === undefined) {								const originalSource = innerSourceContents[innerSourceIndex];								originalSourceLines = originalSource									? splitIntoLines(originalSource)									: null;								innerSourceContentLines[innerSourceIndex] = originalSourceLines;							}							if (originalSourceLines !== null) {								const name = nameIndexValueMapping[nameIndex];								const originalName =									innerOriginalLine <= originalSourceLines.length										? originalSourceLines[innerOriginalLine - 1].slice(												innerOriginalColumn,												innerOriginalColumn + name.length,											)										: "";								if (name === originalName) {									finalNameIndex =										nameIndex < nameIndexMapping.length											? nameIndexMapping[nameIndex]											: -2;									if (finalNameIndex === -2) {										const name = nameIndexValueMapping[nameIndex];										if (name) {											let globalIndex = nameMapping.get(name);											if (globalIndex === undefined) {												nameMapping.set(name, (globalIndex = nameMapping.size));												onName(globalIndex, name);											}											finalNameIndex = globalIndex;										} else {											finalNameIndex = -1;										}										nameIndexMapping[nameIndex] = finalNameIndex;									}								}							}						}						onChunk(							chunk,							generatedLine,							generatedColumn,							sourceIndex,							innerOriginalLine,							innerOriginalColumn,							finalNameIndex,						);						return;					}				}				// We have a mapping to the inner source, but no inner mapping				if (removeInnerSource) {					onChunk(chunk, generatedLine, generatedColumn, -1, -1, -1, -1);					return;				}				if (sourceIndexMapping[sourceIndex] === -2) {					let globalIndex = sourceMapping.get(innerSourceName);					if (globalIndex === undefined) {						sourceMapping.set(source, (globalIndex = sourceMapping.size));						onSource(globalIndex, innerSourceName, innerSource);					}					sourceIndexMapping[sourceIndex] = globalIndex;				}			}			const finalSourceIndex =				sourceIndex < 0 || sourceIndex >= sourceIndexMapping.length					? -1					: sourceIndexMapping[sourceIndex];			if (finalSourceIndex < 0) {				// no source, so we make it a generated chunk				onChunk(chunk, generatedLine, generatedColumn, -1, -1, -1, -1);			} else {				// Pass through the chunk with mapping				let finalNameIndex = -1;				if (nameIndex >= 0 && nameIndex < nameIndexMapping.length) {					finalNameIndex = nameIndexMapping[nameIndex];					if (finalNameIndex === -2) {						const name = nameIndexValueMapping[nameIndex];						let globalIndex = nameMapping.get(name);						if (globalIndex === undefined) {							nameMapping.set(name, (globalIndex = nameMapping.size));							onName(globalIndex, name);						}						finalNameIndex = globalIndex;						nameIndexMapping[nameIndex] = finalNameIndex;					}				}				onChunk(					chunk,					generatedLine,					generatedColumn,					finalSourceIndex,					originalLine,					originalColumn,					finalNameIndex,				);			}		},		(i, source, sourceContent) => {			if (source === innerSourceName) {				outerSourceIndex = i;				if (innerSource !== undefined) sourceContent = innerSource;				else innerSource = /** @type {string} */ (sourceContent);				sourceIndexMapping[i] = -2;				streamChunksOfSourceMap(					/** @type {string} */					(sourceContent),					innerSourceMap,					(						chunk,						generatedLine,						generatedColumn,						sourceIndex,						originalLine,						originalColumn,						nameIndex,					) => {						while (innerSourceMapLineData.length < generatedLine) {							innerSourceMapLineData.push({								mappingsData: [],								chunks: [],							});						}						const data = innerSourceMapLineData[generatedLine - 1];						data.mappingsData.push(							generatedColumn,							sourceIndex,							originalLine,							originalColumn,							nameIndex,						);						data.chunks.push(/** @type {string} */ (chunk));					},					(i, source, sourceContent) => {						innerSourceContents[i] = sourceContent;						innerSourceContentLines[i] = undefined;						innerSourceIndexMapping[i] = -2;						innerSourceIndexValueMapping[i] = [source, sourceContent];					},					(i, name) => {						innerNameIndexMapping[i] = -2;						innerNameIndexValueMapping[i] = name;					},					false,					columns,				);			} else {				let globalIndex = sourceMapping.get(source);				if (globalIndex === undefined) {					sourceMapping.set(source, (globalIndex = sourceMapping.size));					onSource(globalIndex, source, sourceContent);				}				sourceIndexMapping[i] = globalIndex;			}		},		(i, name) => {			nameIndexMapping[i] = -2;			nameIndexValueMapping[i] = name;		},		finalSource,		columns,	);};module.exports = streamChunksOfCombinedSourceMap;
 |