Skip to content

Commit 8eda468

Browse files
authored
(perf) cap full file semantic tokens (#774)
#772 Cap the full file semantic token request to 50000. If the text length of the svelte2tsx generated code is bigger than that, return null and let the client request for ranged semantic tokens, that is what's visible on the screen.
1 parent ffe74f6 commit 8eda468

File tree

6 files changed

+29
-17
lines changed

6 files changed

+29
-17
lines changed

packages/language-server/src/plugins/PluginHost.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -408,14 +408,10 @@ export class PluginHost implements LSProvider, OnWatchFileChanges {
408408
throw new Error('Cannot call methods on an unopened document');
409409
}
410410

411-
return (
412-
(await this.execute<SemanticTokens>(
413-
'getSemanticTokens',
414-
[document, range],
415-
ExecuteMode.FirstNonNull
416-
)) ?? {
417-
data: []
418-
}
411+
return await this.execute<SemanticTokens>(
412+
'getSemanticTokens',
413+
[document, range],
414+
ExecuteMode.FirstNonNull
419415
);
420416
}
421417

packages/language-server/src/plugins/interfaces.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ export interface SelectionRangeProvider {
148148
}
149149

150150
export interface SemanticTokensProvider {
151-
getSemanticTokens(textDocument: Document, range?: Range): Resolvable<SemanticTokens>;
151+
getSemanticTokens(textDocument: Document, range?: Range): Resolvable<SemanticTokens | null>;
152152
}
153153

154154
export interface OnWatchFileChangesPara {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ export class TypeScriptPlugin
413413
return this.signatureHelpProvider.getSignatureHelp(document, position, context);
414414
}
415415

416-
async getSemanticTokens(textDocument: Document, range?: Range): Promise<SemanticTokens> {
416+
async getSemanticTokens(textDocument: Document, range?: Range): Promise<SemanticTokens | null> {
417417
if (!this.featureEnabled('semanticTokens')) {
418418
return {
419419
data: []

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,20 @@ import { SnapshotFragment } from '../DocumentSnapshot';
66
import { LSAndTSDocResolver } from '../LSAndTSDocResolver';
77
import { convertToTextSpan } from '../utils';
88

9+
const CONTENT_LENGTH_LIMIT = 50000;
10+
911
export class SemanticTokensProviderImpl implements SemanticTokensProvider {
1012
constructor(private readonly lsAndTsDocResolver: LSAndTSDocResolver) {}
1113

12-
async getSemanticTokens(textDocument: Document, range?: Range): Promise<SemanticTokens> {
14+
async getSemanticTokens(textDocument: Document, range?: Range): Promise<SemanticTokens | null> {
1315
const { lang, tsDoc } = this.lsAndTsDocResolver.getLSAndTSDoc(textDocument);
1416
const fragment = await tsDoc.getFragment();
17+
18+
// for better performance, don't do full-file semantic tokens when the file is too big
19+
if (!range && fragment.text.length > CONTENT_LENGTH_LIMIT) {
20+
return null;
21+
}
22+
1523
const textSpan = range
1624
? convertToTextSpan(range, fragment)
1725
: {

packages/language-server/src/server.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ import {
1212
TextDocumentIdentifier,
1313
TextDocumentPositionParams,
1414
TextDocumentSyncKind,
15-
WorkspaceEdit
15+
WorkspaceEdit,
16+
SemanticTokensRequest,
17+
SemanticTokensRangeRequest
1618
} from 'vscode-languageserver';
1719
import { IPCMessageReader, IPCMessageWriter, createConnection } from 'vscode-languageserver/node';
1820
import { DiagnosticsManager } from './lib/DiagnosticsManager';
@@ -304,8 +306,10 @@ export function startServer(options?: LSOptions) {
304306
updateAllDiagnostics();
305307
});
306308

307-
connection.languages.semanticTokens.on((evt) => pluginHost.getSemanticTokens(evt.textDocument));
308-
connection.languages.semanticTokens.onRange((evt) =>
309+
connection.onRequest(SemanticTokensRequest.type, (evt) =>
310+
pluginHost.getSemanticTokens(evt.textDocument)
311+
);
312+
connection.onRequest(SemanticTokensRangeRequest.type, (evt) =>
309313
pluginHost.getSemanticTokens(evt.textDocument, evt.range)
310314
);
311315

packages/language-server/test/plugins/typescript/features/SemanticTokensProvider.test.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,22 @@ describe('SemanticTokensProvider', () => {
3333
it('provides semantic token', async () => {
3434
const { provider, document } = setup();
3535

36-
const { data } = await provider.getSemanticTokens(document);
36+
const { data } = (await provider.getSemanticTokens(document)) ?? {
37+
data: []
38+
};
3739

3840
assertResult(data, getExpected(/* isFull */ true));
3941
});
4042

4143
it('provides partial semantic token', async () => {
4244
const { provider, document } = setup();
4345

44-
const { data } = await provider.getSemanticTokens(
46+
const { data } = (await provider.getSemanticTokens(
4547
document,
4648
Range.create(Position.create(0, 0), Position.create(9, 0))
47-
);
49+
)) ?? {
50+
data: []
51+
};
4852

4953
assertResult(data, getExpected(/* isFull */ false));
5054
});

0 commit comments

Comments
 (0)