All files / src/compiler/phases/2-analyze/visitors ExportNamedDeclaration.js

96.55% Statements 56/58
88.88% Branches 16/18
100% Functions 2/2
96.42% Lines 54/56

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 572x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 72x 72x 72x 72x 41x 41x 41x 41x 9x 41x 1x 1x 40x 40x 40x 40x 40x 36x 36x 67x 72x 40x     40x 72x 2x 2x 2x 2x 2x 2x 2x 40x 40x 40x 40x 40x 1x 1x 39x 40x 3x 3x 40x  
/** @import { ExportNamedDeclaration, Node } from 'estree' */
/** @import { Context } from '../types' */
/** @import { Scope } from '../../scope' */
import * as e from '../../../errors.js';
import { extract_identifiers } from '../../../utils/ast.js';
 
/**
 * @param {ExportNamedDeclaration} node
 * @param {Context} context
 */
export function ExportNamedDeclaration(node, context) {
	// visit children, so bindings are correctly initialised
	context.next();
 
	if (node.declaration?.type === 'VariableDeclaration') {
		// in runes mode, forbid `export let`
		if (
			context.state.analysis.runes &&
			context.state.ast_type === 'instance' &&
			node.declaration.kind === 'let'
		) {
			e.legacy_export_invalid(node);
		}
 
		for (const declarator of node.declaration.declarations) {
			for (const id of extract_identifiers(declarator.id)) {
				validate_export(node, context.state.scope, id.name);
			}
		}
	}
 
	if (node.specifiers && context.state.ast_type !== 'instance') {
		for (const specifier of node.specifiers) {
			validate_export(specifier, context.state.scope, specifier.local.name);
		}
	}
}
 
/**
 *
 * @param {Node} node
 * @param {Scope} scope
 * @param {string} name
 */
function validate_export(node, scope, name) {
	const binding = scope.get(name);
	if (!binding) return;
 
	if (binding.kind === 'derived') {
		e.derived_invalid_export(node);
	}
 
	if ((binding.kind === 'state' || binding.kind === 'frozen_state') && binding.reassigned) {
		e.state_invalid_export(node);
	}
}