Skip to content

Commit 803843c

Browse files
author
Aleksander Boruch-Gruszecki
committed
Adjust after review
1 parent 7320339 commit 803843c

File tree

3 files changed

+48
-44
lines changed

3 files changed

+48
-44
lines changed

vscode-dotty/package.json

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,25 @@
4949
"default": true,
5050
"description": "If true, saving a worksheet will also run it."
5151
},
52-
"dotty.tracing.machineId": {
52+
"dotty.trace.remoteWorkspaceDumpUrl": {
53+
"type": "string",
54+
"default": "",
55+
"description": "Url to send local workspace dump to."
56+
},
57+
"dotty.trace.remoteTracingUrl": {
58+
"type": "string",
59+
"default": "",
60+
"description": "Url to send local LSP communication to."
61+
},
62+
"dotty.trace.machineId": {
5363
"type": [
5464
"string",
5565
"null"
5666
],
5767
"default": null,
5868
"description": "ID of your machine used when Dotty Language Server tracing is turned on."
5969
},
60-
"dotty.tracing.maximumMessageSize": {
70+
"dotty.trace.maximumMessageSize": {
6171
"type": "number",
6272
"default": 512,
6373
"description": "Maximum size for the messages sent to remote server. Larger ones will be split."

vscode-dotty/src/extension.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,7 @@ function bootstrapSbtProject(buildSbtFileSource: string,
305305
}
306306

307307
function run(serverOptions: ServerOptions, isOldServer: boolean) {
308-
309-
const { lspOutputChannel } = tracer.run()
308+
const lspOutputChannel = tracer.run()
310309

311310
const clientOptions: LanguageClientOptions = {
312311
documentSelector: [

vscode-dotty/src/tracer.ts

Lines changed: 35 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ export class Tracer {
3939

4040
this.tracingConsent = new TracingConsentCache(ctx.extensionContext.workspaceState)
4141

42-
this.remoteWorkspaceDumpUrl = this.ctx.extensionConfig.get<string>('remoteWorkspaceDumpUrl')
43-
this.remoteTracingUrl = this.ctx.extensionConfig.get<string>('remoteTracingUrl')
44-
const maximumMessageSize = this.ctx.extensionConfig.get<number>('tracing.maximumMessageSize')
42+
this.remoteWorkspaceDumpUrl = this.ctx.extensionConfig.get<string>('trace.remoteWorkspaceDumpUrl')
43+
this.remoteTracingUrl = this.ctx.extensionConfig.get<string>('trace.remoteTracingUrl')
44+
const maximumMessageSize = this.ctx.extensionConfig.get<number>('trace.maximumMessageSize')
4545
this.maximumMessageSize = maximumMessageSize === undefined || maximumMessageSize < 0 ? 0 : maximumMessageSize | 0
4646

4747
this.machineId = (() => {
@@ -73,16 +73,17 @@ export class Tracer {
7373
this.sessionId = new Date().toISOString()
7474
}
7575

76-
run(): { lspOutputChannel?: vscode.OutputChannel } {
76+
run(): vscode.OutputChannel | undefined {
7777
const consentCommandDisposable = vscode.commands.registerCommand(consentCommandName, () => this.askForTracingConsent())
7878
if (this.isTracingEnabled && this.tracingConsent.get() === 'no-answer') this.askForTracingConsent()
7979
this.initializeAsyncWorkspaceDump()
80+
8081
const lspOutputChannel = this.createLspOutputChannel()
8182
const statusBarItem = this.createStatusBarItem()
8283
for (const disposable of [consentCommandDisposable, lspOutputChannel, statusBarItem]) {
8384
if (disposable) this.ctx.extensionContext.subscriptions.push(disposable)
8485
}
85-
return { lspOutputChannel }
86+
return lspOutputChannel
8687
}
8788

8889
private askForTracingConsent(): void {
@@ -97,13 +98,12 @@ export class Tracer {
9798
}
9899

99100
private initializeAsyncWorkspaceDump() {
100-
if (this.remoteWorkspaceDumpUrl === undefined) return
101-
// convince TS that this is a string
102-
const definedUrl: string = this.remoteWorkspaceDumpUrl
101+
const url = this.remoteWorkspaceDumpUrl
102+
if (url === undefined) return
103103

104104
const doInitialize = () => {
105105
try {
106-
this.asyncUploadWorkspaceDump(definedUrl)
106+
this.asyncUploadWorkspaceDump(url)
107107
} catch (err) {
108108
this.logError('error during workspace dump', safeError(err))
109109
}
@@ -144,14 +144,20 @@ export class Tracer {
144144
}
145145

146146
private createLspOutputChannel(): vscode.OutputChannel | undefined {
147-
if (!this.remoteTracingUrl) return undefined
147+
if (this.ctx.extensionConfig.get('trace.server') === undefined) {
148+
if (this.remoteTracingUrl) this.ctx.extensionOut.appendLine(
149+
'error: tracing URL is set, but trace.server not - no remote tracing possible.'
150+
)
151+
return undefined
152+
}
148153

149-
const localLspOutputChannel = vscode.window.createOutputChannel('Dotty LSP Communication')
154+
const lspOutputChannel = vscode.window.createOutputChannel('Dotty LSP Communication')
155+
if (!this.remoteTracingUrl) return lspOutputChannel
150156
try {
151-
return this.createRemoteLspOutputChannel(this.remoteTracingUrl, localLspOutputChannel)
157+
return this.createRemoteLspOutputChannel(this.remoteTracingUrl, lspOutputChannel)
152158
} catch (err) {
153159
this.logError('error during remote output channel creation', safeError(err))
154-
return localLspOutputChannel
160+
return lspOutputChannel
155161
}
156162
}
157163

@@ -225,7 +231,7 @@ export class Tracer {
225231
)
226232

227233
socket.onerror = (event) => {
228-
this.logErrorWithoutNotifying(
234+
this.logError(
229235
'socket error',
230236
remoteTracingUrl,
231237
new SafeJsonifier(event, (event) => ({
@@ -238,7 +244,7 @@ export class Tracer {
238244
}
239245

240246
socket.onclose = (event) => {
241-
this.logErrorWithoutNotifying(
247+
this.logError(
242248
'socket closed',
243249
remoteTracingUrl,
244250
new SafeJsonifier(event, (event) => ({
@@ -319,11 +325,12 @@ export class Tracer {
319325
}
320326
}
321327

322-
private silenceErrors: boolean = false
323-
private logErrorWithoutNotifying(message: string, ...rest: any[]) {
328+
private logError(message: string, ...rest: any[]) {
324329
const msg = `[Dotty LSP Tracer] ${message}`
325-
// unwrap SafeJsonifier, for some reason Electron logs the result
326-
// of .toJSON, unlike browsers
330+
// in a browser, we'd be able to log a SafeJsonifier directly
331+
// and get an inspectable object in the console
332+
// unfortunately, Electron apparently uses .toJson if available,
333+
// so we need to manually unwrap SafeJsonifiers
327334
console.error(msg, ...rest.map((a) => a instanceof SafeJsonifier ? a.value : a))
328335
function cautiousStringify(a: any): string {
329336
try {
@@ -335,34 +342,22 @@ export class Tracer {
335342
}
336343
this.ctx.extensionOut.appendLine([msg].concat(rest.map(cautiousStringify)).join(' '))
337344
}
338-
private logError(message: string, ...rest: any[]) {
339-
this.logErrorWithoutNotifying(message, ...rest)
340-
if (!this.silenceErrors) {
341-
vscode.window.showErrorMessage(
342-
'An error occured which prevents sending usage data to EPFL. ' +
343-
'Please copy the text from "Dotty Language Client" output (View > Output) and send it to your TA.',
344-
'Silence further errors'
345-
).then((result) => {
346-
if (result !== undefined) {
347-
this.silenceErrors = true
348-
}
349-
})
350-
}
351-
}
352345
}
353346

354347
function safeError(e: Error): SafeJsonifier<Error> {
355348
return new SafeJsonifier(e, (e) => e.toString())
356349
}
357350

351+
/**
352+
* Wraps a value of type T so it's possible to safely pass it to JSON.stringify.
353+
*
354+
* Values with circular references (errors, for example) cause JSON.stringify to throw an exception
355+
*/
358356
class SafeJsonifier<T> {
359-
value: T
360-
valueToObject: (t: T) => {}
361-
362-
constructor(value: T, valueToObject: (t: T) => {}) {
363-
this.value = value
364-
this.valueToObject = valueToObject
365-
}
357+
constructor(
358+
readonly value: T,
359+
readonly valueToObject: (t: T) => {}
360+
) {}
366361

367362
toJSON() {
368363
return this.valueToObject(this.value)

0 commit comments

Comments
 (0)