Skip to content

Commit a1ba934

Browse files
committed
Support for new publishInfo endpoint to map file uri to context
1 parent e1e2429 commit a1ba934

File tree

5 files changed

+56
-34
lines changed

5 files changed

+56
-34
lines changed

client/src/extension.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import * as path from 'path';
2-
import { workspace, ExtensionContext } from 'vscode';
32

43
import {
54
LanguageClient,
@@ -10,7 +9,11 @@ import {
109

1110
import {
1211
commands,
13-
window
12+
window,
13+
Uri,
14+
workspace,
15+
ExtensionContext,
16+
TextDocumentChangeEvent
1417
} from 'vscode'
1518

1619
let client: LanguageClient;
@@ -48,8 +51,8 @@ export function activate(context: ExtensionContext) {
4851

4952
// Create the language client and start the client.
5053
client = new LanguageClient(
51-
'languageServerExample',
52-
'Language Server Example',
54+
'sourceLSP',
55+
'Source Language Server',
5356
serverOptions,
5457
clientOptions
5558
);
@@ -62,28 +65,28 @@ export function activate(context: ExtensionContext) {
6265
})();
6366

6467
context.subscriptions.push(
65-
commands.registerCommand("source.setLanguageVersion", async () => {
68+
commands.registerCommand("source.setLanguageVersion", async (uri: Uri) => {
6669
const versions = [`Source ${SECTION}1`, `Source ${SECTION}2`, `Source ${SECTION}3`, `Source ${SECTION}4`]
6770
const selectedVersion = await window.showQuickPick(versions, {
6871
placeHolder: "Select the language version",
6972
});
7073

7174
if (selectedVersion) {
72-
await setLanguageVersion(selectedVersion);
75+
await setLanguageVersion(uri.toString(false), versions.indexOf(selectedVersion)+1);
7376
}
7477

7578
})
7679
)
7780
}
7881

7982
// Function to send the version to the server
80-
async function setLanguageVersion(version: string) {
83+
async function setLanguageVersion(uri: string, version: number) {
8184
if (!client) {
8285
window.showErrorMessage("Language server is not running.");
8386
return;
8487
}
8588
try {
86-
const response = await client.sendRequest("setLanguageVersion", { version });
89+
const response = await client.sendRequest("source/publishInfo", { [uri]: { chapter: version , prelude: "\n\n\n" } });
8790
window.showInformationMessage(`Language version set to ${version}`);
8891
} catch (error) {
8992
window.showErrorMessage(`Failed to set language version: ${error}`);

package.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,16 @@
5353
"command": "source.setLanguageVersion",
5454
"title": "Source: Set Source Version Used"
5555
}
56-
]
56+
],
57+
"menus": {
58+
"explorer/context": [
59+
{
60+
"command": "source.setLanguageVersion",
61+
"when": "resourceFilename",
62+
"group": "navigation"
63+
}
64+
]
65+
}
5766
},
5867
"dependencies": {
5968
"jsdom": "^26.0.0",

server/src/ast.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ export class AST {
2323
private diagnosticsCallbacks: Array<[(child: Node) => void, Node]> = [];
2424

2525
// If prepend is supplied, prepend it to text, and offset all locations returned back to client
26-
constructor(text: string, context: Context, uri: string, prependLines: number = 0) {
27-
this.prependLines = prependLines;
26+
constructor(text: string, context: Context, uri: string) {
27+
this.prependLines = context.prelude ? context.prelude.split("\n").length : 0;
2828
const acornOptions: Options = {
2929
ecmaVersion: DEFAULT_ECMA_VERSION,
3030
sourceType: "module",

server/src/server.ts

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import {
1717
DocumentSymbol,
1818
HoverParams,
1919
Hover,
20-
DocumentHighlight,
2120
} from 'vscode-languageserver/node';
2221

2322
import { TextDocument } from 'vscode-languageserver-textdocument';
@@ -27,13 +26,6 @@ import { sourceLocToRange } from './utils';
2726
import { AST } from './ast';
2827
import { Chapter, Context } from './types';
2928

30-
const SECTION = "\u00A7";
31-
const chapter_names = {
32-
[`Source ${SECTION}1`]: Chapter.SOURCE_1,
33-
[`Source ${SECTION}2`]: Chapter.SOURCE_2,
34-
[`Source ${SECTION}3`]: Chapter.SOURCE_3,
35-
[`Source ${SECTION}4`]: Chapter.SOURCE_4
36-
};
3729

3830
// Create a connection for the server, using Node's IPC as a transport.
3931
// Also include all preview / proposed LSP features.
@@ -45,19 +37,21 @@ let documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument);
4537
let hasConfigurationCapability: boolean = false;
4638
let hasWorkspaceFolderCapability: boolean = false;
4739

48-
// let context: Context = { chapter: Chapter.SOURCE_1 };
40+
// Map between file uri string and context object
4941
let contextCache: Map<string, Context> = new Map();
5042
let astCache: Map<string, AST> = new Map();
43+
const DEFAULT_CONTEXT: Context = { chapter: Chapter.SOURCE_1 };
5144

5245
function getAST(uri: string): AST {
5346
if (astCache.has(uri)) return astCache.get(uri)!;
5447

55-
let context = contextCache.get(uri)
48+
let context = contextCache.get(uri);
5649
if (!context) {
57-
context = { chapter: Chapter.SOURCE_1 };
58-
console.log(`No context found for ${uri}, using default context ${JSON.stringify(context)}`);
50+
context = DEFAULT_CONTEXT;
51+
contextCache.set(uri, DEFAULT_CONTEXT);
52+
console.log(`No context found for ${uri}, using default context ${JSON.stringify(DEFAULT_CONTEXT)}`);
5953
}
60-
console.log(`Creating AST for ${uri} with context ${JSON.stringify(context)}`);
54+
// console.log(`Creating AST for ${uri} with context ${JSON.stringify(context)}`);
6155

6256
// const ast = new AST(documents.get(uri)!.getText(), context, uri, 4);
6357
const ast = new AST(documents.get(uri)!.getText(), context, uri);
@@ -66,7 +60,7 @@ function getAST(uri: string): AST {
6660
}
6761

6862
connection.onInitialize((params: InitializeParams) => {
69-
connection.console.log('LSP INIT');
63+
connection.console.log('LSP INIT');
7064
let capabilities = params.capabilities;
7165

7266
// Does the client support the `workspace/configuration` request?
@@ -193,7 +187,7 @@ connection.onDocumentHighlight((params: DocumentHighlightParams) => {
193187
const document = documents.get(params.textDocument.uri);
194188
if (!document) return null;
195189

196-
return getAST(params.textDocument.uri).getOccurences(params.position).map(x => ({ range: x}));
190+
return getAST(params.textDocument.uri).getOccurences(params.position).map(x => ({ range: x }));
197191
})
198192

199193
connection.onDocumentSymbol(async (params: DocumentSymbolParams): Promise<DocumentSymbol[] | null> => {
@@ -218,19 +212,34 @@ connection.onHover((params: HoverParams): Hover | null => {
218212
return getAST(params.textDocument.uri).onHover(position);
219213
})
220214

221-
connection.onNotification("source/publishInfo", (info) => {
215+
connection.onRequest("source/publishInfo", (info: { [uri: string]: Context }) => {
222216
connection.console.log("Info");
223-
connection.console.log(info);
217+
connection.console.log(JSON.stringify(info));
218+
219+
for (const [uri, context] of Object.entries(info)) {
220+
const document = documents.get(uri);
221+
if (document) {
222+
let oldContext = contextCache.get(uri);
223+
if (!oldContext) {
224+
oldContext = context;
225+
contextCache.set(uri, context);
226+
astCache.delete(uri);
227+
validateTextDocument(document)
228+
}
229+
// Check if context changed
230+
else if (context.chapter !== oldContext.chapter || context.prelude !== oldContext.prelude) {
231+
contextCache.set(uri, context);
232+
astCache.delete(uri);
233+
validateTextDocument(document);
234+
}
235+
}
236+
}
224237

225-
contextCache = new Map(Object.entries(info));
226-
// TODO: We only need to revalidate the documents that have changed
227-
astCache.clear();
228-
documents.all().forEach(validateTextDocument);
229238
return { success: true };
230239
})
231240

232241
// Make the text document manager listen on the connection
233242
documents.listen(connection);
234243

235244
// Listen on the connection
236-
connection.listen();
245+
connection.listen();

server/src/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,5 +105,6 @@ export enum Chapter {
105105
}
106106

107107
export interface Context {
108-
chapter: Chapter
108+
chapter: Chapter,
109+
prelude?: string
109110
}

0 commit comments

Comments
 (0)