roku-debug 0.21.12 → 0.21.14

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.
Files changed (49) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/CompileErrorProcessor.d.ts +65 -4
  3. package/dist/CompileErrorProcessor.js.map +1 -1
  4. package/dist/LaunchConfiguration.d.ts +1 -1
  5. package/dist/adapters/DebugProtocolAdapter.d.ts +11 -0
  6. package/dist/adapters/DebugProtocolAdapter.js +47 -10
  7. package/dist/adapters/DebugProtocolAdapter.js.map +1 -1
  8. package/dist/adapters/TelnetAdapter.d.ts +6 -0
  9. package/dist/adapters/TelnetAdapter.js +14 -5
  10. package/dist/adapters/TelnetAdapter.js.map +1 -1
  11. package/dist/adapters/customVariableUtils.d.ts +7 -0
  12. package/dist/adapters/customVariableUtils.js +44 -0
  13. package/dist/adapters/customVariableUtils.js.map +1 -0
  14. package/dist/cli.js +2 -2
  15. package/dist/cli.js.map +1 -1
  16. package/dist/debugProtocol/Constants.d.ts +44 -5
  17. package/dist/debugProtocol/Constants.js +39 -4
  18. package/dist/debugProtocol/Constants.js.map +1 -1
  19. package/dist/debugProtocol/client/DebugProtocolClient.d.ts +7 -2
  20. package/dist/debugProtocol/client/DebugProtocolClient.js +37 -7
  21. package/dist/debugProtocol/client/DebugProtocolClient.js.map +1 -1
  22. package/dist/debugProtocol/events/requests/SetExceptionBreakpointsRequest.d.ts +33 -0
  23. package/dist/debugProtocol/events/requests/SetExceptionBreakpointsRequest.js +73 -0
  24. package/dist/debugProtocol/events/requests/SetExceptionBreakpointsRequest.js.map +1 -0
  25. package/dist/debugProtocol/events/requests/VariablesRequest.d.ts +27 -1
  26. package/dist/debugProtocol/events/requests/VariablesRequest.js +47 -4
  27. package/dist/debugProtocol/events/requests/VariablesRequest.js.map +1 -1
  28. package/dist/debugProtocol/events/responses/SetExceptionBreakpointsResponse.d.ts +31 -0
  29. package/dist/debugProtocol/events/responses/SetExceptionBreakpointsResponse.js +59 -0
  30. package/dist/debugProtocol/events/responses/SetExceptionBreakpointsResponse.js.map +1 -0
  31. package/dist/debugProtocol/events/responses/VariablesResponse.d.ts +10 -1
  32. package/dist/debugProtocol/events/responses/VariablesResponse.js +11 -3
  33. package/dist/debugProtocol/events/responses/VariablesResponse.js.map +1 -1
  34. package/dist/debugProtocol/events/updates/ExceptionBreakpointErrorUpdate.d.ts +46 -0
  35. package/dist/debugProtocol/events/updates/ExceptionBreakpointErrorUpdate.js +103 -0
  36. package/dist/debugProtocol/events/updates/ExceptionBreakpointErrorUpdate.js.map +1 -0
  37. package/dist/debugProtocol/server/DebugProtocolServer.js +3 -0
  38. package/dist/debugProtocol/server/DebugProtocolServer.js.map +1 -1
  39. package/dist/debugSession/BrightScriptDebugSession.d.ts +6 -3
  40. package/dist/debugSession/BrightScriptDebugSession.js +143 -66
  41. package/dist/debugSession/BrightScriptDebugSession.js.map +1 -1
  42. package/dist/debugSession/Events.d.ts +1 -1
  43. package/dist/managers/BreakpointManager.d.ts +1 -1
  44. package/dist/util.d.ts +1 -0
  45. package/dist/util.js +3 -0
  46. package/dist/util.js.map +1 -1
  47. package/package.json +9 -9
  48. package/roku-debug-0.21.14.tgz +0 -0
  49. package/roku-debug-0.21.12.tgz +0 -0
@@ -5,7 +5,7 @@ const fsExtra = require("fs-extra");
5
5
  const natural_orderby_1 = require("natural-orderby");
6
6
  const path = require("path");
7
7
  const roku_deploy_1 = require("roku-deploy");
8
- const vscode_debugadapter_1 = require("vscode-debugadapter");
8
+ const debugadapter_1 = require("@vscode/debugadapter");
9
9
  const SceneGraphDebugCommandController_1 = require("../SceneGraphDebugCommandController");
10
10
  const util_1 = require("../util");
11
11
  const FileUtils_1 = require("../FileUtils");
@@ -23,7 +23,7 @@ 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 diagnosticSource = 'roku-debug';
26
- class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
26
+ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
27
27
  constructor() {
28
28
  super();
29
29
  this.logger = logging_1.logger.createLogger(`[session]`);
@@ -42,12 +42,13 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
42
42
  this.evaluateRefIdLookup = {};
43
43
  this.evaluateRefIdCounter = 1;
44
44
  this.variables = {};
45
- this.variableHandles = new vscode_debugadapter_1.Handles();
45
+ this.variableHandles = new debugadapter_1.Handles();
46
46
  this.tempVarPrefix = '__rokudebug__';
47
47
  /**
48
48
  * A magic number to represent a fake thread that will be used for showing compile errors in the UI as if they were runtime crashes
49
49
  */
50
50
  this.COMPILE_ERROR_THREAD_ID = 7777;
51
+ this.exceptionBreakpoints = [];
51
52
  this.evaluateRequestPromise = Promise.resolve();
52
53
  this.evaluateVarIndexByFrameId = new Map();
53
54
  /**
@@ -82,7 +83,7 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
82
83
  path: breakpoint.srcPath
83
84
  }
84
85
  };
85
- this.sendEvent(new vscode_debugadapter_1.BreakpointEvent(eventName, event));
86
+ this.sendEvent(new debugadapter_1.BreakpointEvent(eventName, event));
86
87
  }
87
88
  }
88
89
  get enableDebugProtocol() {
@@ -91,8 +92,10 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
91
92
  /**
92
93
  * Get a promise that resolves when the roku adapter is ready to be used
93
94
  */
94
- getRokuAdapter() {
95
- return this.rokuAdapterDeferred.promise;
95
+ async getRokuAdapter() {
96
+ await this.rokuAdapterDeferred.promise;
97
+ await this.rokuAdapter.onReady();
98
+ return this.rokuAdapter;
96
99
  }
97
100
  /**
98
101
  * The 'initialize' request is the first request called by the frontend
@@ -101,10 +104,6 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
101
104
  initializeRequest(response, args) {
102
105
  this.initRequestArgs = args;
103
106
  this.logger.log('initializeRequest');
104
- // since this debug adapter can accept configuration requests like 'setBreakpoint' at any time,
105
- // we request them early by sending an 'initializeRequest' to the frontend.
106
- // The frontend will end the configuration sequence by calling 'configurationDone' request.
107
- this.sendEvent(new vscode_debugadapter_1.InitializedEvent());
108
107
  response.body = response.body || {};
109
108
  // This debug adapter implements the configurationDoneRequest.
110
109
  response.body.supportsConfigurationDoneRequest = true;
@@ -116,6 +115,24 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
116
115
  response.body.supportsStepBack = false;
117
116
  // This debug adapter supports conditional breakpoints
118
117
  response.body.supportsConditionalBreakpoints = true;
118
+ response.body.supportsExceptionFilterOptions = true;
119
+ response.body.supportsExceptionOptions = true;
120
+ //the list of exception breakpoints (we have to send them all the time, even if the device doesn't support them)
121
+ response.body.exceptionBreakpointFilters = [{
122
+ filter: 'caught',
123
+ supportsCondition: true,
124
+ conditionDescription: '__brs_err__.rethrown = true',
125
+ label: 'Caught Exceptions',
126
+ description: `Breaks on all errors, even if they're caught later.`,
127
+ default: false
128
+ }, {
129
+ filter: 'uncaught',
130
+ supportsCondition: true,
131
+ conditionDescription: '__brs_err__.rethrown = true',
132
+ label: 'Uncaught Exceptions',
133
+ description: 'Breaks only on errors that are not handled.',
134
+ default: true
135
+ }];
119
136
  // This debug adapter supports breakpoints that break execution after a specified number of hits
120
137
  response.body.supportsHitConditionalBreakpoints = true;
121
138
  // This debug adapter supports log points by interpreting the 'logMessage' attribute of the SourceBreakpoint
@@ -125,8 +142,58 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
125
142
  logging_1.debugServerLogOutputEventTransport.setWriter((message) => {
126
143
  this.sendEvent(new Events_1.DebugServerLogOutputEvent(message.logger.formatMessage(message, false)));
127
144
  });
145
+ // since this debug adapter can accept configuration requests like 'setBreakpoint' at any time,
146
+ // we request them early by sending an 'initializeRequest' to the frontend.
147
+ // The frontend will end the configuration sequence by calling 'configurationDone' request.
148
+ this.sendEvent(new debugadapter_1.InitializedEvent());
128
149
  this.logger.log('initializeRequest finished');
129
150
  }
151
+ async setExceptionBreakPointsRequest(response, args) {
152
+ var _a;
153
+ (_a = response.body) !== null && _a !== void 0 ? _a : (response.body = {});
154
+ try {
155
+ let filterOptions;
156
+ if (args.filterOptions) {
157
+ filterOptions = args.filterOptions.map(x => ({
158
+ filter: x.filterId,
159
+ conditionExpression: x.condition
160
+ }));
161
+ }
162
+ else if (args.filters) {
163
+ filterOptions = args.filters.map(x => ({
164
+ filter: x
165
+ }));
166
+ }
167
+ this.exceptionBreakpoints = filterOptions;
168
+ //ensure the rokuAdapter is loaded
169
+ await this.getRokuAdapter();
170
+ if (this.rokuAdapter.supportsExceptionBreakpoints) {
171
+ await this.rokuAdapter.setExceptionBreakpoints(filterOptions);
172
+ //if success
173
+ response.body.breakpoints = [
174
+ { verified: true },
175
+ { verified: true }
176
+ ];
177
+ }
178
+ else {
179
+ response.body.breakpoints = [
180
+ { verified: false },
181
+ { verified: false }
182
+ ];
183
+ }
184
+ }
185
+ catch (e) {
186
+ //if error (or not supported)
187
+ response.body.breakpoints = [
188
+ { verified: false },
189
+ { verified: false }
190
+ ];
191
+ this.logger.error('Failed to set exception breakpoints', e);
192
+ }
193
+ finally {
194
+ this.sendResponse(response);
195
+ }
196
+ }
130
197
  showPopupMessage(message, severity, modal = false) {
131
198
  this.logger.trace('[showPopupMessage]', severity, message);
132
199
  this.sendEvent(new Events_1.PopupMessageEvent(message, severity, modal));
@@ -279,6 +346,9 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
279
346
  const message = 'App exit detected; but launchConfiguration.stopDebuggerOnAppExit is set to false, so keeping debug session running.';
280
347
  this.logger.log('[launchRequest]', message);
281
348
  this.sendEvent(new Events_1.LogOutputEvent(message));
349
+ void this.rokuAdapter.once('connected').then(async () => {
350
+ await this.rokuAdapter.setExceptionBreakpoints(this.exceptionBreakpoints);
351
+ });
282
352
  }
283
353
  });
284
354
  await this.publish();
@@ -388,7 +458,7 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
388
458
  //find the first compile error (i.e. first DiagnosticSeverity.Error) if there is one
389
459
  this.compileError = diagnostics.find(x => x.severity === brighterscript_1.DiagnosticSeverity.Error);
390
460
  if (this.compileError) {
391
- this.sendEvent(new vscode_debugadapter_1.StoppedEvent(Events_1.StoppedEventReason.exception, this.COMPILE_ERROR_THREAD_ID, `CompileError: ${this.compileError.message}`));
461
+ this.sendEvent(new debugadapter_1.StoppedEvent(Events_1.StoppedEventReason.exception, this.COMPILE_ERROR_THREAD_ID, `CompileError: ${this.compileError.message}`));
392
462
  }
393
463
  this.sendEvent(new Events_1.DiagnosticsEvent(diagnostics));
394
464
  }
@@ -409,8 +479,7 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
409
479
  const statusCode = (_b = (_a = e === null || e === void 0 ? void 0 : e.results) === null || _a === void 0 ? void 0 : _a.response) === null || _b === void 0 ? void 0 : _b.statusCode;
410
480
  const message = e.message;
411
481
  if (statusCode === 401) {
412
- this.showPopupMessage(message, 'error', true);
413
- await this.shutdown(message);
482
+ await this.shutdown(message, true);
414
483
  throw e;
415
484
  }
416
485
  this.logger.warn('Failed to delete the dev channel...probably not a big deal', e);
@@ -441,9 +510,8 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
441
510
  var _a, _b;
442
511
  const statusCode = (_b = (_a = e === null || e === void 0 ? void 0 : e.results) === null || _a === void 0 ? void 0 : _a.response) === null || _b === void 0 ? void 0 : _b.statusCode;
443
512
  const message = e.message;
444
- if (statusCode && statusCode !== 200) {
445
- this.showPopupMessage(message, 'error', true);
446
- await this.shutdown(message);
513
+ if ((statusCode && statusCode !== 200) || (0, roku_deploy_1.isUpdateCheckRequiredError)(e) || (0, roku_deploy_1.isConnectionResetError)(e)) {
514
+ await this.shutdown(message, true);
447
515
  throw e;
448
516
  }
449
517
  this.logger.error(e);
@@ -471,7 +539,7 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
471
539
  const lines = logOutput.split(/\r?\n/g);
472
540
  for (let line of lines) {
473
541
  line += '\n';
474
- this.sendEvent(new vscode_debugadapter_1.OutputEvent(line, 'stdout'));
542
+ this.sendEvent(new debugadapter_1.OutputEvent(line, 'stdout'));
475
543
  this.sendEvent(new Events_1.LogOutputEvent(line));
476
544
  }
477
545
  }
@@ -672,7 +740,7 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
672
740
  let threads = [];
673
741
  //This is a bit of a hack. If there's a compile error, send a thread to represent it so we can show the compile error like a runtime exception
674
742
  if (this.compileError) {
675
- threads.push(new vscode_debugadapter_1.Thread(this.COMPILE_ERROR_THREAD_ID, 'Compile Error'));
743
+ threads.push(new debugadapter_1.Thread(this.COMPILE_ERROR_THREAD_ID, 'Compile Error'));
676
744
  }
677
745
  else {
678
746
  //wait for the roku adapter to load
@@ -681,7 +749,7 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
681
749
  if (this.rokuAdapter.isAtDebuggerPrompt) {
682
750
  let rokuThreads = await this.rokuAdapter.getThreads();
683
751
  for (let thread of rokuThreads) {
684
- threads.push(new vscode_debugadapter_1.Thread(thread.threadId, `Thread ${thread.threadId}`));
752
+ threads.push(new debugadapter_1.Thread(thread.threadId, `Thread ${thread.threadId}`));
685
753
  }
686
754
  if (threads.length === 0) {
687
755
  threads = [{
@@ -707,12 +775,12 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
707
775
  let frames = [];
708
776
  //this is a bit of a hack. If there's a compile error, send a full stack frame so we can show the compile error like a runtime crash
709
777
  if (this.compileError) {
710
- frames.push(new vscode_debugadapter_1.StackFrame(0, 'Compile Error', new vscode_debugadapter_1.Source(path.basename(this.compileError.path), this.compileError.path),
778
+ frames.push(new debugadapter_1.StackFrame(0, 'Compile Error', new debugadapter_1.Source(path.basename(this.compileError.path), this.compileError.path),
711
779
  //diagnostics are 0 based, vscode expects 1 based
712
780
  this.compileError.range.start.line + 1, this.compileError.range.start.character + 1));
713
781
  }
714
782
  else if (args.threadId === 1001) {
715
- frames.push(new vscode_debugadapter_1.StackFrame(0, 'ERROR: threads would not stop', new vscode_debugadapter_1.Source('main.brs', (0, FileUtils_1.standardizePath) `${this.launchConfiguration.stagingDir}/manifest`), 1, 1));
783
+ frames.push(new debugadapter_1.StackFrame(0, 'ERROR: threads would not stop', new debugadapter_1.Source('main.brs', (0, FileUtils_1.standardizePath) `${this.launchConfiguration.stagingDir}/manifest`), 1, 1));
716
784
  this.showPopupMessage('Unable to suspend threads. Debugger is in an unstable state, please press Continue to resume debugging', 'warn');
717
785
  }
718
786
  else {
@@ -739,7 +807,7 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
739
807
  this.logger.error('Error correcting function identifier case', { error, sourceLocation, debugFrame });
740
808
  }
741
809
  const filePath = (_a = sourceLocation === null || sourceLocation === void 0 ? void 0 : sourceLocation.filePath) !== null && _a !== void 0 ? _a : debugFrame.filePath;
742
- const frame = new vscode_debugadapter_1.StackFrame(debugFrame.frameId, `${debugFrame.functionIdentifier}`, new vscode_debugadapter_1.Source(path.basename(filePath), filePath), (_b = sourceLocation === null || sourceLocation === void 0 ? void 0 : sourceLocation.lineNumber) !== null && _b !== void 0 ? _b : debugFrame.lineNumber, 1);
810
+ const frame = new debugadapter_1.StackFrame(debugFrame.frameId, `${debugFrame.functionIdentifier}`, new debugadapter_1.Source(path.basename(filePath), filePath), (_b = sourceLocation === null || sourceLocation === void 0 ? void 0 : sourceLocation.lineNumber) !== null && _b !== void 0 ? _b : debugFrame.lineNumber, 1);
743
811
  if (!sourceLocation) {
744
812
  frame.presentationHint = 'subtle';
745
813
  }
@@ -783,12 +851,12 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
783
851
  v.request_seq = response.request_seq;
784
852
  v.frameId = args.frameId;
785
853
  }
786
- let scope = new vscode_debugadapter_1.Scope('Local', refId, false);
854
+ let scope = new debugadapter_1.Scope('Local', refId, false);
787
855
  scopes.push(scope);
788
856
  }
789
857
  else {
790
858
  // NOTE: Legacy telnet support
791
- scopes.push(new vscode_debugadapter_1.Scope('Local', this.variableHandles.create('local'), false));
859
+ scopes.push(new debugadapter_1.Scope('Local', this.variableHandles.create('local'), false));
792
860
  }
793
861
  response.body = {
794
862
  scopes: scopes
@@ -901,13 +969,14 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
901
969
  if (this.launchConfiguration.enableVariablesPanel) {
902
970
  const vars = await this.rokuAdapter.getScopeVariables();
903
971
  for (const varName of vars) {
904
- let result = await this.rokuAdapter.getVariable(varName, -1);
972
+ let { evalArgs } = await this.evaluateExpressionToTempVar({ expression: varName, frameId: -1 }, util_1.util.getVariablePath(varName));
973
+ let result = await this.rokuAdapter.getVariable(evalArgs.expression, -1);
905
974
  let tempVar = this.getVariableFromResult(result, -1);
906
975
  childVariables.push(tempVar);
907
976
  }
908
977
  }
909
978
  else {
910
- childVariables.push(new vscode_debugadapter_1.Variable('variables disabled by launch.json setting', 'enableVariablesPanel: false'));
979
+ childVariables.push(new debugadapter_1.Variable('variables disabled by launch.json setting', 'enableVariablesPanel: false'));
911
980
  }
912
981
  }
913
982
  else {
@@ -921,7 +990,8 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
921
990
  logger.log('variable', v);
922
991
  //query for child vars if we haven't done it yet.
923
992
  if (v.childVariables.length === 0) {
924
- let result = await this.rokuAdapter.getVariable(v.evaluateName, v.frameId);
993
+ let { evalArgs } = await this.evaluateExpressionToTempVar({ expression: v.evaluateName, frameId: v.frameId }, util_1.util.getVariablePath(v.evaluateName));
994
+ let result = await this.rokuAdapter.getVariable(evalArgs.expression, v.frameId);
925
995
  let tempVar = this.getVariableFromResult(result, v.frameId);
926
996
  tempVar.frameId = v.frameId;
927
997
  v.childVariables = tempVar.childVariables;
@@ -981,7 +1051,7 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
981
1051
  if (!this.rokuAdapter.isAtDebuggerPrompt) {
982
1052
  let message = 'Skipped evaluate request because RokuAdapter is not accepting requests at this time';
983
1053
  if (args.context === 'repl') {
984
- this.sendEvent(new vscode_debugadapter_1.OutputEvent(message, 'stderr'));
1054
+ this.sendEvent(new debugadapter_1.OutputEvent(message, 'stderr'));
985
1055
  response.body = {
986
1056
  result: 'invalid',
987
1057
  variablesReference: 0
@@ -993,40 +1063,25 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
993
1063
  //is at debugger prompt
994
1064
  }
995
1065
  else {
996
- let variablePath = util_1.util.getVariablePath(args.expression);
997
- if (!variablePath && util_1.util.isAssignableExpression(args.expression)) {
998
- let varIndex = this.getNextVarIndex(args.frameId);
999
- let arrayVarName = this.tempVarPrefix + 'eval';
1000
- if (varIndex === 0) {
1001
- const response = await this.rokuAdapter.evaluate(`${arrayVarName} = []`, args.frameId);
1002
- console.log(response);
1003
- }
1004
- let statement = `${arrayVarName}[${varIndex}] = ${args.expression}`;
1005
- args.expression = `${arrayVarName}[${varIndex}]`;
1006
- let commandResults = await this.rokuAdapter.evaluate(statement, args.frameId);
1007
- if (commandResults.type === 'error') {
1008
- throw new Error(commandResults.message);
1009
- }
1010
- variablePath = [arrayVarName, varIndex.toString()];
1011
- }
1066
+ let { evalArgs, variablePath } = await this.evaluateExpressionToTempVar(args, util_1.util.getVariablePath(args.expression));
1012
1067
  //if we found a variable path (e.g. ['a', 'b', 'c']) then do a variable lookup because it's faster and more widely supported than `evaluate`
1013
1068
  if (variablePath) {
1014
- let refId = this.getEvaluateRefId(args.expression, args.frameId);
1069
+ let refId = this.getEvaluateRefId(evalArgs.expression, evalArgs.frameId);
1015
1070
  let v;
1016
1071
  //if we already looked this item up, return it
1017
1072
  if (this.variables[refId]) {
1018
1073
  v = this.variables[refId];
1019
1074
  }
1020
1075
  else {
1021
- let result = await this.rokuAdapter.getVariable(args.expression, args.frameId);
1076
+ let result = await this.rokuAdapter.getVariable(evalArgs.expression, evalArgs.frameId);
1022
1077
  if (!result) {
1023
1078
  throw new Error('Error: unable to evaluate expression');
1024
1079
  }
1025
- v = this.getVariableFromResult(result, args.frameId);
1080
+ v = this.getVariableFromResult(result, evalArgs.frameId);
1026
1081
  //TODO - testing something, remove later
1027
1082
  // eslint-disable-next-line camelcase
1028
1083
  v.request_seq = response.request_seq;
1029
- v.frameId = args.frameId;
1084
+ v.frameId = evalArgs.frameId;
1030
1085
  }
1031
1086
  response.body = {
1032
1087
  result: v.value,
@@ -1038,16 +1093,16 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
1038
1093
  //run an `evaluate` call
1039
1094
  }
1040
1095
  else {
1041
- let commandResults = await this.rokuAdapter.evaluate(args.expression, args.frameId);
1096
+ let commandResults = await this.rokuAdapter.evaluate(evalArgs.expression, evalArgs.frameId);
1042
1097
  commandResults.message = util_1.util.trimDebugPrompt(commandResults.message);
1043
1098
  if (args.context !== 'watch') {
1044
1099
  //clear variable cache since this action could have side-effects
1045
1100
  this.clearState();
1046
- this.sendInvalidatedEvent(null, args.frameId);
1101
+ this.sendInvalidatedEvent(null, evalArgs.frameId);
1047
1102
  }
1048
1103
  //if the adapter captured output (probably only telnet), print it to the vscode debug console
1049
1104
  if (typeof commandResults.message === 'string') {
1050
- this.sendEvent(new vscode_debugadapter_1.OutputEvent(commandResults.message, commandResults.type === 'error' ? 'stderr' : 'stdio'));
1105
+ this.sendEvent(new debugadapter_1.OutputEvent(commandResults.message, commandResults.type === 'error' ? 'stderr' : 'stdio'));
1051
1106
  }
1052
1107
  if (this.enableDebugProtocol || (typeof commandResults.message !== 'string')) {
1053
1108
  response.body = {
@@ -1075,6 +1130,25 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
1075
1130
  catch (_b) { }
1076
1131
  deferred.resolve();
1077
1132
  }
1133
+ async evaluateExpressionToTempVar(args, variablePath) {
1134
+ let returnVal = { evalArgs: args, variablePath };
1135
+ if (!variablePath && util_1.util.isAssignableExpression(args.expression)) {
1136
+ let varIndex = this.getNextVarIndex(args.frameId);
1137
+ let arrayVarName = this.tempVarPrefix + 'eval';
1138
+ if (varIndex === 0) {
1139
+ const response = await this.rokuAdapter.evaluate(`${arrayVarName} = []`, args.frameId);
1140
+ console.log(response);
1141
+ }
1142
+ let statement = `${arrayVarName}[${varIndex}] = ${args.expression}`;
1143
+ returnVal.evalArgs.expression = `${arrayVarName}[${varIndex}]`;
1144
+ let commandResults = await this.rokuAdapter.evaluate(statement, args.frameId);
1145
+ if (commandResults.type === 'error') {
1146
+ throw new Error(commandResults.message);
1147
+ }
1148
+ returnVal.variablePath = [arrayVarName, varIndex.toString()];
1149
+ }
1150
+ return returnVal;
1151
+ }
1078
1152
  /**
1079
1153
  * Called when the host stops debugging
1080
1154
  * @param response
@@ -1128,7 +1202,7 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
1128
1202
  let rokuAdapter = await this.getRokuAdapter();
1129
1203
  let threads = await rokuAdapter.getThreads();
1130
1204
  let threadId = (_a = threads[0]) === null || _a === void 0 ? void 0 : _a.threadId;
1131
- this.sendEvent(new vscode_debugadapter_1.StoppedEvent(Events_1.StoppedEventReason.exception, threadId, exception.message));
1205
+ this.sendEvent(new debugadapter_1.StoppedEvent(Events_1.StoppedEventReason.exception, threadId, exception.message));
1132
1206
  });
1133
1207
  // If the roku says it can't continue, we are no longer able to debug, so kill the debug session
1134
1208
  this.rokuAdapter.on('cannot-continue', () => {
@@ -1181,7 +1255,7 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
1181
1255
  }
1182
1256
  }
1183
1257
  this.clearState();
1184
- const event = new vscode_debugadapter_1.StoppedEvent(Events_1.StoppedEventReason.breakpoint,
1258
+ const event = new debugadapter_1.StoppedEvent(Events_1.StoppedEventReason.breakpoint,
1185
1259
  //Not sure why, but sometimes there is no active thread. Just pick thread 0 to prevent the app from totally crashing
1186
1260
  (_b = activeThread === null || activeThread === void 0 ? void 0 : activeThread.threadId) !== null && _b !== void 0 ? _b : 0, '' //exception text
1187
1261
  );
@@ -1199,12 +1273,12 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
1199
1273
  // check to see if this is an dictionary or a list
1200
1274
  if (result.keyType === 'Integer') {
1201
1275
  // list type
1202
- v = new vscode_debugadapter_1.Variable(result.name, result.type, refId, result.elementCount, 0);
1276
+ v = new debugadapter_1.Variable(result.name, result.type, refId, result.elementCount, 0);
1203
1277
  this.variables[refId] = v;
1204
1278
  }
1205
1279
  else if (result.keyType === 'String') {
1206
1280
  // dictionary type
1207
- v = new vscode_debugadapter_1.Variable(result.name, result.type, refId, 0, result.elementCount);
1281
+ v = new debugadapter_1.Variable(result.name, result.type, refId, 0, result.elementCount);
1208
1282
  }
1209
1283
  }
1210
1284
  else {
@@ -1218,30 +1292,30 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
1218
1292
  else {
1219
1293
  value = `${result.value}`;
1220
1294
  }
1221
- v = new vscode_debugadapter_1.Variable(result.name, value);
1295
+ v = new debugadapter_1.Variable(result.name, value);
1222
1296
  }
1223
1297
  this.variables[refId] = v;
1224
1298
  }
1225
1299
  else {
1226
1300
  if (result.highLevelType === 'primative' || result.highLevelType === 'uninitialized') {
1227
- v = new vscode_debugadapter_1.Variable(result.name, `${result.value}`);
1301
+ v = new debugadapter_1.Variable(result.name, `${result.value}`);
1228
1302
  }
1229
1303
  else if (result.highLevelType === 'array') {
1230
1304
  let refId = this.getEvaluateRefId(result.evaluateName, frameId);
1231
- v = new vscode_debugadapter_1.Variable(result.name, result.type, refId, (_c = (_b = result.children) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0, 0);
1305
+ v = new debugadapter_1.Variable(result.name, result.type, refId, (_c = (_b = result.children) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0, 0);
1232
1306
  this.variables[refId] = v;
1233
1307
  }
1234
1308
  else if (result.highLevelType === 'object') {
1235
1309
  let refId = this.getEvaluateRefId(result.evaluateName, frameId);
1236
- v = new vscode_debugadapter_1.Variable(result.name, result.type, refId, 0, (_e = (_d = result.children) === null || _d === void 0 ? void 0 : _d.length) !== null && _e !== void 0 ? _e : 0);
1310
+ v = new debugadapter_1.Variable(result.name, result.type, refId, 0, (_e = (_d = result.children) === null || _d === void 0 ? void 0 : _d.length) !== null && _e !== void 0 ? _e : 0);
1237
1311
  this.variables[refId] = v;
1238
1312
  }
1239
1313
  else if (result.highLevelType === 'function') {
1240
- v = new vscode_debugadapter_1.Variable(result.name, result.value);
1314
+ v = new debugadapter_1.Variable(result.name, result.value);
1241
1315
  }
1242
1316
  else {
1243
1317
  //all other cases, but mostly for HighLevelType.unknown
1244
- v = new vscode_debugadapter_1.Variable(result.name, result.value);
1318
+ v = new debugadapter_1.Variable(result.name, result.value);
1245
1319
  }
1246
1320
  }
1247
1321
  v.type = result.type;
@@ -1249,6 +1323,9 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
1249
1323
  v.frameId = frameId;
1250
1324
  v.type = result.type;
1251
1325
  v.presentationHint = result.presentationHint ? { kind: result.presentationHint } : undefined;
1326
+ if (util_1.util.isTransientVariable(v.name)) {
1327
+ v.presentationHint = { kind: 'virtual' };
1328
+ }
1252
1329
  if (result.children) {
1253
1330
  let childVariables = [];
1254
1331
  for (let childContainer of result.children) {
@@ -1283,7 +1360,7 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
1283
1360
  sendInvalidatedEvent(threadId, stackFrameId) {
1284
1361
  //if the client supports this request, send it
1285
1362
  if (this.initRequestArgs.supportsInvalidatedEvent) {
1286
- this.sendEvent(new vscode_debugadapter_1.InvalidatedEvent(['variables'], threadId, stackFrameId));
1363
+ this.sendEvent(new debugadapter_1.InvalidatedEvent(['variables'], threadId, stackFrameId));
1287
1364
  }
1288
1365
  }
1289
1366
  /**
@@ -1301,7 +1378,7 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
1301
1378
  * Called when the debugger is terminated. Feel free to call this as frequently as you want; we'll only run the shutdown process the first time, and return
1302
1379
  * the same promise on subsequent calls
1303
1380
  */
1304
- async shutdown(errorMessage) {
1381
+ async shutdown(errorMessage, modal = false) {
1305
1382
  if (this.shutdownPromise === undefined) {
1306
1383
  this.logger.log('[shutdown] Beginning shutdown sequence', errorMessage);
1307
1384
  this.shutdownPromise = this._shutdown(errorMessage);
@@ -1311,7 +1388,7 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
1311
1388
  }
1312
1389
  return this.shutdownPromise;
1313
1390
  }
1314
- async _shutdown(errorMessage) {
1391
+ async _shutdown(errorMessage, modal = false) {
1315
1392
  var _a, _b, _c, _d, _e, _f, _g;
1316
1393
  try {
1317
1394
  (_a = this.componentLibraryServer) === null || _a === void 0 ? void 0 : _a.stop();
@@ -1333,7 +1410,7 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
1333
1410
  //if there was an error message, display it to the user
1334
1411
  if (errorMessage) {
1335
1412
  this.logger.error(errorMessage);
1336
- this.showPopupMessage(errorMessage, 'error');
1413
+ this.showPopupMessage(errorMessage, 'error', modal);
1337
1414
  }
1338
1415
  this.logger.log('Destroy rokuAdapter');
1339
1416
  await ((_g = (_f = this.rokuAdapter) === null || _f === void 0 ? void 0 : _f.destroy) === null || _g === void 0 ? void 0 : _g.call(_f));
@@ -1346,7 +1423,7 @@ class BrightScriptDebugSession extends vscode_debugadapter_1.DebugSession {
1346
1423
  this.logger.error(e);
1347
1424
  }
1348
1425
  this.logger.log('Send terminated event');
1349
- this.sendEvent(new vscode_debugadapter_1.TerminatedEvent());
1426
+ this.sendEvent(new debugadapter_1.TerminatedEvent());
1350
1427
  //shut down the process
1351
1428
  this.logger.log('super.shutdown()');
1352
1429
  super.shutdown();