You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			136 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
		
		
			
		
	
	
			136 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
| 
											9 months ago
										 | /* | ||
|  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | ||
|  | 	Author Tobias Koppers @sokra | ||
|  | */ | ||
|  | "use strict"; | ||
|  | 
 | ||
|  | const { getMap, getSourceAndMap } = require("./helpers/getFromStreamChunks"); | ||
|  | const splitIntoLines = require("./helpers/splitIntoLines"); | ||
|  | const getGeneratedSourceInfo = require("./helpers/getGeneratedSourceInfo"); | ||
|  | const Source = require("./Source"); | ||
|  | const splitIntoPotentialTokens = require("./helpers/splitIntoPotentialTokens"); | ||
|  | 
 | ||
|  | class OriginalSource extends Source { | ||
|  | 	constructor(value, name) { | ||
|  | 		super(); | ||
|  | 		const isBuffer = Buffer.isBuffer(value); | ||
|  | 		this._value = isBuffer ? undefined : value; | ||
|  | 		this._valueAsBuffer = isBuffer ? value : undefined; | ||
|  | 		this._name = name; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	getName() { | ||
|  | 		return this._name; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	source() { | ||
|  | 		if (this._value === undefined) { | ||
|  | 			this._value = this._valueAsBuffer.toString("utf-8"); | ||
|  | 		} | ||
|  | 		return this._value; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	buffer() { | ||
|  | 		if (this._valueAsBuffer === undefined) { | ||
|  | 			this._valueAsBuffer = Buffer.from(this._value, "utf-8"); | ||
|  | 		} | ||
|  | 		return this._valueAsBuffer; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	map(options) { | ||
|  | 		return getMap(this, options); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	sourceAndMap(options) { | ||
|  | 		return getSourceAndMap(this, options); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @param {object} options options | ||
|  | 	 * @param {function(string, number, number, number, number, number, number): void} onChunk called for each chunk of code | ||
|  | 	 * @param {function(number, string, string)} onSource called for each source | ||
|  | 	 * @param {function(number, string)} onName called for each name | ||
|  | 	 * @returns {void} | ||
|  | 	 */ | ||
|  | 	streamChunks(options, onChunk, onSource, onName) { | ||
|  | 		if (this._value === undefined) { | ||
|  | 			this._value = this._valueAsBuffer.toString("utf-8"); | ||
|  | 		} | ||
|  | 		onSource(0, this._name, this._value); | ||
|  | 		const finalSource = !!(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 < generatedLine; line++) | ||
|  | 					onChunk(undefined, line, 0, 0, line, 0, -1); | ||
|  | 			} else { | ||
|  | 				for (let line = 1; line <= generatedLine; line++) | ||
|  | 					onChunk(undefined, line, 0, 0, line, 0, -1); | ||
|  | 			} | ||
|  | 			return result; | ||
|  | 		} else { | ||
|  | 			// Without column info, but also without final source
 | ||
|  | 			// we need to split source by lines
 | ||
|  | 			let line = 1; | ||
|  | 			const matches = splitIntoLines(this._value); | ||
|  | 			let match; | ||
|  | 			for (match of matches) { | ||
|  | 				onChunk(finalSource ? undefined : match, line, 0, 0, line, 0, -1); | ||
|  | 				line++; | ||
|  | 			} | ||
|  | 			return matches.length === 0 || match.endsWith("\n") | ||
|  | 				? { | ||
|  | 						generatedLine: matches.length + 1, | ||
|  | 						generatedColumn: 0, | ||
|  | 						source: finalSource ? this._value : undefined | ||
|  | 				  } | ||
|  | 				: { | ||
|  | 						generatedLine: matches.length, | ||
|  | 						generatedColumn: match.length, | ||
|  | 						source: finalSource ? this._value : undefined | ||
|  | 				  }; | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	updateHash(hash) { | ||
|  | 		if (this._valueAsBuffer === undefined) { | ||
|  | 			this._valueAsBuffer = Buffer.from(this._value, "utf-8"); | ||
|  | 		} | ||
|  | 		hash.update("OriginalSource"); | ||
|  | 		hash.update(this._valueAsBuffer); | ||
|  | 		hash.update(this._name || ""); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | module.exports = OriginalSource; |