Skip to content

Commit a8ee6e2

Browse files
authored
(fix) fixes around SvelteKit imports (#1663)
- don't update ./$types in TS files (plugin) - handle special root dir case when modifying source during completions - handle leading whitespace in import text
1 parent ce406b1 commit a8ee6e2

File tree

3 files changed

+37
-22
lines changed

3 files changed

+37
-22
lines changed

packages/language-server/src/plugins/typescript/features/CompletionProvider.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,14 @@ export class CompletionsProviderImpl implements CompletionsProvider<CompletionEn
284284
// resolve path from filePath to svelte-kit/types
285285
// src/routes/foo/+page.svelte -> .svelte-kit/types/foo/$types.d.ts
286286
const routesFolder = document.config?.kit?.files?.routes || 'src/routes';
287-
const relativeFilePath = filePath.split(routesFolder)[1]?.slice(1);
288-
if (relativeFilePath) {
287+
const relativeFileName = filePath.split(routesFolder)[1]?.slice(1);
288+
if (relativeFileName) {
289+
const relativePath =
290+
dirname(relativeFileName) === '.' ? '' : `${dirname(relativeFileName)}/`;
291+
const modifiedSource =
292+
$typeImport.data.source.split('.svelte-kit/types')[0] +
293+
// note the missing .d.ts at the end - TS wants it that way for some reason
294+
`.svelte-kit/types/${routesFolder}/${relativePath}$types`;
289295
completionItems.push({
290296
...$typeImport,
291297
// Ensure it's sorted above the other imports
@@ -295,12 +301,7 @@ export class CompletionsProviderImpl implements CompletionsProvider<CompletionEn
295301
data: {
296302
...$typeImport.data,
297303
__is_sveltekit$typeImport: true,
298-
source:
299-
$typeImport.data.source.split('.svelte-kit/types')[0] +
300-
// note the missing .d.ts at the end - TS wants it that way for some reason
301-
`.svelte-kit/types/${routesFolder}/${dirname(
302-
relativeFilePath
303-
)}/$types`,
304+
source: modifiedSource,
304305
data: undefined
305306
}
306307
});
@@ -773,7 +774,7 @@ export class CompletionsProviderImpl implements CompletionsProvider<CompletionEn
773774
actionTriggeredInScript: boolean,
774775
is$typeImport?: boolean
775776
) {
776-
if (is$typeImport && importText.startsWith('import ')) {
777+
if (is$typeImport && importText.trim().startsWith('import ')) {
777778
// Take into account Node16 moduleResolution
778779
return importText.replace(
779780
/(['"])(.+?)['"]/,

packages/typescript-plugin/src/language-service/completions.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ export function decorateCompletions(ls: ts.LanguageService, logger: Logger): voi
2828
const relativeFileName = fileName.split(routesFolder)[1]?.slice(1);
2929

3030
if (relativeFileName) {
31+
const relativePath =
32+
dirname(relativeFileName) === '.' ? '' : `${dirname(relativeFileName)}/`;
3133
const modifiedSource =
3234
$typeImport.source!.split('.svelte-kit/types')[0] +
3335
// note the missing .d.ts at the end - TS wants it that way for some reason
34-
`.svelte-kit/types/${routesFolder}/${dirname(relativeFileName)}/$types`;
36+
`.svelte-kit/types/${routesFolder}/${relativePath}$types`;
3537
completions.entries.push({
3638
...$typeImport,
3739
// Ensure it's sorted above the other imports
Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import path from 'path';
12
import type ts from 'typescript/lib/tsserverlibrary';
23
import { Logger } from '../logger';
34
import { SvelteSnapshotManager } from '../svelte-snapshots';
@@ -16,17 +17,28 @@ export function decorateUpdateImports(
1617
formatOptions,
1718
preferences
1819
);
19-
// If a file move/rename of a TS/JS file results a Svelte file change,
20-
// the Svelte extension will notice that, too, and adjusts the same imports.
21-
// This results in duplicate adjustments or race conditions with conflicting text spans
22-
// which can break imports in some cases.
23-
// Therefore don't do any updates of Svelte files and and also no updates of mixed TS files
24-
// and let the Svelte extension handle that.
25-
return renameLocations?.filter((renameLocation) => {
26-
return (
27-
!isSvelteFilePath(renameLocation.fileName) &&
28-
!renameLocation.textChanges.some((change) => change.newText.endsWith('.svelte'))
29-
);
30-
});
20+
return renameLocations
21+
?.filter((renameLocation) => {
22+
// If a file move/rename of a TS/JS file results a Svelte file change,
23+
// the Svelte extension will notice that, too, and adjusts the same imports.
24+
// This results in duplicate adjustments or race conditions with conflicting text spans
25+
// which can break imports in some cases.
26+
// Therefore don't do any updates of Svelte files and and also no updates of mixed TS files
27+
// and let the Svelte extension handle that.
28+
return (
29+
!isSvelteFilePath(renameLocation.fileName) &&
30+
!renameLocation.textChanges.some((change) => change.newText.endsWith('.svelte'))
31+
);
32+
})
33+
.map((renameLocation) => {
34+
if (path.basename(renameLocation.fileName).startsWith('+')) {
35+
// Filter out changes to './$type' imports for Kit route files,
36+
// you'll likely want these to stay as-is
37+
renameLocation.textChanges = renameLocation.textChanges.filter((change) => {
38+
return !change.newText.includes('.svelte-kit/types/');
39+
});
40+
}
41+
return renameLocation;
42+
});
3143
};
3244
}

0 commit comments

Comments
 (0)