You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Implement InlineValueProvider for TypeScript #119489
Hm, we could parse the source and be smarter about only showing values in current and ancestor scopes.
However this requires parsing TypeScript. Several months ago I actually moved away from using typescript to parse ASTs in favor of Acorn since it's much smaller and faster, and we did not actually need to parse TypeScript in the debugger. Maybe this is something that could live in the TypeScript language features since it already has the typescript package available. I would still be happy to help author it, thoughts Matt Bierner (@mjbvz)?
Yes, that's a good example where VS Code's built-in "inline values" support breaks down.
Especially showing the function's source as its inline value is not really that smart ;-) (see #113987)
Isidor Nikolic (@isidorn) yes, the now finalised "inline values provider" could help here but that would not provided by "js-debug" but by the TypeScript extension because "inline values provider" are registered for a language not a debugger (as Connor Peet (@connor4312) already alluded to).
Connor Peet (@connor4312) Should this come from the TS server? The typescript extension does not do any ast processing (and may not easily be able to since we try to strip out most all of the TypeScript files not related to tsserver)
Yes, if a language extension has no direct access to an AST, then it should delegate this functionality to a language server (e.g. by introducing a LSP extension).
We have this larger issue tracking debug asks from the TS team: #88857
Connor Peet (@connor4312) If you can put together a short proposal on what you'd need specifically to implement this—basically here's the information we'll send over, what we need back, and a few illustrative examples of the expected behavior—I can try to get it scheduled for the next typescript version
The InlineValuesProvider API allows languages to provide hints to the debugger what expressions or values to evaluate when debugging, showing them inline as Ben posted. VS Code has a built-in heuristic for these, but languages can provide them more intelligently.
Specifically, for JavaScript, I think the following behaviors would be a good starting point, feel free to add/remove from these suggestions:
Inline values should only be provided in the current and parent scopes (solving the original issue)
Declarations and assignments assignments should evaluate the declared or assigned expression, bar in bar = foo() or foo in function foo() {}
Conditional expressions (ternary or if statements) should evaluate the conditional and none of its children, !foo && bar in if (!foo && bar)
Property assignments should be evaluated, foo() in { x: foo() }
The debugger will not cause side-effects during evaluation, so you do not need to be concerned about that. Most of these would go through InlineValueEvaluatableExpression, but should use InlineValueVariableLookup when possible.
I think I will later try to do some magic in js-debug so that evaluatable expressions are always invoked on the right call frame--since V8 optimizes away identifiers that are declared in parent scopes but unused in a child scope, calling everything on the top call frame may not always work.
Connor Peet (@connor4312) great proposal, thanks a lot!
And if additional information is needed on the InlineValuesContext object or additional parameters on the InlineValueEvaluatableExpression object, just let me know. Those types can be extended easily.
Connor Peet (@connor4312) Thanks. Could you put together a few illustrative examples for the TS team. For a given code snippet for example, here's the complete list of inline values that should be returned.
Also how will source mapping work with all this? Should TS be talking about ranges/vars in the original TS file? Or would this only be run on compiled JS?
Could you put together a few illustrative examples for the TS team. For a given code snippet for example, here's the complete list of inline values that should be returned.
functiondouble(n: number){// eval('double') -> double()returnn*2;}letx=1;// InlineValueVariableLookup for x hereif(x===2){// eval(x === 2) -> falsex*=2;// this line should NOT be evaluated since it's not the scope or its parents}if(x===1){// eval(x === 1) -> truex*=2;// InlineValueVariableLookup for x hereconsty={z: x**2,// eval(x ** 2) -> 16};console.log(x);// <-- paused here}
Also how will source mapping work with all this? Should TS be talking about ranges/vars in the original TS file? Or would this only be run on compiled JS?
They should report this information based on whatever file VS Code requests -- which will be the file the debugger is paused in. They don't have to do anything special to deal with sourcemaps/ranges. I don't think js-debug will either, but if it does then I'll take care of it as the TS language server is unaware of sourcemaps.
Activity
isidorn commentedon Mar 22, 2021
For this we would need the js-debug to use the inline value provider API created by Andre Weinand (@weinand)
Thus forwarding to Andre Weinand (@weinand) and Connor Peet (@connor4312)
connor4312 commentedon Mar 22, 2021
Hm, we could parse the source and be smarter about only showing values in current and ancestor scopes.
However this requires parsing TypeScript. Several months ago I actually moved away from using
typescriptto parse ASTs in favor of Acorn since it's much smaller and faster, and we did not actually need to parse TypeScript in the debugger. Maybe this is something that could live in the TypeScript language features since it already has the typescript package available. I would still be happy to help author it, thoughts Matt Bierner (@mjbvz)?weinand commentedon Mar 22, 2021
Yes, that's a good example where VS Code's built-in "inline values" support breaks down.
Especially showing the function's source as its inline value is not really that smart ;-) (see #113987)
Isidor Nikolic (@isidorn) yes, the now finalised "inline values provider" could help here but that would not provided by "js-debug" but by the TypeScript extension because "inline values provider" are registered for a language not a debugger (as Connor Peet (@connor4312) already alluded to).
Connor Peet (@connor4312) it would be excellent if you could help author it.
mjbvz commentedon Mar 22, 2021
Connor Peet (@connor4312) Should this come from the TS server? The typescript extension does not do any ast processing (and may not easily be able to since we try to strip out most all of the TypeScript files not related to tsserver)
weinand commentedon Mar 22, 2021
Yes, if a language extension has no direct access to an AST, then it should delegate this functionality to a language server (e.g. by introducing a LSP extension).
mjbvz commentedon Mar 22, 2021
We have this larger issue tracking debug asks from the TS team: #88857
Connor Peet (@connor4312) If you can put together a short proposal on what you'd need specifically to implement this—basically here's the information we'll send over, what we need back, and a few illustrative examples of the expected behavior—I can try to get it scheduled for the next typescript version
connor4312 commentedon Mar 25, 2021
Sure:
The
InlineValuesProviderAPI allows languages to provide hints to the debugger what expressions or values to evaluate when debugging, showing them inline as Ben posted. VS Code has a built-in heuristic for these, but languages can provide them more intelligently.Specifically, for JavaScript, I think the following behaviors would be a good starting point, feel free to add/remove from these suggestions:
barinbar = foo()orfooinfunction foo() {}ifstatements) should evaluate the conditional and none of its children,!foo && barinif (!foo && bar)foo()in{ x: foo() }The debugger will not cause side-effects during evaluation, so you do not need to be concerned about that. Most of these would go through
InlineValueEvaluatableExpression, but should useInlineValueVariableLookupwhen possible.I think I will later try to do some magic in js-debug so that evaluatable expressions are always invoked on the right call frame--since V8 optimizes away identifiers that are declared in parent scopes but unused in a child scope, calling everything on the top call frame may not always work.
[-]Debug: inline values is overwhelming[/-][+]Implement InlineValurProvider for TypeScript[/+][-]Implement InlineValurProvider for TypeScript[/-][+]Implement InlineValueProvider for TypeScript[/+]connor4312 commentedon Mar 25, 2021
Giving this to you, Matt, since I don't think there's any work to be done on the debug front for now
weinand commentedon Mar 25, 2021
Connor Peet (@connor4312) great proposal, thanks a lot!
And if additional information is needed on the
InlineValuesContextobject or additional parameters on theInlineValueEvaluatableExpressionobject, just let me know. Those types can be extended easily.mjbvz commentedon Mar 26, 2021
Connor Peet (@connor4312) Thanks. Could you put together a few illustrative examples for the TS team. For a given code snippet for example, here's the complete list of inline values that should be returned.
Also how will source mapping work with all this? Should TS be talking about ranges/vars in the original TS file? Or would this only be run on compiled JS?
connor4312 commentedon Mar 26, 2021
They should report this information based on whatever file VS Code requests -- which will be the file the debugger is paused in. They don't have to do anything special to deal with sourcemaps/ranges. I don't think js-debug will either, but if it does then I'll take care of it as the TS language server is unaware of sourcemaps.
mjbvz commentedon Mar 30, 2021
Opened microsoft/TypeScript#43449 to track this upstream
Connor Peet (@connor4312) Can you please answer any of the TypeScript team's question about the expected behavior
mjbvz commentedon Mar 24, 2022
Connor Peet (@connor4312) I'm assigning you since we decided this would need to come through a TypeScript plugin (which I think we'd have to develop)