From 9d7907ef8b65efeda2698f61490b964d2f1a7069 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Thu, 2 May 2024 18:08:26 +0200 Subject: [PATCH] fix: rework bindable types strategy (#2361) Instead of using types that declare whether or not a type is bindable directly as part of the property, we're introducing a new for-types-only field to `SvelteComponent`: `$$bindings`, which is typed as the keys of the properties that are bindable (string by default, i.e. everything's bindable; for backwards compat). language-tools can then produce code that assigns to this property which results in an error we can display if the binding is invalid. This means we can revert a lot of the changes we made to make the previous version of bindable types work --- .../features/DiagnosticsProvider.ts | 110 +++++---- .../typescript/features/RenameProvider.ts | 156 +++++------- .../test/plugins/svelte/SveltePlugin.test.ts | 4 +- .../svelte/features/getDiagnostics.test.ts | 8 +- .../features/RenameProvider.test.ts | 231 ++++++++++++++++++ .../$$props-usage/expected_svelte_5.json | 32 --- .../$store-bind/expected_svelte_5.json | 46 ---- .../fixtures/bind-this/expected_svelte_5.json | 6 +- .../fixtures/bindings/expected_svelte_5.json | 25 +- .../component-props-js/expected_svelte_5.json | 83 ------- .../component-props-ts/expected_svelte_5.json | 83 ------- .../component-props-js/expected_svelte_5.json | 102 -------- .../component-props-ts/expected_svelte_5.json | 102 -------- .../component-invalid/expected_svelte_5.json | 57 ----- .../expected_svelte_5.json | 19 -- .../rename/rename-runes-importer.svelte | 8 + .../testfiles/rename/rename-runes.svelte | 6 + .../src/htmlxtojsx_v2/nodes/Binding.ts | 20 +- .../src/svelte2tsx/addComponentExport.ts | 13 +- packages/svelte2tsx/src/svelte2tsx/index.ts | 1 + .../src/svelte2tsx/nodes/ExportedNames.ts | 39 +-- packages/svelte2tsx/svelte-shims-v4.d.ts | 16 +- .../expected/TestRunes.svelte.d.ts | 5 +- .../samples/binding-bare/expected-svelte5.js | 4 +- .../samples/binding/expected-svelte5.js | 8 +- .../editing-binding/expected-svelte5.js | 2 +- .../runes-best-effort-types/expectedv2.ts | 1 + .../samples/runes-bindable/expectedv2.ts | 3 +- .../runes-looking-like-stores/expectedv2.ts | 1 + .../samples/runes-with-slots/expectedv2.ts | 2 +- .../svelte2tsx/samples/runes/expectedv2.ts | 1 + .../expectedv2.ts | 1 + .../expectedv2.ts | 1 + .../ts-runes-best-effort-types/expectedv2.ts | 1 + .../samples/ts-runes-bindable/expectedv2.ts | 3 +- .../samples/ts-runes-generics/expectedv2.ts | 3 +- .../samples/ts-runes-with-slot/expectedv2.ts | 2 +- .../svelte2tsx/samples/ts-runes/expectedv2.ts | 1 + .../expectedv2.ts | 1 + .../expectedv2.ts | 1 + 40 files changed, 457 insertions(+), 751 deletions(-) delete mode 100644 packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/$$props-usage/expected_svelte_5.json delete mode 100644 packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/$store-bind/expected_svelte_5.json delete mode 100644 packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/checkjs-nostrict/component-props-js/expected_svelte_5.json delete mode 100644 packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/checkjs-nostrict/component-props-ts/expected_svelte_5.json delete mode 100644 packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/checkjs/component-props-js/expected_svelte_5.json delete mode 100644 packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/checkjs/component-props-ts/expected_svelte_5.json delete mode 100644 packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/component-invalid/expected_svelte_5.json delete mode 100644 packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/sveltekit-autotypings/expected_svelte_5.json create mode 100644 packages/language-server/test/plugins/typescript/testfiles/rename/rename-runes-importer.svelte create mode 100644 packages/language-server/test/plugins/typescript/testfiles/rename/rename-runes.svelte diff --git a/packages/language-server/src/plugins/typescript/features/DiagnosticsProvider.ts b/packages/language-server/src/plugins/typescript/features/DiagnosticsProvider.ts index 485b041f2..195569ca7 100644 --- a/packages/language-server/src/plugins/typescript/features/DiagnosticsProvider.ts +++ b/packages/language-server/src/plugins/typescript/features/DiagnosticsProvider.ts @@ -145,20 +145,33 @@ export class DiagnosticsProviderImpl implements DiagnosticsProvider { diagnostics = resolveNoopsInReactiveStatements(lang, diagnostics); - return diagnostics - .map((diagnostic) => ({ - range: convertRange(tsDoc, diagnostic), - severity: mapSeverity(diagnostic.category), + const mapRange = rangeMapper(tsDoc, document, lang); + const noFalsePositive = isNoFalsePositive(document, tsDoc); + const converted: Diagnostic[] = []; + + for (const tsDiag of diagnostics) { + let diagnostic: Diagnostic = { + range: convertRange(tsDoc, tsDiag), + severity: mapSeverity(tsDiag.category), source: isTypescript ? 'ts' : 'js', - message: ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'), - code: diagnostic.code, - tags: getDiagnosticTag(diagnostic) - })) - .map(mapRange(tsDoc, document, lang)) - .filter(hasNoNegativeLines) - .filter(isNoFalsePositive(document, tsDoc)) - .map(adjustIfNecessary) - .map(swapDiagRangeStartEndIfNecessary); + message: ts.flattenDiagnosticMessageText(tsDiag.messageText, '\n'), + code: tsDiag.code, + tags: getDiagnosticTag(tsDiag) + }; + diagnostic = mapRange(diagnostic); + + moveBindingErrorMessage(tsDiag, tsDoc, diagnostic, document); + + if (!hasNoNegativeLines(diagnostic) || !noFalsePositive(diagnostic)) { + continue; + } + + diagnostic = adjustIfNecessary(diagnostic); + diagnostic = swapDiagRangeStartEndIfNecessary(diagnostic); + converted.push(diagnostic); + } + + return converted; } private async getLSAndTSDoc(document: Document) { @@ -166,7 +179,43 @@ export class DiagnosticsProviderImpl implements DiagnosticsProvider { } } -function mapRange( +function moveBindingErrorMessage( + tsDiag: ts.Diagnostic, + tsDoc: SvelteDocumentSnapshot, + diagnostic: Diagnostic, + document: Document +) { + if ( + tsDiag.code === DiagnosticCode.TYPE_X_NOT_ASSIGNABLE_TO_TYPE_Y && + tsDiag.start && + tsDoc.getText(tsDiag.start, tsDiag.start + tsDiag.length!).endsWith('.$$bindings') + ) { + let node = tsDoc.svelteNodeAt(diagnostic.range.start); + while (node && node.type !== 'InlineComponent') { + node = node.parent!; + } + if (node) { + let name = tsDoc.getText( + tsDiag.start + tsDiag.length!, + tsDiag.start + tsDiag.length! + 100 + ); + const quoteIdx = name.indexOf("'"); + name = name.substring(quoteIdx + 1, name.indexOf("'", quoteIdx + 1)); + const binding: any = node.attributes.find( + (attr: any) => attr.type === 'Binding' && attr.name === name + ); + if (binding) { + diagnostic.message = 'Cannot bind: to this property\n\n' + diagnostic.message; + diagnostic.range = { + start: document.positionAt(binding.start), + end: document.positionAt(binding.end) + }; + } + } + } +} + +function rangeMapper( snapshot: SvelteDocumentSnapshot, document: Document, lang: ts.LanguageService @@ -194,7 +243,7 @@ function mapRange( diagnostic.code as number ) || (DiagnosticCode.TYPE_X_NOT_ASSIGNABLE_TO_TYPE_Y && - diagnostic.message.includes("'PropsWithChildren<"))) && + diagnostic.message.includes("'Properties<"))) && !hasNonZeroRange({ range }) ) { const node = getNodeIfIsInStartTag(document.html, document.offsetAt(range.start)); @@ -327,37 +376,6 @@ function adjustIfNecessary(diagnostic: Diagnostic): Diagnostic { }; } - if ( - (diagnostic.code === DiagnosticCode.TYPE_X_NOT_ASSIGNABLE_TO_TYPE_Y || - diagnostic.code === DiagnosticCode.TYPE_X_NOT_ASSIGNABLE_TO_TYPE_Y_DID_YOU_MEAN) && - diagnostic.message.includes("'Bindable<") - ) { - const countBindable = (diagnostic.message.match(/'Bindable\ from diagnostic message - const start = diagnostic.message.indexOf("'Bindable<"); - const startType = start + "'Bindable".length; - const end = traverseTypeString(diagnostic.message, startType, '>'); - diagnostic.message = - diagnostic.message.substring(0, start + 1) + - diagnostic.message.substring(startType + 1, end) + - diagnostic.message.substring(end + 1); - } else if (countBinding === 3 && countBindable === 1) { - // Only keep Type '...' is not assignable to type '...' in - // Type Bindings<...> is not assignable to type Bindable<...>, Type Binding<...> is not assignable to type Bindable<...>, Type '...' is not assignable to type '...' - const lines = diagnostic.message.split('\n'); - if (lines.length === 3) { - diagnostic.message = lines[2].trimStart(); - } - } - - return { - ...diagnostic, - message: diagnostic.message - }; - } - return diagnostic; } diff --git a/packages/language-server/src/plugins/typescript/features/RenameProvider.ts b/packages/language-server/src/plugins/typescript/features/RenameProvider.ts index 3ba763e3c..281ae659f 100644 --- a/packages/language-server/src/plugins/typescript/features/RenameProvider.ts +++ b/packages/language-server/src/plugins/typescript/features/RenameProvider.ts @@ -31,6 +31,7 @@ import { } from './utils'; import { LSConfigManager } from '../../../ls-config'; import { isAttributeName, isEventHandler } from '../svelte-ast-utils'; +import { Identifier } from 'estree'; interface TsRenameLocation extends ts.RenameLocation { range: Range; @@ -38,7 +39,6 @@ interface TsRenameLocation extends ts.RenameLocation { } const bind = 'bind:'; -const bindShortHandGeneratedLength = ':__sveltets_2_binding('.length; export class RenameProviderImpl implements RenameProvider { constructor( @@ -76,7 +76,7 @@ export class RenameProviderImpl implements RenameProvider { const renameLocations = lang.findRenameLocations( tsDoc.filePath, - offset + (renameInfo.bindShorthand || 0), + offset, false, false, true @@ -101,7 +101,8 @@ export class RenameProviderImpl implements RenameProvider { convertedRenameLocations = this.checkShortHandBindingOrSlotLetLocation( lang, convertedRenameLocations, - docs + docs, + newName ); const additionalRenameForPropRenameInsideComponentWithProp = @@ -160,7 +161,6 @@ export class RenameProviderImpl implements RenameProvider { ): | (ts.RenameInfoSuccess & { isStore?: boolean; - bindShorthand?: number; }) | null { // Don't allow renames in error-state, because then there is no generated svelte2tsx-code @@ -170,14 +170,6 @@ export class RenameProviderImpl implements RenameProvider { } const svelteNode = tsDoc.svelteNodeAt(originalPosition); - - let bindOffset = 0; - const bindingShorthand = this.getBindingShorthand(tsDoc, originalPosition, svelteNode); - if (bindingShorthand) { - bindOffset = bindingShorthand.end - bindingShorthand.start; - generatedOffset += bindShortHandGeneratedLength + bindOffset; - } - const renameInfo = lang.getRenameInfo(tsDoc.filePath, generatedOffset, { allowRenameOfImportPath: false }); @@ -211,11 +203,6 @@ export class RenameProviderImpl implements RenameProvider { } } - if (bindOffset) { - renameInfo.triggerSpan.start -= bindShortHandGeneratedLength + bindOffset; - (renameInfo as any).bindShorthand = bindShortHandGeneratedLength + bindOffset; - } - return renameInfo; } @@ -366,48 +353,8 @@ export class RenameProviderImpl implements RenameProvider { return location; } - const { parent } = snapshot; - - const bindingShorthand = this.getBindingShorthand(snapshot, location.range.start); - if (bindingShorthand) { - // bind:|foo| -> bind:|newName|={foo} - const name = parent - .getText() - .substring(bindingShorthand.start, bindingShorthand.end); - return { - ...location, - prefixText: '', - suffixText: `={${name}}` - }; - } - - let rangeStart = parent.offsetAt(location.range.start); - - // suffix is of the form `: oldVarName` -> hints at a shorthand - if ( - !location.suffixText?.trimStart()?.startsWith(':') || - !getNodeIfIsInStartTag(parent.html, rangeStart) - ) { - return location; - } - - if (snapshot.getOriginalText().charAt(rangeStart - 1) === '{') { - // {|foo|} -> |{foo|} - rangeStart--; - return { - ...location, - range: { - start: parent.positionAt(rangeStart), - end: location.range.end - }, - // |{foo|} -> newName=|{foo|} - newName: parent.getText(location.range), - prefixText: `${newName}={`, - suffixText: '' - }; - } - - return location; + const shorthandLocation = this.transformShorthand(snapshot, location, newName); + return shorthandLocation || location; }); } @@ -595,7 +542,8 @@ export class RenameProviderImpl implements RenameProvider { private checkShortHandBindingOrSlotLetLocation( lang: ts.LanguageService, renameLocations: TsRenameLocation[], - snapshots: SnapshotMap + snapshots: SnapshotMap, + newName?: string ): TsRenameLocation[] { return renameLocations.map((location) => { const sourceFile = lang.getProgram()?.getSourceFile(location.fileName); @@ -616,6 +564,16 @@ export class RenameProviderImpl implements RenameProvider { const { parent } = snapshot; + if (snapshot.isSvelte5Plus && newName && location.suffixText) { + // Svelte 5 runes mode, thanks to $props(), is much easier to handle rename-wise. + // Notably, it doesn't need the "additional props rename locations" logic, because + // these renames already appear here. + const shorthandLocation = this.transformShorthand(snapshot, location, newName); + if (shorthandLocation) { + return shorthandLocation; + } + } + let rangeStart = parent.offsetAt(location.range.start); let prefixText = location.prefixText?.trimRight(); @@ -638,38 +596,6 @@ export class RenameProviderImpl implements RenameProvider { suffixText: '}' }; } - - if (snapshot.isSvelte5Plus) { - const bindingShorthand = this.getBindingShorthand( - snapshot, - location.range.start - ); - if (bindingShorthand) { - const name = parent - .getText() - .substring(bindingShorthand.start, bindingShorthand.end); - const start = { - line: location.range.start.line, - character: location.range.start.character - name.length - }; - // If binding is followed by the closing tag, start is one character too soon, - // else binding is ending one character too far - if (parent.getText().charAt(parent.offsetAt(start)) === ':') { - start.character++; - } else { - location.range.end.character--; - } - return { - ...location, - range: { - start: start, - end: location.range.end - }, - prefixText: name + '={', - suffixText: '}' - }; - } - } } if (!prefixText || prefixText.slice(-1) !== ':') { @@ -714,16 +640,54 @@ export class RenameProviderImpl implements RenameProvider { }); } - private getBindingShorthand( + private transformShorthand( + snapshot: SvelteDocumentSnapshot, + location: TsRenameLocation, + newName: string + ): TsRenameLocation | undefined { + const shorthand = this.getBindingOrAttrShorthand(snapshot, location.range.start); + if (shorthand) { + if (shorthand.isBinding) { + // bind:|foo| -> bind:|newName|={foo} + return { + ...location, + prefixText: '', + suffixText: `={${shorthand.id.name}}` + }; + } else { + return { + ...location, + range: { + // {|foo|} -> |{foo|} + start: { + line: location.range.start.line, + character: location.range.start.character - 1 + }, + end: location.range.end + }, + // |{foo|} -> newName=|{foo|} + newName: shorthand.id.name, + prefixText: `${newName}={`, + suffixText: '' + }; + } + } + } + + private getBindingOrAttrShorthand( snapshot: SvelteDocumentSnapshot, position: Position, svelteNode = snapshot.svelteNodeAt(position) - ) { + ): { id: Identifier; isBinding: boolean } | undefined { if ( - svelteNode?.parent?.type === 'Binding' && + (svelteNode?.parent?.type === 'Binding' || + svelteNode?.parent?.type === 'AttributeShorthand') && svelteNode.parent.expression.end === svelteNode.parent.end ) { - return svelteNode.parent.expression; + return { + id: svelteNode as any as Identifier, + isBinding: svelteNode.parent.type === 'Binding' + }; } } } diff --git a/packages/language-server/test/plugins/svelte/SveltePlugin.test.ts b/packages/language-server/test/plugins/svelte/SveltePlugin.test.ts index 2712a095c..1e57caea1 100644 --- a/packages/language-server/test/plugins/svelte/SveltePlugin.test.ts +++ b/packages/language-server/test/plugins/svelte/SveltePlugin.test.ts @@ -39,7 +39,7 @@ describe('Svelte Plugin', () => { const diagnostic = Diagnostic.create( Range.create(1, 0, 1, 21), isSvelte5Plus - ? ' element should have an alt attribute' + ? '`` element should have an alt attribute' : 'A11y: element should have an alt attribute', DiagnosticSeverity.Warning, isSvelte5Plus ? 'a11y_missing_attribute' : 'a11y-missing-attribute', @@ -57,7 +57,7 @@ describe('Svelte Plugin', () => { Range.create(0, 10, 0, 18), isSvelte5Plus ? 'Can only bind to state or props' : 'whatever is not declared', DiagnosticSeverity.Error, - isSvelte5Plus ? 'invalid_binding_value' : 'binding-undeclared', + isSvelte5Plus ? 'bind_invalid_value' : 'binding-undeclared', 'svelte' ); diff --git a/packages/language-server/test/plugins/svelte/features/getDiagnostics.test.ts b/packages/language-server/test/plugins/svelte/features/getDiagnostics.test.ts index 9f7ef475b..0915cc35a 100644 --- a/packages/language-server/test/plugins/svelte/features/getDiagnostics.test.ts +++ b/packages/language-server/test/plugins/svelte/features/getDiagnostics.test.ts @@ -459,7 +459,7 @@ describe('SveltePlugin#getDiagnostics', () => { "Component has unused export property 'name'. If it is for external reference only, please consider using `export const name`", severity: 2, source: 'svelte', - code: isSvelte5Plus ? 'unused_export_let' : 'unused-export-let' + code: isSvelte5Plus ? 'export_let_unused' : 'unused-export-let' } ]); }); @@ -477,7 +477,7 @@ describe('SveltePlugin#getDiagnostics', () => { severity: 2, source: 'svelte', code: isSvelte5Plus - ? 'no_reactive_declaration' + ? 'reactive_declaration_invalid_placement' : 'module-script-reactive-declaration' } ]); @@ -489,7 +489,7 @@ describe('SveltePlugin#getDiagnostics', () => { assert.deepStrictEqual(diagnostics, [ { - code: isSvelte5Plus ? 'unused_export_let' : 'unused-export-let', + code: isSvelte5Plus ? 'export_let_unused' : 'unused-export-let', message: "Component has unused export property 'unused1'. If it is for external reference only, please consider using `export const unused1`", range: { @@ -506,7 +506,7 @@ describe('SveltePlugin#getDiagnostics', () => { source: 'svelte' }, { - code: isSvelte5Plus ? 'unused_export_let' : 'unused-export-let', + code: isSvelte5Plus ? 'export_let_unused' : 'unused-export-let', message: "Component has unused export property 'unused2'. If it is for external reference only, please consider using `export const unused2`", range: { diff --git a/packages/language-server/test/plugins/typescript/features/RenameProvider.test.ts b/packages/language-server/test/plugins/typescript/features/RenameProvider.test.ts index 3ad669246..d3ce11c92 100644 --- a/packages/language-server/test/plugins/typescript/features/RenameProvider.test.ts +++ b/packages/language-server/test/plugins/typescript/features/RenameProvider.test.ts @@ -2,6 +2,7 @@ import * as assert from 'assert'; import * as path from 'path'; import ts from 'typescript'; import { Position } from 'vscode-languageserver'; +import { VERSION } from 'svelte/compiler'; import { Document, DocumentManager } from '../../../../src/lib/documents'; import { LSConfigManager } from '../../../../src/ls-config'; import { RenameProviderImpl } from '../../../../src/plugins/typescript/features/RenameProvider'; @@ -12,6 +13,7 @@ import { serviceWarmup } from '../test-utils'; const testDir = path.join(__dirname, '..'); const renameTestDir = path.join(testDir, 'testfiles', 'rename'); +const isSvelte5Plus = +VERSION.split('.')[0] >= 5; describe('RenameProvider', function () { serviceWarmup(this, renameTestDir, pathToUrl(testDir)); @@ -46,6 +48,8 @@ describe('RenameProvider', function () { const renameDocPropWithSlotEvents = await openDoc('rename-prop-with-slot-events.svelte'); const renameDocShorthand = await openDoc('rename-shorthand.svelte'); const renameSlotLet = await openDoc('rename-slot-let.svelte'); + const renameRunes = await openDoc('rename-runes.svelte'); + const renameRunesImporter = await openDoc('rename-runes-importer.svelte'); return { provider, @@ -60,6 +64,8 @@ describe('RenameProvider', function () { renameDocPropWithSlotEvents, renameDocShorthand, renameSlotLet, + renameRunes, + renameRunesImporter, docManager }; @@ -871,4 +877,229 @@ describe('RenameProvider', function () { // Hacky, but it works. Needed due to testing both new and old transformation __resetCache(); }); + + // -------------------- put tests that only run in Svelte 5 below this line and everything else above -------------------- + if (!isSvelte5Plus) return; + + it('renames $props() prop from inside component', async () => { + const { provider, renameRunes } = await setup(); + + const result = await provider.rename(renameRunes, Position.create(1, 40), 'newName'); + + assert.deepStrictEqual(result, { + changes: { + [getUri('rename-runes.svelte')]: [ + { + newText: 'newName', + range: { + start: { + line: 1, + character: 38 + }, + end: { + line: 1, + character: 41 + } + } + }, + { + newText: 'newName: foo', + range: { + start: { + line: 1, + character: 10 + }, + end: { + line: 1, + character: 13 + } + } + } + ], + [getUri('rename-runes-importer.svelte')]: [ + { + newText: 'newName={foo', + range: { + start: { + line: 6, + character: 13 + }, + end: { + line: 6, + character: 17 + } + } + }, + { + newText: 'newName', + range: { + start: { + line: 7, + character: 13 + }, + end: { + line: 7, + character: 16 + } + } + } + ] + } + }); + }); + + it('renames $props() binding from inside component', async () => { + const { provider, renameRunes } = await setup(); + + const result = await provider.rename(renameRunes, Position.create(1, 54), 'newName'); + + console.log(JSON.stringify(result, null, 2)); + + assert.deepStrictEqual(result, { + changes: { + [getUri('rename-runes.svelte')]: [ + { + newText: 'newName', + range: { + start: { + line: 1, + character: 52 + }, + end: { + line: 1, + character: 55 + } + } + }, + { + newText: 'newName: bar', + range: { + start: { + line: 1, + character: 15 + }, + end: { + line: 1, + character: 18 + } + } + } + ], + [getUri('rename-runes-importer.svelte')]: [ + { + newText: 'newName={bar}', + range: { + start: { + line: 6, + character: 24 + }, + end: { + line: 6, + character: 27 + } + } + }, + { + newText: 'newName', + range: { + start: { + line: 7, + character: 28 + }, + end: { + line: 7, + character: 31 + } + } + } + ] + } + }); + }); + + // blocked by https://github.com/microsoft/TypeScript/pull/57201 + it.skip('renames $props() prop inside consumer', async () => { + const { provider, renameRunes } = await setup(); + + const result = await provider.rename(renameRunes, Position.create(7, 15), 'newName'); + + assert.deepStrictEqual(result, { + changes: { + // TODO complete once test can be unskipped + [getUri('rename-runes.svelte')]: [], + [getUri('rename-runes-importer.svelte')]: [] + } + }); + }); + + it('renames $props() binding in consumer', async () => { + const { provider, renameRunesImporter } = await setup(); + + const result = await provider.rename( + renameRunesImporter, + Position.create(7, 30), + 'newName' + ); + + assert.deepStrictEqual(result, { + changes: { + [getUri('rename-runes.svelte')]: [ + { + newText: 'newName', + range: { + start: { + line: 1, + character: 52 + }, + end: { + line: 1, + character: 55 + } + } + }, + { + newText: 'newName: bar', + range: { + start: { + line: 1, + character: 15 + }, + end: { + line: 1, + character: 18 + } + } + } + ], + [getUri('rename-runes-importer.svelte')]: [ + { + newText: 'newName={bar}', + range: { + start: { + line: 6, + character: 24 + }, + end: { + line: 6, + character: 27 + } + } + }, + { + newText: 'newName', + range: { + start: { + line: 7, + character: 28 + }, + end: { + line: 7, + character: 31 + } + } + } + ] + } + }); + }); }); diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/$$props-usage/expected_svelte_5.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/$$props-usage/expected_svelte_5.json deleted file mode 100644 index f98179a38..000000000 --- a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/$$props-usage/expected_svelte_5.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "range": { - "start": { "line": 10, "character": 7 }, - "end": { "line": 10, "character": 16 } - }, - "severity": 1, - "source": "ts", - "message": "Type 'boolean' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { - "start": { "line": 11, "character": 43 }, - "end": { "line": 11, "character": 54 } - }, - "severity": 1, - "source": "ts", - "message": "Object literal may only specify known properties, and '\"invalidProp\"' does not exist in type 'WithBindings<{ exported1: string; exported2?: string | undefined; exported3: string; }>'.", - "code": 2353, - "tags": [] - }, - { - "range": { "start": { "line": 12, "character": 1 }, "end": { "line": 12, "character": 6 } }, - "severity": 1, - "source": "ts", - "message": "Type '{}' is missing the following properties from type 'WithBindings<{ exported1: string; exported2?: string | undefined; exported3: string; }>': exported1, exported3", - "code": 2739, - "tags": [] - } -] diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/$store-bind/expected_svelte_5.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/$store-bind/expected_svelte_5.json deleted file mode 100644 index 9c6757bf6..000000000 --- a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/$store-bind/expected_svelte_5.json +++ /dev/null @@ -1,46 +0,0 @@ -[ - { - "range": { - "start": { "line": 17, "character": 24 }, - "end": { "line": 17, "character": 34 } - }, - "severity": 1, - "source": "ts", - "message": "Type 'number' is not assignable to type 'boolean'.", - "code": 2322, - "tags": [] - }, - { - "range": { - "start": { "line": 18, "character": 16 }, - "end": { "line": 18, "character": 20 } - }, - "severity": 1, - "source": "ts", - "message": "Type 'boolean' is not assignable to type 'number'.", - "code": 2322, - "tags": [] - }, - { - "range": { - "start": { "line": 19, "character": 24 }, - "end": { "line": 19, "character": 41 } - }, - "severity": 1, - "source": "ts", - "message": "Type 'number' is not assignable to type 'boolean'.", - "code": 2322, - "tags": [] - }, - { - "range": { - "start": { "line": 20, "character": 16 }, - "end": { "line": 20, "character": 20 } - }, - "severity": 1, - "source": "ts", - "message": "Type 'Binding' is not assignable to type 'Bindable'.", - "code": 2322, - "tags": [] - } -] diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bind-this/expected_svelte_5.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bind-this/expected_svelte_5.json index 09171f654..06c967066 100644 --- a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bind-this/expected_svelte_5.json +++ b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bind-this/expected_svelte_5.json @@ -36,7 +36,7 @@ }, "severity": 1, "source": "ts", - "message": "Type 'Component' is not assignable to type 'OtherComponent'.\n The types of '$$prop_def.prop' are incompatible between these types.\n Type 'boolean' is not assignable to type 'string'.", + "message": "Type 'Component' is not assignable to type 'OtherComponent'.\n Type '{ prop: boolean; }' is not assignable to type '{ prop: string; }'.\n Types of property 'prop' are incompatible.\n Type 'boolean' is not assignable to type 'string'.", "code": 2322, "tags": [] }, @@ -58,7 +58,7 @@ }, "severity": 1, "source": "ts", - "message": "Type '{}' is not assignable to type 'PropsWithChildren<{ prop: boolean; }, any> | undefined'.", + "message": "Type '{}' is not assignable to type 'Properties<{ prop: boolean; }, any> | undefined'.", "code": 2322, "tags": [] }, @@ -91,7 +91,7 @@ }, "severity": 1, "source": "ts", - "message": "Type '{}' is not assignable to type 'PropsWithChildren<{ prop: boolean; }, any> | undefined'.", + "message": "Type '{}' is not assignable to type 'Properties<{ prop: boolean; }, any> | undefined'.", "code": 2322, "tags": [] } diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bindings/expected_svelte_5.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bindings/expected_svelte_5.json index abd096989..2bc241532 100644 --- a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bindings/expected_svelte_5.json +++ b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bindings/expected_svelte_5.json @@ -1,14 +1,14 @@ [ { "code": 2322, - "message": "Type 'Binding' is not assignable to type 'string'.", + "message": "Cannot bind: to this property\n\nType '\"readonly\"' is not assignable to type '\"can_bind\"'.", "range": { "end": { "character": 20, "line": 25 }, "start": { - "character": 12, + "character": 7, "line": 25 } }, @@ -18,7 +18,7 @@ }, { "code": 2353, - "message": "Object literal may only specify known properties, and 'only_bind' does not exist in type '{ readonly?: string | undefined; can_bind?: Bindable; }'.", + "message": "Object literal may only specify known properties, and 'only_bind' does not exist in type '$$ComponentProps'.", "range": { "end": { "character": 21, @@ -33,9 +33,26 @@ "source": "ts", "tags": [] }, + { + "code": 2322, + "message": "Cannot bind: to this property\n\nType '\"only_bind\"' is not assignable to type '\"can_bind\"'.", + "range": { + "end": { + "character": 21, + "line": 26 + }, + "start": { + "character": 7, + "line": 26 + } + }, + "severity": 1, + "source": "ts", + "tags": [] + }, { "code": 2353, - "message": "Object literal may only specify known properties, and 'only_bind' does not exist in type '{ readonly?: string | undefined; can_bind?: Bindable; }'.", + "message": "Object literal may only specify known properties, and 'only_bind' does not exist in type '$$ComponentProps'.", "range": { "end": { "character": 17, diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/checkjs-nostrict/component-props-js/expected_svelte_5.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/checkjs-nostrict/component-props-js/expected_svelte_5.json deleted file mode 100644 index b17cb454d..000000000 --- a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/checkjs-nostrict/component-props-js/expected_svelte_5.json +++ /dev/null @@ -1,83 +0,0 @@ -[ - { - "range": { "start": { "line": 6, "character": 1 }, "end": { "line": 6, "character": 9 } }, - "severity": 1, - "source": "js", - "message": "Property 'required' is missing in type '{}' but required in type 'WithBindings<{ required: string; optional1?: string; optional2?: string; }>'.", - "code": 2741, - "tags": [] - }, - { - "range": { "start": { "line": 8, "character": 57 }, "end": { "line": 8, "character": 68 } }, - "severity": 1, - "source": "js", - "message": "Object literal may only specify known properties, and '\"doesntExist\"' does not exist in type 'WithBindings<{ required: string; optional1?: string; optional2?: string; }>'.", - "code": 2353, - "tags": [] - }, - { - "range": { "start": { "line": 9, "character": 10 }, "end": { "line": 9, "character": 18 } }, - "severity": 1, - "source": "js", - "message": "Type 'boolean' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { "start": { "line": 9, "character": 26 }, "end": { "line": 9, "character": 35 } }, - "severity": 1, - "source": "js", - "message": "Type 'boolean' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { "start": { "line": 9, "character": 43 }, "end": { "line": 9, "character": 52 } }, - "severity": 1, - "source": "js", - "message": "Type 'boolean' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { "start": { "line": 10, "character": 1 }, "end": { "line": 10, "character": 9 } }, - "severity": 1, - "source": "js", - "message": "Property 'required' is missing in type '{}' but required in type 'WithBindings<{ required: string; optional1?: string; optional2?: string; }>'.", - "code": 2741, - "tags": [] - }, - { - "range": { - "start": { "line": 12, "character": 10 }, - "end": { "line": 12, "character": 18 } - }, - "severity": 1, - "source": "js", - "message": "Type 'boolean' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { - "start": { "line": 12, "character": 26 }, - "end": { "line": 12, "character": 35 } - }, - "severity": 1, - "source": "js", - "message": "Type 'boolean' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { - "start": { "line": 12, "character": 43 }, - "end": { "line": 12, "character": 52 } - }, - "severity": 1, - "source": "js", - "message": "Type 'boolean' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - } -] diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/checkjs-nostrict/component-props-ts/expected_svelte_5.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/checkjs-nostrict/component-props-ts/expected_svelte_5.json deleted file mode 100644 index 1468ca1c4..000000000 --- a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/checkjs-nostrict/component-props-ts/expected_svelte_5.json +++ /dev/null @@ -1,83 +0,0 @@ -[ - { - "range": { "start": { "line": 6, "character": 1 }, "end": { "line": 6, "character": 9 } }, - "severity": 1, - "source": "ts", - "message": "Property 'required' is missing in type '{}' but required in type 'WithBindings<{ required: string; optional1?: string; optional2?: string; }>'.", - "code": 2741, - "tags": [] - }, - { - "range": { "start": { "line": 8, "character": 57 }, "end": { "line": 8, "character": 68 } }, - "severity": 1, - "source": "ts", - "message": "Object literal may only specify known properties, and '\"doesntExist\"' does not exist in type 'WithBindings<{ required: string; optional1?: string; optional2?: string; }>'.", - "code": 2353, - "tags": [] - }, - { - "range": { "start": { "line": 9, "character": 10 }, "end": { "line": 9, "character": 18 } }, - "severity": 1, - "source": "ts", - "message": "Type 'boolean' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { "start": { "line": 9, "character": 26 }, "end": { "line": 9, "character": 35 } }, - "severity": 1, - "source": "ts", - "message": "Type 'boolean' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { "start": { "line": 9, "character": 43 }, "end": { "line": 9, "character": 52 } }, - "severity": 1, - "source": "ts", - "message": "Type 'boolean' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { "start": { "line": 10, "character": 1 }, "end": { "line": 10, "character": 9 } }, - "severity": 1, - "source": "ts", - "message": "Property 'required' is missing in type '{}' but required in type 'WithBindings<{ required: string; optional1?: string; optional2?: string; }>'.", - "code": 2741, - "tags": [] - }, - { - "range": { - "start": { "line": 12, "character": 10 }, - "end": { "line": 12, "character": 18 } - }, - "severity": 1, - "source": "ts", - "message": "Type 'boolean' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { - "start": { "line": 12, "character": 26 }, - "end": { "line": 12, "character": 35 } - }, - "severity": 1, - "source": "ts", - "message": "Type 'boolean' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { - "start": { "line": 12, "character": 43 }, - "end": { "line": 12, "character": 52 } - }, - "severity": 1, - "source": "ts", - "message": "Type 'boolean' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - } -] diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/checkjs/component-props-js/expected_svelte_5.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/checkjs/component-props-js/expected_svelte_5.json deleted file mode 100644 index 89c2f2631..000000000 --- a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/checkjs/component-props-js/expected_svelte_5.json +++ /dev/null @@ -1,102 +0,0 @@ -[ - { - "range": { "start": { "line": 6, "character": 1 }, "end": { "line": 6, "character": 9 } }, - "severity": 1, - "source": "js", - "message": "Property 'required' is missing in type '{}' but required in type 'WithBindings<{ required: string; optional1?: string | undefined; optional2?: string | undefined; }>'.", - "code": 2741, - "tags": [] - }, - { - "range": { "start": { "line": 7, "character": 10 }, "end": { "line": 7, "character": 18 } }, - "severity": 1, - "source": "js", - "message": "Type 'undefined' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { "start": { "line": 8, "character": 57 }, "end": { "line": 8, "character": 68 } }, - "severity": 1, - "source": "js", - "message": "Object literal may only specify known properties, and '\"doesntExist\"' does not exist in type 'WithBindings<{ required: string; optional1?: string | undefined; optional2?: string | undefined; }>'.", - "code": 2353, - "tags": [] - }, - { - "range": { "start": { "line": 9, "character": 10 }, "end": { "line": 9, "character": 18 } }, - "severity": 1, - "source": "js", - "message": "Type 'boolean' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { "start": { "line": 9, "character": 26 }, "end": { "line": 9, "character": 35 } }, - "severity": 1, - "source": "js", - "message": "Type 'true' is not assignable to type 'string | undefined'.", - "code": 2322, - "tags": [] - }, - { - "range": { "start": { "line": 9, "character": 43 }, "end": { "line": 9, "character": 52 } }, - "severity": 1, - "source": "js", - "message": "Type 'true' is not assignable to type 'string | undefined'.", - "code": 2322, - "tags": [] - }, - { - "range": { "start": { "line": 10, "character": 1 }, "end": { "line": 10, "character": 9 } }, - "severity": 1, - "source": "js", - "message": "Property 'required' is missing in type '{}' but required in type 'WithBindings<{ required: string; optional1?: string | undefined; optional2?: string | undefined; }>'.", - "code": 2741, - "tags": [] - }, - { - "range": { - "start": { "line": 11, "character": 10 }, - "end": { "line": 11, "character": 18 } - }, - "severity": 1, - "source": "js", - "message": "Type 'undefined' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { - "start": { "line": 12, "character": 10 }, - "end": { "line": 12, "character": 18 } - }, - "severity": 1, - "source": "js", - "message": "Type 'boolean' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { - "start": { "line": 12, "character": 26 }, - "end": { "line": 12, "character": 35 } - }, - "severity": 1, - "source": "js", - "message": "Type 'true' is not assignable to type 'string | undefined'.", - "code": 2322, - "tags": [] - }, - { - "range": { - "start": { "line": 12, "character": 43 }, - "end": { "line": 12, "character": 52 } - }, - "severity": 1, - "source": "js", - "message": "Type 'true' is not assignable to type 'string | undefined'.", - "code": 2322, - "tags": [] - } -] diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/checkjs/component-props-ts/expected_svelte_5.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/checkjs/component-props-ts/expected_svelte_5.json deleted file mode 100644 index 097f3edf7..000000000 --- a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/checkjs/component-props-ts/expected_svelte_5.json +++ /dev/null @@ -1,102 +0,0 @@ -[ - { - "range": { "start": { "line": 6, "character": 1 }, "end": { "line": 6, "character": 9 } }, - "severity": 1, - "source": "ts", - "message": "Property 'required' is missing in type '{}' but required in type 'WithBindings<{ required: string; optional1?: string | undefined; optional2?: string | undefined; }>'.", - "code": 2741, - "tags": [] - }, - { - "range": { "start": { "line": 7, "character": 10 }, "end": { "line": 7, "character": 18 } }, - "severity": 1, - "source": "ts", - "message": "Type 'undefined' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { "start": { "line": 8, "character": 57 }, "end": { "line": 8, "character": 68 } }, - "severity": 1, - "source": "ts", - "message": "Object literal may only specify known properties, and '\"doesntExist\"' does not exist in type 'WithBindings<{ required: string; optional1?: string | undefined; optional2?: string | undefined; }>'.", - "code": 2353, - "tags": [] - }, - { - "range": { "start": { "line": 9, "character": 10 }, "end": { "line": 9, "character": 18 } }, - "severity": 1, - "source": "ts", - "message": "Type 'boolean' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { "start": { "line": 9, "character": 26 }, "end": { "line": 9, "character": 35 } }, - "severity": 1, - "source": "ts", - "message": "Type 'true' is not assignable to type 'string | undefined'.", - "code": 2322, - "tags": [] - }, - { - "range": { "start": { "line": 9, "character": 43 }, "end": { "line": 9, "character": 52 } }, - "severity": 1, - "source": "ts", - "message": "Type 'true' is not assignable to type 'string | undefined'.", - "code": 2322, - "tags": [] - }, - { - "range": { "start": { "line": 10, "character": 1 }, "end": { "line": 10, "character": 9 } }, - "severity": 1, - "source": "ts", - "message": "Property 'required' is missing in type '{}' but required in type 'WithBindings<{ required: string; optional1?: string | undefined; optional2?: string | undefined; }>'.", - "code": 2741, - "tags": [] - }, - { - "range": { - "start": { "line": 11, "character": 10 }, - "end": { "line": 11, "character": 18 } - }, - "severity": 1, - "source": "ts", - "message": "Type 'undefined' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { - "start": { "line": 12, "character": 10 }, - "end": { "line": 12, "character": 18 } - }, - "severity": 1, - "source": "ts", - "message": "Type 'boolean' is not assignable to type 'string'.", - "code": 2322, - "tags": [] - }, - { - "range": { - "start": { "line": 12, "character": 26 }, - "end": { "line": 12, "character": 35 } - }, - "severity": 1, - "source": "ts", - "message": "Type 'true' is not assignable to type 'string | undefined'.", - "code": 2322, - "tags": [] - }, - { - "range": { - "start": { "line": 12, "character": 43 }, - "end": { "line": 12, "character": 52 } - }, - "severity": 1, - "source": "ts", - "message": "Type 'true' is not assignable to type 'string | undefined'.", - "code": 2322, - "tags": [] - } -] diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/component-invalid/expected_svelte_5.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/component-invalid/expected_svelte_5.json deleted file mode 100644 index 81e4cc4cd..000000000 --- a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/component-invalid/expected_svelte_5.json +++ /dev/null @@ -1,57 +0,0 @@ -[ - { - "range": { - "start": { "line": 19, "character": 1 }, - "end": { "line": 19, "character": 11 } - }, - "severity": 1, - "source": "ts", - "message": "Argument of type 'typeof DoesntWork' is not assignable to parameter of type 'ConstructorOfATypedSvelteComponent'.\n Type 'DoesntWork' is missing the following properties from type 'ATypedSvelteComponent': $$prop_def, $$events_def, $$slot_def, $on\n\nPossible causes:\n- You use the instance type of a component where you should use the constructor type\n- Type definitions are missing for this Svelte Component. If you are using Svelte 3.31+, use SvelteComponentTyped to add a definition:\n import type { SvelteComponentTyped } from \"svelte\";\n class ComponentName extends SvelteComponentTyped<{propertyName: string;}> {}", - "code": 2345, - "tags": [] - }, - { - "range": { - "start": { "line": 20, "character": 10 }, - "end": { "line": 20, "character": 25 } - }, - "severity": 1, - "source": "ts", - "message": "Type 'boolean' is not assignable to type 'Binding'.", - "code": 2322, - "tags": [] - }, - { - "range": { - "start": { "line": 21, "character": 24 }, - "end": { "line": 21, "character": 34 } - }, - "severity": 1, - "source": "ts", - "message": "Argument of type 'typeof DoesntWork' is not assignable to parameter of type 'ConstructorOfATypedSvelteComponent'.\n\nPossible causes:\n- You use the instance type of a component where you should use the constructor type\n- Type definitions are missing for this Svelte Component. If you are using Svelte 3.31+, use SvelteComponentTyped to add a definition:\n import type { SvelteComponentTyped } from \"svelte\";\n class ComponentName extends SvelteComponentTyped<{propertyName: string;}> {}", - "code": 2345, - "tags": [] - }, - { - "range": { - "start": { "line": 24, "character": 1 }, - "end": { "line": 24, "character": 11 } - }, - "severity": 1, - "source": "ts", - "message": "Argument of type 'typeof DoesntWork' is not assignable to parameter of type 'ConstructorOfATypedSvelteComponent'.\n\nPossible causes:\n- You use the instance type of a component where you should use the constructor type\n- Type definitions are missing for this Svelte Component. If you are using Svelte 3.31+, use SvelteComponentTyped to add a definition:\n import type { SvelteComponentTyped } from \"svelte\";\n class ComponentName extends SvelteComponentTyped<{propertyName: string;}> {}", - "code": 2345, - "tags": [] - }, - { - "range": { - "start": { "line": 27, "character": 24 }, - "end": { "line": 27, "character": 34 } - }, - "severity": 1, - "source": "ts", - "message": "Argument of type 'typeof DoesntWork' is not assignable to parameter of type 'ConstructorOfATypedSvelteComponent'.\n\nPossible causes:\n- You use the instance type of a component where you should use the constructor type\n- Type definitions are missing for this Svelte Component. If you are using Svelte 3.31+, use SvelteComponentTyped to add a definition:\n import type { SvelteComponentTyped } from \"svelte\";\n class ComponentName extends SvelteComponentTyped<{propertyName: string;}> {}", - "code": 2345, - "tags": [] - } -] diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/sveltekit-autotypings/expected_svelte_5.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/sveltekit-autotypings/expected_svelte_5.json deleted file mode 100644 index 5243c7e4b..000000000 --- a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/sveltekit-autotypings/expected_svelte_5.json +++ /dev/null @@ -1,19 +0,0 @@ -[ - { - "range": { - "start": { - "line": 5, - "character": 1 - }, - "end": { - "line": 5, - "character": 5 - } - }, - "severity": 1, - "source": "ts", - "message": "Property 'data' is missing in type '{}' but required in type 'WithBindings<{ data: { exists: boolean; }; }>'.", - "code": 2741, - "tags": [] - } -] diff --git a/packages/language-server/test/plugins/typescript/testfiles/rename/rename-runes-importer.svelte b/packages/language-server/test/plugins/typescript/testfiles/rename/rename-runes-importer.svelte new file mode 100644 index 000000000..0856cf355 --- /dev/null +++ b/packages/language-server/test/plugins/typescript/testfiles/rename/rename-runes-importer.svelte @@ -0,0 +1,8 @@ + + + + diff --git a/packages/language-server/test/plugins/typescript/testfiles/rename/rename-runes.svelte b/packages/language-server/test/plugins/typescript/testfiles/rename/rename-runes.svelte new file mode 100644 index 000000000..5ccefe729 --- /dev/null +++ b/packages/language-server/test/plugins/typescript/testfiles/rename/rename-runes.svelte @@ -0,0 +1,6 @@ + + +{foo} +{bar} \ No newline at end of file diff --git a/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/Binding.ts b/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/Binding.ts index 16bffb8b8..5bb17cca7 100644 --- a/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/Binding.ts +++ b/packages/svelte2tsx/src/htmlxtojsx_v2/nodes/Binding.ts @@ -125,18 +125,14 @@ export function handleBinding( const value: TransformationArray | undefined = isShorthand ? preserveBind && element instanceof Element ? [rangeWithTrailingPropertyAccess(str.original, attr.expression)] - : isSvelte5Plus - ? [ - `__sveltets_2_binding(${str.original.substring(attr.expression.start, attr.expression.end)})` - ] - : undefined - : element instanceof Element || !isSvelte5Plus - ? [rangeWithTrailingPropertyAccess(str.original, attr.expression)] - : [ - '__sveltets_2_binding(', - rangeWithTrailingPropertyAccess(str.original, attr.expression), - ')' - ]; + : undefined + : [rangeWithTrailingPropertyAccess(str.original, attr.expression)]; + + if (isSvelte5Plus && element instanceof InlineComponent) { + // To check if property is actually bindable + element.appendToStartEnd([`${element.name}.$$bindings = '${attr.name}';`]); + } + if (element instanceof Element) { element.addAttribute(name, value); } else { diff --git a/packages/svelte2tsx/src/svelte2tsx/addComponentExport.ts b/packages/svelte2tsx/src/svelte2tsx/addComponentExport.ts index 3de132df3..fd7c04610 100644 --- a/packages/svelte2tsx/src/svelte2tsx/addComponentExport.ts +++ b/packages/svelte2tsx/src/svelte2tsx/addComponentExport.ts @@ -20,6 +20,7 @@ export interface AddComponentExportPara { componentDocumentation: ComponentDocumentation; mode: 'ts' | 'dts' | 'tsx'; generics: Generics; + usesSlots: boolean; noSvelteComponentTyped?: boolean; } @@ -47,6 +48,7 @@ function addGenericsComponentExport({ usesAccessors, str, generics, + usesSlots, noSvelteComponentTyped }: AddComponentExportPara) { const genericsDef = generics.toDefinitionString(); @@ -86,7 +88,10 @@ class __sveltets_Render${genericsDef} { */ let customConstructor = ''; if (exportedNames.hasPropsRune()) { - customConstructor = `\n constructor(options: import('svelte').ComponentConstructorOptions<__sveltets_2_PropsWithChildren<${returnType('props')}, ${returnType('slots')}>>) { super(options); }`; + if (!usesSlots) { + customConstructor = `\n constructor(options: import('svelte').ComponentConstructorOptions<${returnType('props')}>) { super(options); }`; + } + customConstructor += exportedNames.createBindingsStr(); } if (mode === 'dts') { @@ -128,6 +133,7 @@ function addSimpleComponentExport({ mode, usesAccessors, str, + usesSlots, noSvelteComponentTyped }: AddComponentExportPara) { const propDef = props( @@ -146,7 +152,10 @@ function addSimpleComponentExport({ */ let customConstructor = ''; if (exportedNames.hasPropsRune()) { - customConstructor = `\n constructor(options = __sveltets_2_runes_constructor(${propDef})) { super(options); }`; + if (!usesSlots) { + customConstructor = `\n constructor(options = __sveltets_2_runes_constructor(${propDef})) { super(options); }`; + } + customConstructor += exportedNames.createBindingsStr(); } let statement: string; diff --git a/packages/svelte2tsx/src/svelte2tsx/index.ts b/packages/svelte2tsx/src/svelte2tsx/index.ts index 181f8da18..96d8f91b8 100644 --- a/packages/svelte2tsx/src/svelte2tsx/index.ts +++ b/packages/svelte2tsx/src/svelte2tsx/index.ts @@ -437,6 +437,7 @@ export function svelte2tsx( isTsFile: options?.isTsFile, exportedNames, usesAccessors, + usesSlots: slots.size > 0, fileName: options?.filename, componentDocumentation, mode: options.mode, diff --git a/packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts b/packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts index 209533261..fdf0ecfbf 100644 --- a/packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts +++ b/packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts @@ -614,41 +614,11 @@ export class ExportedNames { const names = Array.from(this.exports.entries()); if (this.$props.type) { - return ( - '{} as any as ' + - (this.$props.bindings.length - ? `__sveltets_2_Bindings<${this.$props.type}, ${this.$props.bindings.map((b) => `"${b}"`).join('|')}>` - : this.$props.type) - ); + return '{} as any as ' + this.$props.type; } if (this.$props.comment) { - let result = this.$props.comment + '({})'; - - // Try our best to incorporate __sveltets_2_Bindings here - let idx = this.$props.comment.indexOf('@type'); - if (idx !== -1 && /[\s{]/.test(this.$props.comment[idx + 5])) { - idx = this.$props.comment.indexOf('{', idx); - const end = this.$props.comment.lastIndexOf('}'); - if (idx !== -1 && end !== -1 && idx < end) { - const has_bindings = this.$props.bindings.length; - - if (has_bindings) { - idx++; - result = - this.$props.comment.slice(0, idx) + - (has_bindings ? '__sveltets_2_Bindings<' : '') + - this.$props.comment.slice(idx, end) + - (has_bindings - ? `, ${this.$props.bindings.map((b) => `"${b}"`).join('|')}>` - : '') + - this.$props.comment.slice(end) + - '({})'; - } - } - } - - return result; + return this.$props.comment + '({})'; } if (this.usesRunes()) { @@ -700,6 +670,11 @@ export class ExportedNames { return `{${returnElements.join(' , ')}} as {${returnElementsType.join(', ')}}`; } + createBindingsStr(): string { + // will be just the empty strings for zero bindings, which is impossible to create a binding for, so it works out fine + return `\n $$bindings = __sveltets_$$bindings('${this.$props.bindings.join("', '")}');`; + } + /** * In runes mode, exports are no longer part of props because you cannot `bind:` to them, * which is why we need a separate return type for them. diff --git a/packages/svelte2tsx/svelte-shims-v4.d.ts b/packages/svelte2tsx/svelte-shims-v4.d.ts index 51ca1dd9e..e83032bc7 100644 --- a/packages/svelte2tsx/svelte-shims-v4.d.ts +++ b/packages/svelte2tsx/svelte-shims-v4.d.ts @@ -93,7 +93,7 @@ declare function __sveltets_2_with_any( declare function __sveltets_2_with_any_event( render: {props: Props, events: Events, slots: Slots } -): {props: Expand, events: Events & {[evt: string]: CustomEvent;}, slots: Slots } +): {props: Props, events: Events & {[evt: string]: CustomEvent;}, slots: Slots } declare function __sveltets_2_store_get(store: SvelteStore): T declare function __sveltets_2_store_get | undefined | null>(store: Store): Store extends SvelteStore ? T : Store; @@ -229,16 +229,6 @@ declare function __sveltets_2_ensureComponent | Iterable>(array: T): T extends ArrayLike ? U[] : T extends Iterable ? Iterable : any[]; -declare type __sveltets_2_Bindings, Bindings extends string> = { - [K in keyof Props]: K extends Bindings ? - // @ts-ignore not available in Svelte 4 - import('svelte').Bindable : - Props[K] - }; -declare function __sveltets_2_binding(prop: T): - // @ts-ignore not available in Svelte 4 - import('svelte').Binding; - type __sveltets_2_PropsWithChildren = Props & (Slots extends { default: any } // This is unfortunate because it means "accepts no props" turns into "accepts any prop" @@ -248,4 +238,6 @@ type __sveltets_2_PropsWithChildren = Props & ? any : { children?: any } : {}); -declare function __sveltets_2_runes_constructor(render: {props: Props, events: Events, slots: Slots }): import("svelte").ComponentConstructorOptions<__sveltets_2_PropsWithChildren>; +declare function __sveltets_2_runes_constructor(render: {props: Props }): import("svelte").ComponentConstructorOptions; + +declare function __sveltets_$$bindings(...bindings: Bindings): Bindings[number]; diff --git a/packages/svelte2tsx/test/emitDts/samples/typescript-runes.v5/expected/TestRunes.svelte.d.ts b/packages/svelte2tsx/test/emitDts/samples/typescript-runes.v5/expected/TestRunes.svelte.d.ts index 237326ae8..e13bde503 100644 --- a/packages/svelte2tsx/test/emitDts/samples/typescript-runes.v5/expected/TestRunes.svelte.d.ts +++ b/packages/svelte2tsx/test/emitDts/samples/typescript-runes.v5/expected/TestRunes.svelte.d.ts @@ -2,7 +2,7 @@ import { SvelteComponent } from "svelte"; declare const __propDef: { props: { foo: string; - bar?: import("svelte").Bindable; + bar?: number; }; events: { [evt: string]: CustomEvent; @@ -15,8 +15,9 @@ export type TestRunesSlots = typeof __propDef.slots; export default class TestRunes extends SvelteComponent { constructor(options?: import("svelte").ComponentConstructorOptions<{ foo: string; - bar?: import("svelte").Bindable; + bar?: number; }>); + $$bindings: "bar"; get baz(): () => void; } export {}; diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/binding-bare/expected-svelte5.js b/packages/svelte2tsx/test/htmlx2jsx/samples/binding-bare/expected-svelte5.js index 9abd39296..bb934f658 100644 --- a/packages/svelte2tsx/test/htmlx2jsx/samples/binding-bare/expected-svelte5.js +++ b/packages/svelte2tsx/test/htmlx2jsx/samples/binding-bare/expected-svelte5.js @@ -1,5 +1,5 @@ { svelteHTML.createElement("input", { "type":`text`,"bind:value":value,});/*Ωignore_startΩ*/() => value = __sveltets_2_any(null);/*Ωignore_endΩ*/} { svelteHTML.createElement("input", { "type":`checkbox`,"bind:checked":checked,});/*Ωignore_startΩ*/() => checked = __sveltets_2_any(null);/*Ωignore_endΩ*/} - { const $$_tupnI0C = __sveltets_2_ensureComponent(Input); new $$_tupnI0C({ target: __sveltets_2_any(), props: { "type":`text`,value:__sveltets_2_binding(value),}});/*Ωignore_startΩ*/() => value = __sveltets_2_any(null);/*Ωignore_endΩ*/} - { const $$_tupnI0C = __sveltets_2_ensureComponent(Input); new $$_tupnI0C({ target: __sveltets_2_any(), props: { "type":`checkbox`,checked:__sveltets_2_binding(checked),}});/*Ωignore_startΩ*/() => checked = __sveltets_2_any(null);/*Ωignore_endΩ*/} \ No newline at end of file + { const $$_tupnI0C = __sveltets_2_ensureComponent(Input); const $$_tupnI0 = new $$_tupnI0C({ target: __sveltets_2_any(), props: { "type":`text`,value,}});/*Ωignore_startΩ*/() => value = __sveltets_2_any(null);/*Ωignore_endΩ*/$$_tupnI0.$$bindings = 'value';} + { const $$_tupnI0C = __sveltets_2_ensureComponent(Input); const $$_tupnI0 = new $$_tupnI0C({ target: __sveltets_2_any(), props: { "type":`checkbox`,checked,}});/*Ωignore_startΩ*/() => checked = __sveltets_2_any(null);/*Ωignore_endΩ*/$$_tupnI0.$$bindings = 'checked';} \ No newline at end of file diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/binding/expected-svelte5.js b/packages/svelte2tsx/test/htmlx2jsx/samples/binding/expected-svelte5.js index 274bfaf63..6c881fec9 100644 --- a/packages/svelte2tsx/test/htmlx2jsx/samples/binding/expected-svelte5.js +++ b/packages/svelte2tsx/test/htmlx2jsx/samples/binding/expected-svelte5.js @@ -2,7 +2,7 @@ { svelteHTML.createElement("input", { "type":`text`,"bind:value":test,});/*Ωignore_startΩ*/() => test = __sveltets_2_any(null);/*Ωignore_endΩ*/} { svelteHTML.createElement("input", { "type":`text`,"bind:value":test,});/*Ωignore_startΩ*/() => test = __sveltets_2_any(null);/*Ωignore_endΩ*/} - { const $$_tupnI0C = __sveltets_2_ensureComponent(Input); new $$_tupnI0C({ target: __sveltets_2_any(), props: { "type":`text`,value:__sveltets_2_binding(test),}});/*Ωignore_startΩ*/() => test = __sveltets_2_any(null);/*Ωignore_endΩ*/} - { const $$_tupnI0C = __sveltets_2_ensureComponent(Input); new $$_tupnI0C({ target: __sveltets_2_any(), props: { "type":`text`,value:__sveltets_2_binding(test),}});/*Ωignore_startΩ*/() => test = __sveltets_2_any(null);/*Ωignore_endΩ*/} - { const $$_tupnI0C = __sveltets_2_ensureComponent(Input); new $$_tupnI0C({ target: __sveltets_2_any(), props: { "type":`text`,value:__sveltets_2_binding(test),}});/*Ωignore_startΩ*/() => test = __sveltets_2_any(null);/*Ωignore_endΩ*/} - { const $$_tupnI0C = __sveltets_2_ensureComponent(Input); new $$_tupnI0C({ target: __sveltets_2_any(), props: { "type":`text`,value:__sveltets_2_binding(test),}});/*Ωignore_startΩ*/() => test = __sveltets_2_any(null);/*Ωignore_endΩ*/ Input} \ No newline at end of file + { const $$_tupnI0C = __sveltets_2_ensureComponent(Input); const $$_tupnI0 = new $$_tupnI0C({ target: __sveltets_2_any(), props: { "type":`text`,value:test,}});/*Ωignore_startΩ*/() => test = __sveltets_2_any(null);/*Ωignore_endΩ*/$$_tupnI0.$$bindings = 'value';} + { const $$_tupnI0C = __sveltets_2_ensureComponent(Input); const $$_tupnI0 = new $$_tupnI0C({ target: __sveltets_2_any(), props: { "type":`text`,value:test,}});/*Ωignore_startΩ*/() => test = __sveltets_2_any(null);/*Ωignore_endΩ*/$$_tupnI0.$$bindings = 'value';} + { const $$_tupnI0C = __sveltets_2_ensureComponent(Input); const $$_tupnI0 = new $$_tupnI0C({ target: __sveltets_2_any(), props: { "type":`text`,value:test,}});/*Ωignore_startΩ*/() => test = __sveltets_2_any(null);/*Ωignore_endΩ*/$$_tupnI0.$$bindings = 'value';} + { const $$_tupnI0C = __sveltets_2_ensureComponent(Input); const $$_tupnI0 = new $$_tupnI0C({ target: __sveltets_2_any(), props: { "type":`text`,value:test,}});/*Ωignore_startΩ*/() => test = __sveltets_2_any(null);/*Ωignore_endΩ*/$$_tupnI0.$$bindings = 'value'; Input} \ No newline at end of file diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/editing-binding/expected-svelte5.js b/packages/svelte2tsx/test/htmlx2jsx/samples/editing-binding/expected-svelte5.js index 7bcb65399..7bb207fea 100644 --- a/packages/svelte2tsx/test/htmlx2jsx/samples/editing-binding/expected-svelte5.js +++ b/packages/svelte2tsx/test/htmlx2jsx/samples/editing-binding/expected-svelte5.js @@ -1,3 +1,3 @@ { svelteHTML.createElement("input", { });obj = __sveltets_2_any(null);} { svelteHTML.createElement("input", { "bind:value":obj.,});/*Ωignore_startΩ*/() => obj = __sveltets_2_any(null);/*Ωignore_endΩ*/} - { const $$_tupnI0C = __sveltets_2_ensureComponent(Input); new $$_tupnI0C({ target: __sveltets_2_any(), props: { value:__sveltets_2_binding(obj.),}});/*Ωignore_startΩ*/() => obj = __sveltets_2_any(null);/*Ωignore_endΩ*/} \ No newline at end of file + { const $$_tupnI0C = __sveltets_2_ensureComponent(Input); const $$_tupnI0 = new $$_tupnI0C({ target: __sveltets_2_any(), props: { value:obj.,}});/*Ωignore_startΩ*/() => obj = __sveltets_2_any(null);/*Ωignore_endΩ*/$$_tupnI0.$$bindings = 'value';} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes-best-effort-types/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/runes-best-effort-types/expectedv2.ts index 1ec409f7d..1d4b54dcd 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/runes-best-effort-types/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/runes-best-effort-types/expectedv2.ts @@ -8,4 +8,5 @@ return { props: /** @type {$$ComponentProps} */({}), slots: {}, events: {} }} export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { constructor(options = __sveltets_2_runes_constructor(__sveltets_2_partial(__sveltets_2_with_any_event(render())))) { super(options); } + $$bindings = __sveltets_$$bindings(''); } \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes-bindable/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/runes-bindable/expectedv2.ts index f3cd3b456..9267ded4e 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/runes-bindable/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/runes-bindable/expectedv2.ts @@ -4,8 +4,9 @@ let/** @typedef {{ a: unknown, b?: unknown }} $$ComponentProps *//** @type {$$ComponentProps} */ { a, b = $bindable() } = $props(); ; async () => {}; -return { props: /** @type {__sveltets_2_Bindings<$$ComponentProps, "b">} */({}), slots: {}, events: {} }} +return { props: /** @type {$$ComponentProps} */({}), slots: {}, events: {} }} export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { constructor(options = __sveltets_2_runes_constructor(__sveltets_2_partial(__sveltets_2_with_any_event(render())))) { super(options); } + $$bindings = __sveltets_$$bindings('b'); } \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes-looking-like-stores/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/runes-looking-like-stores/expectedv2.ts index 3f52d204a..246499cf6 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/runes-looking-like-stores/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/runes-looking-like-stores/expectedv2.ts @@ -12,4 +12,5 @@ return { props: /** @type {$$ComponentProps} */({}), slots: {}, events: {} }} export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { constructor(options = __sveltets_2_runes_constructor(__sveltets_2_partial(__sveltets_2_with_any_event(render())))) { super(options); } + $$bindings = __sveltets_$$bindings(''); } \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes-with-slots/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/runes-with-slots/expectedv2.ts index 5d0b294a8..b2f64fcb7 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/runes-with-slots/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/runes-with-slots/expectedv2.ts @@ -13,5 +13,5 @@ async () => { return { props: /** @type {SomeType} */({}), slots: {'default': {x:x, y:y}}, events: {} }} export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { - constructor(options = __sveltets_2_runes_constructor(__sveltets_2_partial(__sveltets_2_with_any_event(render())))) { super(options); } + $$bindings = __sveltets_$$bindings(''); } \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/runes/expectedv2.ts index 27e928d7c..888397861 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/runes/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/runes/expectedv2.ts @@ -11,4 +11,5 @@ return { props: /** @type {$$ComponentProps} */({}), slots: {}, events: {} }} export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { constructor(options = __sveltets_2_runes_constructor(__sveltets_2_partial(__sveltets_2_with_any_event(render())))) { super(options); } + $$bindings = __sveltets_$$bindings(''); } \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune-no-changes/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune-no-changes/expectedv2.ts index f1d1c1d07..c416a1d74 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune-no-changes/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune-no-changes/expectedv2.ts @@ -11,5 +11,6 @@ return { props: /** @type {$$ComponentProps} */({}), exports: /** @type {snapsho export default class Page__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { constructor(options = __sveltets_2_runes_constructor(__sveltets_2_partial(__sveltets_2_with_any_event(render())))) { super(options); } + $$bindings = __sveltets_$$bindings(''); get snapshot() { return render().exports.snapshot } } \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune/expectedv2.ts index e49b9dd31..7195620ab 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune/expectedv2.ts @@ -9,5 +9,6 @@ return { props: /** @type {$$ComponentProps} */({}), exports: /** @type {snapsho export default class Page__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { constructor(options = __sveltets_2_runes_constructor(__sveltets_2_partial(__sveltets_2_with_any_event(render())))) { super(options); } + $$bindings = __sveltets_$$bindings(''); get snapshot() { return render().exports.snapshot } } \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-best-effort-types/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-best-effort-types/expectedv2.ts index 4708d001d..530b51e2e 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-best-effort-types/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-best-effort-types/expectedv2.ts @@ -8,4 +8,5 @@ return { props: {} as any as $$ComponentProps, slots: {}, events: {} }} export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_with_any_event(render())) { constructor(options = __sveltets_2_runes_constructor(__sveltets_2_with_any_event(render()))) { super(options); } + $$bindings = __sveltets_$$bindings(''); } \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-bindable/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-bindable/expectedv2.ts index 715a909f9..bc9f4863e 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-bindable/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-bindable/expectedv2.ts @@ -4,8 +4,9 @@ let { a, b = $bindable() }: $$ComponentProps = $props(); ; async () => {}; -return { props: {} as any as __sveltets_2_Bindings<$$ComponentProps, "b">, slots: {}, events: {} }} +return { props: {} as any as $$ComponentProps, slots: {}, events: {} }} export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_with_any_event(render())) { constructor(options = __sveltets_2_runes_constructor(__sveltets_2_with_any_event(render()))) { super(options); } + $$bindings = __sveltets_$$bindings('b'); } \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-generics/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-generics/expectedv2.ts index 49f1e4a69..8ee4f9c16 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-generics/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-generics/expectedv2.ts @@ -22,5 +22,6 @@ class __sveltets_Render { import { SvelteComponentTyped as __SvelteComponentTyped__ } from "svelte" export default class Input__SvelteComponent_ extends __SvelteComponentTyped__['props']>, ReturnType<__sveltets_Render['events']>, ReturnType<__sveltets_Render['slots']>> { - constructor(options: import('svelte').ComponentConstructorOptions<__sveltets_2_PropsWithChildren['props']>, ReturnType<__sveltets_Render['slots']>>>) { super(options); } + constructor(options: import('svelte').ComponentConstructorOptions['props']>>) { super(options); } + $$bindings = __sveltets_$$bindings(''); } \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-with-slot/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-with-slot/expectedv2.ts index 2f4a66108..ab9ba5dc8 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-with-slot/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-with-slot/expectedv2.ts @@ -26,5 +26,5 @@ class __sveltets_Render { import { SvelteComponentTyped as __SvelteComponentTyped__ } from "svelte" export default class Input__SvelteComponent_ extends __SvelteComponentTyped__['props']>, ReturnType<__sveltets_Render['events']>, ReturnType<__sveltets_Render['slots']>> { - constructor(options: import('svelte').ComponentConstructorOptions<__sveltets_2_PropsWithChildren['props']>, ReturnType<__sveltets_Render['slots']>>>) { super(options); } + $$bindings = __sveltets_$$bindings(''); } \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes/expectedv2.ts index cde57ce7f..a79725a86 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes/expectedv2.ts @@ -10,4 +10,5 @@ return { props: {} as any as $$ComponentProps, slots: {}, events: {} }} export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_with_any_event(render())) { constructor(options = __sveltets_2_runes_constructor(__sveltets_2_with_any_event(render()))) { super(options); } + $$bindings = __sveltets_$$bindings(''); } \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune-unchanged/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune-unchanged/expectedv2.ts index 1ef4b622a..6699fbec3 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune-unchanged/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune-unchanged/expectedv2.ts @@ -9,5 +9,6 @@ return { props: {} as any as $$ComponentProps, exports: {} as any as { snapshot: export default class Page__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_with_any_event(render())) { constructor(options = __sveltets_2_runes_constructor(__sveltets_2_with_any_event(render()))) { super(options); } + $$bindings = __sveltets_$$bindings(''); get snapshot() { return render().exports.snapshot } } \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune/expectedv2.ts index be250d042..b3afa9ba5 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune/expectedv2.ts @@ -9,5 +9,6 @@ return { props: {} as any as $$ComponentProps, exports: {} as any as { snapshot: export default class Page__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_with_any_event(render())) { constructor(options = __sveltets_2_runes_constructor(__sveltets_2_with_any_event(render()))) { super(options); } + $$bindings = __sveltets_$$bindings(''); get snapshot() { return render().exports.snapshot } } \ No newline at end of file