Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/cool-chefs-compete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'svelte-language-server': patch
'svelte-check': patch
---

perf: tweak some snapshot hot paths
20 changes: 10 additions & 10 deletions packages/language-server/src/plugins/typescript/DocumentSnapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ export interface SvelteSnapshotOptions {
typingsNamespace: string;
}

const ambientPathPattern = /node_modules[\/\\]svelte[\/\\]types[\/\\]ambient\.d\.ts$/;
const svelteTypesPattern = /node_modules[\/\\]svelte[\/\\]types[\/\\]index\.d\.ts$/;
const shimsPattern =
/svelte2tsx[\/\\]svelte-shims\.d\.ts$|svelte-check[\/\\]dist[\/\\]src[\/\\]svelte-shims\.d\.ts$/;

export namespace DocumentSnapshot {
/**
* Returns a svelte snapshot from a svelte document.
Expand Down Expand Up @@ -121,30 +126,25 @@ export namespace DocumentSnapshot {
* @param options options that apply in case it's a svelte file
*/
export function fromNonSvelteFilePath(filePath: string, tsSystem: ts.System) {
let originalText = '';

// The following (very hacky) code makes sure that the ambient module definitions
// that tell TS "every import ending with .svelte is a valid module" are removed.
// They exist in svelte2tsx and svelte to make sure that people don't
// get errors in their TS files when importing Svelte files and not using our TS plugin.
// If someone wants to get back the behavior they can add an ambient module definition
// on their own.
const normalizedPath = filePath.replace(/\\/g, '/');
if (!normalizedPath.endsWith('node_modules/svelte/types/runtime/ambient.d.ts')) {
let originalText = '';
if (!ambientPathPattern.test(filePath)) {
originalText = tsSystem.readFile(filePath) || '';
}

if (normalizedPath.endsWith('node_modules/svelte/types/index.d.ts')) {
if (svelteTypesPattern.test(filePath)) {
const startIdx = originalText.indexOf(`declare module '*.svelte' {`);
const endIdx = originalText.indexOf(`\n}`, startIdx + 1) + 2;
originalText =
originalText.substring(0, startIdx) +
' '.repeat(endIdx - startIdx) +
originalText.substring(endIdx);
} else if (
normalizedPath.endsWith('svelte2tsx/svelte-shims.d.ts') ||
normalizedPath.endsWith('svelte-check/dist/src/svelte-shims.d.ts')
) {
} else if (shimsPattern.test(filePath)) {
// If not present, the LS uses an older version of svelte2tsx
if (originalText.includes('// -- start svelte-ls-remove --')) {
originalText =
Expand All @@ -157,7 +157,7 @@ export namespace DocumentSnapshot {
}

const declarationExtensions = [ts.Extension.Dcts, ts.Extension.Dts, ts.Extension.Dmts];
if (declarationExtensions.some((ext) => normalizedPath.endsWith(ext))) {
if (declarationExtensions.some((ext) => filePath.endsWith(ext))) {
return new DtsDocumentSnapshot(INITIAL_VERSION, filePath, originalText, tsSystem);
}

Expand Down
111 changes: 56 additions & 55 deletions packages/language-server/src/svelte-check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,66 +252,67 @@ export class SvelteCheck {
const isKitFile = snapshot?.kitFile ?? false;
const diagnostics: Diagnostic[] = [];
if (!skipDiagnosticsForFile) {
const originalDiagnostics = [
...lang.getSyntacticDiagnostics(file.fileName),
...lang.getSuggestionDiagnostics(file.fileName),
...lang.getSemanticDiagnostics(file.fileName)
];

for (let diagnostic of originalDiagnostics) {
if (!diagnostic.start || !diagnostic.length || !isKitFile) {
diagnostics.push(map(diagnostic));
continue;
}
const diagnosticSources = [
'getSyntacticDiagnostics',
'getSuggestionDiagnostics',
'getSemanticDiagnostics'
] as const;
for (const diagnosticSource of diagnosticSources) {
for (let diagnostic of lang[diagnosticSource](file.fileName)) {
if (!diagnostic.start || !diagnostic.length || !isKitFile) {
diagnostics.push(map(diagnostic));
continue;
}

let range: Range | undefined = undefined;
const inGenerated = isInGeneratedCode(
file.text,
diagnostic.start,
diagnostic.start + diagnostic.length
);
if (inGenerated && snapshot) {
const pos = snapshot.getOriginalPosition(
snapshot.positionAt(diagnostic.start)
let range: Range | undefined = undefined;
const inGenerated = isInGeneratedCode(
file.text,
diagnostic.start,
diagnostic.start + diagnostic.length
);
range = {
start: pos,
end: {
line: pos.line,
// adjust length so it doesn't spill over to the next line
character: pos.character + 1
}
};
// If not one of the specific error messages then filter out
if (diagnostic.code === 2307) {
diagnostic = {
...diagnostic,
messageText:
typeof diagnostic.messageText === 'string' &&
diagnostic.messageText.includes('./$types')
? diagnostic.messageText +
` (this likely means that SvelteKit's type generation didn't run yet - try running it by executing 'npm run dev' or 'npm run build')`
: diagnostic.messageText
if (inGenerated && snapshot) {
const pos = snapshot.getOriginalPosition(
snapshot.positionAt(diagnostic.start)
);
range = {
start: pos,
end: {
line: pos.line,
// adjust length so it doesn't spill over to the next line
character: pos.character + 1
}
};
} else if (diagnostic.code === 2694) {
diagnostic = {
...diagnostic,
messageText:
typeof diagnostic.messageText === 'string' &&
diagnostic.messageText.includes('/$types')
? diagnostic.messageText +
` (this likely means that SvelteKit's generated types are out of date - try rerunning it by executing 'npm run dev' or 'npm run build')`
: diagnostic.messageText
};
} else if (
diagnostic.code !==
2355 /* A function whose declared type is neither 'void' nor 'any' must return a value */
) {
continue;
// If not one of the specific error messages then filter out
if (diagnostic.code === 2307) {
diagnostic = {
...diagnostic,
messageText:
typeof diagnostic.messageText === 'string' &&
diagnostic.messageText.includes('./$types')
? diagnostic.messageText +
` (this likely means that SvelteKit's type generation didn't run yet - try running it by executing 'npm run dev' or 'npm run build')`
: diagnostic.messageText
};
} else if (diagnostic.code === 2694) {
diagnostic = {
...diagnostic,
messageText:
typeof diagnostic.messageText === 'string' &&
diagnostic.messageText.includes('/$types')
? diagnostic.messageText +
` (this likely means that SvelteKit's generated types are out of date - try rerunning it by executing 'npm run dev' or 'npm run build')`
: diagnostic.messageText
};
} else if (
diagnostic.code !==
2355 /* A function whose declared type is neither 'void' nor 'any' must return a value */
) {
continue;
}
}
}

diagnostics.push(map(diagnostic, range));
diagnostics.push(map(diagnostic, range));
}
}
}

Expand Down
5 changes: 4 additions & 1 deletion packages/language-server/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ export function normalizeUri(uri: string): string {
* (bar or bar.svelte in this example).
*/
export function getLastPartOfPath(path: string): string {
return path.replace(/\\/g, '/').split('/').pop() || '';
const lastSlash = path.lastIndexOf('/');
const lastBackslash = path.lastIndexOf('\\');
const lastSeparator = Math.max(lastSlash, lastBackslash);
return lastSeparator === -1 ? path : path.slice(lastSeparator + 1);
}

export function flatten<T>(arr: Array<T | T[]>): T[] {
Expand Down