roku-debug 0.21.18 → 0.21.20
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 +23 -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/adapters/customVariables/ifGetMessagePort.js +3 -2
- package/dist/adapters/customVariables/ifGetMessagePort.js.map +1 -1
- package/dist/adapters/customVariables/ifImageMetadata.js +4 -4
- package/dist/adapters/customVariables/ifImageMetadata.js.map +1 -1
- package/dist/adapters/customVariables/ifRegion.js +2 -2
- package/dist/adapters/customVariables/ifRegion.js.map +1 -1
- package/dist/adapters/customVariables/ifSGNodeChildren.js +1 -1
- package/dist/adapters/customVariables/ifSGNodeChildren.js.map +1 -1
- package/dist/adapters/customVariables/ifSGNodeField.js +1 -1
- package/dist/adapters/customVariables/ifSGNodeField.js.map +1 -1
- package/dist/adapters/customVariables/ifSGNodeHttpAgentAccess.js +3 -2
- package/dist/adapters/customVariables/ifSGNodeHttpAgentAccess.js.map +1 -1
- package/dist/adapters/customVariables/ifSGScreen.js +3 -3
- package/dist/adapters/customVariables/ifSGScreen.js.map +1 -1
- package/dist/adapters/customVariables/ifSocket.js +6 -6
- package/dist/adapters/customVariables/ifSocket.js.map +1 -1
- package/dist/adapters/customVariables/ifSprite.js +2 -2
- package/dist/adapters/customVariables/ifSprite.js.map +1 -1
- package/dist/adapters/customVariables/ifVideoPlayer.js +2 -2
- package/dist/adapters/customVariables/ifVideoPlayer.js.map +1 -1
- package/dist/adapters/customVariables/ifXMLElement.js +4 -4
- package/dist/adapters/customVariables/ifXMLElement.js.map +1 -1
- package/dist/adapters/customVariables/ifXMLList.js +4 -4
- package/dist/adapters/customVariables/ifXMLList.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 +16 -0
- package/dist/debugSession/BrightScriptDebugSession.js +342 -23
- package/dist/debugSession/BrightScriptDebugSession.js.map +1 -1
- package/dist/debugSession/ecpRegistryUtils.d.ts +11 -0
- package/dist/debugSession/ecpRegistryUtils.js +168 -0
- package/dist/debugSession/ecpRegistryUtils.js.map +1 -0
- package/dist/interfaces.d.ts +12 -0
- package/dist/managers/BreakpointManager.d.ts +10 -0
- package/dist/managers/BreakpointManager.js +15 -5
- package/dist/managers/BreakpointManager.js.map +1 -1
- 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 +10 -1
- package/dist/util.js +36 -0
- package/dist/util.js.map +1 -1
- package/package.json +2 -2
- package/roku-debug-0.21.20.tgz +0 -0
- package/roku-debug-0.21.18.tgz +0 -0
|
@@ -23,6 +23,10 @@ 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");
|
|
29
|
+
const ecpRegistryUtils_1 = require("./ecpRegistryUtils");
|
|
26
30
|
const diagnosticSource = 'roku-debug';
|
|
27
31
|
class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
28
32
|
constructor() {
|
|
@@ -73,7 +77,10 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
73
77
|
this.breakpointManager = new BreakpointManager_1.BreakpointManager(this.sourceMapManager, this.locationManager);
|
|
74
78
|
//send newly-verified breakpoints to vscode
|
|
75
79
|
this.breakpointManager.on('breakpoints-verified', (data) => this.onDeviceBreakpointsChanged('changed', data));
|
|
76
|
-
this.projectManager = new ProjectManager_1.ProjectManager(
|
|
80
|
+
this.projectManager = new ProjectManager_1.ProjectManager({
|
|
81
|
+
breakpointManager: this.breakpointManager,
|
|
82
|
+
locationManager: this.locationManager
|
|
83
|
+
});
|
|
77
84
|
this.fileLoggingManager = new logging_1.FileLoggingManager();
|
|
78
85
|
}
|
|
79
86
|
onDeviceBreakpointsChanged(eventName, data) {
|
|
@@ -85,6 +92,8 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
85
92
|
column: breakpoint.column,
|
|
86
93
|
verified: breakpoint.verified,
|
|
87
94
|
id: breakpoint.id,
|
|
95
|
+
reason: breakpoint.reason,
|
|
96
|
+
message: breakpoint.message,
|
|
88
97
|
source: {
|
|
89
98
|
path: breakpoint.srcPath
|
|
90
99
|
}
|
|
@@ -143,6 +152,8 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
143
152
|
response.body.supportsHitConditionalBreakpoints = true;
|
|
144
153
|
// This debug adapter supports log points by interpreting the 'logMessage' attribute of the SourceBreakpoint
|
|
145
154
|
response.body.supportsLogPoints = true;
|
|
155
|
+
response.body.supportsCompletionsRequest = true;
|
|
156
|
+
response.body.completionTriggerCharacters = ['.', '(', '{', ',', ' '];
|
|
146
157
|
this.sendResponse(response);
|
|
147
158
|
//register the debug output log transport writer
|
|
148
159
|
logging_1.debugServerLogOutputEventTransport.setWriter((message) => {
|
|
@@ -245,7 +256,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
245
256
|
* @returns
|
|
246
257
|
*/
|
|
247
258
|
normalizeLaunchConfig(config) {
|
|
248
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
259
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
249
260
|
(_a = config.cwd) !== null && _a !== void 0 ? _a : (config.cwd = process.cwd());
|
|
250
261
|
(_b = config.outDir) !== null && _b !== void 0 ? _b : (config.outDir = (0, FileUtils_1.standardizePath) `${config.cwd}/out`);
|
|
251
262
|
(_c = config.stagingDir) !== null && _c !== void 0 ? _c : (config.stagingDir = (0, FileUtils_1.standardizePath) `${config.outDir}/.roku-deploy-staging`);
|
|
@@ -259,14 +270,17 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
259
270
|
(_l = config.emitChannelPublishedEvent) !== null && _l !== void 0 ? _l : (config.emitChannelPublishedEvent = true);
|
|
260
271
|
(_m = config.rewriteDevicePathsInLogs) !== null && _m !== void 0 ? _m : (config.rewriteDevicePathsInLogs = true);
|
|
261
272
|
(_o = config.autoResolveVirtualVariables) !== null && _o !== void 0 ? _o : (config.autoResolveVirtualVariables = false);
|
|
273
|
+
(_p = config.enhanceREPLCompletions) !== null && _p !== void 0 ? _p : (config.enhanceREPLCompletions = true);
|
|
262
274
|
return config;
|
|
263
275
|
}
|
|
264
276
|
async launchRequest(response, config) {
|
|
265
|
-
var _a, _b;
|
|
266
|
-
this.logger.
|
|
277
|
+
var _a, _b, _c, _d, _e;
|
|
278
|
+
const logEnd = this.logger.timeStart('log', '[launchRequest] launch');
|
|
267
279
|
//send the response right away so the UI immediately shows the debugger toolbar
|
|
268
280
|
this.sendResponse(response);
|
|
269
281
|
this.launchConfiguration = this.normalizeLaunchConfig(config);
|
|
282
|
+
//prebake some threads for our ProjectManager to use later on (1 for the main project, and 1 for every complib)
|
|
283
|
+
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
284
|
//set the logLevel provided by the launch config
|
|
271
285
|
if (this.launchConfiguration.logLevel) {
|
|
272
286
|
logging_1.logger.logLevel = this.launchConfiguration.logLevel;
|
|
@@ -289,7 +303,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
289
303
|
return this.shutdown(`Developer mode is not enabled for host '${this.launchConfiguration.host}'.`);
|
|
290
304
|
}
|
|
291
305
|
//initialize all file logging (rokuDevice, debugger, etc)
|
|
292
|
-
this.fileLoggingManager.activate((
|
|
306
|
+
this.fileLoggingManager.activate((_d = this.launchConfiguration) === null || _d === void 0 ? void 0 : _d.fileLogging, this.cwd);
|
|
293
307
|
this.projectManager.launchConfiguration = this.launchConfiguration;
|
|
294
308
|
this.breakpointManager.launchConfiguration = this.launchConfiguration;
|
|
295
309
|
this.sendEvent(new Events_1.LaunchStartEvent(this.launchConfiguration));
|
|
@@ -407,9 +421,10 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
407
421
|
util_1.util.log(e === null || e === void 0 ? void 0 : e.stack);
|
|
408
422
|
this.sendErrorResponse(response, -1, e === null || e === void 0 ? void 0 : e.stack);
|
|
409
423
|
//send any compile errors to the client
|
|
410
|
-
await ((
|
|
424
|
+
await ((_e = this.rokuAdapter) === null || _e === void 0 ? void 0 : _e.sendErrors());
|
|
411
425
|
}
|
|
412
426
|
}
|
|
427
|
+
logEnd();
|
|
413
428
|
//at this point, the project has been deployed. If we need to use a deep link, launch it now.
|
|
414
429
|
if (this.launchConfiguration.deepLinkUrl) {
|
|
415
430
|
//wait until the first entry breakpoint has been hit
|
|
@@ -739,7 +754,8 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
739
754
|
injectRdbOnDeviceComponent: this.launchConfiguration.injectRdbOnDeviceComponent,
|
|
740
755
|
rdbFilesBasePath: this.launchConfiguration.rdbFilesBasePath,
|
|
741
756
|
stagingDir: this.launchConfiguration.stagingDir,
|
|
742
|
-
packagePath: this.launchConfiguration.packagePath
|
|
757
|
+
packagePath: this.launchConfiguration.packagePath,
|
|
758
|
+
enhanceREPLCompletions: this.launchConfiguration.enhanceREPLCompletions
|
|
743
759
|
});
|
|
744
760
|
util_1.util.log('Moving selected files to staging area');
|
|
745
761
|
await this.projectManager.mainProject.stage();
|
|
@@ -810,7 +826,8 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
810
826
|
bsConst: componentLibrary.bsConst,
|
|
811
827
|
injectRaleTrackerTask: componentLibrary.injectRaleTrackerTask,
|
|
812
828
|
raleTrackerTaskFileLocation: componentLibrary.raleTrackerTaskFileLocation,
|
|
813
|
-
libraryIndex: libraryIndex
|
|
829
|
+
libraryIndex: libraryIndex,
|
|
830
|
+
enhanceREPLCompletions: this.launchConfiguration.enhanceREPLCompletions
|
|
814
831
|
}));
|
|
815
832
|
}
|
|
816
833
|
//prepare all of the libraries in parallel
|
|
@@ -985,13 +1002,35 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
985
1002
|
v.request_seq = response.request_seq;
|
|
986
1003
|
v.frameId = args.frameId;
|
|
987
1004
|
}
|
|
988
|
-
|
|
989
|
-
|
|
1005
|
+
scopes.push({
|
|
1006
|
+
name: 'Local',
|
|
1007
|
+
variablesReference: v.variablesReference,
|
|
1008
|
+
expensive: false,
|
|
1009
|
+
presentationHint: 'locals'
|
|
1010
|
+
});
|
|
990
1011
|
}
|
|
991
1012
|
else {
|
|
992
1013
|
// NOTE: Legacy telnet support
|
|
993
|
-
scopes.push(
|
|
1014
|
+
scopes.push({
|
|
1015
|
+
name: 'Local',
|
|
1016
|
+
variablesReference: this.variableHandles.create('local'),
|
|
1017
|
+
expensive: false,
|
|
1018
|
+
presentationHint: 'locals'
|
|
1019
|
+
});
|
|
994
1020
|
}
|
|
1021
|
+
let refId = this.getEvaluateRefId('$$registry', Infinity);
|
|
1022
|
+
scopes.push({
|
|
1023
|
+
name: 'Registry',
|
|
1024
|
+
variablesReference: refId,
|
|
1025
|
+
expensive: true
|
|
1026
|
+
});
|
|
1027
|
+
this.variables[refId] = {
|
|
1028
|
+
variablesReference: refId,
|
|
1029
|
+
name: 'Registry',
|
|
1030
|
+
value: '',
|
|
1031
|
+
type: '$$Registry',
|
|
1032
|
+
childVariables: []
|
|
1033
|
+
};
|
|
995
1034
|
response.body = {
|
|
996
1035
|
scopes: scopes
|
|
997
1036
|
};
|
|
@@ -1138,6 +1177,13 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
1138
1177
|
return this.sendResponse(response);
|
|
1139
1178
|
}
|
|
1140
1179
|
logger.log('variable', v);
|
|
1180
|
+
if (v.type === '$$Registry' && v.childVariables.length === 0) {
|
|
1181
|
+
// This is a special scope variable used to load registry data via an ECP call
|
|
1182
|
+
const url = `http://${this.launchConfiguration.host}:${this.launchConfiguration.remotePort}/query/registry/dev`;
|
|
1183
|
+
// Send the registry ECP call for the `dev` app as side loaded apps are always `dev`
|
|
1184
|
+
const response = await util_1.util.httpGet(url);
|
|
1185
|
+
await (0, ecpRegistryUtils_1.populateVariableFromRegistryEcp)(response, v, this.variables, this.getEvaluateRefId.bind(this));
|
|
1186
|
+
}
|
|
1141
1187
|
//query for child vars if we haven't done it yet or DAP is asking to resolve a lazy variable
|
|
1142
1188
|
if (v.childVariables.length === 0 || v.isResolved) {
|
|
1143
1189
|
let tempVar;
|
|
@@ -1199,8 +1245,10 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
1199
1245
|
updatedVariables = v.childVariables;
|
|
1200
1246
|
}
|
|
1201
1247
|
}
|
|
1248
|
+
// Only send the updated variables if we are not going to trigger an invalidated event.
|
|
1249
|
+
// This is to prevent the UI from updating twice and makes the experience much smoother to the end user.
|
|
1202
1250
|
response.body = {
|
|
1203
|
-
variables: this.filterVariablesUpdates(updatedVariables, args, this.variables[args.variablesReference])
|
|
1251
|
+
variables: sendInvalidatedEvent ? [] : this.filterVariablesUpdates(updatedVariables, args, this.variables[args.variablesReference])
|
|
1204
1252
|
};
|
|
1205
1253
|
}
|
|
1206
1254
|
catch (error) {
|
|
@@ -1436,6 +1484,246 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
1436
1484
|
}
|
|
1437
1485
|
return results;
|
|
1438
1486
|
}
|
|
1487
|
+
async completionsRequest(response, args, request) {
|
|
1488
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
1489
|
+
this.logger.log('completionsRequest', args, request);
|
|
1490
|
+
// this.sendEvent(new LogOutputEvent(`completionsRequest: ${args.text}`));
|
|
1491
|
+
// this.sendEvent(new OutputEvent(`completionsRequest: ${args.text}\n`, 'stderr'));
|
|
1492
|
+
try {
|
|
1493
|
+
let supplyLocalScopeCompletions = false;
|
|
1494
|
+
let closestCompletionDetails = this.getClosestCompletionDetails(args);
|
|
1495
|
+
if (!closestCompletionDetails) {
|
|
1496
|
+
// If the cursor is not at the end of the line, then we should not supply completions at this time
|
|
1497
|
+
response.body = {
|
|
1498
|
+
targets: []
|
|
1499
|
+
};
|
|
1500
|
+
return this.sendResponse(response);
|
|
1501
|
+
}
|
|
1502
|
+
let completions = new Map();
|
|
1503
|
+
let parentVariablePath = closestCompletionDetails.parentVariablePath;
|
|
1504
|
+
// Get the completions if the variable path was valid
|
|
1505
|
+
if (parentVariablePath) {
|
|
1506
|
+
// If the parent variable path is an empty string, then we are looking up the local scope variables and global functions
|
|
1507
|
+
if (parentVariablePath.length === 1 && parentVariablePath[0] === '') {
|
|
1508
|
+
supplyLocalScopeCompletions = true;
|
|
1509
|
+
}
|
|
1510
|
+
// Look up the parent variable
|
|
1511
|
+
let parentVariable = this.findVariableByPath(Object.values(this.variables), parentVariablePath, args.frameId);
|
|
1512
|
+
if (!parentVariable || parentVariable.childVariables.length === 0) {
|
|
1513
|
+
// We did not find the parent variable, so try to look it up from the device
|
|
1514
|
+
try {
|
|
1515
|
+
let { evalArgs } = await this.evaluateExpressionToTempVar({ expression: parentVariablePath.join('.'), frameId: args.frameId }, parentVariablePath);
|
|
1516
|
+
let result = await this.rokuAdapter.getVariable(evalArgs.expression, args.frameId);
|
|
1517
|
+
parentVariable = await this.getVariableFromResult(result, args.frameId);
|
|
1518
|
+
}
|
|
1519
|
+
catch (error) {
|
|
1520
|
+
this.logger.error('Error looking up parent completions', error, { parentVariablePath });
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
// provide completions for the parent variable if one was found
|
|
1524
|
+
if (parentVariable) {
|
|
1525
|
+
let possibleFieldsAndMethods = [];
|
|
1526
|
+
// Filter out virtual variables
|
|
1527
|
+
possibleFieldsAndMethods = parentVariable.childVariables.filter((v) => { var _a; return ((_a = v.presentationHint) === null || _a === void 0 ? void 0 : _a.kind) !== 'virtual'; });
|
|
1528
|
+
for (let v of possibleFieldsAndMethods) {
|
|
1529
|
+
// Default completion type should be variable
|
|
1530
|
+
let completionType = 'variable';
|
|
1531
|
+
if (!supplyLocalScopeCompletions) {
|
|
1532
|
+
// We are not supplying local scope completions, so we need to determine the completion type relative to the parent variable
|
|
1533
|
+
if (parentVariable.type === 'roSGNode' || parentVariable.type === VariablesResponse_1.VariableType.AssociativeArray || parentVariable.type === VariablesResponse_1.VariableType.Object) {
|
|
1534
|
+
completionType = 'field';
|
|
1535
|
+
}
|
|
1536
|
+
switch (v.type) {
|
|
1537
|
+
case VariablesResponse_1.VariableType.Function:
|
|
1538
|
+
case VariablesResponse_1.VariableType.Subroutine:
|
|
1539
|
+
completionType = 'method';
|
|
1540
|
+
break;
|
|
1541
|
+
default:
|
|
1542
|
+
break;
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
let label = v.name;
|
|
1546
|
+
if (parentVariable.type === VariablesResponse_1.VariableType.Array ||
|
|
1547
|
+
parentVariable.type === VariablesResponse_1.VariableType.List ||
|
|
1548
|
+
parentVariable.type === 'roXMLList' ||
|
|
1549
|
+
parentVariable.type === 'roByteArray') {
|
|
1550
|
+
label = `[${v.name}]`;
|
|
1551
|
+
}
|
|
1552
|
+
completions.set(`${completionType}-${v.name}`, {
|
|
1553
|
+
label: label,
|
|
1554
|
+
type: completionType,
|
|
1555
|
+
sortText: '000000'
|
|
1556
|
+
});
|
|
1557
|
+
}
|
|
1558
|
+
let parentComponentType = this.debuggerVarTypeToRoType(parentVariable.type).toLowerCase();
|
|
1559
|
+
//assemble a list of all methods on the parent component
|
|
1560
|
+
const methods = [
|
|
1561
|
+
//if the parent variable is an actual interface (if applicable) Ex: `ifString` or `ifArray`
|
|
1562
|
+
...(_b = (_a = roku_types_1.interfaces[parentComponentType]) === null || _a === void 0 ? void 0 : _a.methods) !== null && _b !== void 0 ? _b : [],
|
|
1563
|
+
//interfaces from component of this name (if applicable) Ex: `roSGNode` or `roDateTime`
|
|
1564
|
+
...(_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 : [],
|
|
1565
|
+
// Add parent event function completions (if applicable) Ex: `roSGNodeEvent` or `roDeviceInfoEvent`
|
|
1566
|
+
...(_f = (_e = roku_types_1.events[parentComponentType]) === null || _e === void 0 ? void 0 : _e.methods) !== null && _f !== void 0 ? _f : []
|
|
1567
|
+
].flat();
|
|
1568
|
+
// Based on the results of interface, component, and event looks up, add all the methods to the completions
|
|
1569
|
+
for (const method of methods) {
|
|
1570
|
+
completions.set(`method-${method.name}`, {
|
|
1571
|
+
label: method.name,
|
|
1572
|
+
type: 'method',
|
|
1573
|
+
detail: (_g = method.description) !== null && _g !== void 0 ? _g : '',
|
|
1574
|
+
sortText: '000000'
|
|
1575
|
+
});
|
|
1576
|
+
}
|
|
1577
|
+
// Add the global functions to the completions results
|
|
1578
|
+
if (supplyLocalScopeCompletions) {
|
|
1579
|
+
for (let globalCallable of globalCallables_1.globalCallables) {
|
|
1580
|
+
completions.set(`function-${globalCallable.name.toLocaleLowerCase()}`, {
|
|
1581
|
+
label: globalCallable.name,
|
|
1582
|
+
type: 'function',
|
|
1583
|
+
detail: (_j = (_h = globalCallable.shortDescription) !== null && _h !== void 0 ? _h : globalCallable.documentation) !== null && _j !== void 0 ? _j : '',
|
|
1584
|
+
sortText: '000000'
|
|
1585
|
+
});
|
|
1586
|
+
}
|
|
1587
|
+
const frame = this.rokuAdapter.getStackFrameById(args.frameId);
|
|
1588
|
+
let scopeFunctions = await this.projectManager.getScopeFunctionsForFile(frame.filePath);
|
|
1589
|
+
for (let scopeFunction of scopeFunctions) {
|
|
1590
|
+
if (!completions.has(`${scopeFunction.completionItemKind}-${scopeFunction.name.toLocaleLowerCase()}`)) {
|
|
1591
|
+
completions.set(`${scopeFunction.completionItemKind}-${scopeFunction.name.toLocaleLowerCase()}`, {
|
|
1592
|
+
label: scopeFunction.name,
|
|
1593
|
+
type: scopeFunction.completionItemKind,
|
|
1594
|
+
sortText: '000000'
|
|
1595
|
+
});
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
// this.sendEvent(new LogOutputEvent(`text: ${args.text} | completions: ${completions.map(v => v.label).join(', ')}`));
|
|
1602
|
+
// this.sendEvent(new OutputEvent(`text: ${args.text} | completions: ${completions.map(v => v.label).join(', ')}\n`, 'stderr'));
|
|
1603
|
+
response.body = {
|
|
1604
|
+
targets: [...completions.values()]
|
|
1605
|
+
};
|
|
1606
|
+
}
|
|
1607
|
+
catch (error) {
|
|
1608
|
+
// this.sendEvent(new LogOutputEvent(`text: ${args.text} | ${error}`));
|
|
1609
|
+
// this.sendEvent(new OutputEvent(`text: ${args.text} | ${error}\n`, 'stderr'));
|
|
1610
|
+
this.logger.error('Error during completionsRequest', error, { args });
|
|
1611
|
+
}
|
|
1612
|
+
this.sendResponse(response);
|
|
1613
|
+
}
|
|
1614
|
+
/**
|
|
1615
|
+
* Gets the closest completion details the incoming completion request.
|
|
1616
|
+
*/
|
|
1617
|
+
getClosestCompletionDetails(args) {
|
|
1618
|
+
var _a;
|
|
1619
|
+
const incomingText = args.text;
|
|
1620
|
+
const lines = incomingText.split('\n');
|
|
1621
|
+
let lineNumber = (_a = args.line) !== null && _a !== void 0 ? _a : (this.initRequestArgs.linesStartAt1 ? 1 : 0);
|
|
1622
|
+
let column = args.column;
|
|
1623
|
+
// Make sure to correct the line and column to 0-based
|
|
1624
|
+
// if they are being sent as 1-based from the client
|
|
1625
|
+
if (this.initRequestArgs.linesStartAt1) {
|
|
1626
|
+
lineNumber--;
|
|
1627
|
+
}
|
|
1628
|
+
if (this.initRequestArgs.columnsStartAt1) {
|
|
1629
|
+
column--;
|
|
1630
|
+
}
|
|
1631
|
+
const targetLine = lines[lineNumber];
|
|
1632
|
+
let variablePathString = '';
|
|
1633
|
+
let i = column - 1;
|
|
1634
|
+
const variableChars = /[a-z0-9_\.]/i;
|
|
1635
|
+
// 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.
|
|
1636
|
+
if (targetLine.length - 1 > i && variableChars.test(targetLine[i + 1])) {
|
|
1637
|
+
return undefined;
|
|
1638
|
+
}
|
|
1639
|
+
// Find the start of the variable path by looking for the first non-alphanumeric or non_underscore character before the cursor
|
|
1640
|
+
while (i >= 0 && (variableChars.test(targetLine[i]))) {
|
|
1641
|
+
i--;
|
|
1642
|
+
}
|
|
1643
|
+
// Pull the variable path string from the line
|
|
1644
|
+
variablePathString = targetLine.slice(i + 1, column);
|
|
1645
|
+
// Attempted dot access something unexpected
|
|
1646
|
+
// Example: `getPerson().name` where `getPerson()` is not a valid variable
|
|
1647
|
+
// and results in `.name` being the variable path string
|
|
1648
|
+
if (variablePathString.startsWith('.')) {
|
|
1649
|
+
return undefined;
|
|
1650
|
+
}
|
|
1651
|
+
// Get the variable path from the text
|
|
1652
|
+
let variablePath = [];
|
|
1653
|
+
if (!variablePathString.trim()) {
|
|
1654
|
+
// The text was empty so assume via '' that we are looking up the local scope variables and global functions
|
|
1655
|
+
variablePath = [''];
|
|
1656
|
+
}
|
|
1657
|
+
else if (variablePathString.endsWith('.')) {
|
|
1658
|
+
// supplied text ends with a period, so strip it off to create a valid variable path
|
|
1659
|
+
variablePath = util_1.util.getVariablePath(variablePathString.slice(0, -1));
|
|
1660
|
+
}
|
|
1661
|
+
else {
|
|
1662
|
+
variablePath = util_1.util.getVariablePath(variablePathString);
|
|
1663
|
+
}
|
|
1664
|
+
// the target string is not a valid variable path
|
|
1665
|
+
if (!variablePath) {
|
|
1666
|
+
return undefined;
|
|
1667
|
+
}
|
|
1668
|
+
let parentVariablePath;
|
|
1669
|
+
// If the last character is a period, then pull completions for the parent variable before the period
|
|
1670
|
+
if (variablePathString.endsWith('.')) {
|
|
1671
|
+
parentVariablePath = variablePath;
|
|
1672
|
+
}
|
|
1673
|
+
else {
|
|
1674
|
+
// Otherwise, pull completions for the parent variable
|
|
1675
|
+
parentVariablePath = variablePath.slice(0, variablePath.length - 1);
|
|
1676
|
+
}
|
|
1677
|
+
// If the parent variable path is empty or an empty string, then we are looking up the local scope variables and global functions
|
|
1678
|
+
if (parentVariablePath.length === 0) {
|
|
1679
|
+
parentVariablePath = [''];
|
|
1680
|
+
}
|
|
1681
|
+
return { parentVariablePath: parentVariablePath };
|
|
1682
|
+
}
|
|
1683
|
+
findVariableByPath(variables, path, frameId) {
|
|
1684
|
+
var _a;
|
|
1685
|
+
let current = null;
|
|
1686
|
+
for (const name of path) {
|
|
1687
|
+
// Find the object matching the current name in the data
|
|
1688
|
+
current = (_a = (Array.isArray(variables) ? variables : current === null || current === void 0 ? void 0 : current.childVariables)) === null || _a === void 0 ? void 0 : _a.find(obj => {
|
|
1689
|
+
return obj.name === name && obj.frameId === frameId;
|
|
1690
|
+
});
|
|
1691
|
+
// If no match is found, return null
|
|
1692
|
+
if (!current) {
|
|
1693
|
+
return null;
|
|
1694
|
+
}
|
|
1695
|
+
// Move to the children for the next iteration
|
|
1696
|
+
variables = current.childVariables;
|
|
1697
|
+
}
|
|
1698
|
+
return current;
|
|
1699
|
+
}
|
|
1700
|
+
debuggerVarTypeToRoType(type) {
|
|
1701
|
+
switch (type) {
|
|
1702
|
+
case VariablesResponse_1.VariableType.Function:
|
|
1703
|
+
case VariablesResponse_1.VariableType.Subroutine:
|
|
1704
|
+
return 'roFunction';
|
|
1705
|
+
case VariablesResponse_1.VariableType.AssociativeArray:
|
|
1706
|
+
return 'roAssociativeArray';
|
|
1707
|
+
case VariablesResponse_1.VariableType.List:
|
|
1708
|
+
return 'roList';
|
|
1709
|
+
case VariablesResponse_1.VariableType.Array:
|
|
1710
|
+
return 'roArray';
|
|
1711
|
+
case VariablesResponse_1.VariableType.Boolean:
|
|
1712
|
+
return 'roBoolean';
|
|
1713
|
+
case VariablesResponse_1.VariableType.Double:
|
|
1714
|
+
return 'roDouble';
|
|
1715
|
+
case VariablesResponse_1.VariableType.Float:
|
|
1716
|
+
return 'roFloat';
|
|
1717
|
+
case VariablesResponse_1.VariableType.Integer:
|
|
1718
|
+
return 'roInteger';
|
|
1719
|
+
case VariablesResponse_1.VariableType.LongInteger:
|
|
1720
|
+
return 'roLongInteger';
|
|
1721
|
+
case VariablesResponse_1.VariableType.String:
|
|
1722
|
+
return 'roString';
|
|
1723
|
+
default:
|
|
1724
|
+
return type;
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1439
1727
|
/**
|
|
1440
1728
|
* Called when the host stops debugging
|
|
1441
1729
|
* @param response
|
|
@@ -1768,19 +2056,35 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
1768
2056
|
return this.shutdownPromise;
|
|
1769
2057
|
}
|
|
1770
2058
|
async _shutdown(errorMessage, modal = false) {
|
|
1771
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
2059
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
2060
|
+
try {
|
|
2061
|
+
(_b = (_a = this.projectManager) === null || _a === void 0 ? void 0 : _a.dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
2062
|
+
}
|
|
2063
|
+
catch (e) {
|
|
2064
|
+
this.logger.error(e);
|
|
2065
|
+
}
|
|
2066
|
+
try {
|
|
2067
|
+
(_c = this.componentLibraryServer) === null || _c === void 0 ? void 0 : _c.stop();
|
|
2068
|
+
}
|
|
2069
|
+
catch (e) {
|
|
2070
|
+
this.logger.error(e);
|
|
2071
|
+
}
|
|
2072
|
+
try {
|
|
2073
|
+
void ((_e = (_d = this.rendezvousTracker) === null || _d === void 0 ? void 0 : _d.destroy) === null || _e === void 0 ? void 0 : _e.call(_d));
|
|
2074
|
+
}
|
|
2075
|
+
catch (e) {
|
|
2076
|
+
this.logger.error(e);
|
|
2077
|
+
}
|
|
2078
|
+
try {
|
|
2079
|
+
(_g = (_f = this.sourceMapManager) === null || _f === void 0 ? void 0 : _f.destroy) === null || _g === void 0 ? void 0 : _g.call(_f);
|
|
2080
|
+
}
|
|
2081
|
+
catch (e) {
|
|
2082
|
+
this.logger.error(e);
|
|
2083
|
+
}
|
|
1772
2084
|
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
2085
|
//if configured, delete the staging directory
|
|
1782
2086
|
if (!this.launchConfiguration.retainStagingFolder) {
|
|
1783
|
-
const stagingDirs = (
|
|
2087
|
+
const stagingDirs = (_j = (_h = this.projectManager) === null || _h === void 0 ? void 0 : _h.getStagingDirs()) !== null && _j !== void 0 ? _j : [];
|
|
1784
2088
|
this.logger.info('deleting staging folders', stagingDirs);
|
|
1785
2089
|
for (let stagingDir of stagingDirs) {
|
|
1786
2090
|
try {
|
|
@@ -1792,13 +2096,23 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
1792
2096
|
}
|
|
1793
2097
|
}
|
|
1794
2098
|
}
|
|
2099
|
+
}
|
|
2100
|
+
catch (e) {
|
|
2101
|
+
this.logger.error(e);
|
|
2102
|
+
}
|
|
2103
|
+
try {
|
|
1795
2104
|
//if there was an error message, display it to the user
|
|
1796
2105
|
if (errorMessage) {
|
|
1797
2106
|
this.logger.error(errorMessage);
|
|
1798
2107
|
this.showPopupMessage(errorMessage, 'error', modal);
|
|
1799
2108
|
}
|
|
2109
|
+
}
|
|
2110
|
+
catch (e) {
|
|
2111
|
+
this.logger.error(e);
|
|
2112
|
+
}
|
|
2113
|
+
try {
|
|
1800
2114
|
this.logger.log('Destroy rokuAdapter');
|
|
1801
|
-
await ((
|
|
2115
|
+
await ((_l = (_k = this.rokuAdapter) === null || _k === void 0 ? void 0 : _k.destroy) === null || _l === void 0 ? void 0 : _l.call(_k));
|
|
1802
2116
|
//press the home button to return to the home screen
|
|
1803
2117
|
try {
|
|
1804
2118
|
this.logger.log('Press home button');
|
|
@@ -1807,6 +2121,11 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
|
|
|
1807
2121
|
catch (e) {
|
|
1808
2122
|
this.logger.error(e);
|
|
1809
2123
|
}
|
|
2124
|
+
}
|
|
2125
|
+
catch (e) {
|
|
2126
|
+
this.logger.error(e);
|
|
2127
|
+
}
|
|
2128
|
+
try {
|
|
1810
2129
|
this.logger.log('Send terminated event');
|
|
1811
2130
|
this.sendEvent(new debugadapter_1.TerminatedEvent());
|
|
1812
2131
|
//shut down the process
|