11// Copyright (c) Microsoft Corporation.
22// Licensed under the MIT License.
33
4+ using System . Management . Automation ;
5+ using System . Management . Automation . Language ;
6+ using System . Threading ;
7+ using System . Threading . Tasks ;
48using Microsoft . Extensions . Logging ;
59using Microsoft . PowerShell . EditorServices . Services ;
610using Microsoft . PowerShell . EditorServices . Services . DebugAdapter ;
1317using OmniSharp . Extensions . DebugAdapter . Protocol . Events ;
1418using OmniSharp . Extensions . DebugAdapter . Protocol . Requests ;
1519using OmniSharp . Extensions . DebugAdapter . Protocol . Server ;
16- using System . Management . Automation ;
17- using System . Management . Automation . Language ;
18- using System . Threading ;
19- using System . Threading . Tasks ;
2020
2121namespace Microsoft . PowerShell . EditorServices . Handlers
2222{
@@ -77,7 +77,10 @@ public Task<ConfigurationDoneResponse> Handle(ConfigurationDoneArguments request
7777
7878 if ( ! string . IsNullOrEmpty ( _debugStateService . ScriptToLaunch ) )
7979 {
80- LaunchScriptAsync ( _debugStateService . ScriptToLaunch ) . HandleErrorsAsync ( _logger ) ;
80+ // NOTE: This is an unawaited task because responding to "configuration done" means
81+ // setting up the debugger, and in our case that means starting the script but not
82+ // waiting for it to finish.
83+ Task _ = LaunchScriptAsync ( _debugStateService . ScriptToLaunch ) . HandleErrorsAsync ( _logger ) ;
8184 }
8285
8386 if ( _debugStateService . IsInteractiveDebugSession && _debugService . IsDebuggerStopped )
@@ -102,48 +105,18 @@ public Task<ConfigurationDoneResponse> Handle(ConfigurationDoneArguments request
102105
103106 private async Task LaunchScriptAsync ( string scriptToLaunch )
104107 {
105- // Is this an untitled script?
106- if ( ScriptFile . IsUntitledPath ( scriptToLaunch ) )
107- {
108- ScriptFile untitledScript = _workspaceService . GetFile ( scriptToLaunch ) ;
109-
110- if ( BreakpointApiUtils . SupportsBreakpointApis ( _runspaceContext . CurrentRunspace ) )
111- {
112- // Parse untitled files with their `Untitled:` URI as the file name which will cache the URI & contents within the PowerShell parser.
113- // By doing this, we light up the ability to debug Untitled files with breakpoints.
114- // This is only possible via the direct usage of the breakpoint APIs in PowerShell because
115- // Set-PSBreakpoint validates that paths are actually on the filesystem.
116- ScriptBlockAst ast = Parser . ParseInput ( untitledScript . Contents , untitledScript . DocumentUri . ToString ( ) , out Token [ ] tokens , out ParseError [ ] errors ) ;
117-
118- // This seems to be the simplest way to invoke a script block (which contains breakpoint information) via the PowerShell API.
119- //
120- // TODO: Fix this so the added script doesn't show up.
121- var cmd = new PSCommand ( ) . AddScript ( ". $args[0]" ) . AddArgument ( ast . GetScriptBlock ( ) ) ;
122- await _executionService
123- . ExecutePSCommandAsync < object > ( cmd , CancellationToken . None , s_debuggerExecutionOptions )
124- . ConfigureAwait ( false ) ;
125- }
126- else
127- {
128- await _executionService
129- . ExecutePSCommandAsync (
130- new PSCommand ( ) . AddScript ( untitledScript . Contents ) ,
131- CancellationToken . None ,
132- s_debuggerExecutionOptions )
133- . ConfigureAwait ( false ) ;
134- }
135- }
136- else
137- {
138- // TODO: Fix this so the added script doesn't show up.
139- await _executionService
140- . ExecutePSCommandAsync (
141- PSCommandHelpers . BuildCommandFromArguments ( scriptToLaunch , _debugStateService . Arguments ) ,
142- CancellationToken . None ,
143- s_debuggerExecutionOptions )
144- . ConfigureAwait ( false ) ;
145- }
108+ // TODO: Theoretically we can make PowerShell respect line breakpoints in untitled
109+ // files, but the previous method was a hack that conflicted with correct passing of
110+ // arguments to the debugged script. We are prioritizing the latter over the former, as
111+ // command breakpoints and `Wait-Debugger` work fine.
112+ string command = ScriptFile . IsUntitledPath ( scriptToLaunch )
113+ ? string . Concat ( "{ " , _workspaceService . GetFile ( scriptToLaunch ) . Contents , " }" )
114+ : string . Concat ( '"' , scriptToLaunch , '"' ) ;
146115
116+ await _executionService . ExecutePSCommandAsync (
117+ PSCommandHelpers . BuildCommandFromArguments ( command , _debugStateService . Arguments ) ,
118+ CancellationToken . None ,
119+ s_debuggerExecutionOptions ) . ConfigureAwait ( false ) ;
147120 _debugAdapterServer . SendNotification ( EventNames . Terminated ) ;
148121 }
149122 }
0 commit comments