From 16df0d32cd9fd66f0fe4ef8121e6b6f1da80df8d Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Tue, 5 Nov 2024 17:27:51 +0100 Subject: [PATCH] fix: allow JS snapshots within TS plugin So far we've always assumed that a Svelte file is a TS file for simplicity, due to our default language (which was removed a long time ago) and also because IIRC there were issues with TS having its snapshot scriptKind being switched. That seems to be no longer the case, and so we can get better at properly analyzing whether or not this is a TS file, to allow JSDoc to take action when it's a JS file. #2555 --- .../typescript-plugin/src/svelte-snapshots.ts | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/packages/typescript-plugin/src/svelte-snapshots.ts b/packages/typescript-plugin/src/svelte-snapshots.ts index 438ceb6ca..5d18b0d66 100644 --- a/packages/typescript-plugin/src/svelte-snapshots.ts +++ b/packages/typescript-plugin/src/svelte-snapshots.ts @@ -16,13 +16,18 @@ export class SvelteSnapshot { private svelteCode: string, private mapper: SourceMapper, private logger: Logger, - public readonly isTsFile: boolean + public isTsFile: boolean ) {} - update(svelteCode: string, mapper: SourceMapper) { + update(svelteCode: string, mapper: SourceMapper, isTsFile: boolean) { this.svelteCode = svelteCode; this.mapper = mapper; this.lineOffsets = undefined; + this.isTsFile = isTsFile; + // @ts-expect-error + this.scriptInfo!.scriptKind = this.isTsFile + ? this.typescript.ScriptKind.TS + : this.typescript.ScriptKind.JS; this.log('Updated Snapshot'); } @@ -107,7 +112,9 @@ export class SvelteSnapshot { setAndPatchScriptInfo(scriptInfo: ts.server.ScriptInfo) { // @ts-expect-error - scriptInfo.scriptKind = this.typescript.ScriptKind.TS; + scriptInfo.scriptKind = this.isTsFile + ? this.typescript.ScriptKind.TS + : this.typescript.ScriptKind.JS; const positionToLineOffset = scriptInfo.positionToLineOffset.bind(scriptInfo); scriptInfo.positionToLineOffset = (position) => { @@ -366,7 +373,17 @@ export class SvelteSnapshotManager { } else if (isSvelteFilePath(path)) { this.logger.debug('Read Svelte file:', path); const svelteCode = readFile(path) || ''; - const isTsFile = true; // TODO check file contents? TS might be okay with importing ts into js. + const version = this.svelteCompiler?.VERSION ?? '4.2.0'; // built-in one is 4.x + const isTsFile = + // At some point we supported a default language of TS, but that was removed. + // Assume that people using Svelte 5 are always using the attribute + Number(version.split('.')[0]) >= 5 + ? svelteCode.includes('lang="ts"') || + svelteCode.includes('lang=ts') || + // Additional measures to prevent each file to start out with JS and then switch to TS + !svelteCode.includes('