Skip to content

Commit 72e815b

Browse files
committed
use .d.svelte.ts for intercepting svelte files, which allows us to make ./foo.svelte make .svelte query before .svelte.ts
1 parent dcc0507 commit 72e815b

File tree

16 files changed

+85
-24
lines changed

16 files changed

+85
-24
lines changed

packages/language-server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"./bin/server.js": "./bin/server.js"
1111
},
1212
"scripts": {
13-
"test": "cross-env TS_NODE_TRANSPILE_ONLY=true mocha --require ts-node/register \"test/**/*.ts\" --exclude \"test/**/*.d.ts\"",
13+
"test": "cross-env TS_NODE_TRANSPILE_ONLY=true mocha --require ts-node/register \"test/**/*.test.ts\"",
1414
"build": "tsc",
1515
"prepublishOnly": "npm run build",
1616
"watch": "tsc -w"

packages/language-server/src/plugins/typescript/module-loader.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,6 @@ class ImpliedNodeFormatResolver {
108108
if (sourceFile) {
109109
this.cacheImpliedNodeFormat(sourceFile, compilerOptions);
110110
mode = ts.getModeForResolutionAtIndex(sourceFile, importIdxInFile, compilerOptions);
111-
if (!mode && isSvelteFilePath(importPath)) {
112-
mode = ts.ModuleKind.ESNext; // necessary for TS' module resolution to go into the right branches
113-
}
114111
}
115112
return mode;
116113
}

packages/language-server/src/plugins/typescript/svelte-sys.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,17 @@ export function createSvelteSys(tsSystem: ts.System) {
1111
function svelteFileExists(path: string) {
1212
if (isVirtualSvelteFilePath(path)) {
1313
const sveltePath = toRealSvelteFilePath(path);
14+
15+
// First check if there's a `.svelte.d.ts` or `.d.svelte.ts` file, which should take precedence
16+
const dtsPath = sveltePath.slice(0, -7) + '.svelte.d.ts';
17+
const dtsPathExists = fileExistsCache.get(dtsPath) ?? tsSystem.fileExists(dtsPath);
18+
fileExistsCache.set(dtsPath, dtsPathExists);
19+
if (dtsPathExists) return false;
20+
21+
const svelteDtsPathExists = fileExistsCache.get(path) ?? tsSystem.fileExists(path);
22+
fileExistsCache.set(path, svelteDtsPathExists);
23+
if (svelteDtsPathExists) return false;
24+
1425
const sveltePathExists =
1526
fileExistsCache.get(sveltePath) ?? tsSystem.fileExists(sveltePath);
1627
fileExistsCache.set(sveltePath, sveltePathExists);
@@ -33,10 +44,11 @@ export function createSvelteSys(tsSystem: ts.System) {
3344
svelteFileExists,
3445
getRealSveltePathIfExists,
3546
fileExists(path: string) {
36-
// We need to check both .svelte and .svelte.ts/js because that's how Svelte 5 will likely mark files with runes in them
47+
// We need to check if this is a virtual svelte file
3748
const sveltePathExists = svelteFileExists(path);
38-
const exists =
39-
sveltePathExists || (fileExistsCache.get(path) ?? tsSystem.fileExists(path));
49+
if (sveltePathExists) return true;
50+
51+
const exists = fileExistsCache.get(path) ?? tsSystem.fileExists(path);
4052
fileExistsCache.set(path, exists);
4153
return exists;
4254
},
@@ -66,7 +78,7 @@ export function createSvelteSys(tsSystem: ts.System) {
6678
const realpath = tsSystem.realpath;
6779
svelteSys.realpath = function (path) {
6880
if (svelteFileExists(path)) {
69-
return realpath(toRealSvelteFilePath(path)) + '.ts';
81+
return realpath(toRealSvelteFilePath(path));
7082
}
7183
return realpath(path);
7284
};

packages/language-server/src/plugins/typescript/utils.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,21 +70,17 @@ export function isSvelteFilePath(filePath: string) {
7070
}
7171

7272
export function isVirtualSvelteFilePath(filePath: string) {
73-
return filePath.endsWith('.svelte.ts');
73+
return filePath.endsWith('.d.svelte.ts');
7474
}
7575

7676
export function toRealSvelteFilePath(filePath: string) {
77-
filePath = filePath.slice(0, -'.ts'.length);
78-
// When a .svelte file referenced inside an exports map of a package.json is tried to be resolved,
79-
// TypeScript will probe for the file with a .d.svelte.ts extension.
80-
if (filePath.endsWith('.d.svelte')) {
81-
filePath = filePath.slice(0, -8) + 'svelte';
82-
}
83-
return filePath;
77+
return filePath.slice(0, -11 /* 'd.svelte.ts'.length */) + 'svelte';
8478
}
8579

86-
export function toVirtualSvelteFilePath(filePath: string) {
87-
return filePath.endsWith('.ts') ? filePath : filePath + '.ts';
80+
export function toVirtualSvelteFilePath(svelteFilePath: string) {
81+
return isVirtualSvelteFilePath(svelteFilePath)
82+
? svelteFilePath
83+
: svelteFilePath.slice(0, -6 /* 'svelte'.length */) + 'd.svelte.ts';
8884
}
8985

9086
export function ensureRealSvelteFilePath(filePath: string) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<script>
2+
export let foo = true;
3+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export declare const a: boolean;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<script>
2+
export let foo = true;
3+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const b = true;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export declare const c: boolean;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<script>
2+
export let foo = true;
3+
</script>

0 commit comments

Comments
 (0)