All files / src/compiler/phases/1-parse/read script.js

94.52% Statements 69/73
85.71% Branches 12/14
100% Functions 2/2
94.28% Lines 66/70

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 712x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 3253x 3253x 3253x 3253x 3253x 45x 3253x     45x 45x 45x 2997x 1x 1x 44x 44x 44x 2x 2x 2x 2x 2x 2x 2x 2x 3255x 3255x 3255x 1x 1x 3253x 3253x 3253x 3253x 3253x 3253x 3253x 3253x 3253x 3253x 3255x     3253x 3253x 3253x 3253x 3253x 3253x 3253x 3253x 3253x 3253x 3253x 3253x 3253x 3253x 3253x  
import * as acorn from '../acorn.js';
import { regex_not_newline_characters } from '../../patterns.js';
import * as e from '../../../errors.js';
 
const regex_closing_script_tag = /<\/script\s*>/;
const regex_starts_with_closing_script_tag = /^<\/script\s*>/;
 
/**
 * @param {any[]} attributes
 * @returns {string}
 */
function get_context(attributes) {
	const context = attributes.find(
		/** @param {any} attribute */ (attribute) => attribute.name === 'context'
	);
	if (!context) return 'default';
 
	if (context.value.length !== 1 || context.value[0].type !== 'Text') {
		e.script_invalid_context(context.start);
	}
 
	const value = context.value[0].data;
 
	if (value !== 'module') {
		e.script_invalid_context(context.start);
	}
 
	return value;
}
 
/**
 * @param {import('../index.js').Parser} parser
 * @param {number} start
 * @param {Array<import('#compiler').Attribute | import('#compiler').SpreadAttribute | import('#compiler').Directive>} attributes
 * @returns {import('#compiler').Script}
 */
export function read_script(parser, start, attributes) {
	const script_start = parser.index;
	const data = parser.read_until(regex_closing_script_tag);
	if (parser.index >= parser.template.length) {
		e.element_unclosed(parser.template.length, 'script');
	}
 
	const source =
		parser.template.slice(0, script_start).replace(regex_not_newline_characters, ' ') + data;
	parser.read(regex_starts_with_closing_script_tag);
 
	/** @type {import('estree').Program} */
	let ast;
 
	try {
		ast = acorn.parse(source, parser.ts);
	} catch (err) {
		parser.acorn_error(err);
	}
 
	// TODO is this necessary?
	ast.start = script_start;
 
	return {
		type: 'Script',
		start,
		end: parser.index,
		context: get_context(attributes),
		content: ast,
		parent: null,
		// @ts-ignore
		attributes: attributes
	};
}