fix private fields

reassign-derived
Dominic Gannaway 2 months ago
parent 78ab02d3e4
commit 06962c8946

@ -546,7 +546,6 @@ export function analyze_component(root, source, options) {
component_slots: new Set(),
expression: null,
render_tag: null,
private_derived_state: [],
function_depth: scope.function_depth,
instance_scope: instance.scope,
reactive_statement: null,
@ -618,7 +617,6 @@ export function analyze_component(root, source, options) {
component_slots: new Set(),
expression: null,
render_tag: null,
private_derived_state: [],
function_depth: scope.function_depth
};

@ -17,7 +17,6 @@ export interface AnalysisState {
expression: ExpressionMetadata | null;
/** The current {@render ...} tag, if any */
render_tag: null | RenderTag;
private_derived_state: string[];
function_depth: number;
// legacy stuff

@ -1,27 +1,10 @@
/** @import { ClassBody } from 'estree' */
/** @import { Context } from '../types' */
import { get_rune } from '../../scope.js';
/**
* @param {ClassBody} node
* @param {Context} context
*/
export function ClassBody(node, context) {
/** @type {string[]} */
const private_derived_state = [];
for (const definition of node.body) {
if (
definition.type === 'PropertyDefinition' &&
definition.key.type === 'PrivateIdentifier' &&
definition.value?.type === 'CallExpression'
) {
const rune = get_rune(definition.value, context.state.scope);
if (rune === '$derived' || rune === '$derived.by') {
private_derived_state.push(definition.key.name);
}
}
}
context.next({ ...context.state, private_derived_state });
context.next({ ...context.state });
}

@ -51,12 +51,6 @@ export function validate_assignment(node, argument, state) {
property = object.property;
object = object.object;
}
if (object.type === 'ThisExpression' && property?.type === 'PrivateIdentifier') {
if (state.private_derived_state.includes(property.name)) {
e.constant_assignment(node, 'derived state');
}
}
}
/**

@ -46,7 +46,7 @@ function build_assignment(operator, left, right, context) {
if (should_proxy(value, context.state.scope)) {
transformed = true;
value =
private_state.kind === 'raw_state'
private_state.kind === 'raw_state' || private_state.kind === 'derived'
? value
: build_proxy_reassignment(value, private_state.id);
}

@ -24,6 +24,23 @@ export function AssignmentExpression(node, context) {
function build_assignment(operator, left, right, context) {
let object = left;
if (
context.state.analysis.runes &&
left.type === 'MemberExpression' &&
left.object.type === 'ThisExpression' &&
left.property.type === 'PrivateIdentifier'
) {
const field = context.state.private_derived.get(left.property.name);
if (field) {
return b.assignment(
operator,
left,
b.call('$.once', b.thunk(/** @type {Expression} */ (context.visit(right))))
);
}
}
while (object.type === 'MemberExpression') {
// @ts-expect-error
object = object.object;

@ -97,17 +97,6 @@ export function ClassBody(node, context) {
// get foo() { return this.#foo; }
body.push(b.method('get', definition.key, [], [b.return(b.call(member))]));
if (dev && (field.kind === 'derived' || field.kind === 'derived_by')) {
body.push(
b.method(
'set',
definition.key,
[b.id('_')],
[b.throw_error(`Cannot update a derived property ('${name}')`)]
)
);
}
}
continue;

@ -1,8 +0,0 @@
import { test } from '../../test';
export default test({
error: {
code: 'constant_assignment',
message: 'Cannot assign to derived state'
}
});

@ -1,10 +0,0 @@
<script>
class Counter {
count = $state();
#doubled = $derived(this.count * 2);
nope() {
this.#doubled += 1;
}
}
</script>

@ -1,8 +0,0 @@
import { test } from '../../test';
export default test({
error: {
code: 'constant_assignment',
message: 'Cannot assign to derived state'
}
});

@ -1,10 +0,0 @@
<script>
class Counter {
count = $state();
#doubled = $derived(this.count * 2);
nope() {
this.#doubled++;
}
}
</script>
Loading…
Cancel
Save