All files / src/compiler/preprocess decode_sourcemap.js

92.78% Statements 90/97
60% Branches 12/20
100% Functions 2/2
92.7% Lines 89/96

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 972x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 94x 94x 14x 14x 14x 14x 14x 94x 78x 78x 78x 78x 78x 78x 78x 78x   78x     78x 94x 94x 94x 94x 94x 94x 94x     94x 94x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x     2x 2x 2x 2x 2x 2x 2x 2x 40x 40x 38x 38x 40x 2x 2x 2x 40x 40x  
/** @import { Processed } from './public.js' */
import { decode as decode_mappings } from '@jridgewell/sourcemap-codec';
 
/**
 * Import decoded sourcemap from mozilla/source-map/SourceMapGenerator
 * Forked from source-map/lib/source-map-generator.js
 * from methods _serializeMappings and toJSON.
 * We cannot use source-map.d.ts types, because we access hidden properties.
 * @param {any} generator
 */
function decoded_sourcemap_from_generator(generator) {
	let previous_generated_line = 1;
	/** @type {number[][][]} */
	const converted_mappings = [[]];
	let result_line = converted_mappings[0];
	let result_segment;
	let mapping;
	const source_idx = generator._sources
		.toArray()
		// @ts-ignore
		.reduce((acc, val, idx) => ((acc[val] = idx), acc), {});
	const name_idx = generator._names
		.toArray()
		// @ts-ignore
		.reduce((acc, val, idx) => ((acc[val] = idx), acc), {});
	const mappings = generator._mappings.toArray();
	for (let i = 0, len = mappings.length; i < len; i++) {
		mapping = mappings[i];
		if (mapping.generatedLine > previous_generated_line) {
			while (mapping.generatedLine > previous_generated_line) {
				converted_mappings.push([]);
				previous_generated_line++;
			}
			result_line = converted_mappings[mapping.generatedLine - 1]; // line is one-based
		} else if (i > 0) {
			const previous_mapping = mappings[i - 1];
			if (
				// sorted by selectivity
				mapping.generatedColumn === previous_mapping.generatedColumn &&
				mapping.originalColumn === previous_mapping.originalColumn &&
				mapping.name === previous_mapping.name &&
				mapping.generatedLine === previous_mapping.generatedLine &&
				mapping.originalLine === previous_mapping.originalLine &&
				mapping.source === previous_mapping.source
			) {
				continue;
			}
		}
		result_line.push([mapping.generatedColumn]);
		result_segment = result_line[result_line.length - 1];
		if (mapping.source != null) {
			result_segment.push(
				...[source_idx[mapping.source], mapping.originalLine - 1, mapping.originalColumn]
			);
			if (mapping.name != null) {
				result_segment.push(name_idx[mapping.name]);
			}
		}
	}
 
	/**
	 * @type {{
	 *  version: number;
	 * sources: string[];
	 * names: string[];
	 * mappings: number[][][];
	 * file?: string;
	 * }}
	 */
	const map = {
		version: generator._version,
		sources: generator._sources.toArray(),
		names: generator._names.toArray(),
		mappings: converted_mappings
	};
	if (generator._file != null) {
		map.file = generator._file;
	}
	// not needed: map.sourcesContent and map.sourceRoot
	return map;
}
 
/**
 * @param {Processed} processed
 */
export function decode_map(processed) {
	let decoded_map = typeof processed.map === 'string' ? JSON.parse(processed.map) : processed.map;
	if (typeof decoded_map.mappings === 'string') {
		decoded_map.mappings = decode_mappings(decoded_map.mappings);
	}
	if (decoded_map._mappings && decoded_map.constructor.name === 'SourceMapGenerator') {
		// import decoded sourcemap from mozilla/source-map/SourceMapGenerator
		decoded_map = decoded_sourcemap_from_generator(decoded_map);
	}
	return decoded_map;
}