Skip to content

Commit 41d5002

Browse files
authored
Fixes #1006: Metamodel does not accurately represent registration for semantic tokens (#1009)
1 parent 2e2658c commit 41d5002

6 files changed

Lines changed: 63 additions & 3 deletions

File tree

protocol/metaModel.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@
456456
"kind": "reference",
457457
"name": "SemanticTokensPartialResult"
458458
},
459+
"registrationMethod": "textDocument/semanticTokens",
459460
"registrationOptions": {
460461
"kind": "reference",
461462
"name": "SemanticTokensRegistrationOptions"
@@ -499,6 +500,7 @@
499500
}
500501
]
501502
},
503+
"registrationMethod": "textDocument/semanticTokens",
502504
"registrationOptions": {
503505
"kind": "reference",
504506
"name": "SemanticTokensRegistrationOptions"
@@ -529,6 +531,7 @@
529531
"kind": "reference",
530532
"name": "SemanticTokensPartialResult"
531533
},
534+
"registrationMethod": "textDocument/semanticTokens",
532535
"documentation": "@since 3.16.0",
533536
"since": "3.16.0"
534537
},
@@ -1783,6 +1786,7 @@
17831786
"kind": "reference",
17841787
"name": "DidOpenNotebookDocumentParams"
17851788
},
1789+
"registrationMethod": "notebookDocument/sync",
17861790
"documentation": "A notification sent when a notebook opens.\n\n@since 3.17.0",
17871791
"since": "3.17.0"
17881792
},
@@ -1791,14 +1795,16 @@
17911795
"params": {
17921796
"kind": "reference",
17931797
"name": "DidChangeNotebookDocumentParams"
1794-
}
1798+
},
1799+
"registrationMethod": "notebookDocument/sync"
17951800
},
17961801
{
17971802
"method": "notebookDocument/didSave",
17981803
"params": {
17991804
"kind": "reference",
18001805
"name": "DidSaveNotebookDocumentParams"
18011806
},
1807+
"registrationMethod": "notebookDocument/sync",
18021808
"documentation": "A notification sent when a notebook document is saved.\n\n@since 3.17.0",
18031809
"since": "3.17.0"
18041810
},
@@ -1808,6 +1814,7 @@
18081814
"kind": "reference",
18091815
"name": "DidCloseNotebookDocumentParams"
18101816
},
1817+
"registrationMethod": "notebookDocument/sync",
18111818
"documentation": "A notification sent when a notebook closes.\n\n@since 3.17.0",
18121819
"since": "3.17.0"
18131820
},

protocol/metaModel.schema.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,10 @@
339339
"description": "Whether this is a proposed notification. If omitted the notification is final.",
340340
"type": "boolean"
341341
},
342+
"registrationMethod": {
343+
"description": "Optional a dynamic registration method if it different from the request's method.",
344+
"type": "string"
345+
},
342346
"registrationOptions": {
343347
"$ref": "#/definitions/Type",
344348
"description": "Optional registration options if the notification supports dynamic registration."
@@ -465,6 +469,10 @@
465469
"description": "Whether this is a proposed feature. If omitted the feature is final.",
466470
"type": "boolean"
467471
},
472+
"registrationMethod": {
473+
"description": "Optional a dynamic registration method if it different from the request's method.",
474+
"type": "string"
475+
},
468476
"registrationOptions": {
469477
"$ref": "#/definitions/Type",
470478
"description": "Optional registration options if the request supports dynamic registration."

protocol/src/common/protocol.notebook.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ export type DidOpenNotebookDocumentParams = {
385385
export namespace DidOpenNotebookDocumentNotification {
386386
export const method: 'notebookDocument/didOpen' = 'notebookDocument/didOpen';
387387
export const type = new ProtocolNotificationType<DidOpenNotebookDocumentParams, void>(method);
388+
export const registrationMethod: typeof NotebookDocumentSyncRegistrationType.method = NotebookDocumentSyncRegistrationType.method;
388389
}
389390

390391
/**
@@ -515,6 +516,7 @@ export type DidChangeNotebookDocumentParams = {
515516
export namespace DidChangeNotebookDocumentNotification {
516517
export const method: 'notebookDocument/didChange' = 'notebookDocument/didChange';
517518
export const type = new ProtocolNotificationType<DidChangeNotebookDocumentParams, void>(method);
519+
export const registrationMethod: typeof NotebookDocumentSyncRegistrationType.method = NotebookDocumentSyncRegistrationType.method;
518520
}
519521

520522
/**
@@ -537,6 +539,7 @@ export type DidSaveNotebookDocumentParams = {
537539
export namespace DidSaveNotebookDocumentNotification {
538540
export const method: 'notebookDocument/didSave' = 'notebookDocument/didSave';
539541
export const type = new ProtocolNotificationType<DidSaveNotebookDocumentParams, void>(method);
542+
export const registrationMethod: typeof NotebookDocumentSyncRegistrationType.method = NotebookDocumentSyncRegistrationType.method;
540543
}
541544

542545
/**
@@ -566,4 +569,5 @@ export type DidCloseNotebookDocumentParams = {
566569
export namespace DidCloseNotebookDocumentNotification {
567570
export const method: 'notebookDocument/didClose' = 'notebookDocument/didClose';
568571
export const type = new ProtocolNotificationType<DidCloseNotebookDocumentParams, void>(method);
572+
export const registrationMethod: typeof NotebookDocumentSyncRegistrationType.method = NotebookDocumentSyncRegistrationType.method;
569573
}

protocol/src/common/protocol.semanticTokens.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ export interface SemanticTokensParams extends WorkDoneProgressParams, PartialRes
183183
export namespace SemanticTokensRequest {
184184
export const method: 'textDocument/semanticTokens/full' = 'textDocument/semanticTokens/full';
185185
export const type = new ProtocolRequestType<SemanticTokensParams, SemanticTokens | null, SemanticTokensPartialResult, void, SemanticTokensRegistrationOptions>(method);
186+
export const registrationMethod: typeof SemanticTokensRegistrationType.method = SemanticTokensRegistrationType.method;
186187
export type HandlerSignature = RequestHandler<SemanticTokensDeltaParams, SemanticTokens | null, void>;
187188
}
188189

@@ -210,6 +211,7 @@ export interface SemanticTokensDeltaParams extends WorkDoneProgressParams, Parti
210211
export namespace SemanticTokensDeltaRequest {
211212
export const method: 'textDocument/semanticTokens/full/delta' = 'textDocument/semanticTokens/full/delta';
212213
export const type = new ProtocolRequestType<SemanticTokensDeltaParams, SemanticTokens | SemanticTokensDelta | null, SemanticTokensPartialResult | SemanticTokensDeltaPartialResult, void, SemanticTokensRegistrationOptions>(method);
214+
export const registrationMethod: typeof SemanticTokensRegistrationType.method = SemanticTokensRegistrationType.method;
213215
export type HandlerSignature = RequestHandler<SemanticTokensDeltaParams, SemanticTokens | SemanticTokensDelta | null, void>;
214216
}
215217

@@ -236,6 +238,7 @@ export interface SemanticTokensRangeParams extends WorkDoneProgressParams, Parti
236238
export namespace SemanticTokensRangeRequest {
237239
export const method: 'textDocument/semanticTokens/range' = 'textDocument/semanticTokens/range';
238240
export const type = new ProtocolRequestType<SemanticTokensRangeParams, SemanticTokens | null, SemanticTokensPartialResult, void, void>(method);
241+
export const registrationMethod: typeof SemanticTokensRegistrationType.method = SemanticTokensRegistrationType.method;
239242
export type HandlerSignature = RequestHandler<SemanticTokensRangeParams, SemanticTokens | null, void>;
240243
}
241244

tools/src/metaModel.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,12 @@ export type Request = {
146146
*/
147147
errorData?: Type;
148148

149+
/**
150+
* Optional a dynamic registration method if it
151+
* different from the request's method.
152+
*/
153+
registrationMethod?: string;
154+
149155
/**
150156
* Optional registration options if the request
151157
* supports dynamic registration.
@@ -155,7 +161,7 @@ export type Request = {
155161
/**
156162
* An optional documentation;
157163
*/
158-
documentation?: string;
164+
documentation?: string;
159165

160166
/**
161167
* Since when (release number) this request is
@@ -184,6 +190,12 @@ export type Notification = {
184190
*/
185191
params?: Type | Type[];
186192

193+
/**
194+
* Optional a dynamic registration method if it
195+
* different from the request's method.
196+
*/
197+
registrationMethod?: string;
198+
187199
/**
188200
* Optional registration options if the notification
189201
* supports dynamic registration.
@@ -193,7 +205,7 @@ export type Notification = {
193205
/**
194206
* An optional documentation;
195207
*/
196-
documentation?: string;
208+
documentation?: string;
197209

198210
/**
199211
* Since when (release number) this notification is

tools/src/visitor.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ export default class Visitor {
321321
result.params = requestTypes.param !== undefined ? asJsonType(requestTypes.param) : undefined;
322322
result.partialResult = asJsonType(requestTypes.partialResult);
323323
result.errorData = asJsonType(requestTypes.errorData);
324+
result.registrationMethod = this.getRegistrationMethodName(symbol);
324325
result.registrationOptions = asJsonType(requestTypes.registrationOptions);
325326
this.fillDocProperties(node, result);
326327
return result;
@@ -353,6 +354,7 @@ export default class Visitor {
353354
};
354355
const result: JsonNotification = { method: methodName };
355356
result.params = notificationTypes.param !== undefined ? asJsonType(notificationTypes.param) : undefined;
357+
result.registrationMethod = this.getRegistrationMethodName(symbol);
356358
result.registrationOptions = asJsonType(notificationTypes.registrationOptions);
357359
this.fillDocProperties(node, result);
358360
return result;
@@ -456,6 +458,30 @@ export default class Visitor {
456458
return this.removeQuotes(text);
457459
}
458460

461+
private getRegistrationMethodName(namespace: ts.Symbol): string | undefined {
462+
const registrationMethod = namespace.exports?.get('registrationMethod' as ts.__String);
463+
if (registrationMethod === undefined) {
464+
return undefined;
465+
}
466+
const declaration = this.getFirstDeclaration(registrationMethod);
467+
if (declaration === undefined || !ts.isVariableDeclaration(declaration) || declaration.initializer === undefined || !ts.isPropertyAccessExpression(declaration.initializer)) {
468+
return undefined;
469+
}
470+
const initializerSymbol = this.typeChecker.getSymbolAtLocation(declaration.initializer.name);
471+
if (initializerSymbol === undefined || initializerSymbol.valueDeclaration === undefined) {
472+
return undefined;
473+
}
474+
const valueDeclaration = initializerSymbol.valueDeclaration;
475+
if (!ts.isVariableDeclaration(valueDeclaration)) {
476+
return undefined;
477+
}
478+
if (valueDeclaration.initializer === undefined || (!ts.isStringLiteral(valueDeclaration.initializer) && !ts.isNoSubstitutionTemplateLiteral(valueDeclaration.initializer))) {
479+
return undefined;
480+
}
481+
482+
return this.removeQuotes(valueDeclaration.initializer.getText());
483+
}
484+
459485
private getRequestTypes(symbol: ts.Symbol): RequestTypes | undefined {
460486
const declaration = this.getFirstDeclaration(symbol);
461487
if (declaration === undefined) {

0 commit comments

Comments
 (0)