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
Today the "Show Inline Values" feature of VS Code's debugger is based on a generic implementation in the VS Code core and provides neither customisability through settings, nor extensibility via extensions.
As a consequence, it is not a perfect fit for all languages (e.g. #101797) and sometimes even shows incorrect values because it doesn't understand the scope regions of the underlying language.
This features asks for an extension API that either replaces the built-in implementation completely or allows to replace parts of the implementation with custom code.
A first attempt for designing an extension API for inline values tried to use a similar approach as done for the debug hover with the EvaluatableExpressionProvider. In the debug hover case the provider returns an expression for a source location typically determined by the mouse, and then this expression is evaluated by the debug adapter and the result is presented in a hover window.
For the "inline values" feature we tried to reuse the EvaluatableExpressionProvider by introducing a second method that takes a source line number as input and returns an array of {name, expressions} pairs. VS Code would evaluate the expression by the debug adapter and the present the name with the value in the editor at the end of the line.
A prototype based on this approach showed two problem areas:
sending multiple "evaluate" requests for every source line to the debug adapter can be slow and affects the stepping performance significantly.
Since the language tokenizer is not available in extensions, implementing an EvaluatableExpressionProvider from scratch is difficult. The only realistic way to get this done is by making the EvaluatableExpressionProvider a companion to a language server so that it has access to the parser or AST.
Today the "Show Inline Values" feature of VS Code's debugger is based on a single, generic implementation in the VS Code core and provides neither customisability through settings, nor extensibility via extensions.
The proposal is a first attempt to create an extension API for inline values.
Proposal:
The new API is basically a new provider that returns the "Inline values" information (a string) for specific lines of a document.
But there is a twist:
The current "closed" implementation is pretty fast because it relies on the internal tokenizer and looks up values in the Variables view's model. Since extensions do not yet have access to those mechanisms, they are somewhat handicapped today. For that reason, I've introduced the InlineValueContext and InlineValueDescriptor which makes it possible to surface additional information on input (in the InlineValueContext), and additional evaluation strategies when returning values (by returning new types of InlineValueDescriptors).
/** * The inline values provider interface defines the contract between extensions and the VS Code inline values feature. * In this contract the provider returns inline value information for a given document range * and VS Code shows this information in the editor at the end of lines. */exportinterfaceInlineValuesProvider{/** * Provide "inline value" information for a given document and range. * VS Code calls this method whenever debugging stops in the given document. * The returned inline values information is rendered in the editor at the end of lines. * * @param document The document for which the inline values information is needed. * @param context A bag containing contextual information like the current location. * @param token A cancellation token. * @return An array of InlineValueDescriptors or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined` or `null`. */provideInlineValues(document: TextDocument,context: InlineValueContext,token: CancellationToken): ProviderResult<InlineValueDescriptor[]>;}/** * An open ended information bag passed to the inline value provider. * A minimal context containes just the document location where the debugger has stopped. * Additional optional information might be scope information or variables and their values. */exportinterfaceInlineValueContext{/** * The document location where execution has stopped. * Typically this is used as the end position of the range where inline values are shown. */position: Position;// ... more to come, e.g. Scope information or variable/value candidate information}/** * Inline value information can exist in multiple forms. The simplest is a direct string value (class InlineValue). * A more complex one is an evaluatable expression. * The InlineValueDescriptor is just an OR-type of all current and future inline value types. */exporttypeInlineValueDescriptor=InlineValue;/** * An InlineValue represents the value (string) that is shown in the editor at the end of a specific line. */exportclassInlineValue{/** * The document's line where to show the inline value. */readonlyline: number;/** * The value to be shown for the line. */readonlyvalue: string;/** * Creates a new InlineValue object. * * @param line The document line where to show the inline value. * @param value The value to be shown for the line. */constructor(line: number,value: string);}exportnamespacelanguages{/** * Register a provider that returns inline values for text documents. * In the active debug session VS Code shows this information in the editor at the end of lines. * * If multiple providers are registered for a language, inline values are concatenated. * * @param selector A selector that defines the documents this provider is applicable to. * @param provider An inline values provider. * @return A [disposable](#Disposable) that unregisters this provider when being disposed. */exportfunctionregisterInlineValuesProvider(selector: DocumentSelector,provider: InlineValuesProvider): Disposable;}
Since the last API discussion a frameId attribute has been added to the open-ended InlineValueContext object.
/** * A value-object that contains contextual information when requesting inline values from a InlineValuesProvider. */exportinterfaceInlineValueContext{/** * The stack frame (as a DAP Id) where the execution has stopped. */readonlyframeId: number;/** * The document range where execution has stopped. * Typically the end position of the range denotes the line where the inline values are shown. */readonlystoppedLocation: Range;}
The API looks good. Here are some feedbacks about the implementation.
We want to use the viewport to crop the results in cases where there is a large list of variables. But the viewPort parameter from provideInlineValues API never changes when i scroll the editor.
For example, in my test case the initial viewport range is L80 ~ L126, and it doesn't change when i scroll up.
Screen.Recording.2021-03-23.at.15.34.55.mov
When Java debugger uses InlineValuesProvider to provide inline debugging feature, the user still needs to manually enable the user setting "debug.inlineValues" to get the feature. Is this by design?
When the user uses the "Set Value" feature to update the variables, the inline values are not refreshed.
Activity
weinand commentedon Aug 30, 2020
The current generic implementation works as follows:
This implementation is lightweight and scales well because:
Problems:
variable = value.weinand commentedon Aug 31, 2020
A first attempt for designing an extension API for inline values tried to use a similar approach as done for the debug hover with the EvaluatableExpressionProvider. In the debug hover case the provider returns an expression for a source location typically determined by the mouse, and then this expression is evaluated by the debug adapter and the result is presented in a hover window.
For the "inline values" feature we tried to reuse the
EvaluatableExpressionProviderby introducing a second method that takes a source line number as input and returns an array of {name, expressions} pairs. VS Code would evaluate the expression by the debug adapter and the present the name with the value in the editor at the end of the line.A prototype based on this approach showed two problem areas:
EvaluatableExpressionProviderfrom scratch is difficult. The only realistic way to get this done is by making theEvaluatableExpressionProvidera companion to a language server so that it has access to the parser or AST.weinand commentedon Jan 12, 2021
During debugging VS Code's "Inline Values" feature shows the value of variables "inline" in the editor:
(see https://code.visualstudio.com/updates/v1_9#_inline-variable-values-in-source-code)
Today the "Show Inline Values" feature of VS Code's debugger is based on a single, generic implementation in the VS Code core and provides neither customisability through settings, nor extensibility via extensions.
The proposal is a first attempt to create an extension API for inline values.
Proposal:
The new API is basically a new provider that returns the "Inline values" information (a string) for specific lines of a document.
But there is a twist:
The current "closed" implementation is pretty fast because it relies on the internal tokenizer and looks up values in the Variables view's model. Since extensions do not yet have access to those mechanisms, they are somewhat handicapped today. For that reason, I've introduced the
InlineValueContextandInlineValueDescriptorwhich makes it possible to surface additional information on input (in theInlineValueContext), and additional evaluation strategies when returning values (by returning new types ofInlineValueDescriptors).gjsjohnmurray commentedon Jan 12, 2021
InlineValuedoc talks about range and expression, yet its properties are namedlineandvalue😕weinand commentedon Jan 12, 2021
John Murray (@gjsjohnmurray) thanks for spotting this.
22 remaining items
weinand commentedon Mar 16, 2021
Proposed API for the Inline Values Provider.
Since the last API discussion a
frameIdattribute has been added to the open-endedInlineValueContextobject.weinand commentedon Mar 16, 2021
The InlineValuesProvider API has been finalized and will appear in the next Insiders.
weinand commentedon Mar 22, 2021
In this milestone we've finalised the API without changing it. So the test-plan item from the previous milestone still covers it.
testforstephen commentedon Mar 23, 2021
The API looks good. Here are some feedbacks about the implementation.
provideInlineValuesAPI never changes when i scroll the editor.For example, in my test case the initial viewport range is L80 ~ L126, and it doesn't change when i scroll up.
Screen.Recording.2021-03-23.at.15.34.55.mov
When Java debugger uses InlineValuesProvider to provide inline debugging feature, the user still needs to manually enable the user setting "debug.inlineValues" to get the feature. Is this by design?
When the user uses the "Set Value" feature to update the variables, the inline values are not refreshed.
weinand commentedon Mar 23, 2021
Jinbo Wang (@testforstephen) thanks for the feedback.
I've created issues #119559, #119560, #119564 for it.