* Updates visualization library.

* Adds support for more js debug adapters.
* Minor improvements.
This commit is contained in:
Henning Dieterichs
2021-06-12 16:02:54 +02:00
parent 6da44bd722
commit 6ce5d666a3
16 changed files with 340 additions and 38 deletions

View File

@@ -26,7 +26,11 @@ export class JsEvaluationEngine implements EvaluationEngine {
"chrome",
"pwa-chrome",
"pwa-node",
"pwa-extensionHost",
"node-terminal",
"pwa-msedge",
];
if (supportedDebugAdapters.indexOf(session.session.type) !== -1) {
return new JsEvaluator(session);
}
@@ -54,6 +58,31 @@ class JsEvaluator implements Evaluator {
| { kind: "data"; result: DataExtractionResult }
| { kind: "error"; message: FormattedMessage }
> {
const variableNames = new Array<string>();
if (frameId) {
const scopes = await this.session.getScopes({ frameId });
const scopeVariables = await Promise.all(
scopes
.filter(s => !s.expensive)
.map(s =>
this.session.getVariables({
variablesReference: s.variablesReference,
})
)
);
for (const variables of scopeVariables) {
variableNames.push(
...variables
.filter(v => v.value !== "undefined")
.map(v => v.name)
);
}
if (variableNames.length > 100) {
variableNames.length = 100;
}
}
while (true) {
try {
const preferredExtractorExpr = preferredExtractorId
@@ -63,7 +92,8 @@ class JsEvaluator implements Evaluator {
const body = `${getExpressionForDataExtractorApi()}.getData(
e => (${expression}),
expr => eval(expr),
${preferredExtractorExpr}
${preferredExtractorExpr},
{${variableNames.map(n => `${n}: ${n}`).join(",")}},
)`;
const wrappedExpr = `

View File

@@ -5,11 +5,13 @@ import {
} from "./EvaluationWatchService";
import { observable, autorun, action } from "mobx";
import { Disposable } from "@hediet/std/disposable";
import { CancellationTokenSource, CancellationToken } from "vscode";
import { DataExtractorId } from "@hediet/debug-visualizer-data-extraction";
import { DataExtractionState, CompletionItem } from "../webviewContract";
import { hotClass } from "@hediet/node-reload";
import { VsCodeDebuggerView } from "../debugger/VsCodeDebuggerView";
import { EvaluationEngine } from "./EvaluationEngine/EvaluationEngine";
import { wait } from "@hediet/std/timer";
@hotClass(module)
export class EvaluationWatchServiceImpl implements EvaluationWatchService {
@@ -63,7 +65,25 @@ export class EvaluationWatchServiceImpl implements EvaluationWatchService {
return evaluator.languageId;
}
public async refresh(w: ObservableEvaluationWatcher): Promise<void> {
private runningRefreshOperation: Disposable | undefined;
public refresh(w: ObservableEvaluationWatcher): void {
if (this.runningRefreshOperation) {
this.runningRefreshOperation.dispose();
}
const tokenSource = new CancellationTokenSource();
this.runningRefreshOperation = {
dispose: () => {
tokenSource.cancel();
},
};
this._refresh(w, tokenSource.token);
}
private async _refresh(
w: ObservableEvaluationWatcher,
token: CancellationToken
): Promise<void> {
const session = this.vsCodeDebuggerView.activeDebugSession;
if (!session) {
w._state = { kind: "noDebugSession" };
@@ -89,6 +109,15 @@ export class EvaluationWatchServiceImpl implements EvaluationWatchService {
preferredExtractorId: w.preferredDataExtractor,
});
if (result.kind === "error") {
// give cancellation requested more time in case of errors
await wait(330);
}
if (token.isCancellationRequested) {
return;
}
w._state = result;
}

View File

@@ -46,12 +46,27 @@ export class EnhancedDebugSession {
}
}
public async getScopes(args: { frameId: number }): Promise<Scope[]> {
try {
const reply = await this.session.customRequest("scopes", {
frameId: args.frameId,
});
if (!reply) {
return [];
}
return reply.scopes;
} catch (error) {
console.error(error);
return [];
}
}
public async getVariables(args: {
variablesReference: number
variablesReference: number;
}): Promise<Variable[]> {
try {
const reply = await this.session.customRequest("variables", {
variablesReference: args.variablesReference
variablesReference: args.variablesReference,
});
if (!reply) {
return [];
@@ -72,16 +87,25 @@ export class EnhancedDebugSession {
expression: string;
frameId: number | undefined;
context: "watch" | "repl" | "copy";
}): Promise<{ result: string, variablesReference: number }> {
}): Promise<{ result: string; variablesReference: number }> {
const reply = await this.session.customRequest("evaluate", {
expression: args.expression,
frameId: args.frameId,
context: args.context,
});
return { result: reply.result, variablesReference: reply.variablesReference };
return {
result: reply.result,
variablesReference: reply.variablesReference,
};
}
}
interface Scope {
name: string;
expensive: boolean;
variablesReference: number;
}
interface Variable {
name: string;
value: string;