forked from redhat-developer/vscode-java
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTracingLanguageClient.ts
More file actions
99 lines (86 loc) · 3.17 KB
/
TracingLanguageClient.ts
File metadata and controls
99 lines (86 loc) · 3.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import { performance } from "perf_hooks";
import { Event, EventEmitter } from "vscode";
import { CancellationToken, LanguageClient, LanguageClientOptions, ProtocolRequestType, ProtocolRequestType0, RequestType, RequestType0, ServerOptions } from "vscode-languageclient/node";
import { TraceEvent } from "./extension.api";
const requestEventEmitter = new EventEmitter<TraceEvent>();
export const onDidRequestEnd: Event<TraceEvent> = requestEventEmitter.event;
export class TracingLanguageClient extends LanguageClient {
private isStarted: boolean = false;
constructor(id: string, name: string, serverOptions: ServerOptions, clientOptions: LanguageClientOptions, forceDebug?: boolean) {
super(id, name, serverOptions, clientOptions, forceDebug);
}
start(): Promise<void> {
const isFirstTimeStart: boolean = !this.isStarted;
this.isStarted = true;
const startAt: number = performance.now();
return super.start().then(value => {
if (isFirstTimeStart) {
this.fireTraceEvent("initialize", startAt);
}
return value;
}, reason => {
if (isFirstTimeStart) {
this.fireTraceEvent("initialize", startAt, reason);
}
throw reason;
});
}
stop(timeout?: number): Promise<void> {
this.isStarted = false;
return super.stop(timeout);
}
sendRequest<R, PR, E, RO>(type: ProtocolRequestType0<R, PR, E, RO>, token?: CancellationToken): Promise<R>;
sendRequest<P, R, PR, E, RO>(type: ProtocolRequestType<P, R, PR, E, RO>, params: P, token?: CancellationToken): Promise<R>;
sendRequest<R, E>(type: RequestType0<R, E>, token?: CancellationToken): Promise<R>;
sendRequest<P, R, E>(type: RequestType<P, R, E>, params: P, token?: CancellationToken): Promise<R>;
sendRequest<R>(method: string, token?: CancellationToken): Promise<R>;
sendRequest<R>(method: string, param: any, token?: CancellationToken): Promise<R>;
sendRequest(method: any, ...args) {
const startAt: number = performance.now();
const requestType: string = this.getRequestType(method, ...args);
return this.sendRequest0(method, ...args).then(value => {
this.fireTraceEvent(requestType, startAt);
return value;
}, reason => {
this.fireTraceEvent(requestType, startAt, reason);
throw reason;
});
}
private sendRequest0(method: any, ...args) {
if (!args || !args.length) {
return super.sendRequest(method);
}
const first = args[0];
const last = args[args.length - 1];
if (CancellationToken.is(last)) {
if (first === last) {
return super.sendRequest(method, last);
} else {
return super.sendRequest(method, first, last);
}
}
return super.sendRequest(method, first);
}
private getRequestType(method: any, ...args): string {
let requestType: string;
if (typeof method === 'string' || method instanceof String) {
requestType = String(method);
} else {
requestType = method?.method;
}
if (requestType === "workspace/executeCommand") {
if (args?.[0]?.command) {
requestType = `workspace/executeCommand/${args[0].command}`;
}
}
return requestType;
}
private fireTraceEvent(type: string, startAt: number, reason?: any): void {
const duration: number = performance.now() - startAt;
requestEventEmitter.fire({
type,
duration,
error: reason,
});
}
}