-
Notifications
You must be signed in to change notification settings - Fork 237
Open
Labels
Description
In the debugger code we currently go to great lengths to find and execute a type conversion attribute on variables:
PowerShellEditorServices/src/PowerShellEditorServices/Services/DebugAdapter/DebugService.cs
Lines 489 to 522 in f9bde73
// We have the PSVariable object for the variable the user wants to set and an object to assign to that variable. | |
// The last step is to determine whether the PSVariable is "strongly typed" which may require a conversion. | |
// If it is not strongly typed, we simply assign the object directly to the PSVariable potentially changing its type. | |
// Turns out ArgumentTypeConverterAttribute is not public. So we call the attribute through it's base class - | |
// ArgumentTransformationAttribute. | |
var argTypeConverterAttr = | |
psVariable.Attributes | |
.OfType<ArgumentTransformationAttribute>() | |
.FirstOrDefault(a => a.GetType().Name.Equals("ArgumentTypeConverterAttribute")); | |
if (argTypeConverterAttr != null) | |
{ | |
// PSVariable is strongly typed. Need to apply the conversion/transform to the new value. | |
psCommand.Commands.Clear(); | |
psCommand = new PSCommand(); | |
psCommand.AddCommand(@"Microsoft.PowerShell.Utility\Get-Variable"); | |
psCommand.AddParameter("Name", "ExecutionContext"); | |
psCommand.AddParameter("ValueOnly"); | |
errorMessages.Clear(); | |
var getExecContextResults = | |
await this.powerShellContext.ExecuteCommandAsync<object>( | |
psCommand, | |
errorMessages, | |
sendErrorToHost: false).ConfigureAwait(false); | |
EngineIntrinsics executionContext = getExecContextResults.OfType<EngineIntrinsics>().FirstOrDefault(); | |
var msg = $"Setting variable '{name}' using conversion to value: {psobject ?? "<null>"}"; | |
this.logger.LogTrace(msg); | |
psVariable.Value = argTypeConverterAttr.Transform(executionContext, psobject); | |
} |
Most of this can't be avoided, but one thing we do here is use the EngineIntrinsics value to execute the conversion attribute on the pipeline thread, which means we need to contend for and wait on a pipeline thread execution.
Instead of this, we could maybe call LanguagePrimitives.ConvertTo()
with the known target type and ideally not need to use the pipeline thread.
This might not be possible, but is worth investigating...