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

100% Statements 39/39
100% Branches 8/8
100% Functions 1/1
100% Lines 38/38

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 392x 2x 2x 2x 2x 2x 2x 2x 2x 3739x 3739x 3739x 3739x 3739x 3739x 4x 4x 4x 3739x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3739x 3739x 3739x  
/** @import { ExpressionStatement, ImportDeclaration } from 'estree' */
/** @import { Context } from '../types' */
import * as w from '../../../warnings.js';
 
/**
 * @param {ExpressionStatement} node
 * @param {Context} context
 */
export function ExpressionStatement(node, context) {
	// warn on `new Component({ target: ... })` if imported from a `.svelte` file
	if (
		node.expression.type === 'NewExpression' &&
		node.expression.callee.type === 'Identifier' &&
		node.expression.arguments.length === 1 &&
		node.expression.arguments[0].type === 'ObjectExpression' &&
		node.expression.arguments[0].properties.some(
			(p) => p.type === 'Property' && p.key.type === 'Identifier' && p.key.name === 'target'
		)
	) {
		const binding = context.state.scope.get(node.expression.callee.name);
 
		if (binding?.kind === 'normal' && binding.declaration_kind === 'import') {
			const declaration = /** @type {ImportDeclaration} */ (binding.initial);
 
			// Theoretically someone could import a class from a `.svelte.js` module, but that's too rare to worry about
			if (
				/** @type {string} */ (declaration.source.value).endsWith('.svelte') &&
				declaration.specifiers.find(
					(s) => s.local.name === binding.node.name && s.type === 'ImportDefaultSpecifier'
				)
			) {
				w.legacy_component_creation(node.expression);
			}
		}
	}
 
	context.next();
}