All files / src/compiler/utils extract_svelte_ignore.js

100% Statements 85/85
100% Branches 21/21
100% Functions 2/2
100% Lines 83/83

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 842x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 608x 608x 115x 115x 115x 115x 115x 115x 115x 115x 330x 122x 122x 122x 122x 122x 17x 17x 17x 3x 3x 3x 3x 3x 2x 3x 1x 1x 1x 17x 8x 8x 17x 122x 122x 115x 115x 122x 115x 115x 115x 2x 2x 2x 2x 2x 2x 2x 3x 3x 2x 2x 2x 2x 2x 2x 2x 2x 2x  
import fuzzymatch from '../phases/1-parse/utils/fuzzymatch.js';
import * as w from '../warnings.js';
 
const regex_svelte_ignore = /^\s*svelte-ignore\s/;
 
/** @type {Record<string, string>} Map of legacy code -> new code */
const replacements = {
	'non-top-level-reactive-declaration': 'reactive_declaration_invalid_placement',
	'module-script-reactive-declaration': 'reactive_declaration_module_script',
	'empty-block': 'block_empty',
	'avoid-is': 'attribute_avoid_is',
	'invalid-html-attribute': 'attribute_invalid_property_name',
	'a11y-structure': 'a11y_figcaption_parent',
	'illegal-attribute-character': 'attribute_illegal_colon',
	'invalid-rest-eachblock-binding': 'bind_invalid_each_rest'
};
 
/**
 * @param {number} offset
 * @param {string} text
 * @param {boolean} runes
 * @returns {string[]}
 */
export function extract_svelte_ignore(offset, text, runes) {
	const match = regex_svelte_ignore.exec(text);
	if (!match) return [];
 
	let length = match[0].length;
	offset += length;
 
	/** @type {string[]} */
	const ignores = [];
 
	// Warnings have to be separated by commas, everything after is interpreted as prose
	for (const match of text.slice(length).matchAll(/([\w$-]+)(,)?/gm)) {
		const code = match[1];
 
		ignores.push(code);
 
		if (!w.codes.includes(code)) {
			const replacement = replacements[code] ?? code.replace(/-/g, '_');
 
			if (runes) {
				// The type cast is for some reason necessary to pass the type check in CI
				const start = offset + /** @type {number} */ (match.index);
				const end = start + code.length;
 
				if (w.codes.includes(replacement)) {
					w.legacy_code({ start, end }, code, replacement);
				} else {
					const suggestion = fuzzymatch(code, w.codes);
					w.unknown_code({ start, end }, code, suggestion);
				}
			} else if (w.codes.includes(replacement)) {
				ignores.push(replacement);
			}
		}
 
		if (!match[2]) {
			break;
		}
	}
 
	return ignores;
}
 
/**
 * Replaces legacy svelte-ignore codes with new codes.
 * @param {string} text
 * @returns {string}
 */
export function migrate_svelte_ignore(text) {
	const match = regex_svelte_ignore.exec(text);
	if (!match) return text;
 
	const length = match[0].length;
	return (
		text.substring(0, length) +
		text
			.substring(length)
			.replace(/\w+-\w+(-\w+)*/g, (code) => replacements[code] ?? code.replace(/-/g, '_'))
	);
}