Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/api/node/extHostConsoleForwarder.ts
5221 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { AbstractExtHostConsoleForwarder } from '../common/extHostConsoleForwarder.js';
7
import { IExtHostInitDataService } from '../common/extHostInitDataService.js';
8
import { IExtHostRpcService } from '../common/extHostRpcService.js';
9
import { NativeLogMarkers } from '../../services/extensions/common/extensionHostProtocol.js';
10
11
const MAX_STREAM_BUFFER_LENGTH = 1024 * 1024;
12
13
export class ExtHostConsoleForwarder extends AbstractExtHostConsoleForwarder {
14
15
private _isMakingConsoleCall: boolean = false;
16
17
constructor(
18
@IExtHostRpcService extHostRpc: IExtHostRpcService,
19
@IExtHostInitDataService initData: IExtHostInitDataService,
20
) {
21
super(extHostRpc, initData);
22
23
this._wrapStream('stderr', 'error');
24
this._wrapStream('stdout', 'log');
25
}
26
27
protected override _nativeConsoleLogMessage(method: 'log' | 'info' | 'warn' | 'error' | 'debug', original: (...args: any[]) => void, args: IArguments) {
28
const stream = method === 'error' || method === 'warn' ? process.stderr : process.stdout;
29
this._isMakingConsoleCall = true;
30
stream.write(`\n${NativeLogMarkers.Start}\n`);
31
// eslint-disable-next-line local/code-no-any-casts
32
original.apply(console, args as any);
33
stream.write(`\n${NativeLogMarkers.End}\n`);
34
this._isMakingConsoleCall = false;
35
}
36
37
/**
38
* Wraps process.stderr/stdout.write() so that it is transmitted to the
39
* renderer or CLI. It both calls through to the original method as well
40
* as to console.log with complete lines so that they're made available
41
* to the debugger/CLI.
42
*/
43
private _wrapStream(streamName: 'stdout' | 'stderr', severity: 'log' | 'warn' | 'error') {
44
const stream = process[streamName];
45
const original = stream.write;
46
47
let buf = '';
48
49
Object.defineProperty(stream, 'write', {
50
set: () => { },
51
get: () => (chunk: Uint8Array | string, encoding?: BufferEncoding, callback?: (err?: Error | null) => void) => {
52
if (!this._isMakingConsoleCall) {
53
// eslint-disable-next-line local/code-no-any-casts
54
buf += (chunk as any).toString(encoding);
55
const eol = buf.length > MAX_STREAM_BUFFER_LENGTH ? buf.length : buf.lastIndexOf('\n');
56
if (eol !== -1) {
57
console[severity](buf.slice(0, eol));
58
buf = buf.slice(eol + 1);
59
}
60
}
61
62
original.call(stream, chunk, encoding, callback);
63
},
64
});
65
}
66
}
67
68