Skip to content

Commit e97e1ec

Browse files
committed
Create decorator that logs execution time of the method
1 parent 872987b commit e97e1ec

9 files changed

+96
-145
lines changed

.vscode/settings.json

+6-3
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@
1212
"**/CVS": true,
1313
"**/.DS_Store": true,
1414
"**/Thumbs.db": true,
15-
"out": false,
16-
"**/*_cp_aux.v": true
15+
"out": false
1716
},
1817
"search.exclude": {
1918
"out": true // set this to false to include "out" folder in search results
2019
},
2120
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
22-
"typescript.tsc.autoDetect": "off"
21+
"typescript.tsc.autoDetect": "off",
22+
"coq-lsp.check_only_on_request": false,
23+
"eslint.options": {
24+
"experimentalDecorators": true
25+
}
2326
}

set_gitignore.sh

-33
This file was deleted.

src/coqLsp/coqLspBuilders.ts

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
import { OutputChannel, window } from "vscode";
22

3+
import { EventLogger } from "../logging/eventLogger";
4+
35
import { CoqLspClient, CoqLspClientInterface } from "./coqLspClient";
46
import { CoqLspClientConfig, CoqLspConfig } from "./coqLspConfig";
57

68
export async function createCoqLspClient(
79
coqLspServerPath: string,
8-
logOutputChannel?: OutputChannel
10+
logOutputChannel?: OutputChannel,
11+
eventLogger?: EventLogger
912
): Promise<CoqLspClientInterface> {
1013
return createAbstractCoqLspClient(
1114
CoqLspConfig.createClientConfig(coqLspServerPath),
12-
logOutputChannel
15+
logOutputChannel,
16+
eventLogger
1317
);
1418
}
1519

@@ -28,12 +32,14 @@ async function createAbstractCoqLspClient(
2832
coqLspClientConfig: CoqLspClientConfig,
2933
logOutputChannel: OutputChannel = window.createOutputChannel(
3034
"CoqPilot: coq-lsp events"
31-
)
35+
),
36+
eventLogger?: EventLogger
3237
): Promise<CoqLspClientInterface> {
3338
const coqLspServerConfig = CoqLspConfig.createServerConfig();
3439
return await CoqLspClient.create(
3540
coqLspServerConfig,
3641
coqLspClientConfig,
37-
logOutputChannel
42+
logOutputChannel,
43+
eventLogger
3844
);
3945
}

src/coqLsp/coqLspClient.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
VersionedTextDocumentIdentifier,
2020
} from "vscode-languageclient";
2121

22+
import { EventLogger } from "../logging/eventLogger";
2223
import { Uri } from "../utils/uri";
2324

2425
import { CoqLspClientConfig, CoqLspServerConfig } from "./coqLspConfig";
@@ -33,6 +34,7 @@ import {
3334
GoalRequest,
3435
PpString,
3536
} from "./coqLspTypes";
37+
import { logExecutionTime } from "../logging/timeMeasureDecorator";
3638

3739
export interface CoqLspClientInterface extends Disposable {
3840
getGoalsAtPoint(
@@ -66,14 +68,18 @@ export class CoqLspClient implements CoqLspClientInterface {
6668
private subscriptions: Disposable[] = [];
6769
private mutex = new Mutex();
6870

69-
private constructor(coqLspConnector: CoqLspConnector) {
71+
private constructor(
72+
coqLspConnector: CoqLspConnector,
73+
public readonly eventLogger?: EventLogger
74+
) {
7075
this.client = coqLspConnector;
7176
}
7277

7378
static async create(
7479
serverConfig: CoqLspServerConfig,
7580
clientConfig: CoqLspClientConfig,
76-
logOutputChannel: OutputChannel
81+
logOutputChannel: OutputChannel,
82+
eventLogger?: EventLogger
7783
): Promise<CoqLspClient> {
7884
const connector = new CoqLspConnector(
7985
serverConfig,
@@ -86,9 +92,10 @@ export class CoqLspClient implements CoqLspClientInterface {
8692
clientConfig.coq_lsp_server_path
8793
);
8894
});
89-
return new CoqLspClient(connector);
95+
return new CoqLspClient(connector, eventLogger);
9096
}
9197

98+
@logExecutionTime
9299
async getGoalsAtPoint(
93100
position: Position,
94101
documentUri: Uri,
@@ -120,6 +127,7 @@ export class CoqLspClient implements CoqLspClientInterface {
120127
});
121128
}
122129

130+
@logExecutionTime
123131
async getFlecheDocument(uri: Uri): Promise<FlecheDocument> {
124132
return await this.mutex.runExclusive(async () => {
125133
return this.getFlecheDocumentUnsafe(uri);

src/extension/coqPilot.ts

-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
workspace,
88
} from "vscode";
99

10-
// import { createCoqLspClient } from "../coqLsp/coqLspBuilders";
1110
import { CoqLspStartupError } from "../coqLsp/coqLspTypes";
1211

1312
import {
@@ -37,7 +36,6 @@ import {
3736
highlightTextInEditor,
3837
insertCompletion,
3938
} from "./documentEditor";
40-
import { suggestAddingAuxFilesToGitignore } from "./editGitignoreCommand";
4139
import {
4240
EditorMessages,
4341
showMessageToUser,
@@ -51,7 +49,6 @@ import {
5149
toVSCodeRange,
5250
} from "./positionRangeUtils";
5351
import { SettingsValidationError } from "./settingsValidationError";
54-
import { cleanAuxFiles, hideAuxFiles } from "./tmpFilesCleanup";
5552

5653
export const pluginId = "coqpilot";
5754
export const pluginName = "CoqPilot";
@@ -64,9 +61,6 @@ export class CoqPilot {
6461
vscodeExtensionContext: ExtensionContext,
6562
globalExtensionState: GlobalExtensionState
6663
) {
67-
hideAuxFiles();
68-
suggestAddingAuxFilesToGitignore();
69-
7064
this.vscodeExtensionContext = vscodeExtensionContext;
7165
this.globalExtensionState = globalExtensionState;
7266

@@ -332,7 +326,6 @@ export class CoqPilot {
332326
}
333327

334328
dispose(): void {
335-
cleanAuxFiles();
336329
this.globalExtensionState.dispose();
337330
}
338331
}

src/extension/editGitignoreCommand.ts

-52
This file was deleted.

src/extension/globalExtensionState.ts

+10-4
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,34 @@ import { pluginId } from "./coqPilot";
2424
import VSCodeLogWriter from "./vscodeLogWriter";
2525

2626
export class GlobalExtensionState {
27-
public readonly eventLogger: EventLogger = new EventLogger();
2827
public readonly logWriter: VSCodeLogWriter = new VSCodeLogWriter(
2928
this.eventLogger,
3029
this.parseLoggingVerbosity(workspace.getConfiguration(pluginId))
3130
);
3231

3332
private constructor(
3433
public readonly coqLspClient: CoqLspClientInterface,
35-
public readonly logOutputChannel: OutputChannel
34+
public readonly logOutputChannel: OutputChannel,
35+
public readonly eventLogger: EventLogger
3636
) {}
3737

3838
static async create(): Promise<GlobalExtensionState> {
3939
const coqLspServerPath = parseCoqLspServerPath();
4040
const logOutputChannel = window.createOutputChannel(
4141
"CoqPilot: coq-lsp events"
4242
);
43+
const eventLogger = new EventLogger();
4344
const coqLspClient = await createCoqLspClient(
4445
coqLspServerPath,
45-
logOutputChannel
46+
logOutputChannel,
47+
eventLogger
4648
);
4749

48-
return new GlobalExtensionState(coqLspClient, logOutputChannel);
50+
return new GlobalExtensionState(
51+
coqLspClient,
52+
logOutputChannel,
53+
eventLogger
54+
);
4955
}
5056

5157
public readonly llmServicesLogsDir = path.join(

src/extension/tmpFilesCleanup.ts

-39
This file was deleted.

src/logging/timeMeasureDecorator.ts

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { Severity } from "./eventLogger";
2+
3+
4+
/**
5+
* A decorator that logs the execution time of a method.
6+
* Execution time is logged in milliseconds with severity
7+
* `DEBUG` in the event logger. If the class does not have
8+
* an event logger, the execution time is logged to the console.
9+
*
10+
* (Note: typescript supports decorators only for class methods).
11+
*/
12+
export function logExecutionTime(
13+
_target: any,
14+
propertyKey: string,
15+
descriptor: PropertyDescriptor
16+
) {
17+
const originalMethod = descriptor.value;
18+
19+
descriptor.value = function (this: any, ...args: any[]) {
20+
const start = performance.now();
21+
22+
const result = originalMethod.apply(this, args);
23+
24+
const logTime = (duration: number) => {
25+
if (this.eventLogger) {
26+
this.eventLogger.log(
27+
"function-execution-time",
28+
`${propertyKey} took ${duration.toFixed(2)}ms to execute`,
29+
undefined,
30+
Severity.DEBUG
31+
);
32+
} else {
33+
console.log(
34+
`${propertyKey} took ${duration.toFixed(2)}ms to execute`
35+
);
36+
}
37+
};
38+
39+
if (result && typeof result.then === "function") {
40+
return result
41+
.then((res: any) => {
42+
const duration = performance.now() - start;
43+
logTime(duration);
44+
return res;
45+
})
46+
.catch((err: any) => {
47+
const duration = performance.now() - start;
48+
logTime(duration);
49+
throw err;
50+
});
51+
} else {
52+
const duration = performance.now() - start;
53+
logTime(duration);
54+
return result;
55+
}
56+
};
57+
58+
return descriptor;
59+
}

0 commit comments

Comments
 (0)