vscode-js-debug icon indicating copy to clipboard operation
vscode-js-debug copied to clipboard

Support letting a language server provide additional metadata on values

Open orta opened this issue 5 years ago • 3 comments

👋 been enjoying this extension, great work.

It's a bit of a blue-sky idea, but an interesting case would be enum values.

For example selecting kind in the editor below could request some kind extended metadata about the raw value. So it would have the chance go from this:

Screen Shot 2020-01-30 at 12 44 24 PM

To this:

Frame 2

And maybe type information could then be available if you keep the mouse hovering?

orta avatar Jan 30 '20 17:01 orta

Thanks for the kind words!

Indeed, something we're talking about that would provide several things is the ability for language implementations in the editor to provide 'helper' APIs that debug adapters can use. This has many use cases--being able to figure out how to handle hovers correctly, better intellisense and autocompletion in the debug console/repl, figuring out renamed/mapped variables (like TS imports).

In your example, maybe there would be a way for the debug extension to ask the language server the metadata for a symbol in the current scope--the debug server knows the runtime position and the value of child.kind, and tssserver will know that that's a SyntaxKind enum, so it can pass that back. Then we could figure out how to show represent that nicely DAP variables response, the easy way we could do it without changes is to show SyntaxKind.VariableDeclarationList by default and let the user expand it to see the underlying value, like how we handle getters.

cc @weinand

connor4312 avatar Jan 30 '20 18:01 connor4312

There are at least two obstacles that make collaboration between language servers and debuggers more difficult than expected:

  • VS Code knows nothing about language servers since they are an implementation detail of an extension. So VS Code debugging (or debug adapters) do not have generic access to language servers. That's the reason why we are starting to introduce new APIs (e.g. #89084) that the VS Code debugger or debug adapters can use to get access to specific language features (but not the full language server API).
  • There are basically no common types and abstractions shared between language API and debugger APIs. So it is not trivial to map some entity from the debugger world (e.g. a variable accessible in the current stack frame) to something in the language world (the correct variable with its type). Just using the name is not sufficient. The only shared information that can be used to map between the two worlds is the symbol's location in the source (if that information is actually available on the debugger side). And if the source language (e.g. TS) and the runtime language (e.g. JS) are different and require another mapping, things become even more difficult...

weinand avatar Jan 31 '20 09:01 weinand

I'd love to revive this discussion! I think this is not that far out of reach.

JS Debug could provide a typescript language server plugin that exposes a command getNumberDisplay:

function getNumberDisplay(value: number, expression: string, scope: Range, uri: Uri): Promise<Display | undefined> {}

type Display = { value: string } | { functionExpression: string };

Const Enum Example

const enum Foo {
    A = 1,
    B = 2,
}

const x = Foo.A;
console.log(x);

const y = { kind: Foo.B };

getNumberDisplay(1, "x", ..., ...) would return { value: "Foo.A" } getNumberDisplay(2, "y.kind", ..., ...) would return { value: "Foo.B" }

User Defined Example

/**
* @display {x => x.toString(2)}
*/
type Binary = number;

const binX: Binary = 0b11011;

getNumberDisplay(27, "binX", ..., ...) would return { functionExpression: "(x => x.toString(2))" }


Evaluate requests that resolve an expression to a number could then use this command to improve the representation. For functionExpressions, it would eval ${functionExpression}(${value}).


I don't think getNumberDisplay is very hard to implement. We could start with just supporting variables that are in the given scope and then extend it to chained properties/array access etc.

hediet avatar Jun 29 '23 16:06 hediet