function validate_slot_attribute(context, attribute, is_component = false) {
	const parent = context.path.at(-2);
	let owner = undefined;

	if (parent?.type === 'SnippetBlock') {
		if (!is_text_attribute(attribute)) {
			e.slot_attribute_invalid(attribute);
		}
		return;
	}

	let i = context.path.length;
	while (i--) {
		const ancestor = context.path[i];
		if (
			!owner &&
			(ancestor.type === 'Component' ||
				ancestor.type === 'SvelteComponent' ||
				ancestor.type === 'SvelteSelf' ||
				ancestor.type === 'SvelteElement' ||
				(ancestor.type === 'RegularElement' && is_custom_element_node(ancestor)))
		) {
			owner = ancestor;
		}
	}

	if (owner) {
		if (
			owner.type === 'Component' ||
			owner.type === 'SvelteComponent' ||
			owner.type === 'SvelteSelf'
		) {
			if (owner !== parent) {
				if (!is_component) {
					e.slot_attribute_invalid_placement(attribute);
				}
			} else {
				if (!is_text_attribute(attribute)) {
					e.slot_attribute_invalid(attribute);
				}

				const name = attribute.value[0].data;

				if (context.state.component_slots.has(name)) {
					e.slot_attribute_duplicate(attribute, name, owner.name);
				}

				context.state.component_slots.add(name);

				if (name === 'default') {
					for (const node of owner.fragment.nodes) {
						if (node.type === 'Text' && regex_only_whitespaces.test(node.data)) {
							continue;
						}

						if (node.type === 'RegularElement' || node.type === 'SvelteFragment') {
							if (node.attributes.some((a) => a.type === 'Attribute' && a.name === 'slot')) {
								continue;
							}
						}

						e.slot_default_duplicate(node);
					}
				}
			}
		}
	} else if (!is_component) {
		e.slot_attribute_invalid_placement(attribute);
	}
}
@param {Context} context
@param {AST.Attribute} attribute
@param {boolean} is_component