roku-debug 0.21.18 → 0.21.19
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 +11 -0
- package/dist/LaunchConfiguration.d.ts +7 -0
- package/dist/adapters/DebugProtocolAdapter.d.ts +1 -1
- package/dist/adapters/DebugProtocolAdapter.js.map +1 -1
- package/dist/adapters/TelnetAdapter.d.ts +2 -0
- package/dist/adapters/TelnetAdapter.js +6 -0
- package/dist/adapters/TelnetAdapter.js.map +1 -1
- package/dist/bsc/BscProject.d.ts +27 -0
- package/dist/bsc/BscProject.js +50 -0
- package/dist/bsc/BscProject.js.map +1 -0
- package/dist/bsc/BscProjectThreaded.d.ts +45 -0
- package/dist/bsc/BscProjectThreaded.js +90 -0
- package/dist/bsc/BscProjectThreaded.js.map +1 -0
- package/dist/bsc/threading/BscProjectWorkerPool.d.ts +5 -0
- package/dist/bsc/threading/BscProjectWorkerPool.js +29 -0
- package/dist/bsc/threading/BscProjectWorkerPool.js.map +1 -0
- package/dist/bsc/threading/ThreadMessageHandler.d.ts +99 -0
- package/dist/bsc/threading/ThreadMessageHandler.js +138 -0
- package/dist/bsc/threading/ThreadMessageHandler.js.map +1 -0
- package/dist/bsc/threading/ThreadRunner.d.ts +30 -0
- package/dist/bsc/threading/ThreadRunner.js +50 -0
- package/dist/bsc/threading/ThreadRunner.js.map +1 -0
- package/dist/bsc/threading/WorkerPool.d.ts +38 -0
- package/dist/bsc/threading/WorkerPool.js +78 -0
- package/dist/bsc/threading/WorkerPool.js.map +1 -0
- package/dist/debugSession/BrightScriptDebugSession.d.ts +7 -0
- package/dist/debugSession/BrightScriptDebugSession.js +304 -19
- package/dist/debugSession/BrightScriptDebugSession.js.map +1 -1
- package/dist/interfaces.d.ts +12 -0
- package/dist/managers/ProjectManager.d.ts +31 -12
- package/dist/managers/ProjectManager.js +61 -9
- package/dist/managers/ProjectManager.js.map +1 -1
- package/dist/util.d.ts +6 -1
- package/dist/util.js +20 -0
- package/dist/util.js.map +1 -1
- package/package.json +2 -2
- package/roku-debug-0.21.19.tgz +0 -0
- package/roku-debug-0.21.18.tgz +0 -0
|
@@ -23,6 +23,9 @@ const logging_1 = require("../logging");
|
|
|
23
23
|
const VariablesResponse_1 = require("../debugProtocol/events/responses/VariablesResponse");
|
|
24
24
|
const brighterscript_1 = require("brighterscript");
|
|
25
25
|
const debounce_1 = require("debounce");
|
|
26
|
+
const roku_types_1 = require("brighterscript/dist/roku-types");
|
|
27
|
+
const globalCallables_1 = require("brighterscript/dist/globalCallables");
|
|
28
|
+
const BscProjectWorkerPool_1 = require("../bsc/threading/BscProjectWorkerPool");
|
|
26
29
|
const diagnosticSource = 'roku-debug';
|
|
27
30
|
class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
28
31
|
constructor() {
|
|
@@ -73,7 +76,10 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
73
76
|
this.breakpointManager = new BreakpointManager_1.BreakpointManager(this.sourceMapManager, this.locationManager);
|
|
74
77
|
//send newly-verified breakpoints to vscode
|
|
75
78
|
this.breakpointManager.on('breakpoints-verified', (data) => this.onDeviceBreakpointsChanged('changed', data));
|
|
76
|
-
this.projectManager = new ProjectManager_1.ProjectManager(
|
|
79
|
+
this.projectManager = new ProjectManager_1.ProjectManager({
|
|
80
|
+
breakpointManager: this.breakpointManager,
|
|
81
|
+
locationManager: this.locationManager
|
|
82
|
+
});
|
|
77
83
|
this.fileLoggingManager = new logging_1.FileLoggingManager();
|
|
78
84
|
}
|
|
79
85
|
onDeviceBreakpointsChanged(eventName, data) {
|
|
@@ -143,6 +149,8 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
143
149
|
response.body.supportsHitConditionalBreakpoints = true;
|
|
144
150
|
// This debug adapter supports log points by interpreting the 'logMessage' attribute of the SourceBreakpoint
|
|
145
151
|
response.body.supportsLogPoints = true;
|
|
152
|
+
response.body.supportsCompletionsRequest = true;
|
|
153
|
+
response.body.completionTriggerCharacters = ['.', '(', '{', ',', ' '];
|
|
146
154
|
this.sendResponse(response);
|
|
147
155
|
//register the debug output log transport writer
|
|
148
156
|
logging_1.debugServerLogOutputEventTransport.setWriter((message) => {
|
|
@@ -245,7 +253,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
245
253
|
* @returns
|
|
246
254
|
*/
|
|
247
255
|
normalizeLaunchConfig(config) {
|
|
248
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
256
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
249
257
|
(_a = config.cwd) !== null && _a !== void 0 ? _a : (config.cwd = process.cwd());
|
|
250
258
|
(_b = config.outDir) !== null && _b !== void 0 ? _b : (config.outDir = (0, FileUtils_1.standardizePath) `${config.cwd}/out`);
|
|
251
259
|
(_c = config.stagingDir) !== null && _c !== void 0 ? _c : (config.stagingDir = (0, FileUtils_1.standardizePath) `${config.outDir}/.roku-deploy-staging`);
|
|
@@ -259,14 +267,17 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
259
267
|
(_l = config.emitChannelPublishedEvent) !== null && _l !== void 0 ? _l : (config.emitChannelPublishedEvent = true);
|
|
260
268
|
(_m = config.rewriteDevicePathsInLogs) !== null && _m !== void 0 ? _m : (config.rewriteDevicePathsInLogs = true);
|
|
261
269
|
(_o = config.autoResolveVirtualVariables) !== null && _o !== void 0 ? _o : (config.autoResolveVirtualVariables = false);
|
|
270
|
+
(_p = config.enhanceREPLCompletions) !== null && _p !== void 0 ? _p : (config.enhanceREPLCompletions = true);
|
|
262
271
|
return config;
|
|
263
272
|
}
|
|
264
273
|
async launchRequest(response, config) {
|
|
265
|
-
var _a, _b;
|
|
266
|
-
this.logger.
|
|
274
|
+
var _a, _b, _c, _d, _e;
|
|
275
|
+
const logEnd = this.logger.timeStart('log', '[launchRequest] launch');
|
|
267
276
|
//send the response right away so the UI immediately shows the debugger toolbar
|
|
268
277
|
this.sendResponse(response);
|
|
269
278
|
this.launchConfiguration = this.normalizeLaunchConfig(config);
|
|
279
|
+
//prebake some threads for our ProjectManager to use later on (1 for the main project, and 1 for every complib)
|
|
280
|
+
BscProjectWorkerPool_1.bscProjectWorkerPool.preload(1 + ((_c = (_b = (_a = this.launchConfiguration) === null || _a === void 0 ? void 0 : _a.componentLibraries) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0));
|
|
270
281
|
//set the logLevel provided by the launch config
|
|
271
282
|
if (this.launchConfiguration.logLevel) {
|
|
272
283
|
logging_1.logger.logLevel = this.launchConfiguration.logLevel;
|
|
@@ -289,7 +300,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
289
300
|
return this.shutdown(`Developer mode is not enabled for host '${this.launchConfiguration.host}'.`);
|
|
290
301
|
}
|
|
291
302
|
//initialize all file logging (rokuDevice, debugger, etc)
|
|
292
|
-
this.fileLoggingManager.activate((
|
|
303
|
+
this.fileLoggingManager.activate((_d = this.launchConfiguration) === null || _d === void 0 ? void 0 : _d.fileLogging, this.cwd);
|
|
293
304
|
this.projectManager.launchConfiguration = this.launchConfiguration;
|
|
294
305
|
this.breakpointManager.launchConfiguration = this.launchConfiguration;
|
|
295
306
|
this.sendEvent(new Events_1.LaunchStartEvent(this.launchConfiguration));
|
|
@@ -407,9 +418,10 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
407
418
|
util_1.util.log(e === null || e === void 0 ? void 0 : e.stack);
|
|
408
419
|
this.sendErrorResponse(response, -1, e === null || e === void 0 ? void 0 : e.stack);
|
|
409
420
|
//send any compile errors to the client
|
|
410
|
-
await ((
|
|
421
|
+
await ((_e = this.rokuAdapter) === null || _e === void 0 ? void 0 : _e.sendErrors());
|
|
411
422
|
}
|
|
412
423
|
}
|
|
424
|
+
logEnd();
|
|
413
425
|
//at this point, the project has been deployed. If we need to use a deep link, launch it now.
|
|
414
426
|
if (this.launchConfiguration.deepLinkUrl) {
|
|
415
427
|
//wait until the first entry breakpoint has been hit
|
|
@@ -739,7 +751,8 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
739
751
|
injectRdbOnDeviceComponent: this.launchConfiguration.injectRdbOnDeviceComponent,
|
|
740
752
|
rdbFilesBasePath: this.launchConfiguration.rdbFilesBasePath,
|
|
741
753
|
stagingDir: this.launchConfiguration.stagingDir,
|
|
742
|
-
packagePath: this.launchConfiguration.packagePath
|
|
754
|
+
packagePath: this.launchConfiguration.packagePath,
|
|
755
|
+
enhanceREPLCompletions: this.launchConfiguration.enhanceREPLCompletions
|
|
743
756
|
});
|
|
744
757
|
util_1.util.log('Moving selected files to staging area');
|
|
745
758
|
await this.projectManager.mainProject.stage();
|
|
@@ -810,7 +823,8 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
810
823
|
bsConst: componentLibrary.bsConst,
|
|
811
824
|
injectRaleTrackerTask: componentLibrary.injectRaleTrackerTask,
|
|
812
825
|
raleTrackerTaskFileLocation: componentLibrary.raleTrackerTaskFileLocation,
|
|
813
|
-
libraryIndex: libraryIndex
|
|
826
|
+
libraryIndex: libraryIndex,
|
|
827
|
+
enhanceREPLCompletions: this.launchConfiguration.enhanceREPLCompletions
|
|
814
828
|
}));
|
|
815
829
|
}
|
|
816
830
|
//prepare all of the libraries in parallel
|
|
@@ -1436,6 +1450,246 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
1436
1450
|
}
|
|
1437
1451
|
return results;
|
|
1438
1452
|
}
|
|
1453
|
+
async completionsRequest(response, args, request) {
|
|
1454
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
1455
|
+
this.logger.log('completionsRequest', args, request);
|
|
1456
|
+
// this.sendEvent(new LogOutputEvent(`completionsRequest: ${args.text}`));
|
|
1457
|
+
// this.sendEvent(new OutputEvent(`completionsRequest: ${args.text}\n`, 'stderr'));
|
|
1458
|
+
try {
|
|
1459
|
+
let supplyLocalScopeCompletions = false;
|
|
1460
|
+
let closestCompletionDetails = this.getClosestCompletionDetails(args);
|
|
1461
|
+
if (!closestCompletionDetails) {
|
|
1462
|
+
// If the cursor is not at the end of the line, then we should not supply completions at this time
|
|
1463
|
+
response.body = {
|
|
1464
|
+
targets: []
|
|
1465
|
+
};
|
|
1466
|
+
return this.sendResponse(response);
|
|
1467
|
+
}
|
|
1468
|
+
let completions = new Map();
|
|
1469
|
+
let parentVariablePath = closestCompletionDetails.parentVariablePath;
|
|
1470
|
+
// Get the completions if the variable path was valid
|
|
1471
|
+
if (parentVariablePath) {
|
|
1472
|
+
// If the parent variable path is an empty string, then we are looking up the local scope variables and global functions
|
|
1473
|
+
if (parentVariablePath.length === 1 && parentVariablePath[0] === '') {
|
|
1474
|
+
supplyLocalScopeCompletions = true;
|
|
1475
|
+
}
|
|
1476
|
+
// Look up the parent variable
|
|
1477
|
+
let parentVariable = this.findVariableByPath(Object.values(this.variables), parentVariablePath, args.frameId);
|
|
1478
|
+
if (!parentVariable || parentVariable.childVariables.length === 0) {
|
|
1479
|
+
// We did not find the parent variable, so try to look it up from the device
|
|
1480
|
+
try {
|
|
1481
|
+
let { evalArgs } = await this.evaluateExpressionToTempVar({ expression: parentVariablePath.join('.'), frameId: args.frameId }, parentVariablePath);
|
|
1482
|
+
let result = await this.rokuAdapter.getVariable(evalArgs.expression, args.frameId);
|
|
1483
|
+
parentVariable = await this.getVariableFromResult(result, args.frameId);
|
|
1484
|
+
}
|
|
1485
|
+
catch (error) {
|
|
1486
|
+
this.logger.error('Error looking up parent completions', error, { parentVariablePath });
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
// provide completions for the parent variable if one was found
|
|
1490
|
+
if (parentVariable) {
|
|
1491
|
+
let possibleFieldsAndMethods = [];
|
|
1492
|
+
// Filter out virtual variables
|
|
1493
|
+
possibleFieldsAndMethods = parentVariable.childVariables.filter((v) => { var _a; return ((_a = v.presentationHint) === null || _a === void 0 ? void 0 : _a.kind) !== 'virtual'; });
|
|
1494
|
+
for (let v of possibleFieldsAndMethods) {
|
|
1495
|
+
// Default completion type should be variable
|
|
1496
|
+
let completionType = 'variable';
|
|
1497
|
+
if (!supplyLocalScopeCompletions) {
|
|
1498
|
+
// We are not supplying local scope completions, so we need to determine the completion type relative to the parent variable
|
|
1499
|
+
if (parentVariable.type === 'roSGNode' || parentVariable.type === VariablesResponse_1.VariableType.AssociativeArray || parentVariable.type === VariablesResponse_1.VariableType.Object) {
|
|
1500
|
+
completionType = 'field';
|
|
1501
|
+
}
|
|
1502
|
+
switch (v.type) {
|
|
1503
|
+
case VariablesResponse_1.VariableType.Function:
|
|
1504
|
+
case VariablesResponse_1.VariableType.Subroutine:
|
|
1505
|
+
completionType = 'method';
|
|
1506
|
+
break;
|
|
1507
|
+
default:
|
|
1508
|
+
break;
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
let label = v.name;
|
|
1512
|
+
if (parentVariable.type === VariablesResponse_1.VariableType.Array ||
|
|
1513
|
+
parentVariable.type === VariablesResponse_1.VariableType.List ||
|
|
1514
|
+
parentVariable.type === 'roXMLList' ||
|
|
1515
|
+
parentVariable.type === 'roByteArray') {
|
|
1516
|
+
label = `[${v.name}]`;
|
|
1517
|
+
}
|
|
1518
|
+
completions.set(`${completionType}-${v.name}`, {
|
|
1519
|
+
label: label,
|
|
1520
|
+
type: completionType,
|
|
1521
|
+
sortText: '000000'
|
|
1522
|
+
});
|
|
1523
|
+
}
|
|
1524
|
+
let parentComponentType = this.debuggerVarTypeToRoType(parentVariable.type).toLowerCase();
|
|
1525
|
+
//assemble a list of all methods on the parent component
|
|
1526
|
+
const methods = [
|
|
1527
|
+
//if the parent variable is an actual interface (if applicable) Ex: `ifString` or `ifArray`
|
|
1528
|
+
...(_b = (_a = roku_types_1.interfaces[parentComponentType]) === null || _a === void 0 ? void 0 : _a.methods) !== null && _b !== void 0 ? _b : [],
|
|
1529
|
+
//interfaces from component of this name (if applicable) Ex: `roSGNode` or `roDateTime`
|
|
1530
|
+
...(_d = (_c = roku_types_1.components[parentComponentType]) === null || _c === void 0 ? void 0 : _c.interfaces.map((i) => { var _a; return (_a = roku_types_1.interfaces[i.name.toLowerCase()]) === null || _a === void 0 ? void 0 : _a.methods; })) !== null && _d !== void 0 ? _d : [],
|
|
1531
|
+
// Add parent event function completions (if applicable) Ex: `roSGNodeEvent` or `roDeviceInfoEvent`
|
|
1532
|
+
...(_f = (_e = roku_types_1.events[parentComponentType]) === null || _e === void 0 ? void 0 : _e.methods) !== null && _f !== void 0 ? _f : []
|
|
1533
|
+
].flat();
|
|
1534
|
+
// Based on the results of interface, component, and event looks up, add all the methods to the completions
|
|
1535
|
+
for (const method of methods) {
|
|
1536
|
+
completions.set(`method-${method.name}`, {
|
|
1537
|
+
label: method.name,
|
|
1538
|
+
type: 'method',
|
|
1539
|
+
detail: (_g = method.description) !== null && _g !== void 0 ? _g : '',
|
|
1540
|
+
sortText: '000000'
|
|
1541
|
+
});
|
|
1542
|
+
}
|
|
1543
|
+
// Add the global functions to the completions results
|
|
1544
|
+
if (supplyLocalScopeCompletions) {
|
|
1545
|
+
for (let globalCallable of globalCallables_1.globalCallables) {
|
|
1546
|
+
completions.set(`function-${globalCallable.name.toLocaleLowerCase()}`, {
|
|
1547
|
+
label: globalCallable.name,
|
|
1548
|
+
type: 'function',
|
|
1549
|
+
detail: (_j = (_h = globalCallable.shortDescription) !== null && _h !== void 0 ? _h : globalCallable.documentation) !== null && _j !== void 0 ? _j : '',
|
|
1550
|
+
sortText: '000000'
|
|
1551
|
+
});
|
|
1552
|
+
}
|
|
1553
|
+
const frame = this.rokuAdapter.getStackFrameById(args.frameId);
|
|
1554
|
+
let scopeFunctions = await this.projectManager.getScopeFunctionsForFile(frame.filePath);
|
|
1555
|
+
for (let scopeFunction of scopeFunctions) {
|
|
1556
|
+
if (!completions.has(`${scopeFunction.completionItemKind}-${scopeFunction.name.toLocaleLowerCase()}`)) {
|
|
1557
|
+
completions.set(`${scopeFunction.completionItemKind}-${scopeFunction.name.toLocaleLowerCase()}`, {
|
|
1558
|
+
label: scopeFunction.name,
|
|
1559
|
+
type: scopeFunction.completionItemKind,
|
|
1560
|
+
sortText: '000000'
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
// this.sendEvent(new LogOutputEvent(`text: ${args.text} | completions: ${completions.map(v => v.label).join(', ')}`));
|
|
1568
|
+
// this.sendEvent(new OutputEvent(`text: ${args.text} | completions: ${completions.map(v => v.label).join(', ')}\n`, 'stderr'));
|
|
1569
|
+
response.body = {
|
|
1570
|
+
targets: [...completions.values()]
|
|
1571
|
+
};
|
|
1572
|
+
}
|
|
1573
|
+
catch (error) {
|
|
1574
|
+
// this.sendEvent(new LogOutputEvent(`text: ${args.text} | ${error}`));
|
|
1575
|
+
// this.sendEvent(new OutputEvent(`text: ${args.text} | ${error}\n`, 'stderr'));
|
|
1576
|
+
this.logger.error('Error during completionsRequest', error, { args });
|
|
1577
|
+
}
|
|
1578
|
+
this.sendResponse(response);
|
|
1579
|
+
}
|
|
1580
|
+
/**
|
|
1581
|
+
* Gets the closest completion details the incoming completion request.
|
|
1582
|
+
*/
|
|
1583
|
+
getClosestCompletionDetails(args) {
|
|
1584
|
+
var _a;
|
|
1585
|
+
const incomingText = args.text;
|
|
1586
|
+
const lines = incomingText.split('\n');
|
|
1587
|
+
let lineNumber = (_a = args.line) !== null && _a !== void 0 ? _a : (this.initRequestArgs.linesStartAt1 ? 1 : 0);
|
|
1588
|
+
let column = args.column;
|
|
1589
|
+
// Make sure to correct the line and column to 0-based
|
|
1590
|
+
// if they are being sent as 1-based from the client
|
|
1591
|
+
if (this.initRequestArgs.linesStartAt1) {
|
|
1592
|
+
lineNumber--;
|
|
1593
|
+
}
|
|
1594
|
+
if (this.initRequestArgs.columnsStartAt1) {
|
|
1595
|
+
column--;
|
|
1596
|
+
}
|
|
1597
|
+
const targetLine = lines[lineNumber];
|
|
1598
|
+
let variablePathString = '';
|
|
1599
|
+
let i = column - 1;
|
|
1600
|
+
const variableChars = /[a-z0-9_\.]/i;
|
|
1601
|
+
// If the character at immediate to the right of the cursor is a variable character, then we are not at the end of the variable path.
|
|
1602
|
+
if (targetLine.length - 1 > i && variableChars.test(targetLine[i + 1])) {
|
|
1603
|
+
return undefined;
|
|
1604
|
+
}
|
|
1605
|
+
// Find the start of the variable path by looking for the first non-alphanumeric or non_underscore character before the cursor
|
|
1606
|
+
while (i >= 0 && (variableChars.test(targetLine[i]))) {
|
|
1607
|
+
i--;
|
|
1608
|
+
}
|
|
1609
|
+
// Pull the variable path string from the line
|
|
1610
|
+
variablePathString = targetLine.slice(i + 1, column);
|
|
1611
|
+
// Attempted dot access something unexpected
|
|
1612
|
+
// Example: `getPerson().name` where `getPerson()` is not a valid variable
|
|
1613
|
+
// and results in `.name` being the variable path string
|
|
1614
|
+
if (variablePathString.startsWith('.')) {
|
|
1615
|
+
return undefined;
|
|
1616
|
+
}
|
|
1617
|
+
// Get the variable path from the text
|
|
1618
|
+
let variablePath = [];
|
|
1619
|
+
if (!variablePathString.trim()) {
|
|
1620
|
+
// The text was empty so assume via '' that we are looking up the local scope variables and global functions
|
|
1621
|
+
variablePath = [''];
|
|
1622
|
+
}
|
|
1623
|
+
else if (variablePathString.endsWith('.')) {
|
|
1624
|
+
// supplied text ends with a period, so strip it off to create a valid variable path
|
|
1625
|
+
variablePath = util_1.util.getVariablePath(variablePathString.slice(0, -1));
|
|
1626
|
+
}
|
|
1627
|
+
else {
|
|
1628
|
+
variablePath = util_1.util.getVariablePath(variablePathString);
|
|
1629
|
+
}
|
|
1630
|
+
// the target string is not a valid variable path
|
|
1631
|
+
if (!variablePath) {
|
|
1632
|
+
return undefined;
|
|
1633
|
+
}
|
|
1634
|
+
let parentVariablePath;
|
|
1635
|
+
// If the last character is a period, then pull completions for the parent variable before the period
|
|
1636
|
+
if (variablePathString.endsWith('.')) {
|
|
1637
|
+
parentVariablePath = variablePath;
|
|
1638
|
+
}
|
|
1639
|
+
else {
|
|
1640
|
+
// Otherwise, pull completions for the parent variable
|
|
1641
|
+
parentVariablePath = variablePath.slice(0, variablePath.length - 1);
|
|
1642
|
+
}
|
|
1643
|
+
// If the parent variable path is empty or an empty string, then we are looking up the local scope variables and global functions
|
|
1644
|
+
if (parentVariablePath.length === 0) {
|
|
1645
|
+
parentVariablePath = [''];
|
|
1646
|
+
}
|
|
1647
|
+
return { parentVariablePath: parentVariablePath };
|
|
1648
|
+
}
|
|
1649
|
+
findVariableByPath(variables, path, frameId) {
|
|
1650
|
+
var _a;
|
|
1651
|
+
let current = null;
|
|
1652
|
+
for (const name of path) {
|
|
1653
|
+
// Find the object matching the current name in the data
|
|
1654
|
+
current = (_a = (Array.isArray(variables) ? variables : current === null || current === void 0 ? void 0 : current.childVariables)) === null || _a === void 0 ? void 0 : _a.find(obj => {
|
|
1655
|
+
return obj.name === name && obj.frameId === frameId;
|
|
1656
|
+
});
|
|
1657
|
+
// If no match is found, return null
|
|
1658
|
+
if (!current) {
|
|
1659
|
+
return null;
|
|
1660
|
+
}
|
|
1661
|
+
// Move to the children for the next iteration
|
|
1662
|
+
variables = current.childVariables;
|
|
1663
|
+
}
|
|
1664
|
+
return current;
|
|
1665
|
+
}
|
|
1666
|
+
debuggerVarTypeToRoType(type) {
|
|
1667
|
+
switch (type) {
|
|
1668
|
+
case VariablesResponse_1.VariableType.Function:
|
|
1669
|
+
case VariablesResponse_1.VariableType.Subroutine:
|
|
1670
|
+
return 'roFunction';
|
|
1671
|
+
case VariablesResponse_1.VariableType.AssociativeArray:
|
|
1672
|
+
return 'roAssociativeArray';
|
|
1673
|
+
case VariablesResponse_1.VariableType.List:
|
|
1674
|
+
return 'roList';
|
|
1675
|
+
case VariablesResponse_1.VariableType.Array:
|
|
1676
|
+
return 'roArray';
|
|
1677
|
+
case VariablesResponse_1.VariableType.Boolean:
|
|
1678
|
+
return 'roBoolean';
|
|
1679
|
+
case VariablesResponse_1.VariableType.Double:
|
|
1680
|
+
return 'roDouble';
|
|
1681
|
+
case VariablesResponse_1.VariableType.Float:
|
|
1682
|
+
return 'roFloat';
|
|
1683
|
+
case VariablesResponse_1.VariableType.Integer:
|
|
1684
|
+
return 'roInteger';
|
|
1685
|
+
case VariablesResponse_1.VariableType.LongInteger:
|
|
1686
|
+
return 'roLongInteger';
|
|
1687
|
+
case VariablesResponse_1.VariableType.String:
|
|
1688
|
+
return 'roString';
|
|
1689
|
+
default:
|
|
1690
|
+
return type;
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1439
1693
|
/**
|
|
1440
1694
|
* Called when the host stops debugging
|
|
1441
1695
|
* @param response
|
|
@@ -1768,19 +2022,35 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
1768
2022
|
return this.shutdownPromise;
|
|
1769
2023
|
}
|
|
1770
2024
|
async _shutdown(errorMessage, modal = false) {
|
|
1771
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
2025
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
2026
|
+
try {
|
|
2027
|
+
(_b = (_a = this.projectManager) === null || _a === void 0 ? void 0 : _a.dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
2028
|
+
}
|
|
2029
|
+
catch (e) {
|
|
2030
|
+
this.logger.error(e);
|
|
2031
|
+
}
|
|
2032
|
+
try {
|
|
2033
|
+
(_c = this.componentLibraryServer) === null || _c === void 0 ? void 0 : _c.stop();
|
|
2034
|
+
}
|
|
2035
|
+
catch (e) {
|
|
2036
|
+
this.logger.error(e);
|
|
2037
|
+
}
|
|
2038
|
+
try {
|
|
2039
|
+
void ((_e = (_d = this.rendezvousTracker) === null || _d === void 0 ? void 0 : _d.destroy) === null || _e === void 0 ? void 0 : _e.call(_d));
|
|
2040
|
+
}
|
|
2041
|
+
catch (e) {
|
|
2042
|
+
this.logger.error(e);
|
|
2043
|
+
}
|
|
2044
|
+
try {
|
|
2045
|
+
(_g = (_f = this.sourceMapManager) === null || _f === void 0 ? void 0 : _f.destroy) === null || _g === void 0 ? void 0 : _g.call(_f);
|
|
2046
|
+
}
|
|
2047
|
+
catch (e) {
|
|
2048
|
+
this.logger.error(e);
|
|
2049
|
+
}
|
|
1772
2050
|
try {
|
|
1773
|
-
(_a = this.componentLibraryServer) === null || _a === void 0 ? void 0 : _a.stop();
|
|
1774
|
-
void ((_c = (_b = this.rendezvousTracker) === null || _b === void 0 ? void 0 : _b.destroy) === null || _c === void 0 ? void 0 : _c.call(_b));
|
|
1775
|
-
try {
|
|
1776
|
-
(_e = (_d = this.sourceMapManager) === null || _d === void 0 ? void 0 : _d.destroy) === null || _e === void 0 ? void 0 : _e.call(_d);
|
|
1777
|
-
}
|
|
1778
|
-
catch (e) {
|
|
1779
|
-
this.logger.error(e);
|
|
1780
|
-
}
|
|
1781
2051
|
//if configured, delete the staging directory
|
|
1782
2052
|
if (!this.launchConfiguration.retainStagingFolder) {
|
|
1783
|
-
const stagingDirs = (
|
|
2053
|
+
const stagingDirs = (_j = (_h = this.projectManager) === null || _h === void 0 ? void 0 : _h.getStagingDirs()) !== null && _j !== void 0 ? _j : [];
|
|
1784
2054
|
this.logger.info('deleting staging folders', stagingDirs);
|
|
1785
2055
|
for (let stagingDir of stagingDirs) {
|
|
1786
2056
|
try {
|
|
@@ -1792,13 +2062,23 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
1792
2062
|
}
|
|
1793
2063
|
}
|
|
1794
2064
|
}
|
|
2065
|
+
}
|
|
2066
|
+
catch (e) {
|
|
2067
|
+
this.logger.error(e);
|
|
2068
|
+
}
|
|
2069
|
+
try {
|
|
1795
2070
|
//if there was an error message, display it to the user
|
|
1796
2071
|
if (errorMessage) {
|
|
1797
2072
|
this.logger.error(errorMessage);
|
|
1798
2073
|
this.showPopupMessage(errorMessage, 'error', modal);
|
|
1799
2074
|
}
|
|
2075
|
+
}
|
|
2076
|
+
catch (e) {
|
|
2077
|
+
this.logger.error(e);
|
|
2078
|
+
}
|
|
2079
|
+
try {
|
|
1800
2080
|
this.logger.log('Destroy rokuAdapter');
|
|
1801
|
-
await ((
|
|
2081
|
+
await ((_l = (_k = this.rokuAdapter) === null || _k === void 0 ? void 0 : _k.destroy) === null || _l === void 0 ? void 0 : _l.call(_k));
|
|
1802
2082
|
//press the home button to return to the home screen
|
|
1803
2083
|
try {
|
|
1804
2084
|
this.logger.log('Press home button');
|
|
@@ -1807,6 +2087,11 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
1807
2087
|
catch (e) {
|
|
1808
2088
|
this.logger.error(e);
|
|
1809
2089
|
}
|
|
2090
|
+
}
|
|
2091
|
+
catch (e) {
|
|
2092
|
+
this.logger.error(e);
|
|
2093
|
+
}
|
|
2094
|
+
try {
|
|
1810
2095
|
this.logger.log('Send terminated event');
|
|
1811
2096
|
this.sendEvent(new debugadapter_1.TerminatedEvent());
|
|
1812
2097
|
//shut down the process
|