skip the noop if known to be a function

pull/16021/head
Rich Harris 4 months ago
parent 8f152de6dc
commit a34c2337c0

@ -258,12 +258,17 @@ export function build_component(node, component_name, context, anchor = context.
}
}
} else if (attribute.type === 'AttachTag') {
const evaluated = context.state.scope.evaluate(attribute.expression);
let expression = /** @type {Expression} */ (context.visit(attribute.expression));
if (attribute.metadata.expression.has_state) {
expression = b.arrow(
[b.id('$$node')],
b.call(b.call('$.safe_call', expression), b.id('$$node'))
b.call(
evaluated.is_function ? expression : b.logical('||', expression, b.id('$.noop')),
b.id('$$node')
)
);
}

@ -20,6 +20,7 @@ const UNKNOWN = Symbol('unknown');
/** Includes `BigInt` */
export const NUMBER = Symbol('number');
export const STRING = Symbol('string');
export const FUNCTION = Symbol('string');
/** @type {Record<string, [type: NUMBER | STRING | UNKNOWN, fn?: Function]>} */
const globals = {
@ -200,6 +201,13 @@ class Evaluation {
*/
is_number = true;
/**
* True if the value is known to be a function
* @readonly
* @type {boolean}
*/
is_function = true;
/**
* @readonly
* @type {any}
@ -209,7 +217,7 @@ class Evaluation {
/**
*
* @param {Scope} scope
* @param {Expression} expression
* @param {Expression | FunctionDeclaration} expression
* @param {Set<any>} values
*/
constructor(scope, expression, values) {
@ -500,6 +508,13 @@ class Evaluation {
break;
}
case 'ArrowFunctionExpression':
case 'FunctionExpression':
case 'FunctionDeclaration': {
this.values.add(FUNCTION);
break;
}
default: {
this.values.add(UNKNOWN);
}
@ -516,6 +531,10 @@ class Evaluation {
this.is_number = false;
}
if (value !== FUNCTION) {
this.is_function = false;
}
if (value == null || value === UNKNOWN) {
this.is_defined = false;
}

@ -155,7 +155,7 @@ export {
} from './dom/operations.js';
export { attr, clsx } from '../shared/attributes.js';
export { snapshot } from '../shared/clone.js';
export { noop, fallback, safe_call, to_array } from '../shared/utils.js';
export { noop, fallback, to_array } from '../shared/utils.js';
export {
invalid_default_snippet,
validate_dynamic_element_tag,

@ -82,16 +82,6 @@ export function fallback(value, fallback, lazy = false) {
: value;
}
/**
* @param {*} value
*/
export function safe_call(value) {
if (is_function(value)) {
return value;
}
return noop;
}
/**
* When encountering a situation like `let [a, b, c] = $derived(blah())`,
* we need to stash an intermediate value that `a`, `b`, and `c` derive

Loading…
Cancel
Save