Skip to content

Commit 214d1fe

Browse files
committed
vscode-dotty: typesafe messages
This replaces the use of strings for identifying messages by types (WorksheetExecRequest and WorksheetPublishOutputNotification). Also contains some light cleanup/uniformization
1 parent f693e04 commit 214d1fe

File tree

7 files changed

+72
-46
lines changed

7 files changed

+72
-46
lines changed

language-server/src/dotty/tools/languageserver/worksheet/WorksheetClient.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import org.eclipse.lsp4j.services.LanguageClient
44
import org.eclipse.lsp4j.jsonrpc.services.JsonNotification
55

66
/**
7-
* A `LanguageClient` that supports the `worksheet/publishOutput` notification.
8-
*
9-
* @see dotty.tools.languageserver.worksheet.WorksheetExecOutput
7+
* A `LanguageClient` that supports worksheet-specific notifications.
108
*/
119
trait WorksheetClient extends LanguageClient {
10+
/**
11+
* A notification that tells the client that a line of a worksheet produced
12+
* the specified output.
13+
*/
1214
@JsonNotification("worksheet/publishOutput")
1315
def publishOutput(output: WorksheetExecOutput): Unit
1416
}

language-server/src/dotty/tools/languageserver/worksheet/WorksheetMessages.scala

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,21 @@ package dotty.tools.languageserver.worksheet
22

33
import org.eclipse.lsp4j.VersionedTextDocumentIdentifier
44

5+
// All case classes in this file should have zero-parameters secondary
6+
// constructors to allow Gson to reflectively create instances on
7+
// deserialization without relying on sun.misc.Unsafe.
8+
59
/** The parameter for the `worksheet/exec` request. */
610
case class WorksheetExecParams(textDocument: VersionedTextDocumentIdentifier) {
7-
// Used for deserialization
8-
// see https://github.com/lampepfl/dotty/pull/5102#discussion_r222055355
911
def this() = this(null)
1012
}
1113

1214
/** The response to a `worksheet/exec` request. */
13-
case class WorksheetExecResponse(success: Boolean) {
14-
// Used for deserialization
15-
// see https://github.com/lampepfl/dotty/pull/5102#discussion_r222055355
15+
case class WorksheetExecResult(success: Boolean) {
1616
def this() = this(false)
1717
}
1818

19-
/**
20-
* A notification that tells the client that a line of a worksheet
21-
* produced the specified output.
22-
*/
19+
/** The parameters to the `worksheet/publishOutput` notification. */
2320
case class WorksheetExecOutput(textDocument: VersionedTextDocumentIdentifier, line: Int, content: String) {
24-
// Used for deserialization
25-
// see https://github.com/lampepfl/dotty/pull/5102#discussion_r222055355
2621
def this() = this(null, 0, null)
2722
}

language-server/src/dotty/tools/languageserver/worksheet/WorksheetService.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@ trait WorksheetService { thisServer: DottyLanguageServer =>
1616
val worksheets: ConcurrentHashMap[URI, CompletableFuture[_]] = new ConcurrentHashMap()
1717

1818
@JsonRequest
19-
def exec(params: WorksheetExecParams): CompletableFuture[WorksheetExecResponse] = thisServer.synchronized {
19+
def exec(params: WorksheetExecParams): CompletableFuture[WorksheetExecResult] = thisServer.synchronized {
2020
val uri = new URI(params.textDocument.getUri)
2121
val future =
2222
computeAsync { cancelChecker =>
2323
try {
2424
val driver = driverFor(uri)
2525
val sendMessage = (line: Int, msg: String) => client.publishOutput(WorksheetExecOutput(params.textDocument, line, msg))
2626
evaluateWorksheet(driver, uri, sendMessage, cancelChecker)(driver.currentCtx)
27-
WorksheetExecResponse(success = true)
27+
WorksheetExecResult(success = true)
2828
} catch {
2929
case _: Throwable =>
30-
WorksheetExecResponse(success = false)
30+
WorksheetExecResult(success = false)
3131
} finally {
3232
worksheets.remove(uri)
3333
}

language-server/test/dotty/tools/languageserver/util/actions/WorksheetAction.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package dotty.tools.languageserver.util.actions
22

3-
import dotty.tools.languageserver.worksheet.{WorksheetExecOutput, WorksheetExecParams, WorksheetExecResponse}
3+
import dotty.tools.languageserver.worksheet.{WorksheetExecOutput, WorksheetExecParams, WorksheetExecResult}
44
import dotty.tools.languageserver.util.embedded.CodeMarker
55

66
import java.net.URI
@@ -11,7 +11,7 @@ import org.eclipse.lsp4j.VersionedTextDocumentIdentifier
1111
abstract class WorksheetAction extends Action {
1212

1313
/** Triggers the evaluation of the worksheet. */
14-
def triggerEvaluation(marker: CodeMarker): Exec[CompletableFuture[WorksheetExecResponse]] = {
14+
def triggerEvaluation(marker: CodeMarker): Exec[CompletableFuture[WorksheetExecResult]] = {
1515
server.exec(WorksheetExecParams(marker.toVersionedTextDocumentIdentifier))
1616
}
1717

vscode-dotty/src/extension.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ import * as vscode from 'vscode';
1111
import { LanguageClient, LanguageClientOptions, RevealOutputChannelOn,
1212
ServerOptions } from 'vscode-languageclient';
1313
import { enableOldServerWorkaround } from './compat'
14-
14+
import { WorksheetPublishOutputNotification } from './protocol'
1515
import * as worksheet from './worksheet'
1616

17+
1718
let extensionContext: ExtensionContext
1819
let outputChannel: vscode.OutputChannel
1920
export let client: LanguageClient
@@ -206,7 +207,7 @@ function run(serverOptions: ServerOptions, isOldServer: boolean) {
206207
enableOldServerWorkaround(client)
207208

208209
client.onReady().then(() => {
209-
client.onNotification("worksheet/publishOutput", (params) => {
210+
client.onNotification(WorksheetPublishOutputNotification.type, params => {
210211
worksheet.handleMessage(params)
211212
})
212213
})

vscode-dotty/src/protocol.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import * as vscode from 'vscode'
2+
import { RequestType, NotificationType } from 'vscode-jsonrpc'
3+
import { VersionedTextDocumentIdentifier } from 'vscode-languageserver-protocol'
4+
5+
import { client } from './extension'
6+
7+
/** The parameters for the `worksheet/exec` request. */
8+
export interface WorksheetExecParams {
9+
textDocument: VersionedTextDocumentIdentifier
10+
}
11+
12+
/** The result of the `worksheet/exec` request. */
13+
export interface WorksheetExecResult {
14+
success: boolean
15+
}
16+
17+
/** The parameters for the `worksheet/publishOutput` notification. */
18+
export interface WorksheetPublishOutputParams {
19+
textDocument: VersionedTextDocumentIdentifier
20+
line: number
21+
content: string
22+
}
23+
24+
// TODO: Can be removed once https://github.com/Microsoft/vscode-languageserver-node/pull/421
25+
// is merged.
26+
export function asVersionedTextDocumentIdentifier(textDocument: vscode.TextDocument): VersionedTextDocumentIdentifier {
27+
return {
28+
uri: client.code2ProtocolConverter.asUri(textDocument.uri),
29+
version: textDocument.version
30+
}
31+
}
32+
33+
export function asWorksheetExecParams(textDocument: vscode.TextDocument): WorksheetExecParams {
34+
return {
35+
textDocument: asVersionedTextDocumentIdentifier(textDocument)
36+
}
37+
}
38+
39+
/** The `worksheet/exec` request */
40+
export namespace WorksheetExecRequest {
41+
export const type = new RequestType<WorksheetExecParams, WorksheetExecResult, void, void>("worksheet/exec")
42+
}
43+
44+
/** The `worksheet/publishOutput` notification */
45+
export namespace WorksheetPublishOutputNotification {
46+
export const type = new NotificationType<WorksheetPublishOutputParams, void>("worksheet/publishOutput")
47+
}

vscode-dotty/src/worksheet.ts

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import * as vscode from 'vscode'
2+
23
import { client } from './extension'
3-
import { VersionedTextDocumentIdentifier } from 'vscode-languageserver-protocol'
4+
import {
5+
asWorksheetExecParams, WorksheetExecRequest, WorksheetExecParams, WorksheetPublishOutputParams
6+
} from './protocol'
47

58
/** A worksheet managed by vscode */
69
class Worksheet {
@@ -61,28 +64,6 @@ class Worksheet {
6164
}
6265
}
6366

64-
/** The parameter for the `worksheet/exec` request. */
65-
class WorksheetExecParams {
66-
constructor(textDocument: vscode.TextDocument) {
67-
this.textDocument = VersionedTextDocumentIdentifier.create(textDocument.uri.toString(), textDocument.version)
68-
}
69-
70-
readonly textDocument: VersionedTextDocumentIdentifier
71-
}
72-
73-
/** The parameter for the `worksheet/publishOutput` notification. */
74-
class WorksheetOutput {
75-
constructor(textDocument: VersionedTextDocumentIdentifier, line: number, content: string) {
76-
this.textDocument = textDocument
77-
this.line = line
78-
this.content = content
79-
}
80-
81-
readonly textDocument: VersionedTextDocumentIdentifier
82-
readonly line: number
83-
readonly content: string
84-
}
85-
8667
/**
8768
* The command key for evaluating a worksheet. Exposed to users as
8869
* `Run worksheet`.
@@ -139,7 +120,7 @@ export function evaluateWorksheet(document: vscode.TextDocument): Thenable<{}> {
139120
title: "Evaluating worksheet",
140121
cancellable: true
141122
}, (_, token) => {
142-
return client.sendRequest("worksheet/exec", new WorksheetExecParams(worksheet.document), token)
123+
return client.sendRequest(WorksheetExecRequest.type, asWorksheetExecParams(document), token)
143124
})
144125
} else {
145126
return Promise.reject()
@@ -173,7 +154,7 @@ function _prepareWorksheet(worksheet: Worksheet) {
173154
*
174155
* @param message The result of evaluating part of a worksheet.
175156
*/
176-
export function handleMessage(output: WorksheetOutput) {
157+
export function handleMessage(output: WorksheetPublishOutputParams) {
177158

178159
const editor = vscode.window.visibleTextEditors.find(e => {
179160
let uri = e.document.uri.toString()

0 commit comments

Comments
 (0)