pull/15593/merge
ComputerGuy 4 months ago committed by GitHub
commit 05fa5e345b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': minor
---
feat: allow runes in POJO properties

@ -118,7 +118,8 @@ export function CallExpression(node, context) {
if ( if (
(parent.type !== 'VariableDeclarator' || (parent.type !== 'VariableDeclarator' ||
get_parent(context.path, -3).type === 'ConstTag') && get_parent(context.path, -3).type === 'ConstTag') &&
!(parent.type === 'PropertyDefinition' && !parent.static && !parent.computed) !(parent.type === 'PropertyDefinition' && !parent.static && !parent.computed) &&
!(parent.type === 'Property' && parent.value === node)
) { ) {
e.state_invalid_placement(node, rune); e.state_invalid_placement(node, rune);
} }

@ -36,6 +36,7 @@ import { KeyBlock } from './visitors/KeyBlock.js';
import { LabeledStatement } from './visitors/LabeledStatement.js'; import { LabeledStatement } from './visitors/LabeledStatement.js';
import { LetDirective } from './visitors/LetDirective.js'; import { LetDirective } from './visitors/LetDirective.js';
import { MemberExpression } from './visitors/MemberExpression.js'; import { MemberExpression } from './visitors/MemberExpression.js';
import { ObjectExpression } from './visitors/ObjectExpression.js';
import { OnDirective } from './visitors/OnDirective.js'; import { OnDirective } from './visitors/OnDirective.js';
import { Program } from './visitors/Program.js'; import { Program } from './visitors/Program.js';
import { RegularElement } from './visitors/RegularElement.js'; import { RegularElement } from './visitors/RegularElement.js';
@ -112,6 +113,7 @@ const visitors = {
LabeledStatement, LabeledStatement,
LetDirective, LetDirective,
MemberExpression, MemberExpression,
ObjectExpression,
OnDirective, OnDirective,
Program, Program,
RegularElement, RegularElement,

@ -0,0 +1,73 @@
/** @import { ObjectExpression, Property, CallExpression, Expression, SpreadElement, Statement } from 'estree' */
/** @import { Context } from '../types' */
import * as b from '../../../../utils/builders.js';
import { get_rune } from '../../../scope.js';
import { should_proxy } from '../utils.js';
/**
* @param {ObjectExpression} node
* @param {Context} context
*/
export function ObjectExpression(node, context) {
let has_runes = false;
const valid_property_runes = ['$state', '$derived', '$state.raw', '$derived.by'];
/** @type {Statement[]} */
const body = [];
let counter = 0;
/** @type {(Property | SpreadElement)[]} */
const properties = [];
for (let property of node.properties) {
if (property.type !== 'Property') {
properties.push(/** @type {SpreadElement} */ (context.visit(property)));
continue;
}
const rune = get_rune(property.value, context.state.scope);
if (rune && valid_property_runes.includes(rune)) {
has_runes = true;
const name = context.state.scope.generate(`$$${++counter}`);
const call = rune.match(/^\$state/) ? '$.state' : '$.derived';
/** @type {Expression} */
let value = /** @type {Expression} */ (
context.visit(/** @type {CallExpression} */ (property.value).arguments[0] ?? b.void0)
);
const key = /** @type {Expression} */ (context.visit(property.key));
value =
rune === '$derived'
? b.thunk(value)
: rune === '$state' && should_proxy(value, context.state.scope)
? b.call('$.proxy', value)
: value;
properties.push(
b.prop(
'get',
key,
b.function(null, [], b.block([b.return(b.call('$.get', b.id(name)))])),
property.computed
),
b.prop(
'set',
key,
b.function(
null,
[b.id('$$value')],
b.block([
b.stmt(
b.call('$.set', b.id(name), b.id('$$value'), rune === '$state' ? b.true : undefined)
)
])
),
property.computed
)
);
body.push(b.let(name, b.call(call, value)));
} else {
properties.push(/** @type {Property} */ (context.visit(property)));
}
}
if (!has_runes) {
context.next();
return;
}
body.push(b.return(b.object(properties)));
return b.call(b.arrow([], b.block(body)));
}
Loading…
Cancel
Save