* Implements languageId support
* Implements typing of helper functions * Shift+F1 opens a new debug visualizer window if none is opened yet
This commit is contained in:
@@ -20,7 +20,7 @@ export class ClientConnection {
|
||||
private readonly client: typeof debugVisualizerUIContract["TClientInterface"];
|
||||
|
||||
constructor(
|
||||
dataSource: EvaluationWatchService,
|
||||
evaluationWatchService: EvaluationWatchService,
|
||||
stream: WebSocketStream,
|
||||
server: Server,
|
||||
config: Config,
|
||||
@@ -65,9 +65,12 @@ export class ClientConnection {
|
||||
this.dispose.untrack(this.watcher).dispose();
|
||||
}
|
||||
this.watcher = this.dispose.track(
|
||||
dataSource.createEvaluationWatcher(newExpression, {
|
||||
preferredDataExtractor: oldPreferredDataExtractor,
|
||||
})
|
||||
evaluationWatchService.createEvaluationWatcher(
|
||||
newExpression,
|
||||
{
|
||||
preferredDataExtractor: oldPreferredDataExtractor,
|
||||
}
|
||||
)
|
||||
);
|
||||
},
|
||||
openInBrowser: async ({}) => {
|
||||
@@ -98,7 +101,7 @@ export class ClientConnection {
|
||||
getCompletions: async ({ text, column }) => {
|
||||
throwIfNotAuthenticated();
|
||||
|
||||
const completions = await dataSource.getCompletions(
|
||||
const completions = await evaluationWatchService.getCompletions(
|
||||
text,
|
||||
column
|
||||
);
|
||||
@@ -111,7 +114,7 @@ export class ClientConnection {
|
||||
|
||||
this.client = client;
|
||||
|
||||
this.dispose.track(
|
||||
this.dispose.track([
|
||||
Disposable.create(
|
||||
autorun(() => {
|
||||
if (this.watcher) {
|
||||
@@ -120,8 +123,15 @@ export class ClientConnection {
|
||||
});
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
),
|
||||
Disposable.create(
|
||||
autorun(() => {
|
||||
client.updateLanguageId({
|
||||
languageId: evaluationWatchService.languageId || null,
|
||||
});
|
||||
})
|
||||
),
|
||||
]);
|
||||
|
||||
stream.onClosed.then(() => {
|
||||
this.dispose();
|
||||
|
||||
@@ -16,6 +16,11 @@ export interface Evaluator {
|
||||
| { kind: "data"; result: DataExtractionResult }
|
||||
| { kind: "error"; message: FormattedMessage }
|
||||
>;
|
||||
|
||||
/**
|
||||
* The language that expressions must be written in.
|
||||
*/
|
||||
readonly languageId: string | undefined;
|
||||
}
|
||||
|
||||
export interface EvaluationArgs {
|
||||
|
||||
@@ -22,6 +22,8 @@ export class GenericEvaluationEngine implements EvaluationEngine {
|
||||
}
|
||||
|
||||
export class GenericEvaluator implements Evaluator {
|
||||
public readonly languageId = "text";
|
||||
|
||||
constructor(private readonly session: VsCodeDebugSession) {}
|
||||
|
||||
public async evaluate({
|
||||
|
||||
@@ -33,6 +33,8 @@ export class JsEvaluationEngine implements EvaluationEngine {
|
||||
}
|
||||
|
||||
class JsEvaluator implements Evaluator {
|
||||
public readonly languageId = "javascript";
|
||||
|
||||
constructor(private readonly session: VsCodeDebugSession) {}
|
||||
|
||||
public async evaluate({
|
||||
|
||||
@@ -8,6 +8,13 @@ export interface EvaluationWatchService {
|
||||
): EvaluationWatcher;
|
||||
|
||||
getCompletions(text: string, column: number): Promise<CompletionItem[]>;
|
||||
|
||||
/**
|
||||
* The language the expressions must be written in.
|
||||
* `undefined`, if unknown.
|
||||
* This field is observable.
|
||||
*/
|
||||
readonly languageId: string | undefined;
|
||||
}
|
||||
|
||||
export interface EvaluationWatcherOptions {
|
||||
|
||||
@@ -18,7 +18,7 @@ export class EvaluationWatchServiceImpl implements EvaluationWatchService {
|
||||
|
||||
constructor(
|
||||
private readonly vsCodeDebuggerView: VsCodeDebuggerView,
|
||||
private readonly dataExtractionProviderFactory: EvaluationEngine
|
||||
private readonly evaluationEngine: EvaluationEngine
|
||||
) {
|
||||
this.dispose.track({
|
||||
dispose: autorun(() => {
|
||||
@@ -48,6 +48,21 @@ export class EvaluationWatchServiceImpl implements EvaluationWatchService {
|
||||
this.watchers.delete(w);
|
||||
}
|
||||
|
||||
private lastLanguageId: string | undefined = undefined;
|
||||
|
||||
get languageId(): string | undefined {
|
||||
const session = this.vsCodeDebuggerView.activeDebugSession;
|
||||
if (!session) {
|
||||
return this.lastLanguageId;
|
||||
}
|
||||
const evaluator = this.evaluationEngine.createEvaluator(session);
|
||||
if (!evaluator) {
|
||||
return this.lastLanguageId;
|
||||
}
|
||||
this.lastLanguageId = evaluator.languageId;
|
||||
return evaluator.languageId;
|
||||
}
|
||||
|
||||
public async refresh(w: ObservableEvaluationWatcher): Promise<void> {
|
||||
const session = this.vsCodeDebuggerView.activeDebugSession;
|
||||
if (!session) {
|
||||
@@ -59,10 +74,8 @@ export class EvaluationWatchServiceImpl implements EvaluationWatchService {
|
||||
|
||||
w._state = { kind: "loading" };
|
||||
|
||||
const extractionProvider = this.dataExtractionProviderFactory.createEvaluator(
|
||||
session
|
||||
);
|
||||
if (!extractionProvider) {
|
||||
const evaluator = this.evaluationEngine.createEvaluator(session);
|
||||
if (!evaluator) {
|
||||
w._state = {
|
||||
kind: "error",
|
||||
message: `The debug adapter "${session.session.type}" is not supported.`,
|
||||
@@ -70,7 +83,7 @@ export class EvaluationWatchServiceImpl implements EvaluationWatchService {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await extractionProvider.evaluate({
|
||||
const result = await evaluator.evaluate({
|
||||
expression: w.expression,
|
||||
frameId,
|
||||
preferredExtractorId: w.preferredDataExtractor,
|
||||
|
||||
@@ -27,7 +27,7 @@ export class WebViews {
|
||||
});
|
||||
}
|
||||
|
||||
public createNew() {
|
||||
public createNew(expression: string | undefined = undefined) {
|
||||
const panel = window.createWebviewPanel(
|
||||
debugVisualizer,
|
||||
"Debug Visualizer",
|
||||
@@ -35,15 +35,18 @@ export class WebViews {
|
||||
{ enableScripts: true }
|
||||
);
|
||||
|
||||
this.setupView(panel);
|
||||
this.setupView(panel, expression);
|
||||
}
|
||||
|
||||
public restore(webviewPanel: WebviewPanel) {
|
||||
this.setupView(webviewPanel);
|
||||
}
|
||||
|
||||
private setupView(webviewPanel: WebviewPanel) {
|
||||
webviewPanel.webview.html = getHtml(this.server);
|
||||
private setupView(
|
||||
webviewPanel: WebviewPanel,
|
||||
expression: string | undefined = undefined
|
||||
) {
|
||||
webviewPanel.webview.html = getHtml(this.server, expression);
|
||||
const view = new WebView(webviewPanel);
|
||||
this.debugVisualizations.set(webviewPanel, view);
|
||||
webviewPanel.onDidDispose(() => {
|
||||
@@ -56,7 +59,10 @@ export class WebView {
|
||||
constructor(private readonly webviewPanel: WebviewPanel) {}
|
||||
}
|
||||
|
||||
export function getHtml(server: Server) {
|
||||
export function getHtml(
|
||||
server: Server,
|
||||
expression: string | undefined = undefined
|
||||
) {
|
||||
const isDev = !!process.env.USE_DEV_UI;
|
||||
return `
|
||||
<html>
|
||||
@@ -75,6 +81,7 @@ export function getHtml(server: Server) {
|
||||
serverSecret: server.secret,
|
||||
serverPort: server.port,
|
||||
publicPath: server.publicPath,
|
||||
expression,
|
||||
})};
|
||||
const api = window.VsCodeApi = acquireVsCodeApi();
|
||||
window.addEventListener('message', event => {
|
||||
@@ -94,7 +101,7 @@ export function getHtml(server: Server) {
|
||||
${
|
||||
isDev
|
||||
? `<iframe sandbox="allow-top-navigation allow-scripts allow-same-origin allow-popups allow-pointer-lock allow-forms" src="${server.getIndexUrl(
|
||||
{ mode: "webViewIFrame" }
|
||||
{ mode: "webViewIFrame", expression }
|
||||
)}"></iframe>`
|
||||
: `<script type="text/javascript" src="${server.mainBundleUrl}"></script>`
|
||||
}
|
||||
|
||||
@@ -100,6 +100,11 @@ export const debugVisualizerUIContract = contract({
|
||||
newState: unchecked<DataExtractionState>(),
|
||||
}),
|
||||
}),
|
||||
updateLanguageId: notificationContract({
|
||||
params: types.type({
|
||||
languageId: types.union([types.null, types.string]),
|
||||
}),
|
||||
}),
|
||||
setExpression: requestContract({
|
||||
params: types.type({
|
||||
expression: types.string,
|
||||
|
||||
@@ -85,8 +85,7 @@ export class Extension {
|
||||
|
||||
latestConnection.setExpression(selectedText);
|
||||
} else {
|
||||
// TODO pass expression
|
||||
// this.views.createNew();
|
||||
this.views.createNew(selectedText);
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user