Skip to content

Commit

Permalink
chore: tweak render tag logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Rich-Harris committed Jan 24, 2025
1 parent 24b6fab commit f32920e
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 27 deletions.
2 changes: 1 addition & 1 deletion packages/svelte/src/compiler/phases/1-parse/state/tag.js
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ function special(parser) {
expression: /** @type {AST.RenderTag['expression']} */ (expression),
metadata: {
dynamic: false,
args_with_call_expression: new Set(),
arguments: [],
path: [],
snippets: new Set()
}
Expand Down
2 changes: 0 additions & 2 deletions packages/svelte/src/compiler/phases/2-analyze/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,6 @@ export function analyze_component(root, source, options) {
has_props_rune: false,
component_slots: new Set(),
expression: null,
render_tag: null,
private_derived_state: [],
function_depth: scope.function_depth,
instance_scope: instance.scope,
Expand Down Expand Up @@ -677,7 +676,6 @@ export function analyze_component(root, source, options) {
reactive_statements: analysis.reactive_statements,
component_slots: new Set(),
expression: null,
render_tag: null,
private_derived_state: [],
function_depth: scope.function_depth
};
Expand Down
2 changes: 0 additions & 2 deletions packages/svelte/src/compiler/phases/2-analyze/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ export interface AnalysisState {
component_slots: Set<string>;
/** Information about the current expression/directive/block value */
expression: ExpressionMetadata | null;
/** The current {@render ...} tag, if any */
render_tag: null | AST.RenderTag;
private_derived_state: string[];
function_depth: number;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,18 +186,6 @@ export function CallExpression(node, context) {
break;
}

if (context.state.render_tag) {
// Find out which of the render tag arguments contains this call expression
const arg_idx = unwrap_optional(context.state.render_tag.expression).arguments.findIndex(
(arg) => arg === node || context.path.includes(arg)
);

// -1 if this is the call expression of the render tag itself
if (arg_idx !== -1) {
context.state.render_tag.metadata.args_with_call_expression.add(arg_idx);
}
}

if (node.callee.type === 'Identifier') {
const binding = context.state.scope.get(node.callee.name);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as e from '../../../errors.js';
import { validate_opening_tag } from './shared/utils.js';
import { mark_subtree_dynamic } from './shared/fragment.js';
import { is_resolved_snippet } from './shared/snippets.js';
import { create_expression_metadata } from '../../nodes.js';

/**
* @param {AST.RenderTag} node
Expand All @@ -15,7 +16,8 @@ export function RenderTag(node, context) {

node.metadata.path = [...context.path];

const callee = unwrap_optional(node.expression).callee;
const expression = unwrap_optional(node.expression);
const callee = expression.callee;

const binding = callee.type === 'Identifier' ? context.state.scope.get(callee.name) : null;

Expand Down Expand Up @@ -52,5 +54,15 @@ export function RenderTag(node, context) {

mark_subtree_dynamic(context.path);

context.next({ ...context.state, render_tag: node });
context.visit(callee);

for (const arg of expression.arguments) {
const metadata = create_expression_metadata();
node.metadata.arguments.push(metadata);

context.visit(arg, {
...context.state,
expression: metadata
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,24 @@ import * as b from '../../../../utils/builders.js';
*/
export function RenderTag(node, context) {
context.state.template.push('<!>');
const callee = unwrap_optional(node.expression).callee;
const raw_args = unwrap_optional(node.expression).arguments;

const expression = unwrap_optional(node.expression);

const callee = expression.callee;
const raw_args = expression.arguments;

/** @type {Expression[]} */
let args = [];
for (let i = 0; i < raw_args.length; i++) {
const raw = raw_args[i];
const arg = /** @type {Expression} */ (context.visit(raw));
if (node.metadata.args_with_call_expression.has(i)) {
let thunk = b.thunk(/** @type {Expression} */ (context.visit(raw_args[i])));
const { has_call } = node.metadata.arguments[i];

if (has_call) {
const id = b.id(context.state.scope.generate('render_arg'));
context.state.init.push(b.var(id, b.call('$.derived_safe_equal', b.thunk(arg))));
context.state.init.push(b.var(id, b.call('$.derived_safe_equal', thunk)));
args.push(b.thunk(b.call('$.get', id)));
} else {
args.push(b.thunk(arg));
args.push(thunk);
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/svelte/src/compiler/types/template.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export namespace AST {
/** @internal */
metadata: {
dynamic: boolean;
args_with_call_expression: Set<number>;
arguments: ExpressionMetadata[];
path: SvelteNode[];
/** The set of locally-defined snippets that this render tag could correspond to,
* used for CSS pruning purposes */
Expand Down

0 comments on commit f32920e

Please sign in to comment.