Implements the debugVisualizer.debugAdapterConfigurations configuration option.

This commit is contained in:
Henning Dieterichs
2020-03-02 10:52:19 +01:00
parent f6a554c897
commit f12ea19369
19 changed files with 338 additions and 118 deletions

View File

@@ -1,8 +1,6 @@
import {
DataResult,
DataExtractionResult,
ExtractedData,
isExtractedData,
DataExtractorId,
} from "@hediet/debug-visualizer-data-extraction";
import { VsCodeDebugSession } from "../../VsCodeDebugger";
import {
@@ -10,6 +8,7 @@ import {
DataExtractionProvider,
DataExtractionProviderArgs,
} from "./DataExtractionProvider";
import { parseEvaluationResultFromGenericDebugAdapter } from "./parseEvaluationResultFromGenericDebugAdapter";
export class GenericDataExtractionProviderFactory
implements DataExtractionProviderFactory {
@@ -20,84 +19,46 @@ export class GenericDataExtractionProviderFactory
}
}
class GenericDataExtractionProvider implements DataExtractionProvider {
export class GenericDataExtractionProvider implements DataExtractionProvider {
constructor(private readonly session: VsCodeDebugSession) {}
public async evaluate({
expression,
preferredExtractor,
preferredExtractorId,
frameId,
}: DataExtractionProviderArgs): Promise<
| { kind: "data"; result: DataExtractionResult }
| { kind: "error"; message: string }
> {
const finalExpression = this.getFinalExpression({
expression,
preferredExtractorId,
});
let reply;
try {
const reply = await this.session.evaluate({
expression,
reply = await this.session.evaluate({
expression: finalExpression,
frameId,
context: this.getContext(),
});
function isEnclosedWith(str: string, char: string): boolean {
return str.startsWith(char) && str.endsWith(char);
}
const jsonData = reply.result.trim();
function parseJson(str: string) {
try {
return JSON.parse(str);
} catch (error) {
throw new Error(
`Could not parse \`${str}\` as JSON.\n${error.message}`
);
}
}
let result;
try {
let jsonData2;
// Remove optionally enclosing characters.
if (
isEnclosedWith(jsonData, '"') ||
isEnclosedWith(jsonData, "'")
) {
// In case of JavaScript: `"{ "kind": { ... }, "text": "some\ntext" }"`
jsonData2 = jsonData.substr(1, jsonData.length - 2);
} else {
// Just in case no quoting is done.
jsonData2 = jsonData;
}
result = parseJson(jsonData2);
} catch (e) {
// in case of C++: `"{ \"kind\": { ... }, \"text\": \"some\\ntext\" }"`
const str = parseJson(jsonData);
// str is now `{ "kind": { ... }, "text": "some\ntext" }"`
result = parseJson(str);
// result is now { kind: { ... }, text: "some\ntext" }
}
if (!isExtractedData(result)) {
throw new Error("Data does not match ExtractedData interface.");
}
return {
kind: "data",
result: {
availableExtractors: [],
usedExtractor: {
id: "generic" as any,
name: "Generic",
priority: 1,
},
data: result,
},
};
} catch (error) {
return {
kind: "error",
message: error.message,
};
}
return parseEvaluationResultFromGenericDebugAdapter(reply.result);
}
protected getFinalExpression(args: {
expression: string;
preferredExtractorId: DataExtractorId | undefined;
}): string {
return args.expression;
}
protected getContext(): "watch" | "repl" {
return "watch";
}
}