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 3625x 3625x 3625x 3625x 3625x 3625x 4x 4x 4x 3625x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3625x 3625x 3625x  
/** @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();
}