pull/12215/head
Rich Harris 2 months ago
parent 3a2a9699e1
commit fdf3d84885

@ -594,7 +594,10 @@ function special(parser) {
type: 'RenderTag',
start,
end: parser.index,
expression: expression
expression: expression,
metadata: {
dynamic: false
}
});
}
}

@ -1511,6 +1511,13 @@ const common_visitors = {
return;
}
}
},
Component(node, context) {
const binding = context.state.scope.get(
node.name.includes('.') ? node.name.slice(0, node.name.indexOf('.')) : node.name
);
node.metadata.dynamic = binding !== null && binding.kind !== 'normal';
}
};

@ -625,6 +625,11 @@ const validation = {
});
},
RenderTag(node, context) {
const callee = unwrap_optional(node.expression).callee;
node.metadata.dynamic =
callee.type !== 'Identifier' || context.state.scope.get(callee.name)?.kind !== 'normal';
context.state.analysis.uses_render_tags = true;
const raw_args = unwrap_optional(node.expression).arguments;
@ -634,7 +639,6 @@ const validation = {
}
}
const callee = unwrap_optional(node.expression).callee;
if (
callee.type === 'MemberExpression' &&
callee.property.type === 'Identifier' &&

@ -1682,6 +1682,8 @@ export const template_visitors = {
process_children(trimmed, expression, false, { ...context, state });
var first = trimmed[0];
/**
* If the first item in an effect is a static slot or render tag, it will clone
* a template but without creating a child effect. In these cases, we need to keep
@ -1689,32 +1691,9 @@ export const template_visitors = {
* the item in question
* TODO come up with a better name than `unset`
*/
var unset = false;
var first = trimmed[0];
if (first.type === 'SlotElement') {
unset = true;
}
if (first.type === 'Component') {
// if it's not a `$.component`, mark as unset
const binding = context.state.scope.get(
first.name.includes('.') ? first.name.slice(0, first.name.indexOf('.')) : first.name
);
if (binding === null || binding.kind === 'normal') {
unset = true;
}
}
if (first.type === 'RenderTag') {
const callee = unwrap_optional(first.expression).callee;
const is_reactive =
callee.type !== 'Identifier' || context.state.scope.get(callee.name)?.kind !== 'normal';
if (!is_reactive) {
unset = true;
}
}
var unset =
first.type === 'SlotElement' ||
((first.type === 'Component' || first.type === 'RenderTag') && !first.metadata.dynamic);
const use_comment_template = state.template.length === 1 && state.template[0] === '<!>';
@ -1872,8 +1851,6 @@ export const template_visitors = {
context.state.template.push('<!>');
const callee = unwrap_optional(node.expression).callee;
const raw_args = unwrap_optional(node.expression).arguments;
const is_reactive =
callee.type !== 'Identifier' || context.state.scope.get(callee.name)?.kind !== 'normal';
const args = raw_args.map((arg) =>
b.thunk(/** @type {import('estree').Expression} */ (context.visit(arg)))
@ -1884,7 +1861,7 @@ export const template_visitors = {
snippet_function = b.call('$.validate_snippet', snippet_function);
}
if (is_reactive) {
if (node.metadata.dynamic) {
context.state.init.push(
b.stmt(b.call('$.snippet', context.state.node, b.thunk(snippet_function), ...args))
);
@ -3014,10 +2991,7 @@ export const template_visitors = {
}
},
Component(node, context) {
const binding = context.state.scope.get(
node.name.includes('.') ? node.name.slice(0, node.name.indexOf('.')) : node.name
);
if (binding !== null && binding.kind !== 'normal') {
if (node.metadata.dynamic) {
// Handle dynamic references to what seems like static inline components
const component = serialize_inline_component(node, '$$component', context);
context.state.init.push(
@ -3036,6 +3010,7 @@ export const template_visitors = {
);
return;
}
const component = serialize_inline_component(node, node.name, context);
context.state.init.push(component);
},

@ -152,6 +152,9 @@ export interface DebugTag extends BaseNode {
export interface RenderTag extends BaseNode {
type: 'RenderTag';
expression: SimpleCallExpression | (ChainExpression & { expression: SimpleCallExpression });
metadata: {
dynamic: boolean;
};
}
type Tag = ExpressionTag | HtmlTag | ConstTag | DebugTag | RenderTag;
@ -271,6 +274,9 @@ interface BaseElement extends BaseNode {
export interface Component extends BaseElement {
type: 'Component';
metadata: {
dynamic: boolean;
};
}
interface TitleElement extends BaseElement {

Loading…
Cancel
Save