Skip to content

Commit

Permalink
fix: disambiguate render in module script
Browse files Browse the repository at this point in the history
  • Loading branch information
paoloricciuti committed Jan 16, 2025
1 parent 2f46701 commit 1f771d6
Show file tree
Hide file tree
Showing 18 changed files with 174 additions and 25 deletions.
27 changes: 15 additions & 12 deletions packages/svelte2tsx/src/svelte2tsx/addComponentExport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface AddComponentExportPara {
usesSlots: boolean;
isSvelte5: boolean;
noSvelteComponentTyped?: boolean;
renderName: string;
}

/**
Expand Down Expand Up @@ -54,7 +55,8 @@ function addGenericsComponentExport({
generics,
usesSlots,
isSvelte5,
noSvelteComponentTyped
noSvelteComponentTyped,
renderName
}: AddComponentExportPara) {
const genericsDef = generics.toDefinitionString();
const genericsRef = generics.toReferencesString();
Expand All @@ -71,29 +73,29 @@ function addGenericsComponentExport({
let statement = `
class __sveltets_Render${genericsDef} {
props() {
return ${props(true, canHaveAnyProp, exportedNames, `render${genericsRef}()`)}.props;
return ${props(true, canHaveAnyProp, exportedNames, `${renderName}${genericsRef}()`)}.props;
}
events() {
return ${_events(events.hasStrictEvents() || exportedNames.usesRunes(), `render${genericsRef}()`)}.events;
return ${_events(events.hasStrictEvents() || exportedNames.usesRunes(), `${renderName}${genericsRef}()`)}.events;
}
slots() {
return render${genericsRef}().slots;
return ${renderName}${genericsRef}().slots;
}
`;

// For Svelte 5+ we assume TS > 4.7
if (isSvelte5 && !isTsFile && exportedNames.usesRunes()) {
statement = `
class __sveltets_Render${genericsDef} {
props(): ReturnType<typeof render${genericsRef}>['props'] { return null as any; }
events(): ReturnType<typeof render${genericsRef}>['events'] { return null as any; }
slots(): ReturnType<typeof render${genericsRef}>['slots'] { return null as any; }
props(): ReturnType<typeof ${renderName}${genericsRef}>['props'] { return null as any; }
events(): ReturnType<typeof ${renderName}${genericsRef}>['events'] { return null as any; }
slots(): ReturnType<typeof ${renderName}${genericsRef}>['slots'] { return null as any; }
`;
}

statement += isSvelte5
? ` bindings() { return ${exportedNames.createBindingsStr()}; }
exports() { return ${exportedNames.hasExports() ? `render${genericsRef}().exports` : '{}'}; }
exports() { return ${exportedNames.hasExports() ? `${renderName}${genericsRef}().exports` : '{}'}; }
}\n`
: '}\n';

Expand Down Expand Up @@ -175,13 +177,14 @@ function addSimpleComponentExport({
str,
usesSlots,
noSvelteComponentTyped,
isSvelte5
isSvelte5,
renderName
}: AddComponentExportPara) {
const propDef = props(
isTsFile,
canHaveAnyProp,
exportedNames,
_events(events.hasStrictEvents(), 'render()')
_events(events.hasStrictEvents(), `${renderName}()`)
);

const doc = componentDocumentation.getFormatted();
Expand All @@ -192,7 +195,7 @@ function addSimpleComponentExport({
if (mode === 'dts') {
if (isSvelte5 && exportedNames.usesRunes() && !usesSlots && !events.hasEvents()) {
statement =
`\n${doc}const ${componentName} = __sveltets_2_fn_component(render());\n` +
`\n${doc}const ${componentName} = __sveltets_2_fn_component(${renderName}());\n` +
`type ${componentName} = ReturnType<typeof ${componentName}>;\n` +
`export default ${componentName};`;
} else if (isSvelte5) {
Expand Down Expand Up @@ -258,7 +261,7 @@ declare function $$__sveltets_2_isomorphic_component<
if (isSvelte5) {
if (exportedNames.usesRunes() && !usesSlots && !events.hasEvents()) {
statement =
`\n${doc}const ${componentName} = __sveltets_2_fn_component(render());\n` +
`\n${doc}const ${componentName} = __sveltets_2_fn_component(${renderName}());\n` +
`type ${componentName} = ReturnType<typeof ${componentName}>;\n` +
`export default ${componentName};`;
} else {
Expand Down
11 changes: 7 additions & 4 deletions packages/svelte2tsx/src/svelte2tsx/createRenderFunction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface CreateRenderFunctionPara extends InstanceScriptProcessResult {
svelte5Plus: boolean;
isTsFile: boolean;
mode?: 'ts' | 'dts';
renderName: string;
}

export function createRenderFunction({
Expand All @@ -33,7 +34,8 @@ export function createRenderFunction({
uses$$SlotsInterface,
generics,
isTsFile,
mode
mode,
renderName
}: CreateRenderFunctionPara) {
const htmlx = str.original;
let propsDecl = '';
Expand Down Expand Up @@ -75,7 +77,8 @@ export function createRenderFunction({
start++;
end--;
}
str.overwrite(scriptTag.start + 1, start - 1, `function render`);

str.overwrite(scriptTag.start + 1, start - 1, `function ${renderName}`);
str.overwrite(start - 1, start, isTsFile ? '<' : `<${IGNORE_START_COMMENT}`); // if the generics are unused, only this char is colored opaque
str.overwrite(
end,
Expand All @@ -86,7 +89,7 @@ export function createRenderFunction({
str.overwrite(
scriptTag.start + 1,
scriptTagEnd,
`function render${generics.toDefinitionString(true)}() {${propsDecl}\n`
`function ${renderName}${generics.toDefinitionString(true)}() {${propsDecl}\n`
);
}

Expand All @@ -98,7 +101,7 @@ export function createRenderFunction({
} else {
str.prependRight(
scriptDestination,
`;function render() {` + `${propsDecl}${slotsDeclaration}\nasync () => {`
`;function ${renderName}() {` + `${propsDecl}${slotsDeclaration}\nasync () => {`
);
}

Expand Down
19 changes: 15 additions & 4 deletions packages/svelte2tsx/src/svelte2tsx/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,15 @@ export function svelte2tsx(
: instanceScriptTarget;
const implicitStoreValues = new ImplicitStoreValues(resolvedStores, renderFunctionStart);
//move the instance script and process the content
let exportedNames = new ExportedNames(str, 0, basename, isTsFile, svelte5Plus, isRunes);
let exportedNames = new ExportedNames(
str,
0,
basename,
isTsFile,
svelte5Plus,
isRunes,
moduleAst.renderName
);
let generics = new Generics(str, 0, { attributes: [] } as any);
let uses$$SlotsInterface = false;
if (scriptTag) {
Expand All @@ -114,7 +122,8 @@ export function svelte2tsx(
isTsFile,
basename,
svelte5Plus,
isRunes
isRunes,
moduleAst.renderName
);
uses$$props = uses$$props || res.uses$$props;
uses$$restProps = uses$$restProps || res.uses$$restProps;
Expand Down Expand Up @@ -143,7 +152,8 @@ export function svelte2tsx(
generics,
svelte5Plus,
isTsFile,
mode: options.mode
mode: options.mode,
renderName: moduleAst.renderName
});

// we need to process the module script after the instance script has moved otherwise we get warnings about moving edited items
Expand Down Expand Up @@ -201,7 +211,8 @@ export function svelte2tsx(
mode: options.mode,
generics,
isSvelte5: svelte5Plus,
noSvelteComponentTyped: options.noSvelteComponentTyped
noSvelteComponentTyped: options.noSvelteComponentTyped,
renderName: moduleAst.renderName
});

if (options.mode === 'dts') {
Expand Down
8 changes: 6 additions & 2 deletions packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ export class ExportedNames {
private basename: string,
private isTsFile: boolean,
private isSvelte5Plus: boolean,
private isRunes: boolean
private isRunes: boolean,
private renderName: string
) {}

handleVariableStatement(node: ts.VariableStatement, parent: ts.Node): void {
Expand Down Expand Up @@ -506,7 +507,10 @@ export class ExportedNames {
if (this.usesRunes()) {
// In runes mode, exports are no longer part of props
return Array.from(this.getters)
.map((name) => `\n get ${name}() { return render${generics}().exports.${name} }`)
.map(
(name) =>
`\n get ${name}() { return ${this.renderName}${generics}().exports.${name} }`
)
.join('');
} else {
return Array.from(this.getters)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ export function processInstanceScriptContent(
isTSFile: boolean,
basename: string,
isSvelte5Plus: boolean,
isRunes: boolean
isRunes: boolean,
renderName: string
): InstanceScriptProcessResult {
const htmlx = str.original;
const scriptContent = htmlx.substring(script.content.start, script.content.end);
Expand All @@ -62,7 +63,8 @@ export function processInstanceScriptContent(
basename,
isTSFile,
isSvelte5Plus,
isRunes
isRunes,
renderName
);
const generics = new Generics(str, astOffset, script);
const interfacesAndTypes = new InterfacesAndTypes();
Expand Down
21 changes: 20 additions & 1 deletion packages/svelte2tsx/src/svelte2tsx/processModuleScriptTag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface ModuleAst {
htmlx: string;
tsAst: ts.SourceFile;
astOffset: number;
renderName: string;
}

export function createModuleAst(str: MagicString, script: Node): ModuleAst {
Expand All @@ -25,9 +26,27 @@ export function createModuleAst(str: MagicString, script: Node): ModuleAst {
true,
ts.ScriptKind.TS
);

const identifiers = new Set<string>();

const walk = (node: ts.Node) => {
if (ts.isIdentifier(node)) {
identifiers.add(node.getText());
}
ts.forEachChild(node, (n) => walk(n));
};

walk(tsAst);

let renderName = 'render';
let i = 0;
while (identifiers.has(renderName)) {
renderName = `render_${i++}`;
}

const astOffset = script.content.start;

return { htmlx, tsAst, astOffset };
return { htmlx, tsAst, astOffset, renderName };
}

export function processModuleScriptTag(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
///<reference types="svelte" />
;
function render(){}
;;function render_0() {
async () => {};
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_0())));
/*Ω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,3 @@
<script module lang="ts">
function render(){}
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
///<reference types="svelte" />
;
import { render } from "render";
;;function render_0() {


;
async () => {

};
return { props: {render: render}, exports: /** @type {{render: typeof render}} */ ({}), bindings: "", slots: {}, events: {} }}
const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(['render'], __sveltets_2_with_any_event(render_0())));
/*Ω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,7 @@
<script module lang="ts">
import { render } from "render";
</script>

<script lang="ts">
export { render }
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
///<reference types="svelte" />
;
import { render } from "render";
;;function render_0</*Ωignore_startΩ*/T>/*Ωignore_endΩ*/() {

;
async () => {

};
return { props: /** @type {Record<string, never>} */ ({}), exports: {}, bindings: "", slots: {}, events: {} }}
class __sveltets_Render<T> {
props() {
return render_0<T>().props;
}
events() {
return __sveltets_2_with_any_event(render_0<T>()).events;
}
slots() {
return render_0<T>().slots;
}
bindings() { return ""; }
exports() { return {}; }
}

interface $$IsomorphicComponent {
new <T>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & { $$bindings?: ReturnType<__sveltets_Render<T>['bindings']> } & ReturnType<__sveltets_Render<T>['exports']>;
<T>(internal: unknown, props: {$$events?: ReturnType<__sveltets_Render<T>['events']>}): ReturnType<__sveltets_Render<T>['exports']>;
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
}
const Input__SvelteComponent_: $$IsomorphicComponent = null as any;
/*Ωignore_startΩ*/type Input__SvelteComponent_<T> = InstanceType<typeof Input__SvelteComponent_<T>>;
/*Ωignore_endΩ*/export default Input__SvelteComponent_;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<script module lang="ts">
import { render } from "render";
</script>

<script lang="ts" generics="T">
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
///<reference types="svelte" />
;
import { render } from "render";
;;function render_0() {
async () => {};
return { props: /** @type {Record<string, never>} */ ({}), slots: {}, events: {} }}

export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render_0()))) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<script module lang="ts">
import { render } from "render";
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
///<reference types="svelte" />
;
import render from "render";
;;function render_0() {
async () => {};
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_0())));
/*Ω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,3 @@
<script module lang="ts">
import render from "render";
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
///<reference types="svelte" />
;
const render = 42;
;;function render_0() {
async () => {};
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_0())));
/*Ω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,3 @@
<script module lang="ts">
const render = 42;
</script>

0 comments on commit 1f771d6

Please sign in to comment.