-
-
Notifications
You must be signed in to change notification settings - Fork 409
/
PyVisualizationSupport.ts
149 lines (134 loc) · 3.92 KB
/
PyVisualizationSupport.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import {
DataExtractionResult,
DataExtractorId,
GraphNode,
GraphVisualizationData,
} from "@hediet/debug-visualizer-data-extraction";
import { DebugSessionProxy } from "../proxies/DebugSessionProxy";
import {
DebugSessionVisualizationSupport,
VisualizationBackend,
GetVisualizationDataArgs,
VisualizationBackendBase,
} from "./VisualizationBackend";
import { Config } from "../Config";
import { parseEvaluationResultFromGenericDebugAdapter } from "./parseEvaluationResultFromGenericDebugAdapter";
import { FormattedMessage } from "../webviewContract";
import { hotClass, registerUpdateReconciler } from "@hediet/node-reload";
import { DebuggerViewProxy } from "../proxies/DebuggerViewProxy";
registerUpdateReconciler(module);
@hotClass(module)
export class PyEvaluationEngine
implements DebugSessionVisualizationSupport {
constructor(
private readonly debuggerView: DebuggerViewProxy,
private readonly config: Config
) { }
createBackend(
session: DebugSessionProxy
): VisualizationBackend | undefined {
const supportedDebugAdapters = [
"python",
];
if (supportedDebugAdapters.indexOf(session.session.type) !== -1) {
return new PyVisualizationBackend(
session,
this.debuggerView,
this.config
);
}
return undefined;
}
}
export class PyVisualizationBackend extends VisualizationBackendBase {
public readonly expressionLanguageId = "python";
constructor(
debugSession: DebugSessionProxy,
debuggerView: DebuggerViewProxy,
private readonly config: Config
) {
super(debugSession, debuggerView);
}
protected getContext(): "watch" | "repl" {
// we will use "repl" as default so that results are not truncated.
return "repl";
}
public async getVisualizationData({
expression,
preferredExtractorId,
}: GetVisualizationDataArgs): Promise<
| { kind: "data"; result: DataExtractionResult }
| { kind: "error"; message: FormattedMessage }
> {
const frameId = this.debuggerView.getActiveStackFrameId(
this.debugSession
);
const finalExpression = this.getFinalExpression({
expression,
preferredExtractorId,
});
let reply: { result: string; variablesReference: number };
try {
// inject vscodedebugvisualizer for python
await this.debugSession.evaluate({
expression: 'from vscodedebugvisualizer import visualize\ntry:\n import debugvisualizer\nexcept ImportError:\n pass',
frameId,
context: this.getContext(),
});
reply = await this.debugSession.evaluate({
expression: finalExpression,
frameId,
context: this.getContext(),
});
let result = reply.result;
// remove the initial escape by the the debug session e.g. `''{"kind": {"text": true}, "text": "{"asdf1\'"}''`
result = result.replace(/\\'/g, "'");
result = result.replace(/\\\\/g, "\\");
return parseEvaluationResultFromGenericDebugAdapter(
result,
{
debugAdapterType: this.debugSession.session
.configuration.type,
}
);
} catch (error) {
let errorTyped = error as Error;
if (errorTyped.message.includes("ModuleNotFoundError: No module named 'vscodedebugvisualizer'")) {
return {
kind: "error",
message: {
kind: "list",
items: ["Please make sure vscodedebugvisualizer is installed: `pip install vscodedebugvisualizer`"],
},
};
}
return {
kind: "error",
message: {
kind: "list",
items: [
"An error occurred while evaluating the expression:",
errorTyped.message,
`Used debug adapter: ${this.debugSession.session.configuration.type}`,
{
kind: "inlineList",
items: [
"Evaluated expression is",
{ kind: "code", content: finalExpression },
],
},
],
},
};
}
}
protected getFinalExpression(args: {
expression: string;
preferredExtractorId: DataExtractorId | undefined;
}): string {
// wrap expression with visualize function
let pythonInject = "";
pythonInject += "visualize(" + args.expression + ")";
return pythonInject;
}
}