Skip to content

Commit 13c3274

Browse files
committed
Fix #47: Add 'context' param to EvaluateRequest
This change adds the next 'context' parameter to EvaluateRequest, allowing the debug adapter client to identify whether an 'evaluate' request will be used for evaluating an expression for value display or REPL execution. This allows us to write out REPL command output only when expressions are being evaluated in that context.
1 parent 177d09f commit 13c3274

File tree

5 files changed

+54
-12
lines changed

5 files changed

+54
-12
lines changed

src/PowerShellEditorServices.Protocol/DebugAdapter/EvaluateRequest.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,37 @@ public static readonly
1616

1717
public class EvaluateRequestArguments
1818
{
19+
/// <summary>
20+
/// The expression to evaluate.
21+
/// </summary>
1922
public string Expression { get; set; }
2023

21-
// /** Evaluate the expression in the context of this stack frame. If not specified, the top most frame is used. */
24+
/// <summary>
25+
/// The context in which the evaluate request is run. Possible
26+
/// values are 'watch' if evaluate is run in a watch or 'repl'
27+
/// if run from the REPL console.
28+
/// </summary>
29+
public string Context { get; set; }
30+
31+
/// <summary>
32+
/// Evaluate the expression in the context of this stack frame.
33+
/// If not specified, the top most frame is used.
34+
/// </summary>
2235
public int FrameId { get; set; }
2336
}
2437

2538
public class EvaluateResponseBody
2639
{
40+
/// <summary>
41+
/// The evaluation result.
42+
/// </summary>
2743
public string Result { get; set; }
2844

29-
// /** If variablesReference is > 0, the evaluate result is structured and its children can be retrieved by passing variablesReference to the VariablesRequest */
45+
/// <summary>
46+
/// If variablesReference is > 0, the evaluate result is
47+
/// structured and its children can be retrieved by passing
48+
/// variablesReference to the VariablesRequest
49+
/// </summary>
3050
public int VariablesReference { get; set; }
3151
}
3252
}

src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,17 @@ protected async Task HandleEvaluateRequest(
312312
EvaluateRequestArguments evaluateParams,
313313
RequestContext<EvaluateResponseBody> requestContext)
314314
{
315+
bool isFromRepl =
316+
string.Equals(
317+
evaluateParams.Context,
318+
"repl",
319+
StringComparison.InvariantCultureIgnoreCase);
320+
315321
VariableDetails result =
316322
await editorSession.DebugService.EvaluateExpression(
317323
evaluateParams.Expression,
318-
evaluateParams.FrameId);
324+
evaluateParams.FrameId,
325+
isFromRepl);
319326

320327
string valueString = null;
321328
int variableId = 0;

src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,7 @@ protected async Task HandleEvaluateRequest(
679679
var results =
680680
await this.editorSession.PowerShellContext.ExecuteScriptString(
681681
evaluateParams.Expression,
682+
true,
682683
true);
683684

684685
// Return an empty result since the result value is irrelevant

src/PowerShellEditorServices/Debugging/DebugService.cs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -233,26 +233,38 @@ public VariableDetailsBase GetVariableFromExpression(string variableExpression,
233233
/// </summary>
234234
/// <param name="expressionString">The expression string to execute.</param>
235235
/// <param name="stackFrameId">The ID of the stack frame in which the expression should be executed.</param>
236+
/// <param name="writeResultAsOutput">
237+
/// If true, writes the expression result as host output rather than returning the results.
238+
/// In this case, the return value of this function will be null.</param>
236239
/// <returns>A VariableDetails object containing the result.</returns>
237-
public async Task<VariableDetails> EvaluateExpression(string expressionString, int stackFrameId)
240+
public async Task<VariableDetails> EvaluateExpression(
241+
string expressionString,
242+
int stackFrameId,
243+
bool writeResultAsOutput)
238244
{
239245
var results =
240246
await this.powerShellContext.ExecuteScriptString(
241247
expressionString,
242-
false);
248+
false,
249+
writeResultAsOutput);
243250

244251
// Since this method should only be getting invoked in the debugger,
245252
// we can assume that Out-String will be getting used to format results
246253
// of command executions into string output. However, if null is returned
247-
// then pass null through so that no output gets displayed.
254+
// then return null so that no output gets displayed.
248255
string outputString =
249256
results != null ?
250257
string.Join(Environment.NewLine, results) :
251258
null;
252259

253-
return new VariableDetails(
254-
expressionString,
255-
outputString);
260+
// If we've written the result as output, don't return a
261+
// VariableDetails instance.
262+
return
263+
writeResultAsOutput ?
264+
null :
265+
new VariableDetails(
266+
expressionString,
267+
outputString);
256268
}
257269

258270
/// <summary>

src/PowerShellEditorServices/Session/PowerShellContext.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -380,18 +380,20 @@ public Task ExecuteCommand(PSCommand psCommand)
380380
public Task<IEnumerable<object>> ExecuteScriptString(
381381
string scriptString)
382382
{
383-
return this.ExecuteScriptString(scriptString, false);
383+
return this.ExecuteScriptString(scriptString, false, true);
384384
}
385385

386386
/// <summary>
387387
/// Executes a script string in the session's runspace.
388388
/// </summary>
389389
/// <param name="scriptString">The script string to execute.</param>
390390
/// <param name="writeInputToHost">If true, causes the script string to be written to the host.</param>
391+
/// <param name="writeOutputToHost">If true, causes the script output to be written to the host.</param>
391392
/// <returns>A Task that can be awaited for the script completion.</returns>
392393
public async Task<IEnumerable<object>> ExecuteScriptString(
393394
string scriptString,
394-
bool writeInputToHost)
395+
bool writeInputToHost,
396+
bool writeOutputToHost)
395397
{
396398
if (writeInputToHost)
397399
{
@@ -404,7 +406,7 @@ public async Task<IEnumerable<object>> ExecuteScriptString(
404406
PSCommand psCommand = new PSCommand();
405407
psCommand.AddScript(scriptString);
406408

407-
return await this.ExecuteCommand<object>(psCommand, true);
409+
return await this.ExecuteCommand<object>(psCommand, writeOutputToHost);
408410
}
409411

410412
/// <summary>

0 commit comments

Comments
 (0)