Skip to content

Commit c60e30d

Browse files
committed
feat: allow usage of $props.id everywhere if invoked within a component script
1 parent 868e3fa commit c60e30d

File tree

25 files changed

+161
-78
lines changed

25 files changed

+161
-78
lines changed

.changeset/empty-sloths-give.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': minor
3+
---
4+
5+
feat: allow usage of `$props.id` everywhere if invoked within a component script

documentation/docs/98-reference/.generated/compile-errors.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -576,12 +576,6 @@ Unrecognised compiler option %keypath%
576576
Cannot use `%rune%()` more than once
577577
```
578578

579-
### props_id_invalid_placement
580-
581-
```
582-
`$props.id()` can only be used at the top level of components as a variable declaration initializer
583-
```
584-
585579
### props_illegal_name
586580

587581
```

documentation/docs/98-reference/.generated/shared-errors.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ Certain lifecycle methods can only be used during component initialisation. To f
5454
<button onclick={handleClick}>click me</button>
5555
```
5656

57+
### props_id_invalid_placement
58+
59+
```
60+
`$props.id()` can only be used inside a component initialization phase
61+
```
62+
5763
### store_invalid_shape
5864

5965
```

packages/svelte/messages/compile-errors/script.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,6 @@ This turned out to be buggy and unpredictable, particularly when working with de
122122

123123
> Cannot use `%rune%()` more than once
124124
125-
## props_id_invalid_placement
126-
127-
> `$props.id()` can only be used at the top level of components as a variable declaration initializer
128-
129125
## props_illegal_name
130126

131127
> Declaring or accessing a prop starting with `$$` is illegal (they are reserved for Svelte internals)

packages/svelte/messages/shared-errors/errors.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ Certain lifecycle methods can only be used during component initialisation. To f
4848
<button onclick={handleClick}>click me</button>
4949
```
5050

51+
## props_id_invalid_placement
52+
53+
> `$props.id()` can only be used inside a component initialization phase
54+
5155
## store_invalid_shape
5256

5357
> `%name%` is not a store with a `subscribe` method

packages/svelte/src/compiler/errors.js

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -288,15 +288,6 @@ export function props_duplicate(node, rune) {
288288
e(node, 'props_duplicate', `Cannot use \`${rune}()\` more than once\nhttps://svelte.dev/e/props_duplicate`);
289289
}
290290

291-
/**
292-
* `$props.id()` can only be used at the top level of components as a variable declaration initializer
293-
* @param {null | number | NodeLike} node
294-
* @returns {never}
295-
*/
296-
export function props_id_invalid_placement(node) {
297-
e(node, 'props_id_invalid_placement', `\`$props.id()\` can only be used at the top level of components as a variable declaration initializer\nhttps://svelte.dev/e/props_id_invalid_placement`);
298-
}
299-
300291
/**
301292
* Declaring or accessing a prop starting with `$$` is illegal (they are reserved for Svelte internals)
302293
* @param {null | number | NodeLike} node

packages/svelte/src/compiler/phases/2-analyze/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,6 @@ export function analyze_component(root, source, options) {
416416
immutable: runes || options.immutable,
417417
exports: [],
418418
uses_props: false,
419-
props_id: null,
420419
uses_rest_props: false,
421420
uses_slots: false,
422421
uses_component_bindings: false,

packages/svelte/src/compiler/phases/2-analyze/visitors/CallExpression.js

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -75,28 +75,9 @@ export function CallExpression(node, context) {
7575
break;
7676

7777
case '$props.id': {
78-
const grand_parent = get_parent(context.path, -2);
79-
80-
if (context.state.analysis.props_id) {
81-
e.props_duplicate(node, rune);
82-
}
83-
84-
if (
85-
parent.type !== 'VariableDeclarator' ||
86-
parent.id.type !== 'Identifier' ||
87-
context.state.ast_type !== 'instance' ||
88-
context.state.scope !== context.state.analysis.instance.scope ||
89-
grand_parent.type !== 'VariableDeclaration'
90-
) {
91-
e.props_id_invalid_placement(node);
92-
}
93-
9478
if (node.arguments.length > 0) {
9579
e.rune_invalid_arguments(node, rune);
9680
}
97-
98-
context.state.analysis.props_id = parent.id;
99-
10081
break;
10182
}
10283

packages/svelte/src/compiler/phases/2-analyze/visitors/shared/utils.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ export function validate_assignment(node, argument, state) {
2525
e.constant_assignment(node, 'derived state');
2626
}
2727

28-
if (binding?.node === state.analysis.props_id) {
29-
e.constant_assignment(node, '$props.id()');
30-
}
31-
3228
if (binding?.kind === 'each') {
3329
e.each_item_invalid_assignment(node);
3430
}

packages/svelte/src/compiler/phases/3-transform/client/transform-client.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,10 @@ export function client_component(analysis, options) {
226226
if (store_setup.length === 0) {
227227
needs_store_cleanup = true;
228228
store_setup.push(
229-
b.const(b.array_pattern([b.id('$$stores'), b.id('$$cleanup')]), b.call('$.setup_stores'))
229+
b.const(
230+
b.array_pattern([b.id('$$stores'), b.id('$$cleanup_stores')]),
231+
b.call('$.setup_stores')
232+
)
230233
);
231234
}
232235

@@ -414,11 +417,13 @@ export function client_component(analysis, options) {
414417
}
415418

416419
if (needs_store_cleanup) {
417-
component_block.body.push(b.stmt(b.call('$$cleanup')));
420+
component_block.body.push(b.stmt(b.call('$$cleanup_stores')));
418421
if (component_returned_object.length > 0) {
419422
component_block.body.push(b.return(b.id('$$pop')));
420423
}
421424
}
425+
component_block.body.unshift(b.const('$$cleanup', b.call('$.setup')));
426+
component_block.body.push(b.stmt(b.call('$$cleanup')));
422427

423428
if (analysis.uses_rest_props) {
424429
const named_props = analysis.exports.map(({ name, alias }) => alias ?? name);
@@ -562,11 +567,6 @@ export function client_component(analysis, options) {
562567
component_block.body.unshift(b.stmt(b.call('$.check_target', b.id('new.target'))));
563568
}
564569

565-
if (analysis.props_id) {
566-
// need to be placed on first line of the component for hydration
567-
component_block.body.unshift(b.const(analysis.props_id, b.call('$.props_id')));
568-
}
569-
570570
if (state.events.size > 0) {
571571
body.push(
572572
b.stmt(b.call('$.delegate', b.array(Array.from(state.events).map((name) => b.literal(name)))))

0 commit comments

Comments
 (0)