Skip to content

Commit

Permalink
fix: properly transform $props.id when $props is assigned to props
Browse files Browse the repository at this point in the history
  • Loading branch information
paoloricciuti committed Feb 24, 2025
1 parent a24d819 commit a5d694b
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 4 deletions.
42 changes: 38 additions & 4 deletions packages/svelte2tsx/src/svelte2tsx/processInstanceScriptContent.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MagicString from 'magic-string';
import { Node } from 'estree-walker';
import ts from 'typescript';
import ts, { VariableDeclaration } from 'typescript';
import { getBinaryAssignmentExpr, isNotPropertyNameOfImport, moveNode } from './utils/tsAst';
import { ExportedNames, is$$PropsDeclaration } from './nodes/ExportedNames';
import { ImplicitTopLevelNames } from './nodes/ImplicitTopLevelNames';
Expand Down Expand Up @@ -32,6 +32,7 @@ interface PendingStoreResolution {
node: ts.Identifier;
parent: ts.Node;
scope: Scope;
isPropsId: boolean;
}

export function processInstanceScriptContent(
Expand Down Expand Up @@ -82,13 +83,18 @@ export function processInstanceScriptContent(
//track if we are in a declaration scope
let isDeclaration = false;

//track the variable declaration node
let variableDeclarationNode: VariableDeclaration | null = null;

//track $store variables since we are only supposed to give top level scopes special treatment, and users can declare $blah variables at higher scopes
//which prevents us just changing all instances of Identity that start with $
const pendingStoreResolutions: PendingStoreResolution[] = [];
let pendingStoreResolutions: PendingStoreResolution[] = [];

let scope = new Scope();
const rootScope = scope;

let isPropsDeclarationRune = false;

const pushScope = () => (scope = new Scope(scope));
const popScope = () => (scope = scope.parent);

Expand Down Expand Up @@ -124,6 +130,16 @@ export function processInstanceScriptContent(
return;
}

if (
ident.text === 'props' &&
variableDeclarationNode &&
variableDeclarationNode.initializer &&
ts.isCallExpression(variableDeclarationNode.initializer) &&
variableDeclarationNode.initializer.getText() === '$props()'
) {
isPropsDeclarationRune = true;
}

if (isDeclaration || ts.isParameter(parent)) {
if (
isNotPropertyNameOfImport(ident) &&
Expand All @@ -148,14 +164,25 @@ export function processInstanceScriptContent(
!ts.isTypeAliasDeclaration(parent) &&
!ts.isInterfaceDeclaration(parent)
) {
let isPropsId = false;
if (
text === '$props' &&
ts.isPropertyAccessExpression(parent) &&
parent.parent &&
ts.isCallExpression(parent.parent) &&
parent.parent.arguments.length === 0
) {
const text = parent.getText();
isPropsId = text === '$props.id';
}
// Handle the const { ...props } = $props() case
const is_rune =
(text === '$props' || text === '$derived' || text === '$state') &&
ts.isCallExpression(parent) &&
ts.isVariableDeclaration(parent.parent) &&
parent.parent.name.getText().includes(text.slice(1));
if (!is_rune) {
pendingStoreResolutions.push({ node: ident, parent, scope });
pendingStoreResolutions.push({ node: ident, parent, scope, isPropsId });
}
}
}
Expand Down Expand Up @@ -234,7 +261,11 @@ export function processInstanceScriptContent(

if (ts.isVariableDeclaration(parent) && parent.name == node) {
isDeclaration = true;
onLeaveCallbacks.push(() => (isDeclaration = false));
variableDeclarationNode = parent;
onLeaveCallbacks.push(() => {
isDeclaration = false;
variableDeclarationNode = null;
});
}

if (ts.isBindingElement(parent) && parent.name == node) {
Expand Down Expand Up @@ -295,6 +326,9 @@ export function processInstanceScriptContent(
tsAst.forEachChild((n) => walk(n, tsAst));

//resolve stores
if (isPropsDeclarationRune) {
pendingStoreResolutions = pendingStoreResolutions.filter(({ isPropsId }) => !isPropsId);
}
pendingStoreResolutions.map(resolveStore);

// declare implicit reactive variables we found in the script
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
///<reference types="svelte" />
;function $$render() {

let/** @typedef {{ props: any }} $$ComponentProps *//** @type {$$ComponentProps} */ { props } = $props();
let id = $props.id();
;
async () => {

id; props;};
return { props: /** @type {$$ComponentProps} */({}), exports: {}, bindings: __sveltets_$$bindings(''), slots: {}, events: {} }}
const Input__SvelteComponent_ = __sveltets_2_fn_component($$render());
type Input__SvelteComponent_ = ReturnType<typeof Input__SvelteComponent_>;
export default Input__SvelteComponent_;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<script>
let { props } = $props();
let id = $props.id();
</script>

{id} {props}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
///<reference types="svelte" />
;function $$render() {

let props = {}/*Ωignore_startΩ*/;let $props = __sveltets_2_store_get(props);/*Ωignore_endΩ*/;
let id = $props.id();
;
async () => {

id; props;};
return { props: /** @type {Record<string, never>} */ ({}), exports: {}, bindings: "", slots: {}, events: {} }}
const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(__sveltets_2_with_any_event($$render())));
/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType<typeof Input__SvelteComponent_>;
/*Ωignore_endΩ*/export default Input__SvelteComponent_;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<script>
let props = {};
let id = $props.id();
</script>

{id} {props}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
///<reference types="svelte" />
;function $$render() {

let/** @typedef {Record<string, any>} $$ComponentProps *//** @type {$$ComponentProps} */ {...props} = $props();
let id = $props.id();
;
async () => {

id; props;};
return { props: /** @type {$$ComponentProps} */({}), exports: {}, bindings: __sveltets_$$bindings(''), slots: {}, events: {} }}
const Input__SvelteComponent_ = __sveltets_2_fn_component($$render());
type Input__SvelteComponent_ = ReturnType<typeof Input__SvelteComponent_>;
export default Input__SvelteComponent_;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<script>
let {...props} = $props();
let id = $props.id();
</script>

{id} {props}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
///<reference types="svelte" />
;function $$render() {

let props = $props();
let id = $props.id();
;
async () => {

id; props;};
return { props: /** @type {$$ComponentProps} */({}), exports: {}, bindings: __sveltets_$$bindings(''), slots: {}, events: {} }}
const Input__SvelteComponent_ = __sveltets_2_fn_component($$render());
type Input__SvelteComponent_ = ReturnType<typeof Input__SvelteComponent_>;
export default Input__SvelteComponent_;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<script>
let props = $props();
let id = $props.id();
</script>

{id} {props}

0 comments on commit a5d694b

Please sign in to comment.