| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 | /*	MIT License http://www.opensource.org/licenses/mit-license.php	Author Tobias Koppers @sokra*/"use strict";const streamChunksOfSourceMap = require("./streamChunksOfSourceMap");const splitIntoLines = require("./splitIntoLines");const streamChunksOfCombinedSourceMap = (	source,	sourceMap,	innerSourceName,	innerSource,	innerSourceMap,	removeInnerSource,	onChunk,	onSource,	onName,	finalSource,	columns) => {	let sourceMapping = new Map();	let nameMapping = new Map();	const sourceIndexMapping = [];	const nameIndexMapping = [];	const nameIndexValueMapping = [];	let innerSourceIndex = -2;	const innerSourceIndexMapping = [];	const innerSourceIndexValueMapping = [];	const innerSourceContents = [];	const innerSourceContentLines = [];	const innerNameIndexMapping = [];	const innerNameIndexValueMapping = [];	const innerSourceMapLineData = [];	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) {			let 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 === innerSourceIndex) {				// 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;				} else {					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) {				innerSourceIndex = i;				if (innerSource !== undefined) sourceContent = innerSource;				else innerSource = sourceContent;				sourceIndexMapping[i] = -2;				streamChunksOfSourceMap(					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(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;
 |