chore: better `get_rune` helper (#9594)

* chore: add $effect.active rune

* chore: add $effect.active rune

* WIP

* allow get_rune to return a keypath

* oops

---------

Co-authored-by: Dominic Gannaway <dg@domgan.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
pull/9598/head
Rich Harris 1 year ago committed by GitHub
parent 1f4ae5ef45
commit c837771ca6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -503,24 +503,19 @@ function validate_call_expression(node, scope, path) {
error(node, rune === '$derived' ? 'invalid-derived-location' : 'invalid-state-location');
}
if (rune === '$effect') {
const callee = node.callee;
if (
callee.type === 'MemberExpression' &&
callee.property.type === 'Identifier' &&
callee.property.name === 'active'
) {
if (node.arguments.length !== 0) {
error(node, 'invalid-rune-args-length', '$effect.active', [0]);
}
return;
}
if (rune === '$effect' || rune === '$effect.pre') {
if (parent.type !== 'ExpressionStatement') {
error(node, 'invalid-effect-location');
}
if (node.arguments.length !== 1) {
error(node, 'invalid-rune-args-length', '$effect', [1]);
error(node, 'invalid-rune-args-length', rune, [1]);
}
}
if (rune === '$effect.active') {
if (node.arguments.length !== 0) {
error(node, 'invalid-rune-args-length', '$effect.active', [0]);
}
}
}

@ -135,7 +135,7 @@ export const javascript_visitors_runes = {
for (const declarator of node.declarations) {
const init = declarator.init;
const rune = get_rune(init, state.scope);
if (!rune || rune === '$effect') {
if (!rune || rune === '$effect.active') {
if (init != null && is_hoistable_function(init)) {
const hoistable_function = visit(init);
state.hoisted.push(
@ -294,16 +294,11 @@ export const javascript_visitors_runes = {
},
CallExpression(node, { state, next }) {
const rune = get_rune(node, state.scope);
const callee = node.callee;
if (
rune === '$effect' &&
callee.type === 'MemberExpression' &&
callee.property.type === 'Identifier' &&
callee.property.name === 'active'
) {
if (rune === '$effect.active') {
return b.call('$.effect_active');
}
next();
}
};

@ -550,7 +550,7 @@ const javascript_visitors_runes = {
for (const declarator of node.declarations) {
const rune = get_rune(declarator.init, state.scope);
if (!rune || rune === '$effect') {
if (!rune || rune === '$effect.active') {
declarations.push(/** @type {import('estree').VariableDeclarator} */ (visit(declarator)));
continue;
}
@ -607,16 +607,11 @@ const javascript_visitors_runes = {
},
CallExpression(node, { state, next }) {
const rune = get_rune(node, state.scope);
const callee = node.callee;
if (
rune === '$effect' &&
callee.type === 'MemberExpression' &&
callee.property.type === 'Identifier' &&
callee.property.name === 'active'
) {
if (rune === '$effect.active') {
return b.literal(false);
}
next();
}
};

@ -110,7 +110,7 @@ export const ElementBindings = [
'indeterminate'
];
export const Runes = ['$state', '$props', '$derived', '$effect'];
export const Runes = ['$state', '$props', '$derived', '$effect', '$effect.pre', '$effect.active'];
/**
* Whitespace inside one of these elements will not result in

@ -668,15 +668,31 @@ export function set_scope(scopes) {
/**
* Returns the name of the rune if the given expression is a `CallExpression` using a rune.
* @param {import('estree').Expression | null | undefined} node
* @param {import('estree').Node | null | undefined} node
* @param {Scope} scope
*/
export function get_rune(node, scope) {
const callee = get_callee_name(node);
if (callee === null || !Runes.includes(callee)) return null;
if (!node) return null;
if (node.type !== 'CallExpression') return null;
const binding = scope.get(callee);
let n = node.callee;
let joined = '';
while (n.type === 'MemberExpression') {
if (n.computed) return null;
if (n.property.type !== 'Identifier') return null;
joined = '.' + n.property.name + joined;
n = n.object;
}
if (n.type !== 'Identifier') return null;
joined = n.name + joined;
if (!Runes.includes(joined)) return null;
const binding = scope.get(n.name);
if (binding !== null) return null; // rune name, but references a variable or store
return callee;
return joined;
}

Loading…
Cancel
Save