我为Roku的BrightScript语言维护了VSCode调试器扩展。 Roku没有正式的调试协议,因此我的调试器使用telnet command-line utility发出各种调试命令(例如打印变量,继续,步骤等)。由于Roku是网络设备,并且我们正在执行字符串解析,因此与调试诸如node或C#之类的机上程序相比,每个命令都相当慢。因此,我们尽可能地延迟加载数据,而不是急于加载数据。
以该对象为例:
business = {
employeeNames: ["Michael", "Jim", "Pam", "Dwight"],
name: "Dunder Mifflin Paper Company"
}
当用户将business
添加到监视面板时,vscode为"business"
发出evaluateRequest。在后台,我运行telnet命令print business
,该命令返回以下内容:
<Component: roAssociativeArray> =
{
employeeNames: <Component: roArray>
name: "Dunder Mifflin Paper Company"
}
在这一点上,我们知道employeeNames
是一个数组,但是我们不知道它的大小,因此不应该急于查找它的大小,因为这需要一个单独的命令来减慢整个调试的速度经验。
接下来,在VSCode监视面板中,用户展开employeeNames
属性,然后vscode调用variablesRequest。我的调试扩展程序运行telnet命令print business.employeeNames
,并返回以下内容:
<Component: roArray> =
[
"Michael"
"Jim"
"Pam"
"Dwight"
]
这时,我想更新employeeNames
类型以显示数组计数,如下所示:
这是我将在调试扩展中更改的DebugProtocol.Variable
...但是当VSCode尚未要求对此变量进行更新时,我不知道如何将其发送到VSCode。
//hardcoded for the sake of this question...is dynamic in actual code
var variableName = "business.employeeNames"
var arrayValues= getArrayValues(variableName); // ["Michael", "Jim", "Pam", "Dwight"]
let variable: DebugProtocol.Variable = {
name: "employeeNames";
evaluateName: "business.employeeNames";
type: `roArray (${arrayValues})`;
value: arrayValues;
children: [];
}
我试图欺骗vscode重新请求所有内容,但是VSCode并没有请求新变量,因为它足够聪明,可以意识到StoppedEvent
位于先前停止的位置。
//send a continue
this.sendEvent(new ContinuedEvent(0, true));
//wait a short time
setTimeout(()=>{
//send a stopped event
this.sendEvent(new StoppedEvent('exception', threadId, exception.message));
}, 10);
作为调试扩展作者,如何通过调试扩展代码告诉VSCode监视面板中的变量已更改,并且需要刷新?