roku-debug 0.22.5 → 0.22.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/CompileErrorProcessor.d.ts +6 -0
- package/dist/CompileErrorProcessor.js +41 -0
- package/dist/CompileErrorProcessor.js.map +1 -1
- package/dist/LaunchConfiguration.d.ts +23 -0
- package/dist/PerfettoManager.d.ts +108 -0
- package/dist/PerfettoManager.js +394 -0
- package/dist/PerfettoManager.js.map +1 -0
- package/dist/RendezvousTracker.d.ts +1 -1
- package/dist/RokuECP.d.ts +27 -2
- package/dist/RokuECP.js +33 -0
- package/dist/RokuECP.js.map +1 -1
- package/dist/SceneGraphDebugCommandController.js.map +1 -1
- package/dist/adapters/DebugProtocolAdapter.d.ts +1 -0
- package/dist/adapters/DebugProtocolAdapter.js +5 -0
- package/dist/adapters/DebugProtocolAdapter.js.map +1 -1
- package/dist/adapters/TelnetAdapter.d.ts +1 -0
- package/dist/adapters/TelnetAdapter.js +3 -0
- package/dist/adapters/TelnetAdapter.js.map +1 -1
- package/dist/adapters/customVariables/ifDateTime.js +1 -9
- package/dist/adapters/customVariables/ifDateTime.js.map +1 -1
- package/dist/bsc/threading/ThreadMessageHandler.d.ts +2 -2
- package/dist/debugProtocol/PluginInterface.d.ts +1 -1
- package/dist/debugProtocol/client/DebugProtocolClientPlugin.d.ts +2 -2
- package/dist/debugProtocol/events/ProtocolEvent.d.ts +3 -3
- package/dist/debugProtocol/server/DebugProtocolServerPlugin.d.ts +2 -2
- package/dist/debugSession/BrightScriptDebugSession.d.ts +26 -1
- package/dist/debugSession/BrightScriptDebugSession.js +187 -18
- package/dist/debugSession/BrightScriptDebugSession.js.map +1 -1
- package/dist/debugSession/Events.d.ts +53 -2
- package/dist/debugSession/Events.js +57 -1
- package/dist/debugSession/Events.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +4 -4
- package/dist/logging.d.ts +1 -1
- package/dist/managers/BreakpointManager.d.ts +2 -2
- package/dist/managers/ProjectManager.js +1 -1
- package/dist/managers/ProjectManager.js.map +1 -1
- package/dist/util.d.ts +6 -0
- package/dist/util.js +15 -2
- package/dist/util.js.map +1 -1
- package/package.json +7 -4
|
@@ -4,6 +4,7 @@ exports.BrightScriptDebugSession = void 0;
|
|
|
4
4
|
const fsExtra = require("fs-extra");
|
|
5
5
|
const natural_orderby_1 = require("natural-orderby");
|
|
6
6
|
const path = require("path");
|
|
7
|
+
const semver = require("semver");
|
|
7
8
|
const roku_deploy_1 = require("roku-deploy");
|
|
8
9
|
const debugadapter_1 = require("@vscode/debugadapter");
|
|
9
10
|
const SceneGraphDebugCommandController_1 = require("../SceneGraphDebugCommandController");
|
|
@@ -19,6 +20,7 @@ const FileManager_1 = require("../managers/FileManager");
|
|
|
19
20
|
const SourceMapManager_1 = require("../managers/SourceMapManager");
|
|
20
21
|
const LocationManager_1 = require("../managers/LocationManager");
|
|
21
22
|
const BreakpointManager_1 = require("../managers/BreakpointManager");
|
|
23
|
+
const PerfettoManager_1 = require("../PerfettoManager");
|
|
22
24
|
const logging_1 = require("../logging");
|
|
23
25
|
const VariablesResponse_1 = require("../debugProtocol/events/responses/VariablesResponse");
|
|
24
26
|
const brighterscript_1 = require("brighterscript");
|
|
@@ -106,6 +108,14 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
106
108
|
get enableDebugProtocol() {
|
|
107
109
|
return this.launchConfiguration.enableDebugProtocol;
|
|
108
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Check if the Roku firmware supports Perfetto tracing (requires OS 15.2 or higher)
|
|
113
|
+
*/
|
|
114
|
+
get supportsPerfettoTracing() {
|
|
115
|
+
var _a, _b;
|
|
116
|
+
this.logger.log('Checking if device supports Perfetto tracing', this.deviceInfo.softwareVersion);
|
|
117
|
+
return semver.satisfies((_b = (_a = this.deviceInfo) === null || _a === void 0 ? void 0 : _a.softwareVersion) !== null && _b !== void 0 ? _b : '0.0', '>= 15.2');
|
|
118
|
+
}
|
|
109
119
|
/**
|
|
110
120
|
* Get a promise that resolves when the roku adapter is ready to be used
|
|
111
121
|
*/
|
|
@@ -121,7 +131,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
121
131
|
initializeRequest(response, args) {
|
|
122
132
|
this.initRequestArgs = args;
|
|
123
133
|
this.logger.log('initializeRequest');
|
|
124
|
-
response.body
|
|
134
|
+
response.body || (response.body = {});
|
|
125
135
|
// This debug adapter implements the configurationDoneRequest.
|
|
126
136
|
response.body.supportsConfigurationDoneRequest = true;
|
|
127
137
|
// The debug adapter supports the 'restart' request. In this case a client should not implement 'restart' by terminating and relaunching the adapter but by calling the RestartRequest.
|
|
@@ -258,7 +268,8 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
258
268
|
* @returns
|
|
259
269
|
*/
|
|
260
270
|
normalizeLaunchConfig(config) {
|
|
261
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
271
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
272
|
+
var _w, _x;
|
|
262
273
|
(_a = config.cwd) !== null && _a !== void 0 ? _a : (config.cwd = process.cwd());
|
|
263
274
|
(_b = config.outDir) !== null && _b !== void 0 ? _b : (config.outDir = (0, FileUtils_1.standardizePath) `${config.cwd}/out`);
|
|
264
275
|
(_c = config.stagingDir) !== null && _c !== void 0 ? _c : (config.stagingDir = (0, FileUtils_1.standardizePath) `${config.outDir}/.roku-deploy-staging`);
|
|
@@ -274,11 +285,16 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
274
285
|
(_o = config.autoResolveVirtualVariables) !== null && _o !== void 0 ? _o : (config.autoResolveVirtualVariables = false);
|
|
275
286
|
(_p = config.enhanceREPLCompletions) !== null && _p !== void 0 ? _p : (config.enhanceREPLCompletions = true);
|
|
276
287
|
(_q = config.username) !== null && _q !== void 0 ? _q : (config.username = 'rokudev');
|
|
288
|
+
if ((_s = (_r = config.profiling) === null || _r === void 0 ? void 0 : _r.tracing) === null || _s === void 0 ? void 0 : _s.enable) {
|
|
289
|
+
(_t = (_w = config.profiling.tracing).dir) !== null && _t !== void 0 ? _t : (_w.dir = (0, FileUtils_1.standardizePath) `${config.cwd}/traces/`);
|
|
290
|
+
// eslint-disable-next-line no-template-curly-in-string
|
|
291
|
+
(_u = (_x = config.profiling.tracing).filename) !== null && _u !== void 0 ? _u : (_x.filename = '${appTitle}_${timestamp}.perfetto-trace');
|
|
292
|
+
}
|
|
277
293
|
// migrate the old `enableVariablesPanel` setting to the new `deferScopeLoading` setting
|
|
278
294
|
if (typeof config.enableVariablesPanel !== 'boolean') {
|
|
279
295
|
config.enableVariablesPanel = true;
|
|
280
296
|
}
|
|
281
|
-
(
|
|
297
|
+
(_v = config.deferScopeLoading) !== null && _v !== void 0 ? _v : (config.deferScopeLoading = config.enableVariablesPanel === false);
|
|
282
298
|
return config;
|
|
283
299
|
}
|
|
284
300
|
async launchRequest(response, config) {
|
|
@@ -304,13 +320,20 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
304
320
|
// fetches the device info and parses the xml data to JSON object
|
|
305
321
|
try {
|
|
306
322
|
this.deviceInfo = await roku_deploy_1.rokuDeploy.getDeviceInfo({ host: this.launchConfiguration.host, remotePort: this.launchConfiguration.remotePort, enhance: true, timeout: 4000 });
|
|
323
|
+
if (this.deviceInfo.ecpSettingMode === 'limited') {
|
|
324
|
+
return await this.shutdown(`ECP access is limited on this Roku. Please change it to 'permissive' or 'enabled' and try again. (device: ${this.launchConfiguration.host})`);
|
|
325
|
+
}
|
|
307
326
|
}
|
|
308
327
|
catch (e) {
|
|
328
|
+
if (e instanceof roku_deploy_1.EcpNetworkAccessModeDisabledError) {
|
|
329
|
+
return this.shutdown(`ECP access is disabled on this Roku. Please change it to 'permissive' or 'enabled' and try again. (device: ${this.launchConfiguration.host})`);
|
|
330
|
+
}
|
|
309
331
|
return this.shutdown(`Unable to connect to roku at '${this.launchConfiguration.host}'. Verify the IP address is correct and that the device is powered on and connected to same network as this computer.`);
|
|
310
332
|
}
|
|
311
333
|
if (this.deviceInfo && !this.deviceInfo.developerEnabled) {
|
|
312
334
|
return this.shutdown(`Developer mode is not enabled for host '${this.launchConfiguration.host}'.`);
|
|
313
335
|
}
|
|
336
|
+
await this.initializeProfiling();
|
|
314
337
|
//initialize all file logging (rokuDevice, debugger, etc)
|
|
315
338
|
this.fileLoggingManager.activate((_d = this.launchConfiguration) === null || _d === void 0 ? void 0 : _d.fileLogging, this.cwd);
|
|
316
339
|
this.projectManager.launchConfiguration = this.launchConfiguration;
|
|
@@ -320,6 +343,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
320
343
|
this.logger.log('[launchRequest] Packaging and deploying to roku');
|
|
321
344
|
try {
|
|
322
345
|
const packageEnd = this.logger.timeStart('log', 'Packaging');
|
|
346
|
+
this.sendLaunchProgress('start', 'Packaging');
|
|
323
347
|
//build the main project and all component libraries at the same time
|
|
324
348
|
await Promise.all([
|
|
325
349
|
this.prepareMainProject(),
|
|
@@ -353,12 +377,12 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
353
377
|
//pass along the console output
|
|
354
378
|
if (this.launchConfiguration.consoleOutput === 'full') {
|
|
355
379
|
this.rokuAdapter.on('console-output', (data) => {
|
|
356
|
-
|
|
380
|
+
this.sendLogOutput(data).catch(e => this.logger.error('Failed to send log output', e));
|
|
357
381
|
});
|
|
358
382
|
}
|
|
359
383
|
else {
|
|
360
384
|
this.rokuAdapter.on('unhandled-console-output', (data) => {
|
|
361
|
-
|
|
385
|
+
this.sendLogOutput(data).catch(e => this.logger.error('Failed to send log output', e));
|
|
362
386
|
});
|
|
363
387
|
}
|
|
364
388
|
this.rokuAdapter.on('device-unresponsive', async (data) => {
|
|
@@ -386,7 +410,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
386
410
|
});
|
|
387
411
|
// handle any compile errors
|
|
388
412
|
this.rokuAdapter.on('diagnostics', (diagnostics) => {
|
|
389
|
-
|
|
413
|
+
this.handleDiagnostics(diagnostics).catch(e => this.logger.error('Failed to handle diagnostics', e));
|
|
390
414
|
});
|
|
391
415
|
// close disconnect if required when the app is exited
|
|
392
416
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
@@ -403,17 +427,21 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
403
427
|
const message = 'App exit detected; but launchConfiguration.stopDebuggerOnAppExit is set to false, so keeping debug session running.';
|
|
404
428
|
this.logger.log('[launchRequest]', message);
|
|
405
429
|
this.sendEvent(new Events_1.LogOutputEvent(message));
|
|
406
|
-
|
|
430
|
+
this.rokuAdapter.once('connected').then(async () => {
|
|
407
431
|
await this.rokuAdapter.setExceptionBreakpoints(this.exceptionBreakpoints);
|
|
408
|
-
});
|
|
432
|
+
}).catch(e => this.logger.error('Failed to set exception breakpoints after reconnect', e));
|
|
409
433
|
}
|
|
410
434
|
});
|
|
435
|
+
//profiling supports connecting to the socket BEFORE a channel is published, so go ahead and connect now
|
|
436
|
+
await this.tryProfilingConnectOnStart();
|
|
437
|
+
this.sendLaunchProgress('update', 'Uploading to Roku');
|
|
411
438
|
await this.publish();
|
|
412
439
|
//hack for certain roku devices that lock up when this event is emitted (no idea why!).
|
|
413
440
|
if (this.launchConfiguration.emitChannelPublishedEvent) {
|
|
414
441
|
this.sendEvent(new Events_1.ChannelPublishedEvent(this.launchConfiguration));
|
|
415
442
|
}
|
|
416
443
|
//tell the adapter adapter that the channel has been launched.
|
|
444
|
+
this.sendLaunchProgress('update', 'Waiting on application');
|
|
417
445
|
await this.rokuAdapter.activate();
|
|
418
446
|
if (this.rokuAdapter.isDestroyed) {
|
|
419
447
|
throw new Error('Debug session encountered an error');
|
|
@@ -436,7 +464,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
436
464
|
throw error;
|
|
437
465
|
}
|
|
438
466
|
//at this point, the project has been deployed. If we need to use a deep link, launch it now.
|
|
439
|
-
if (this.launchConfiguration.deepLinkUrl) {
|
|
467
|
+
if (this.launchConfiguration.deepLinkUrl && !this.enableDebugProtocol) {
|
|
440
468
|
//wait until the first entry breakpoint has been hit
|
|
441
469
|
await this.firstRunDeferred.promise;
|
|
442
470
|
//if we are at a breakpoint, continue
|
|
@@ -459,9 +487,80 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
459
487
|
const message = (e instanceof Exceptions_1.SocketConnectionInUseError) ? e.message : ((_f = e === null || e === void 0 ? void 0 : e.stack) !== null && _f !== void 0 ? _f : e);
|
|
460
488
|
await this.shutdown(message, true);
|
|
461
489
|
}
|
|
490
|
+
else {
|
|
491
|
+
this.sendLaunchProgress('end', 'Aborted (compile error)');
|
|
492
|
+
}
|
|
462
493
|
}
|
|
463
494
|
logEnd();
|
|
464
495
|
}
|
|
496
|
+
/**
|
|
497
|
+
* Activate all required functionality for profiling
|
|
498
|
+
*/
|
|
499
|
+
async initializeProfiling() {
|
|
500
|
+
var _a, _b, _c, _d, _e;
|
|
501
|
+
// Initialize PerfettoManager
|
|
502
|
+
this.perfettoManager = new PerfettoManager_1.PerfettoManager({
|
|
503
|
+
host: this.launchConfiguration.host,
|
|
504
|
+
rootDir: this.launchConfiguration.rootDir,
|
|
505
|
+
remotePort: this.launchConfiguration.remotePort,
|
|
506
|
+
...(_a = this.launchConfiguration.profiling) === null || _a === void 0 ? void 0 : _a.tracing
|
|
507
|
+
});
|
|
508
|
+
//send certain profiling events back to the client
|
|
509
|
+
this.perfettoManager.on('enable', (event) => {
|
|
510
|
+
this.sendEvent(new Events_1.ProfilingEnabledEvent({
|
|
511
|
+
types: event.types
|
|
512
|
+
}));
|
|
513
|
+
});
|
|
514
|
+
this.perfettoManager.on('start', (event) => {
|
|
515
|
+
this.sendEvent(new Events_1.ProfilingStartEvent({
|
|
516
|
+
type: event.type
|
|
517
|
+
}));
|
|
518
|
+
});
|
|
519
|
+
this.perfettoManager.on('stop', (event) => {
|
|
520
|
+
this.sendEvent(new Events_1.ProfilingStopEvent({
|
|
521
|
+
type: event.type,
|
|
522
|
+
result: event.result
|
|
523
|
+
}));
|
|
524
|
+
});
|
|
525
|
+
this.perfettoManager.on('error', (event) => {
|
|
526
|
+
this.sendEvent(new Events_1.ProfilingErrorEvent({
|
|
527
|
+
error: event.error
|
|
528
|
+
}));
|
|
529
|
+
});
|
|
530
|
+
//tracing is explicitly enabled. Turn it on
|
|
531
|
+
if (((_c = (_b = this.launchConfiguration.profiling) === null || _b === void 0 ? void 0 : _b.tracing) === null || _c === void 0 ? void 0 : _c.enable) && this.supportsPerfettoTracing) {
|
|
532
|
+
this.logger.info('Enabling perfetto tracing because it is supported by the device and enabled in the launch configuration');
|
|
533
|
+
try {
|
|
534
|
+
await this.perfettoManager.enableTracing();
|
|
535
|
+
}
|
|
536
|
+
catch (e) {
|
|
537
|
+
this.logger.error('Failed to enable perfetto tracing', e);
|
|
538
|
+
}
|
|
539
|
+
//tracing is expicitly DISabled. turn it off
|
|
540
|
+
}
|
|
541
|
+
else if (((_e = (_d = this.launchConfiguration.profiling) === null || _d === void 0 ? void 0 : _d.tracing) === null || _e === void 0 ? void 0 : _e.enable) === false && this.supportsPerfettoTracing) {
|
|
542
|
+
this.logger.info('Disabling perfetto tracing because it is disabled in the launch configuration');
|
|
543
|
+
//TODO implement a way to disable perfetto tracing on the device
|
|
544
|
+
//profiling.tracing.enabled is set to `undefined`, which means we should do nothing
|
|
545
|
+
}
|
|
546
|
+
else {
|
|
547
|
+
this.logger.info('Skipping perfetto initalization because `profiling.tracing.enable` is not defined in the launch configuration');
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* If profiling was marked "connectOnStart", try connecting right away
|
|
552
|
+
*/
|
|
553
|
+
async tryProfilingConnectOnStart() {
|
|
554
|
+
var _a, _b;
|
|
555
|
+
if (((_b = (_a = this.launchConfiguration.profiling) === null || _a === void 0 ? void 0 : _a.tracing) === null || _b === void 0 ? void 0 : _b.connectOnStart) && this.supportsPerfettoTracing) {
|
|
556
|
+
try {
|
|
557
|
+
await this.perfettoManager.startTracing();
|
|
558
|
+
}
|
|
559
|
+
catch (e) {
|
|
560
|
+
this.logger.error('Failed to start perfetto tracing on start', e);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
465
564
|
/**
|
|
466
565
|
* Clear certain properties that need reset whenever a debug session is restarted (via vscode or launched from the Roku home screen)
|
|
467
566
|
*/
|
|
@@ -528,6 +627,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
528
627
|
//find the first compile error (i.e. first DiagnosticSeverity.Error) if there is one
|
|
529
628
|
this.compileError = diagnostics.find(x => x.severity === brighterscript_1.DiagnosticSeverity.Error);
|
|
530
629
|
if (this.compileError) {
|
|
630
|
+
this.sendLaunchProgress('end', 'Aborted (compile error)');
|
|
531
631
|
this.sendEvent(new debugadapter_1.StoppedEvent(Events_1.StoppedEventReason.exception, this.COMPILE_ERROR_THREAD_ID, `CompileError: ${this.compileError.message}`));
|
|
532
632
|
}
|
|
533
633
|
this.sendEvent(new Events_1.DiagnosticsEvent(diagnostics));
|
|
@@ -832,7 +932,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
832
932
|
* Accepts custom events and requests from the extension
|
|
833
933
|
* @param command name of the command to execute
|
|
834
934
|
*/
|
|
835
|
-
customRequest(command, response, args) {
|
|
935
|
+
async customRequest(command, response, args) {
|
|
836
936
|
if (command === 'rendezvous.clearHistory') {
|
|
837
937
|
this.rokuAdapter.clearRendezvousHistory();
|
|
838
938
|
}
|
|
@@ -845,6 +945,27 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
845
945
|
else if (command === 'popupMessageEventResponse') {
|
|
846
946
|
this.emit('popupMessageEventResponse', args);
|
|
847
947
|
}
|
|
948
|
+
else if (command === 'captureHeapSnapshot') {
|
|
949
|
+
this.perfettoManager.captureHeapSnapshot().catch((e) => this.logger.error('Failed to capture heap snapshot', e));
|
|
950
|
+
}
|
|
951
|
+
else if (command === 'startPerfettoTracing') {
|
|
952
|
+
try {
|
|
953
|
+
await this.perfettoManager.startTracing();
|
|
954
|
+
}
|
|
955
|
+
catch (e) {
|
|
956
|
+
response.success = false;
|
|
957
|
+
response.body = { message: (e === null || e === void 0 ? void 0 : e.message) || String(e) };
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
else if (command === 'stopPerfettoTracing') {
|
|
961
|
+
try {
|
|
962
|
+
await this.perfettoManager.stopTracing();
|
|
963
|
+
}
|
|
964
|
+
catch (e) {
|
|
965
|
+
response.success = false;
|
|
966
|
+
response.body = { message: (e === null || e === void 0 ? void 0 : e.message) || String(e) };
|
|
967
|
+
}
|
|
968
|
+
}
|
|
848
969
|
this.sendResponse(response);
|
|
849
970
|
}
|
|
850
971
|
/**
|
|
@@ -1931,10 +2052,14 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
1931
2052
|
*/
|
|
1932
2053
|
async connectRokuAdapter() {
|
|
1933
2054
|
this.rokuAdapter.on('start', () => {
|
|
2055
|
+
this.sendLaunchProgress('end', 'Complete');
|
|
1934
2056
|
if (!this.firstRunDeferred.isCompleted) {
|
|
1935
2057
|
this.firstRunDeferred.resolve();
|
|
1936
2058
|
}
|
|
1937
2059
|
});
|
|
2060
|
+
this.rokuAdapter.on('launch-status', (message) => {
|
|
2061
|
+
this.sendLaunchProgress('update', message);
|
|
2062
|
+
});
|
|
1938
2063
|
//when the debugger suspends (pauses for debugger input)
|
|
1939
2064
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
1940
2065
|
this.rokuAdapter.on('suspend', async () => {
|
|
@@ -1951,7 +2076,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
1951
2076
|
});
|
|
1952
2077
|
// If the roku says it can't continue, we are no longer able to debug, so kill the debug session
|
|
1953
2078
|
this.rokuAdapter.on('cannot-continue', () => {
|
|
1954
|
-
|
|
2079
|
+
this.shutdown().catch(e => this.logger.error(e));
|
|
1955
2080
|
});
|
|
1956
2081
|
//make the connection
|
|
1957
2082
|
await this.rokuAdapter.connect();
|
|
@@ -2191,6 +2316,35 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
2191
2316
|
//erase all cached variables
|
|
2192
2317
|
this.variables = {};
|
|
2193
2318
|
}
|
|
2319
|
+
/**
|
|
2320
|
+
* Sends a launch progress event to the client if the client supports progress reporting.
|
|
2321
|
+
* - `'start'`: begins a new progress bar with the given message. Assigns a new progressId.
|
|
2322
|
+
* - `'update'`: updates the message on the active progress bar.
|
|
2323
|
+
* - `'end'`: dismisses the active progress bar with an optional final message.
|
|
2324
|
+
*/
|
|
2325
|
+
sendLaunchProgress(type, message) {
|
|
2326
|
+
var _a;
|
|
2327
|
+
if (!((_a = this.initRequestArgs) === null || _a === void 0 ? void 0 : _a.supportsProgressReporting)) {
|
|
2328
|
+
return;
|
|
2329
|
+
}
|
|
2330
|
+
if (type === 'start') {
|
|
2331
|
+
this.launchProgressId = `rokudebug-launch-${this.idCounter++}`;
|
|
2332
|
+
this.sendEvent(new debugadapter_1.ProgressStartEvent(this.launchProgressId, 'Launching', `${message}...`));
|
|
2333
|
+
}
|
|
2334
|
+
else if (this.launchProgressId) {
|
|
2335
|
+
if (type === 'update') {
|
|
2336
|
+
this.sendEvent(new debugadapter_1.ProgressUpdateEvent(this.launchProgressId, `${message}...`));
|
|
2337
|
+
}
|
|
2338
|
+
else {
|
|
2339
|
+
const lastId = this.launchProgressId;
|
|
2340
|
+
this.sendEvent(new debugadapter_1.ProgressUpdateEvent(lastId, message));
|
|
2341
|
+
setTimeout(() => {
|
|
2342
|
+
this.sendEvent(new debugadapter_1.ProgressEndEvent(lastId, message));
|
|
2343
|
+
}, 1000); // add a slight delay before ending the progress to improve UX
|
|
2344
|
+
this.launchProgressId = undefined;
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2194
2348
|
/**
|
|
2195
2349
|
* Tells the client to re-request all variables because we've invalidated them
|
|
2196
2350
|
* @param threadId
|
|
@@ -2274,7 +2428,9 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
2274
2428
|
return this.shutdownPromise;
|
|
2275
2429
|
}
|
|
2276
2430
|
async _shutdown(errorMessage, modal = false) {
|
|
2277
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
2431
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
2432
|
+
// Ensure any active launch progress bar is dismissed before showing error messages or the terminated event.
|
|
2433
|
+
this.sendLaunchProgress('end', 'Complete');
|
|
2278
2434
|
//send the message FIRST before anything else. This improves the chances that the message will be displayed to the user
|
|
2279
2435
|
try {
|
|
2280
2436
|
if (errorMessage) {
|
|
@@ -2287,10 +2443,23 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
2287
2443
|
catch (e) {
|
|
2288
2444
|
this.logger.error(e);
|
|
2289
2445
|
}
|
|
2446
|
+
// stop perfetto tracing if it's running
|
|
2447
|
+
try {
|
|
2448
|
+
await this.perfettoManager.stopTracing();
|
|
2449
|
+
}
|
|
2450
|
+
catch (e) {
|
|
2451
|
+
this.logger.error('Error stopping perfetto tracing', e);
|
|
2452
|
+
}
|
|
2453
|
+
try {
|
|
2454
|
+
await ((_b = (_a = this.perfettoManager) === null || _a === void 0 ? void 0 : _a.dispose) === null || _b === void 0 ? void 0 : _b.call(_a));
|
|
2455
|
+
}
|
|
2456
|
+
catch (e) {
|
|
2457
|
+
this.logger.error('Error disposing perfetto manager', e);
|
|
2458
|
+
}
|
|
2290
2459
|
//close the debugger connection
|
|
2291
2460
|
try {
|
|
2292
2461
|
this.logger.log('Destroy rokuAdapter');
|
|
2293
|
-
await ((
|
|
2462
|
+
await ((_d = (_c = this.rokuAdapter) === null || _c === void 0 ? void 0 : _c.destroy) === null || _d === void 0 ? void 0 : _d.call(_c));
|
|
2294
2463
|
//press the home button to return to the home screen
|
|
2295
2464
|
try {
|
|
2296
2465
|
this.logger.log('Press home button');
|
|
@@ -2304,25 +2473,25 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
2304
2473
|
this.logger.error(e);
|
|
2305
2474
|
}
|
|
2306
2475
|
try {
|
|
2307
|
-
(
|
|
2476
|
+
(_f = (_e = this.projectManager) === null || _e === void 0 ? void 0 : _e.dispose) === null || _f === void 0 ? void 0 : _f.call(_e);
|
|
2308
2477
|
}
|
|
2309
2478
|
catch (e) {
|
|
2310
2479
|
this.logger.error(e);
|
|
2311
2480
|
}
|
|
2312
2481
|
try {
|
|
2313
|
-
(
|
|
2482
|
+
(_g = this.componentLibraryServer) === null || _g === void 0 ? void 0 : _g.stop();
|
|
2314
2483
|
}
|
|
2315
2484
|
catch (e) {
|
|
2316
2485
|
this.logger.error(e);
|
|
2317
2486
|
}
|
|
2318
2487
|
try {
|
|
2319
|
-
await ((
|
|
2488
|
+
await ((_j = (_h = this.rendezvousTracker) === null || _h === void 0 ? void 0 : _h.destroy) === null || _j === void 0 ? void 0 : _j.call(_h));
|
|
2320
2489
|
}
|
|
2321
2490
|
catch (e) {
|
|
2322
2491
|
this.logger.error(e);
|
|
2323
2492
|
}
|
|
2324
2493
|
try {
|
|
2325
|
-
await ((
|
|
2494
|
+
await ((_l = (_k = this.sourceMapManager) === null || _k === void 0 ? void 0 : _k.destroy) === null || _l === void 0 ? void 0 : _l.call(_k));
|
|
2326
2495
|
}
|
|
2327
2496
|
catch (e) {
|
|
2328
2497
|
this.logger.error(e);
|
|
@@ -2330,7 +2499,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
2330
2499
|
try {
|
|
2331
2500
|
//if configured, delete the staging directory
|
|
2332
2501
|
if (!this.launchConfiguration.retainStagingFolder) {
|
|
2333
|
-
const stagingDirs = (
|
|
2502
|
+
const stagingDirs = (_o = (_m = this.projectManager) === null || _m === void 0 ? void 0 : _m.getStagingDirs()) !== null && _o !== void 0 ? _o : [];
|
|
2334
2503
|
this.logger.info('deleting staging folders', stagingDirs);
|
|
2335
2504
|
for (let stagingDir of stagingDirs) {
|
|
2336
2505
|
try {
|